Files
kiss-vscode/projects/flixel-desktop-habit-puzzle-game/source/HabitState.kiss

220 lines
9.8 KiB
Plaintext

(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))
(var KEYBOARD_SCROLL_SPEED 200)
(method &override :Void update [:Float elapsed]
(super.update elapsed)
(pieceCamera.updateScrollWheelZoom elapsed 1)
(pieceCamera.updateMouseBorderControl elapsed KEYBOARD_SCROLL_SPEED 0.15)
// 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 :FlxSave save null)
(prop &mut :FlxTypedGroup<FlxText> entryTexts null)
(prop &mut :FlxKeyShortcutHandler<Entry> shortcutHandler null)
(prop &mut :HabitModel model null)
(prop EDGE_LEEWAY 25)
(prop BUBBLE_SIZE 15)
(var PUZZLE_WIDTH 6)
(var PUZZLE_HEIGHT 5)
(var TOTAL_PIECES (* PUZZLE_WIDTH PUZZLE_HEIGHT))
(prop &mut :FlxTypedGroup<FlxExtendedSprite> rewardSprites null)
(prop &mut :Map<Int,FlxExtendedSprite> matchingPiecesLeft (new Map))
(prop &mut :Map<Int,FlxExtendedSprite> matchingPiecesRight (new Map))
(prop &mut :Map<Int,FlxExtendedSprite> matchingPiecesUp (new Map))
(prop &mut :Map<Int,FlxExtendedSprite> matchingPiecesDown (new Map))
(prop &mut :Map<Int,Array<FlxExtendedSprite>> connectedPieces (new Map))
(prop &mut rewardFileIndex 0)
(prop &mut maxRewardFile 0)
(var SCROLL_BOUND_MARGIN 200)
(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))))
(set save (new FlxSave))
(save.bind currentRewardFile.path)
(unless save.data.storedPositions
(set save.data.storedPositions (new Map<Int,FlxPoint>)))
(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))
(doFor map [matchingPiecesLeft matchingPiecesRight matchingPiecesUp matchingPiecesDown]
(map.clear))
(connectedPieces.clear)
(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 BUBBLE_SIZE PUZZLE_HEIGHT PUZZLE_WIDTH r)
PIECE_WIDTH
(/ rewardSprite.width PUZZLE_WIDTH)
PIECE_HEIGHT
(/ rewardSprite.height PUZZLE_HEIGHT)
:Array<FlxPoint> startingPoints []]
(let [&mut i 0]
(doFor y (range PUZZLE_HEIGHT)
(doFor x (range PUZZLE_WIDTH)
(startingPoints.push
(new FlxPoint (+ rewardSprite.x (* x PIECE_WIDTH)) (+ rewardSprite.y (* y PIECE_HEIGHT))))
(+= i 1))))
(r.shuffle startingPoints)
(set jigsaw j)
(r.shuffle jigsaw.jigs)
(localVar spriteGrid (for y (range PUZZLE_HEIGHT) (for x (range PUZZLE_WIDTH) null)))
(localVar indexGrid (for y (range PUZZLE_HEIGHT) (for x (range PUZZLE_WIDTH) 0)))
(doFor i (range (min TOTAL_PIECES (- p currentRewardFile.startingPoints)))
(let [jig (nth jigsaw.jigs i)
pos (ifLet [point (dictGet (the Map<Int,FlxPoint> save.data.storedPositions) i)]
point
(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)]
(setNth spriteGrid jig.row jig.col s)
(setNth indexGrid jig.row jig.col i)
(set s.draggable true)
(s.enableMouseDrag false true)
(set s.mouseStopDragCallback
->:Void [s x y]
{
// TODO check for matches (in a function that is also called once at generation)
(pieceCamera.calculateScrollBounds rewardSprites SCROLL_BOUND_MARGIN)
(dictSet (the Map<Int,FlxPoint> save.data.storedPositions) i (new FlxPoint s.x s.y))
(save.flush)
})
(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)))
(doFor row (range PUZZLE_HEIGHT)
(doFor col (range PUZZLE_WIDTH)
(let [id (nth indexGrid row col)]
(try (let [toLeft (nth spriteGrid row (- col 1))]
(dictSet matchingPiecesLeft id toLeft)) (catch [e] null))
(try (let [toRight (nth spriteGrid row (+ col 1))]
(dictSet matchingPiecesRight id toRight)) (catch [e] null))
(try (let [toUp (nth spriteGrid (- row 1) col)]
(dictSet matchingPiecesUp id toUp)) (catch [e] null))
(try (let [toDown (nth spriteGrid (+ row 1) col)]
(dictSet matchingPiecesDown id toDown)) (catch [e] null)))))
(add rewardSprites))))
(pieceCamera.calculateScrollBounds rewardSprites SCROLL_BOUND_MARGIN)
(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)))