(prop &mut :Jigsawx jigsaw) (prop &mut :FlxCamera pieceCamera) (prop &mut :FlxCamera uiCamera) (method &override :Void create [] (set FlxG.cameras.bgColor FlxColor.TRANSPARENT) (set pieceCamera FlxG.camera) (set uiCamera (new FlxCamera)) (pieceCamera.copyFrom FlxG.camera) (set FlxG.camera pieceCamera) (FlxG.cameras.add uiCamera) (FlxG.plugins.add (new FlxMouseControl)) (set bgColor FlxColor.TRANSPARENT) (super.create)) (method &override :Void update [:Float elapsed] (super.update elapsed) // Hold left-click to hide the habit text and see the image clearly: (when entryTexts (if FlxG.mouse.pressed (remove entryTexts) (add entryTexts))) // Left and right arrow keys can switch between unlocked puzzles (when FlxG.keys.justPressed.LEFT (unless (= rewardFileIndex 0) (-= rewardFileIndex 1) (setModel model (nth model.rewardFiles rewardFileIndex)))) (when FlxG.keys.justPressed.RIGHT (unless (= rewardFileIndex maxRewardFile) (+= rewardFileIndex 1) (setModel model (nth model.rewardFiles rewardFileIndex)))) // Handle keyboard input: (when shortcutHandler (shortcutHandler.update))) (prop &mut :FlxTypedGroup entryTexts null) (prop &mut :FlxKeyShortcutHandler shortcutHandler null) (prop &mut :HabitModel model null) (prop EDGE_LEEWAY 20) (var PUZZLE_WIDTH 4) (var PUZZLE_HEIGHT 4) (var TOTAL_PIECES (* PUZZLE_WIDTH PUZZLE_HEIGHT)) (prop &mut :FlxTypedGroup rewardSprites null) (prop &mut rewardFileIndex 0) (prop &mut maxRewardFile 0) (method setModel [m &opt :RewardFile currentRewardFile] (set model m) (set shortcutHandler (new FlxKeyShortcutHandler)) (let [p (m.totalPoints) &mut i 0 ] // Find, load, and add the current reward image as big as possible: (unless currentRewardFile (set currentRewardFile (nth m.rewardFiles 0)) (while (> p .startingPoints (nth m.rewardFiles i)) (set rewardFileIndex i) (set currentRewardFile (nth m.rewardFiles i)) (set maxRewardFile i) (if (>= ++i m.rewardFiles.length) (break)))) (when rewardSprites (remove rewardSprites)) (let [rewardSprite (new FlxSprite 0 0 (BitmapData.fromFile (joinPath (Path.directory m.textFile) currentRewardFile.path)))] (when rewardSprites (remove rewardSprites)) (rewardSprite.setGraphicSize FlxG.width 0) (rewardSprite.updateHitbox) (when (> rewardSprite.height FlxG.height) (rewardSprite.setGraphicSize 0 FlxG.height)) (rewardSprite.updateHitbox) (rewardSprite.screenCenter) (set pieceCamera.zoom rewardSprite.scale.x) (set rewardSprites (new FlxTypedGroup)) (let [r (new FlxRandom (Strings.hashCode currentRewardFile.path)) graphicWidth rewardSprite.pixels.width graphicHeight rewardSprite.pixels.height pieceAssetWidth (Std.int (/ graphicWidth PUZZLE_WIDTH)) pieceAssetHeight (Std.int (/ graphicHeight PUZZLE_HEIGHT)) j (new Jigsawx pieceAssetWidth pieceAssetHeight EDGE_LEEWAY PUZZLE_HEIGHT PUZZLE_WIDTH r) PIECE_WIDTH (/ rewardSprite.width PUZZLE_WIDTH) PIECE_HEIGHT (/ rewardSprite.height PUZZLE_HEIGHT) :Array startingPoints []] (doFor y (range PUZZLE_HEIGHT) (doFor x (range PUZZLE_WIDTH) (startingPoints.push (new FlxPoint (+ rewardSprite.x (* x PIECE_WIDTH)) (+ rewardSprite.y (* y PIECE_HEIGHT)))))) (r.shuffle startingPoints) (set jigsaw j) (doFor i (range (min TOTAL_PIECES (- p currentRewardFile.startingPoints))) (let [jig (nth jigsaw.jigs i) pos (nth startingPoints i) s (new FlxExtendedSprite pos.x pos.y) source (new FlxSprite) mask (new FlxSprite) sourceRect (new Rectangle jig.xy.x jig.xy.y jig.wh.x jig.wh.y)] (set s.draggable true) (s.enableMouseDrag false true) (source.makeGraphic (Std.int sourceRect.width) (Std.int sourceRect.height) FlxColor.TRANSPARENT true) (source.pixels.copyPixels rewardSprite.pixels sourceRect (new Point 0 0)) (mask.makeGraphic (Std.int sourceRect.width) (Std.int sourceRect.height) FlxColor.TRANSPARENT true) (drawPieceShape mask jig FlxColor.BLACK) (FlxSpriteUtil.alphaMask s source.pixels mask.pixels) (set s.cameras [pieceCamera]) (rewardSprites.add s))) (add rewardSprites)))) (when entryTexts (remove entryTexts)) (set entryTexts (new FlxTypedGroup)) (set textY 0) (set color FlxColor.ORANGE) (map (m.activeDailyEntries) makeText) (set color FlxColor.GREEN) (map (m.activeMonthlyEntries) makeText) (set color FlxColor.BLUE) (map (m.activeIntervalEntries) makeText) (set color FlxColor.WHITE) (map (m.activeBonusEntries) makeText) (set color FlxColor.YELLOW) (map (m.activeTodoEntries) makeText) (add entryTexts) (doFor e (m.allEntries) (when (HabitModel.isActive e) (let [label (HabitModel.activeLabel e)] (shortcutHandler.registerItem label.label e)))) (set shortcutHandler.onBadKey ->:Void [_ _] {}) (set shortcutHandler.onSelectItem ->:Void [:Entry e] (let [label (HabitModel.activeLabel e)] (+= label.points 1) (whenLet [(Daily days lastDayDone) e.type] (set e.type (Daily days (HabitModel.todayString)))) (whenLet [(Monthly days lastDayDone) e.type] (set e.type (Monthly days (.toString (DateTime.now))))) (whenLet [(Interval days lastDayDone) e.type] (set e.type (Interval days (.toString (DateTime.now))))) (m.save) (setModel m) (shortcutHandler.start))) (shortcutHandler.start)) (prop &mut textY 0) (prop &mut :FlxColor color FlxColor.BLACK) (method makeText [:Entry e] (let [label (HabitModel.activeLabel e) text (new FlxText 0 textY 0 (+ label.label (* label.points "+")) 16)] (set text.color color) (set text.cameras [uiCamera]) (+= textY text.height) (entryTexts.add text)))