CameraTools/GroupTools bugfixing and sprite scale support

This commit is contained in:
2022-08-02 02:24:22 +00:00
parent 744f99bc46
commit 9e8036deb2
6 changed files with 192 additions and 152 deletions

View File

@@ -5,9 +5,13 @@
(prop &mut :FlxCamera uiCamera) (prop &mut :FlxCamera uiCamera)
(method &override :Void create [] (method &override :Void create []
(#when debug
(add cameraBounds))
(add logTexts) (add logTexts)
(set Prelude.printStr log) (set Prelude.printStr log)
(set pieceCamera FlxG.camera) (set pieceCamera FlxG.camera)
(set cameraBounds.cameras [pieceCamera])
(set uiCamera (new FlxCamera)) (set uiCamera (new FlxCamera))
(set uiCamera.bgColor FlxColor.TRANSPARENT) (set uiCamera.bgColor FlxColor.TRANSPARENT)
(pieceCamera.copyFrom FlxG.camera) (pieceCamera.copyFrom FlxG.camera)
@@ -23,10 +27,19 @@
(prop &mut :EntryType typeAdding Todo) (prop &mut :EntryType typeAdding Todo)
(prop &mut :FlxInputText entryNameText) (prop &mut :FlxInputText entryNameText)
(prop :FlxSprite cameraBounds (new FlxSprite))
(method &override :Void update [:Float elapsed] (method &override :Void update [:Float elapsed]
(super.update elapsed) (super.update elapsed)
(pieceCamera.updateScrollWheelZoom elapsed 1) (#when debug
(let [b (pieceCamera.getScrollBounds)]
(set cameraBounds.x b.x)
(set cameraBounds.y b.y)
(cameraBounds.makeGraphic (Std.int b.width) (Std.int b.height) FlxColor.TRANSPARENT true)
(cameraBounds.drawRect 0 0 b.width b.height FlxColor.TRANSPARENT (object color FlxColor.LIME thickness 5))))
(pieceCamera.updateScrollWheelZoom elapsed 5)
(pieceCamera.updateMouseBorderControl elapsed KEYBOARD_SCROLL_SPEED 0.002 uiCamera) (pieceCamera.updateMouseBorderControl elapsed KEYBOARD_SCROLL_SPEED 0.002 uiCamera)
// Hold left-click to hide the habit text and see the image clearly: // Hold left-click to hide the habit text and see the image clearly:
@@ -42,7 +55,7 @@
(set save.data.backgroundIndex #{(save.data.backgroundIndex + 1) % backgroundOptions.length;}#) (set save.data.backgroundIndex #{(save.data.backgroundIndex + 1) % backgroundOptions.length;}#)
(save.flush) (save.flush)
// setModel so the entry text gets remade in inverted/lightened colors when necessary // setModel so the entry text gets remade in inverted/lightened colors when necessary
(setModel model (nth model.rewardFiles rewardFileIndex)))) (refreshModel)))
(method startAdding [:EntryType type] (method startAdding [:EntryType type]
(set typeAdding type) (set typeAdding type)
@@ -54,8 +67,9 @@
(when FlxG.keys.justPressed.ENTER (when FlxG.keys.justPressed.ENTER
(cond (cond
(entryNameText (entryNameText
// addEntry() calls save()
(model.addEntry typeAdding [entryNameText.text]) (model.addEntry typeAdding [entryNameText.text])
(setModel model (nth model.rewardFiles rewardFileIndex)) (refreshModel)
(entryNameText.kill) (entryNameText.kill)
(set entryNameText null)) (set entryNameText null))
(true (true
@@ -79,11 +93,11 @@
(when FlxG.keys.justPressed.LEFT (when FlxG.keys.justPressed.LEFT
(unless (= rewardFileIndex 0) (unless (= rewardFileIndex 0)
(-= rewardFileIndex 1) (-= rewardFileIndex 1)
(setModel model (nth model.rewardFiles rewardFileIndex)))) (refreshModel)))
(when FlxG.keys.justPressed.RIGHT (when FlxG.keys.justPressed.RIGHT
(unless (= rewardFileIndex maxRewardFile) (unless (= rewardFileIndex maxRewardFile)
(+= rewardFileIndex 1) (+= rewardFileIndex 1)
(setModel model (nth model.rewardFiles rewardFileIndex))))) (refreshModel))))
// Handle keyboard input: // Handle keyboard input:
(when (and shortcutHandler !entryNameText) (when (and shortcutHandler !entryNameText)
(shortcutHandler.update))) (shortcutHandler.update)))
@@ -110,6 +124,7 @@
(prop &mut :Map<FlxExtendedSprite,Int> indexMap (new Map)) (prop &mut :Map<FlxExtendedSprite,Int> indexMap (new Map))
(prop &mut :Map<Int,FlxExtendedSprite> spriteMap (new Map)) // Because rewardSprites will be re-ordered in depth handling, this is required (prop &mut :Map<Int,FlxExtendedSprite> spriteMap (new Map)) // Because rewardSprites will be re-ordered in depth handling, this is required
(prop &mut lastRewardFileIndex -1)
(prop &mut rewardFileIndex 0) (prop &mut rewardFileIndex 0)
(prop &mut maxRewardFile 0) (prop &mut maxRewardFile 0)
@@ -144,6 +159,7 @@
(set save.data.backgroundIndex 0)) (set save.data.backgroundIndex 0))
(set pieceCamera.bgColor (nth backgroundOptions save.data.backgroundIndex)) (set pieceCamera.bgColor (nth backgroundOptions save.data.backgroundIndex))
(unless (= lastRewardFileIndex rewardFileIndex)
(let [rewardSprite (let [rewardSprite
(new FlxSprite 0 0 (new FlxSprite 0 0
(BitmapData.fromFile (BitmapData.fromFile
@@ -226,10 +242,9 @@
(dictSet (the Map<Int,FlxPoint> save.data.storedPositions) i (new FlxPoint s.x s.y)) (dictSet (the Map<Int,FlxPoint> save.data.storedPositions) i (new FlxPoint s.x s.y))
(doFor connected (recursivelyConnectedPieces s) (doFor connected (recursivelyConnectedPieces s)
(checkMatches (dictGet indexMap connected)) (checkMatches (dictGet indexMap connected))
(log "uh $(dictGet indexMap connected)")
(dictSet (the Map<Int,FlxPoint> save.data.storedPositions) (dictGet indexMap connected) (new FlxPoint connected.x connected.y))) (dictSet (the Map<Int,FlxPoint> save.data.storedPositions) (dictGet indexMap connected) (new FlxPoint connected.x connected.y)))
(pieceCamera.calculateScrollBounds rewardSprites SCROLL_BOUND_MARGIN) (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN)
(save.flush) (save.flush)
}) })
@@ -264,9 +279,10 @@
(dictSet matchingPiecesDown id toDown)) (catch [e] null))))) (dictSet matchingPiecesDown id toDown)) (catch [e] null)))))
(add rewardSprites) (add rewardSprites)
(doFor i (range TOTAL_PIECES) (doFor i (range TOTAL_PIECES)
(checkMatches i)))) (checkMatches i)))))
(set lastRewardFileIndex rewardFileIndex)
(pieceCamera.calculateScrollBounds rewardSprites SCROLL_BOUND_MARGIN) (pieceCamera.calculateScrollBounds rewardSprites uiCamera SCROLL_BOUND_MARGIN)
(when entryTexts (remove entryTexts)) (when entryTexts (remove entryTexts))
(set entryTexts (new FlxTypedGroup)) (set entryTexts (new FlxTypedGroup))
@@ -307,6 +323,10 @@
(shortcutHandler.start))) (shortcutHandler.start)))
(shortcutHandler.start)) (shortcutHandler.start))
(method refreshModel [&opt m]
(let [m (or m model)]
(setModel m (nth m.rewardFiles rewardFileIndex))))
(prop &mut textY 0) (prop &mut textY 0)
// Color currently used for making text, may be inverted or lightened to contrast with background: // Color currently used for making text, may be inverted or lightened to contrast with background:
(prop &mut :FlxColor _color FlxColor.BLACK) (prop &mut :FlxColor _color FlxColor.BLACK)
@@ -361,8 +381,8 @@
(prop &mut c 0) (prop &mut c 0)
(method :Void connectPiece [id self toSprite] (method :Void connectPiece [id self toSprite]
(let [thisConnectedPieces (dictGet connectedPieces ~id) (let [thisConnectedPieces (dictGet connectedPieces id)
toConnectedPieces (dictGet connectedPieces ~(dictGet indexMap toSprite))] toConnectedPieces (dictGet connectedPieces (dictGet indexMap toSprite))]
(+= c 1) (+= c 1)
// Don't add duplicates // Don't add duplicates
(thisConnectedPieces.remove toSprite) (thisConnectedPieces.remove toSprite)
@@ -388,13 +408,13 @@
(unless .isEmpty (mzl.intersection mzr) (unless .isEmpty (mzl.intersection mzr)
(connectPiece id s toRight))) (connectPiece id s toRight)))
(whenLet [toUp (dictGet matchingPiecesUp id) (whenLet [toUp (dictGet matchingPiecesUp id)
mzu ~(matchZoneUp s) mzu (matchZoneUp s)
mzd ~(matchZoneDown toUp)] mzd (matchZoneDown toUp)]
(unless .isEmpty (mzu.intersection mzd) (unless .isEmpty (mzu.intersection mzd)
(connectPiece id s toUp))) (connectPiece id s toUp)))
(whenLet [toDown (dictGet matchingPiecesDown id) (whenLet [toDown (dictGet matchingPiecesDown id)
mzd ~(matchZoneDown s) mzd (matchZoneDown s)
mzu ~(matchZoneUp toDown)] mzu (matchZoneUp toDown)]
(unless .isEmpty (mzu.intersection mzd) (unless .isEmpty (mzu.intersection mzd)
(connectPiece id s toDown))))) (connectPiece id s toDown)))))

View File

@@ -19,12 +19,11 @@ class Main extends Sprite
}; };
function reloadModel(_) { function reloadModel(_) {
if (t.draggingSprite == null) { if (t.draggingSprite == null) {
// TODO don't change camera position and zoom when this happens: t.refreshModel(new HabitModel(habitFile));
t.setModel(new HabitModel(habitFile));
t.model.save(); t.model.save();
} }
} }
reloadModel(null); t.setModel(new HabitModel(habitFile));
new FlxTimer().start(30, reloadModel, 0); new FlxTimer().start(30, reloadModel, 0);
} }

View File

@@ -7,6 +7,7 @@ import flash.display.BitmapData;
import flixel.FlxCamera; import flixel.FlxCamera;
import flixel.math.FlxVector; import flixel.math.FlxVector;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.FlxSprite; import flixel.FlxSprite;
import flixel.FlxG; import flixel.FlxG;
import flixel.util.FlxColor; import flixel.util.FlxColor;

View File

@@ -76,20 +76,36 @@
(<= (- bottom margin) mPos.y) (<= (- bottom margin) mPos.y)
(<= (- bottom margin) mPos.y bottom))))) (<= (- bottom margin) mPos.y bottom)))))
(function updateScrollWheelZoom [:FlxCamera camera :Float elapsed :Float speed] // GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
#{ (function updateScrollWheelZoom [:FlxCamera camera :Float elapsed :Float speed &opt :FlxCamera screenCamera]
if (FlxG.mouse.wheel != 0) { (case FlxG.mouse.wheel
camera.zoom += (FlxG.mouse.wheel * elapsed * speed); (0 null)
} (v
}#) (let [deltaZoom (* camera.zoom v elapsed speed)
scrollPosition (camera.scroll.copyTo)
mouseWorldPosition (FlxG.mouse.getWorldPosition camera)]
(+= camera.zoom deltaZoom)
(let [newMouseWorldPosition (FlxG.mouse.getWorldPosition camera)
deltaMousePosition (newMouseWorldPosition.subtractPoint mouseWorldPosition)]
(camera.scroll.subtractPoint deltaMousePosition))
// Undo any scrolling that expands the viewport past its bounds
**(unless (.containsPoint (getScrollBounds camera) camera.scroll)
(-= camera.zoom deltaZoom)
(set camera.scroll scrollPosition))))
(otherwise null)))
(function calculateScrollBounds <>[:FlxObject T] [:FlxCamera camera :FlxTypedGroup<T> group &opt :Float margin] (function getScrollBounds [:FlxCamera camera]
(let [r (GroupTools.calculateBounds group margin)] (.fromTwoPoints (new FlxRect) (new FlxPoint camera.minScrollX camera.minScrollY) (new FlxPoint camera.maxScrollX camera.maxScrollY)))
(camera.setScrollBoundsRect r.x r.y r.width r.height)))
(function extendScrollBounds [:FlxCamera camera :FlxObject object &opt :Float margin] // GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
(function calculateScrollBounds <>[:FlxSprite T] [:FlxCamera camera :FlxTypedGroup<T> group &opt :FlxCamera screenCamera :Float margin]
(let [r (GroupTools.calculateScreenBounds group screenCamera margin)]
(camera.setScrollBoundsRect r.x r.y ~r.width ~r.height)))
// GOTCHA: if you change FlxG.camera to a moving camera, you MUST provide a default camera for FlxG.mouse.getScreenPosition()
(function extendScrollBounds [:FlxCamera camera :FlxSprite sprite &opt :FlxCamera screenCamera :Float margin]
// if the given object is out of bounds, extend the bounds // if the given object is out of bounds, extend the bounds
(let [r (object.getRotatedBounds)] (let [r (sprite.getScreenBounds camera)]
(setMin camera.minScrollX (- r.left margin)) (setMin camera.minScrollX (- r.left margin))
(setMin camera.minScrollY (- r.top margin)) (setMin camera.minScrollY (- r.top margin))
(setMax camera.maxScrollX (+ r.right margin)) (setMax camera.maxScrollX (+ r.right margin))

View File

@@ -6,7 +6,9 @@ import flixel.FlxObject;
import flixel.FlxState; import flixel.FlxState;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.FlxCamera;
import flixel.group.FlxGroup; import flixel.group.FlxGroup;
import flixel.FlxSprite;
@:build(kiss.Kiss.build()) @:build(kiss.Kiss.build())
class GroupTools {} class GroupTools {}

View File

@@ -8,20 +8,22 @@
(group.remove obj) (group.remove obj)
(group.insert 0 obj))) (group.insert 0 obj)))
(function :FlxRect calculateBounds <>[:FlxObject T] [:FlxTypedGroup<T> group &opt :Float margin] (function :FlxRect calculateScreenBounds <>[:FlxSprite T] [:FlxTypedGroup<T> group &opt :FlxCamera camera :Float margin]
(unless margin (set margin 0)) (unless margin (set margin 0))
(let [&mut minX 0 (let [s (group.getFirstAlive)
&mut maxX 0 r (new FlxRect)
&mut minY 0 bounds (s.getScreenBounds r camera)
&mut maxY 0 &mut minX bounds.left
r (new FlxRect)] &mut maxX bounds.right
&mut minY bounds.top
&mut maxY bounds.bottom]
(group.forEach ->object (group.forEach ->sprite
(let [bounds (object.getRotatedBounds r)] (let [bounds (sprite.getScreenBounds r camera)]
(set minX (min minX bounds.left)) (setMin minX bounds.left)
(set minY (min minY bounds.top)) (setMin minY bounds.top)
(set maxX (max maxX bounds.right)) (setMax maxX bounds.right)
(set maxY (max maxY bounds.bottom)))) (setMax maxY bounds.bottom)))
(r.fromTwoPoints (r.fromTwoPoints
(new FlxPoint (- minX margin) (- minY margin)) (new FlxPoint (- minX margin) (- minY margin))