From f3c5fdb71e9973a3c6b4e263e303a12b9e401e0a Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Tue, 16 Aug 2022 15:39:58 +0000 Subject: [PATCH] habit game fix launching with no puzzles started --- .../source/HabitState.kiss | 429 +++++++++--------- 1 file changed, 221 insertions(+), 208 deletions(-) diff --git a/projects/flixel-desktop-habit-puzzle-game/source/HabitState.kiss b/projects/flixel-desktop-habit-puzzle-game/source/HabitState.kiss index f705096a..98b6cb7b 100644 --- a/projects/flixel-desktop-habit-puzzle-game/source/HabitState.kiss +++ b/projects/flixel-desktop-habit-puzzle-game/source/HabitState.kiss @@ -39,40 +39,49 @@ (#when debug (debugLayer.clear) - (doFor s rewardSprites - null - // Uncomment for debugging piece rotation: - //(debugLayer.drawCircle s.x s.y 1 FlxColor.RED) - //(debugLayer.drawCircle (+ s.x s.origin.x) (+ s.y s.origin.y) 1 FlxColor.LIME) - // Uncomment for debugging match zones: - **(let [matchZones [(matchZoneLeft s) (matchZoneRight s)(matchZoneUp s)(matchZoneDown s)]] - (doFor z matchZones - (unless z.isEmpty - (debugLayer.drawFlxRect z FlxColor.RED)))))) + (when model.rewardFiles + (doFor s rewardSprites + null + // Uncomment for debugging piece rotation: + //(debugLayer.drawCircle s.x s.y 1 FlxColor.RED) + //(debugLayer.drawCircle (+ s.x s.origin.x) (+ s.y s.origin.y) 1 FlxColor.LIME) + // Uncomment for debugging match zones: + **(let [matchZones [(matchZoneLeft s) (matchZoneRight s)(matchZoneUp s)(matchZoneDown s)]] + (doFor z matchZones + (unless z.isEmpty + (debugLayer.drawFlxRect z FlxColor.RED))))))) - (let [zoom pieceCamera.zoom - scroll (pieceCamera.scroll.copyTo)] - (pieceCamera.updateScrollWheelZoom elapsed 5) - (pieceCamera.updateMouseBorderControl elapsed KEYBOARD_SCROLL_SPEED 0.002 uiCamera) - (when (or !(= zoom pieceCamera.zoom) !(scroll.equals pieceCamera.scroll)) - (set save.data.zoom pieceCamera.zoom) - (set save.data.scroll pieceCamera.scroll) - (save.flush))) + (when model.rewardFiles + (let [zoom pieceCamera.zoom + scroll (pieceCamera.scroll.copyTo)] + (pieceCamera.updateScrollWheelZoom elapsed 5) + (pieceCamera.updateMouseBorderControl elapsed KEYBOARD_SCROLL_SPEED 0.002 uiCamera) + (when (or !(= zoom pieceCamera.zoom) !(scroll.equals pieceCamera.scroll)) + (set save.data.zoom pieceCamera.zoom) + (set save.data.scroll pieceCamera.scroll) + (save.flush))) - (when entryWindow - (when FlxG.keys.justPressed.ESCAPE - (if (entryWindow.isShown) - (entryWindow.hide) - (entryWindow.show)))) - - (#when debug - (when FlxG.keys.justPressed.SEMICOLON - (set pieceCamera.zoom 1)) - **(when FlxG.keys.justPressed.CONTROL - (set save.data.storedPositions (new Map)) - (set save.data.storedAngles (new Map)) - (set save.data.storedOrigins (new Map)) - (save.flush))) + (when entryWindow + (when FlxG.keys.justPressed.ESCAPE + (if (entryWindow.isShown) + (entryWindow.hide) + (entryWindow.show)))) + + (when (and FlxG.keys.justPressed.SPACE !entryNameText) + (defAndCall method toggleBackgroundColor + (set save.data.backgroundIndex #{(save.data.backgroundIndex + 1) % backgroundOptions.length;}#) + (save.flush) + // setModel so the entry text gets remade in inverted/lightened colors when necessary + (refreshModel))) + + (#when debug + (when FlxG.keys.justPressed.SEMICOLON + (set pieceCamera.zoom 1)) + **(when FlxG.keys.justPressed.CONTROL + (set save.data.storedPositions (new Map)) + (set save.data.storedAngles (new Map)) + (set save.data.storedOrigins (new Map)) + (save.flush)))) (when FlxG.keys.justPressed.DELETE (Sys.exit 0)) @@ -87,12 +96,7 @@ (dictSet (the Map save.data.storedOrigins) (dictGet indexMap s) s.origin)) (save.flush))) - (when (and FlxG.keys.justPressed.SPACE !entryNameText) - (defAndCall method toggleBackgroundColor - (set save.data.backgroundIndex #{(save.data.backgroundIndex + 1) % backgroundOptions.length;}#) - (save.flush) - // setModel so the entry text gets remade in inverted/lightened colors when necessary - (refreshModel))) + (method startAdding [:EntryType type] (set typeAdding type) @@ -180,175 +184,24 @@ // 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) - (when (>= ++i m.rewardFiles.length) - --i - (let [lastStartingPoints .startingPoints (nth m.rewardFiles i) - piecesPerPoint .piecesPerPoint (nth m.rewardFiles i) - nextStartingPoints (+ lastStartingPoints (Math.ceil (/ TOTAL_PIECES piecesPerPoint)))] - (when (> p nextStartingPoints) - (set puzzleUnlocked nextStartingPoints)) - (break))))) - - (set save (new FlxSave)) - (save.bind currentRewardFile.path) - (unless save.data.storedPositions - (set save.data.storedPositions (new Map))) - (unless save.data.storedAngles - (set save.data.storedAngles (new Map))) - (unless save.data.storedOrigins - (set save.data.storedOrigins (new Map))) - (unless save.data.backgroundIndex - (set save.data.backgroundIndex 0)) - (set pieceCamera.bgColor (nth backgroundOptions save.data.backgroundIndex)) - (when save.data.zoom - (set pieceCamera.zoom save.data.zoom) - (set pieceCamera.scroll save.data.scroll)) - - (unless (and (= lastRewardFileIndex rewardFileIndex) (= lastTotalPoints (m.totalPoints))) - (set rewardSprite - (new FlxSprite 0 0 - (BitmapData.fromFile - 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) - - (unless save.data.zoom - (set pieceCamera.zoom rewardSprite.scale.x)) - - (set rewardSprites (new FlxTypedGroup)) - (doFor map [matchingPiecesLeft matchingPiecesRight matchingPiecesUp matchingPiecesDown] - (map.clear)) - (connectedPieces.clear) - (doFor i (range TOTAL_PIECES) (dictSet connectedPieces i [])) - (indexMap.clear) - - (let [r (new FlxRandom (Strings.hashCode currentRewardFile.path)) - ros (roughOptimalScale) - graphicWidth (* ros rewardSprite.pixels.width) - graphicHeight (* ros rewardSprite.pixels.height) - pieceAssetWidth (/ (- graphicWidth (* EDGE_LEEWAY 2)) PUZZLE_WIDTH) - pieceAssetHeight (/ (- graphicHeight (* EDGE_LEEWAY 2)) PUZZLE_HEIGHT) - j (new Jigsawx pieceAssetWidth pieceAssetHeight graphicWidth graphicHeight EDGE_LEEWAY BUBBLE_SIZE PUZZLE_HEIGHT PUZZLE_WIDTH r) - PIECE_WIDTH - (/ rewardSprite.width PUZZLE_WIDTH) - PIECE_HEIGHT - (/ rewardSprite.height PUZZLE_HEIGHT) - :Array startingPoints [] - :Array startingAngles []] - (let [&mut i 0] - (doFor y (range PUZZLE_HEIGHT) - (doFor x (range PUZZLE_WIDTH) - (startingAngles.push (* 90 (r.int 0 3))) - (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) -1))) - (doFor i (range (min TOTAL_PIECES (* currentRewardFile.piecesPerPoint (- p currentRewardFile.startingPoints)))) - (let [jig (nth jigsaw.jigs i) - pos (ifLet [point (dictGet (the Map save.data.storedPositions) i)] - point - (nth startingPoints i)) - angle (ifLet [angle (dictGet (the Map save.data.storedAngles) i)] - angle - (nth startingAngles i)) - s (new KissExtendedSprite pos.x pos.y) - source (new FlxSprite) - mask (new FlxSprite) - sourceRect (new Rectangle (/ jig.xy.x ros) (/ jig.xy.y ros) (/ jig.wh.x ros) (/ jig.wh.y ros))] - (set s.angle angle) - (set s.priorityID i) - (setNth spriteGrid jig.row jig.col s) - (setNth indexGrid jig.row jig.col i) - (dictSet pieceData i jig) - (dictSet indexMap s i) - (dictSet spriteMap i s) - (set s.draggable true) - (s.enableMouseDrag false true) - (set s.mouseStartDragCallback - ->:Void [s x y] - (let [s (cast s KissExtendedSprite)] - (set s.priorityID (+ 1 .priorityID (last (the kiss.List rewardSprites.members)))) - (let [connectedPieces (recursivelyConnectedPieces s)] - // Bring currently held pieces to the front: - (rewardSprites.bringAllToFront connectedPieces) - (set s.connectedSprites connectedPieces)) - (set draggingSprite s) - (set draggingLastPos (new FlxPoint s.x s.y)))) - (set s.mouseStopDragCallback - ->:Void [s x y] - (let [s (cast s KissExtendedSprite)] - (set draggingSprite null) - - (let [connectedPieces (recursivelyConnectedPieces s)] - (doFor connected connectedPieces - (checkMatches (dictGet indexMap connected))) - - (doFor connected connectedPieces - (dictSet (the Map save.data.storedPositions) (dictGet indexMap connected) (new FlxPoint connected.x connected.y)))) - - (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN) - (save.flush))) - - (var ROT_PADDING 2) - (localVar fWidth (+ (Std.int sourceRect.width) (* 2 ROT_PADDING))) - (localVar fHeight (+ (Std.int sourceRect.height) (* 2 ROT_PADDING))) - (source.makeGraphic fWidth fHeight FlxColor.TRANSPARENT true) - (source.pixels.copyPixels rewardSprite.pixels sourceRect (new Point ROT_PADDING ROT_PADDING)) - - (mask.makeGraphic fWidth fHeight FlxColor.TRANSPARENT true) - (drawPieceShape mask jig ros FlxColor.BLACK) - (FlxSpriteUtil.alphaMask s source.pixels mask.pixels) - - // Uncomment to debug piece ids and row/columns - **(#when debug - (kiss_flixel.SpriteTools.writeOnSprite "$i" 32 s (object x (Percent 0.5) y (Percent 0.5)) FlxColor.RED) - (kiss_flixel.SpriteTools.writeOnSprite "(${jig.col},${jig.row})" 32 s (object x (Percent 0.5) y (Percent 0.7)) FlxColor.RED)) - - (s.loadRotatedGraphic s.pixels 4 -1 /*false true*/) - - (set s.cameras [pieceCamera]) - - - (rewardSprites.add s))) - (doFor row (range PUZZLE_HEIGHT) - (doFor col (range PUZZLE_WIDTH) - (let [id (nth indexGrid row col)] - (when (= id -1) (continue)) - (when (>= (- col 1) 0) - (let [toLeft (nth spriteGrid row (- col 1))] - (dictSet matchingPiecesLeft id toLeft))) - (when (< (+ col 1) PUZZLE_WIDTH) - (let [toRight (nth spriteGrid row (+ col 1))] - (dictSet matchingPiecesRight id toRight))) - (when (>= (- row 1) 0) - (let [toUp (nth spriteGrid (- row 1) col)] - (dictSet matchingPiecesUp id toUp))) - (when (< (+ row 1) PUZZLE_HEIGHT) - (let [toDown (nth spriteGrid (+ row 1) col)] - (dictSet matchingPiecesDown id toDown)))))) - (add rewardSprites) - (doFor i (range TOTAL_PIECES) - (checkMatches i)))) - (set lastRewardFileIndex rewardFileIndex) - (prop &mut lastTotalPoints -1) - (set lastTotalPoints (m.totalPoints)) - - (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN) + (if m.rewardFiles + (while (> p .startingPoints (nth m.rewardFiles i)) + (set rewardFileIndex i) + (set currentRewardFile (nth m.rewardFiles i)) + (set maxRewardFile i) + (when (>= ++i m.rewardFiles.length) + --i + (let [lastStartingPoints .startingPoints (nth m.rewardFiles i) + piecesPerPoint .piecesPerPoint (nth m.rewardFiles i) + nextStartingPoints (+ lastStartingPoints (Math.ceil (/ TOTAL_PIECES piecesPerPoint)))] + (when (> p nextStartingPoints) + (set puzzleUnlocked nextStartingPoints)) + (break)))) + (set puzzleUnlocked 0))) + + (when m.rewardFiles + (makeRewardSprites m p currentRewardFile)) (localVar &mut windowWasShown true) (when entryWindow @@ -357,7 +210,8 @@ (set entryWindow (new SimpleWindow "" (FlxColor.fromRGBFloat 0 0 0 0.5) FlxColor.WHITE 0.9 0.9)) (set entryWindow.cameras [uiCamera]) (set entryWindow.textColor FlxColor.LIME) - (_makeText "Puzzle #$(+ 1 rewardFileIndex) / ${model.rewardFiles.length}" (max 0 (- TOTAL_PIECES (* currentRewardFile.piecesPerPoint (- p currentRewardFile.startingPoints))))) + (when m.rewardFiles + (_makeText "Puzzle #$(+ 1 rewardFileIndex) / ${model.rewardFiles.length}" (max 0 (- TOTAL_PIECES (* currentRewardFile.piecesPerPoint (- p currentRewardFile.startingPoints)))))) (set entryWindow.textColor FlxColor.ORANGE) (map (m.activeDailyEntries) makeText) (set entryWindow.textColor FlxColor.GREEN) @@ -369,7 +223,8 @@ (set entryWindow.textColor FlxColor.YELLOW) (map (m.activeTodoEntries) makeText) (set entryWindow.textColor FlxColor.GRAY) - (_makeText "[SPACE] Cycle background color" 0) + (when m.rewardFiles + (_makeText "[SPACE] Cycle background color" 0)) (when windowWasShown (entryWindow.show)) @@ -394,6 +249,164 @@ FlxColor.GRAY ]) +(method makeRewardSprites [m p currentRewardFile] + (set save (new FlxSave)) + (save.bind currentRewardFile.path) + (unless save.data.storedPositions + (set save.data.storedPositions (new Map))) + (unless save.data.storedAngles + (set save.data.storedAngles (new Map))) + (unless save.data.storedOrigins + (set save.data.storedOrigins (new Map))) + (unless save.data.backgroundIndex + (set save.data.backgroundIndex 0)) + (set pieceCamera.bgColor (nth backgroundOptions save.data.backgroundIndex)) + (when save.data.zoom + (set pieceCamera.zoom save.data.zoom) + (set pieceCamera.scroll save.data.scroll)) + + (unless (and (= lastRewardFileIndex rewardFileIndex) (= lastTotalPoints (m.totalPoints))) + (set rewardSprite + (new FlxSprite 0 0 + (BitmapData.fromFile + 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) + + (unless save.data.zoom + (set pieceCamera.zoom rewardSprite.scale.x)) + + (set rewardSprites (new FlxTypedGroup)) + + (doFor map [matchingPiecesLeft matchingPiecesRight matchingPiecesUp matchingPiecesDown] + (map.clear)) + (connectedPieces.clear) + (doFor i (range TOTAL_PIECES) (dictSet connectedPieces i [])) + (indexMap.clear) + + (let [r (new FlxRandom (Strings.hashCode currentRewardFile.path)) + ros (roughOptimalScale) + graphicWidth (* ros rewardSprite.pixels.width) + graphicHeight (* ros rewardSprite.pixels.height) + pieceAssetWidth (/ (- graphicWidth (* EDGE_LEEWAY 2)) PUZZLE_WIDTH) + pieceAssetHeight (/ (- graphicHeight (* EDGE_LEEWAY 2)) PUZZLE_HEIGHT) + j (new Jigsawx pieceAssetWidth pieceAssetHeight graphicWidth graphicHeight EDGE_LEEWAY BUBBLE_SIZE PUZZLE_HEIGHT PUZZLE_WIDTH r) + PIECE_WIDTH + (/ rewardSprite.width PUZZLE_WIDTH) + PIECE_HEIGHT + (/ rewardSprite.height PUZZLE_HEIGHT) + :Array startingPoints [] + :Array startingAngles []] + (let [&mut i 0] + (doFor y (range PUZZLE_HEIGHT) + (doFor x (range PUZZLE_WIDTH) + (startingAngles.push (* 90 (r.int 0 3))) + (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) -1))) + (doFor i (range (min TOTAL_PIECES (* currentRewardFile.piecesPerPoint (- p currentRewardFile.startingPoints)))) + (let [jig (nth jigsaw.jigs i) + pos (ifLet [point (dictGet (the Map save.data.storedPositions) i)] + point + (nth startingPoints i)) + angle (ifLet [angle (dictGet (the Map save.data.storedAngles) i)] + angle + (nth startingAngles i)) + s (new KissExtendedSprite pos.x pos.y) + source (new FlxSprite) + mask (new FlxSprite) + sourceRect (new Rectangle (/ jig.xy.x ros) (/ jig.xy.y ros) (/ jig.wh.x ros) (/ jig.wh.y ros))] + (set s.angle angle) + (set s.priorityID i) + (setNth spriteGrid jig.row jig.col s) + (setNth indexGrid jig.row jig.col i) + (dictSet pieceData i jig) + (dictSet indexMap s i) + (dictSet spriteMap i s) + (set s.draggable true) + (s.enableMouseDrag false true) + (set s.mouseStartDragCallback + ->:Void [s x y] + (let [s (cast s KissExtendedSprite)] + (set s.priorityID (+ 1 .priorityID (last (the kiss.List rewardSprites.members)))) + (let [connectedPieces (recursivelyConnectedPieces s)] + // Bring currently held pieces to the front: + (rewardSprites.bringAllToFront connectedPieces) + (set s.connectedSprites connectedPieces)) + (set draggingSprite s) + (set draggingLastPos (new FlxPoint s.x s.y)))) + (set s.mouseStopDragCallback + ->:Void [s x y] + (let [s (cast s KissExtendedSprite)] + (set draggingSprite null) + + (let [connectedPieces (recursivelyConnectedPieces s)] + (doFor connected connectedPieces + (checkMatches (dictGet indexMap connected))) + + (doFor connected connectedPieces + (dictSet (the Map save.data.storedPositions) (dictGet indexMap connected) (new FlxPoint connected.x connected.y)))) + + (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN) + (save.flush))) + + (var ROT_PADDING 2) + (localVar fWidth (+ (Std.int sourceRect.width) (* 2 ROT_PADDING))) + (localVar fHeight (+ (Std.int sourceRect.height) (* 2 ROT_PADDING))) + (source.makeGraphic fWidth fHeight FlxColor.TRANSPARENT true) + (source.pixels.copyPixels rewardSprite.pixels sourceRect (new Point ROT_PADDING ROT_PADDING)) + + (mask.makeGraphic fWidth fHeight FlxColor.TRANSPARENT true) + (drawPieceShape mask jig ros FlxColor.BLACK) + (FlxSpriteUtil.alphaMask s source.pixels mask.pixels) + + // Uncomment to debug piece ids and row/columns + **(#when debug + (kiss_flixel.SpriteTools.writeOnSprite "$i" 32 s (object x (Percent 0.5) y (Percent 0.5)) FlxColor.RED) + (kiss_flixel.SpriteTools.writeOnSprite "(${jig.col},${jig.row})" 32 s (object x (Percent 0.5) y (Percent 0.7)) FlxColor.RED)) + + (s.loadRotatedGraphic s.pixels 4 -1 /*false true*/) + + (set s.cameras [pieceCamera]) + + + (rewardSprites.add s))) + (doFor row (range PUZZLE_HEIGHT) + (doFor col (range PUZZLE_WIDTH) + (let [id (nth indexGrid row col)] + (when (= id -1) (continue)) + (when (>= (- col 1) 0) + (let [toLeft (nth spriteGrid row (- col 1))] + (dictSet matchingPiecesLeft id toLeft))) + (when (< (+ col 1) PUZZLE_WIDTH) + (let [toRight (nth spriteGrid row (+ col 1))] + (dictSet matchingPiecesRight id toRight))) + (when (>= (- row 1) 0) + (let [toUp (nth spriteGrid (- row 1) col)] + (dictSet matchingPiecesUp id toUp))) + (when (< (+ row 1) PUZZLE_HEIGHT) + (let [toDown (nth spriteGrid (+ row 1) col)] + (dictSet matchingPiecesDown id toDown)))))) + (add rewardSprites) + (doFor i (range TOTAL_PIECES) + (checkMatches i)))) + (set lastRewardFileIndex rewardFileIndex) + (prop &mut lastTotalPoints -1) + (set lastTotalPoints (m.totalPoints)) + + (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN)) + (method makeText [:Entry e] (let [label (HabitModel.activeLabel e)] (_makeText label.label label.points ->:Void text {