From 57ea3aee39f5239743a9b109667153aa67838131 Mon Sep 17 00:00:00 2001 From: royd2023 Date: Mon, 2 Feb 2026 21:58:18 -0500 Subject: [PATCH 1/3] added console log whenever candy falls off path --- src/js/SceneClasses/AnimationExecutor.js | 16 ++++++++++++++++ src/js/level1.js | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/js/SceneClasses/AnimationExecutor.js b/src/js/SceneClasses/AnimationExecutor.js index f307be0..15cdbeb 100644 --- a/src/js/SceneClasses/AnimationExecutor.js +++ b/src/js/SceneClasses/AnimationExecutor.js @@ -25,6 +25,22 @@ export default class AnimationExecutor { console.log( `[AnimationExecutor] Queued movement to (${targetPosition.x}, ${targetPosition.y}). Queue size: ${this.commandQueue.length}`, ); + + let onPath = false; + // if the queued movement target is out of bounds (off the conveyer), display a popup for now + for (const value of Object.values(this.pathManager.lines)) { + console.log("Start:", value.p0.x, value.p0.y); + console.log("End:", value.p1.x, value.p1.y); + if (targetPosition.x == value.p0.x && targetPosition.y == value.p0.y || + targetPosition.x == value.p1.x && targetPosition.y == value.p1.y) { + onPath = true; + } + } + + if (!onPath) { + console.log("Candy fell of conveyer belt"); + } + } queueCandyDump() { diff --git a/src/js/level1.js b/src/js/level1.js index d12d189..c30165b 100644 --- a/src/js/level1.js +++ b/src/js/level1.js @@ -35,8 +35,7 @@ export default class Level1 extends Phaser.Scene { this.pathManager.addLine("center", { x: 400, y: 100 }, { x: 400, y: 400 }); this.pathManager.addLineFrom("center", "left", { x: 200, y: 400 }); this.pathManager.addLineFrom('center', 'right', { x: 600, y: 400 }); - this.pathManager.addLineFrom('center', 'leftDown', { x: 400, y: 500 }); - // this.pathManager.addLineFrom('center', 'rightDown', { x: 600, y: 150 }); + this.pathManager.addLineFrom('center', 'down', { x: 400, y: 500 }); } createIncrementalCommands() { From a8afa22a740fa82750cc6452ceb58ba3e8e03fcf Mon Sep 17 00:00:00 2001 From: royd2023 Date: Mon, 9 Feb 2026 19:19:10 -0500 Subject: [PATCH 2/3] popup when candy falls off functionality --- src/js/SceneClasses/AnimationExecutor.js | 33 ++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/js/SceneClasses/AnimationExecutor.js b/src/js/SceneClasses/AnimationExecutor.js index 15cdbeb..03e6718 100644 --- a/src/js/SceneClasses/AnimationExecutor.js +++ b/src/js/SceneClasses/AnimationExecutor.js @@ -25,22 +25,6 @@ export default class AnimationExecutor { console.log( `[AnimationExecutor] Queued movement to (${targetPosition.x}, ${targetPosition.y}). Queue size: ${this.commandQueue.length}`, ); - - let onPath = false; - // if the queued movement target is out of bounds (off the conveyer), display a popup for now - for (const value of Object.values(this.pathManager.lines)) { - console.log("Start:", value.p0.x, value.p0.y); - console.log("End:", value.p1.x, value.p1.y); - if (targetPosition.x == value.p0.x && targetPosition.y == value.p0.y || - targetPosition.x == value.p1.x && targetPosition.y == value.p1.y) { - onPath = true; - } - } - - if (!onPath) { - console.log("Candy fell of conveyer belt"); - } - } queueCandyDump() { @@ -168,6 +152,23 @@ export default class AnimationExecutor { ); this.executeNextCommand(); } + + // Handles if candy falls off path(s) + let onPath = false; + // if the queued movement target is out of bounds (off the conveyer), console log for now + for (const value of Object.values(this.pathManager.lines)) { + console.log("Start:", value.p0.x, value.p0.y); + console.log("End:", value.p1.x, value.p1.y); + // idk if this is the best way to check + if (end.x == value.p0.x && end.y == value.p0.y || + end.x == value.p1.x && end.y == value.p1.y) { + onPath = true; + } + } + if (!onPath) { + console.log("***** CANDY FELL OF CONVEYER BELT *****"); + alert("CANDY FELL OF CONVEYER BELT"); + } }, }); } From 134918ae77ee29a004b875629d0846cfcf31f6a6 Mon Sep 17 00:00:00 2001 From: Casey Bartman Date: Mon, 16 Feb 2026 19:11:15 -0500 Subject: [PATCH 3/3] Fixed candy on line detection, pre level helper initialization --- src/js/SceneClasses/AnimationExecutor.js | 17 ------ src/js/SceneClasses/LevelHelper.js | 16 ++--- src/js/SceneClasses/PathManager.js | 78 +++++++++++++++++++----- src/js/SceneClasses/QueueManager.js | 23 ++++++- src/js/SceneClasses/fixstuff.md | 1 + src/js/level1.js | 18 +++--- 6 files changed, 103 insertions(+), 50 deletions(-) create mode 100644 src/js/SceneClasses/fixstuff.md diff --git a/src/js/SceneClasses/AnimationExecutor.js b/src/js/SceneClasses/AnimationExecutor.js index 03e6718..f307be0 100644 --- a/src/js/SceneClasses/AnimationExecutor.js +++ b/src/js/SceneClasses/AnimationExecutor.js @@ -152,23 +152,6 @@ export default class AnimationExecutor { ); this.executeNextCommand(); } - - // Handles if candy falls off path(s) - let onPath = false; - // if the queued movement target is out of bounds (off the conveyer), console log for now - for (const value of Object.values(this.pathManager.lines)) { - console.log("Start:", value.p0.x, value.p0.y); - console.log("End:", value.p1.x, value.p1.y); - // idk if this is the best way to check - if (end.x == value.p0.x && end.y == value.p0.y || - end.x == value.p1.x && end.y == value.p1.y) { - onPath = true; - } - } - if (!onPath) { - console.log("***** CANDY FELL OF CONVEYER BELT *****"); - alert("CANDY FELL OF CONVEYER BELT"); - } }, }); } diff --git a/src/js/SceneClasses/LevelHelper.js b/src/js/SceneClasses/LevelHelper.js index f694547..7a6519e 100644 --- a/src/js/SceneClasses/LevelHelper.js +++ b/src/js/SceneClasses/LevelHelper.js @@ -2,6 +2,12 @@ // Utility class to abstract common level setup and UI logic for C4C SortingGame levels export default class LevelHelper { + constructor(setupLevelCandies, animationExecutor, queueManager) { + this.animationExecutor = animationExecutor; + this.queueManager = queueManager; + this.setupLevelCandies = setupLevelCandies; + } + static initializeEditorWindow(scene, initialText = "") { C4C.Editor.Window.init(scene); C4C.Editor.Window.open(); @@ -92,16 +98,12 @@ export default class LevelHelper { } resetBtn.addEventListener("click", () => { console.log(`[${scene.currentLevel}] Reset Level button clicked.`); - setupLevelCandies(); - animationExecutor.reset(); - if (queueManager && typeof queueManager.reset === "function") { - queueManager.reset(); - } + resetLevel(); }); } - static resetLevel(scene, setupLevelCandies, animationExecutor, queueManager) { - setupLevelCandies(); + resetLevel(scene, setupLevelCandies, animationExecutor, queueManager) { + setupLevelCandies; animationExecutor.reset(); if (queueManager && typeof queueManager.reset === "function") { queueManager.reset(); diff --git a/src/js/SceneClasses/PathManager.js b/src/js/SceneClasses/PathManager.js index 9d99444..4b59082 100644 --- a/src/js/SceneClasses/PathManager.js +++ b/src/js/SceneClasses/PathManager.js @@ -4,7 +4,7 @@ export default class PathManager { this.lines = new Map(); //Stores phaser line objects with the count of times referenced this.paths = new Map(); //Stores our paths with a count value attached to it this.currentPosition = { x: 400, y: 300 }; // Starting position - this.startingPosition = { x: 400, y: 300 }; //Remember the starting position, TODO: Grab the one frorm Animation Executor! + this.startingPosition = { x: 400, y: 300 }; //Remember the starting position, TODO: Grab the one from Animation Executor! this.incrementalCommands = new Map(); //Store increment functions this.goalPositions = new Map(); //Store goal positions for each candy type this.currentCandy = null; //Track current candy being processed @@ -18,17 +18,13 @@ export default class PathManager { } addLine(name, start, end) { - // Original console.logs removed or consolidated for clarity - // console.log('Start object:', start); - // console.log('Start.x:', start.x); - const startVec = new window.Phaser.Math.Vector2(start.x, start.y); const endVec = new window.Phaser.Math.Vector2(end.x, end.y); this.lines[name] = new window.Phaser.Curves.Line(startVec, endVec); console.log( `[PathManager] Created line: '${name}' from (${start.x}, ${start.y}) to (${end.x}, ${end.y})`, - ); // MODIFIED/ADDED + ); return this.lines[name]; } @@ -41,9 +37,6 @@ export default class PathManager { ); throw new Error(`Line ${fromLineName} not found`); } - - // console.log('fromLine:', fromLine); // Original log removed - var endPoint; if (fromLine.getPoint) { endPoint = this._getEndpointOfFromLine(fromLine); @@ -82,13 +75,13 @@ export default class PathManager { this.currentPosition = { ...newPosition }; console.log( `[PathManager] Executed '${commandName}'. Position changed from (${oldPosition.x}, ${oldPosition.y}) to (${this.currentPosition.x}, ${this.currentPosition.y})`, - ); // MODIFIED/ADDED + ); return this.currentPosition; } console.warn( `[PathManager] Incremental command '${commandName}' not found. Position remains:`, this.currentPosition, - ); // MODIFIED/ADDED + ); return this.currentPosition; } @@ -127,7 +120,7 @@ export default class PathManager { this.resetPosition(); console.log( `[PathManager] Starting next candy: ${this.currentCandy.type}. Remaining in queue: ${this.candyQueue.length}`, - ); // MODIFIED/ADDED + ); return true; } else { this.currentCandy = null; @@ -141,7 +134,7 @@ export default class PathManager { this.currentPosition = { ...this.startingPosition }; console.log( `[PathManager] Position reset to starting position: (${this.startingPosition.x}, ${this.startingPosition.y})`, - ); // MODIFIED/ADDED + ); } //Check if current candy is at its goal position @@ -169,7 +162,7 @@ export default class PathManager { console.log( `[PathManager] Checking goal for ${this.currentCandy.type} (Tolerance: ${tolerance}). Current: (${this.currentPosition.x}, ${this.currentPosition.y}) | Goal: (${goalPosition.x}, ${goalPosition.y}). Match: ${isAtGoal}`, - ); // MODIFIED/ADDED + ); return isAtGoal; } @@ -214,6 +207,61 @@ export default class PathManager { } } + /** + * Validates if the candy's current position exists on any defined path. + * @param {object} positionOfCandy - The {x, y} coordinates to validate. + * @returns {boolean} - True if the candy is safely on a conveyer line. + */ + checkCandyPositionOnLines(positionOfCandy) { + const LINE_PROXIMITY_TOLERANCE = 2; + const candyPoint = new window.Phaser.Math.Vector2( + positionOfCandy.x, + positionOfCandy.y, + ); + + // Convert lines object to array for iteration + const linesList = Object.values(this.lines); + + const isOnPath = linesList.some((curve) => { + // 1. Create a Geometric Line from the Curve's start (p0) and end (p1) + const geomLine = new window.Phaser.Geom.Line( + curve.p0.x, + curve.p0.y, + curve.p1.x, + curve.p1.y, + ); + + // 2. Use Phaser.Geom.Line.GetNearestPoint (static method) + const closestPoint = window.Phaser.Geom.Line.GetNearestPoint( + geomLine, + candyPoint, + ); + + // 3. Measure distance + const distanceToLine = window.Phaser.Math.Distance.BetweenPoints( + candyPoint, + closestPoint, + ); + + return distanceToLine <= LINE_PROXIMITY_TOLERANCE; + }); + + if (!isOnPath) { + this._logCandyOffPath(positionOfCandy); + } + + return isOnPath; + } + + _logCandyOffPath(pos) { + alert( + `[PathManager] Validation Failed: Candy at (${pos.x.toFixed(2)}, ${pos.y.toFixed(2)}) is off the path.`, + ); + console.error( + `[PathManager] Validation Failed: Candy at (${pos.x.toFixed(2)}, ${pos.y.toFixed(2)}) is off the path.`, + ); + } + /* Getters and Setters */ //Get current position getCurrentPosition() { @@ -225,7 +273,7 @@ export default class PathManager { this.currentPosition = { ...position }; console.log( `[PathManager] Position manually set to: (${this.currentPosition.x}, ${this.currentPosition.y})`, - ); // MODIFIED/ADDED + ); } //Get current candy being processed diff --git a/src/js/SceneClasses/QueueManager.js b/src/js/SceneClasses/QueueManager.js index 2a114a1..528d734 100644 --- a/src/js/SceneClasses/QueueManager.js +++ b/src/js/SceneClasses/QueueManager.js @@ -1,7 +1,17 @@ +import LevelHelper from "./LevelHelper.js"; export default class QueueManager { - constructor(pathManager, animationExecutor) { + constructor( + pathManager, + animationExecutor, + scene = null, + setupLevelCandies = null, + levelHelper, + ) { this.pathManager = pathManager; this.animationExecutor = animationExecutor; + this.scene = scene; + this.setupLevelCandies = setupLevelCandies; + this.levelHelper = levelHelper; this.queue = []; // plannedPosition represents the logical position after queued-but-not-yet-animated moves this.plannedPosition = this.pathManager.getCurrentPosition(); @@ -99,12 +109,19 @@ export default class QueueManager { this.animationExecutor.followerPosition = { x: pos.x, y: pos.y }; } // queue movement on animationExecutor (copy) - this.animationExecutor.queueMovementToPosition({ + let finalPosition = { x: cmd.targetPosition.x, y: cmd.targetPosition.y, - }); + }; + this.animationExecutor.queueMovementToPosition(finalPosition); // trigger executor to start (it will call back to us on complete) this.animationExecutor.executeNextCommand(); + let isCandyOffPath = + !this.pathManager.checkCandyPositionOnLines(finalPosition); + if (isCandyOffPath) { + this.levelHelper.resetLevel(); //ERROR HERE... levelHelper not initialized + } + break; case "dumpCandy": console.log("[QueueManager] Executing dumpCandy"); diff --git a/src/js/SceneClasses/fixstuff.md b/src/js/SceneClasses/fixstuff.md new file mode 100644 index 0000000..59f66d0 --- /dev/null +++ b/src/js/SceneClasses/fixstuff.md @@ -0,0 +1 @@ +okay so the checking if something is on the line works. The RESETTING OF THE LEVEL doesn't- I changed a bunch of stuff for that, just comment that out and refactor it later! diff --git a/src/js/level1.js b/src/js/level1.js index c30165b..c9d3e3d 100644 --- a/src/js/level1.js +++ b/src/js/level1.js @@ -34,8 +34,8 @@ export default class Level1 extends Phaser.Scene { createLinesForConveyerBelt() { this.pathManager.addLine("center", { x: 400, y: 100 }, { x: 400, y: 400 }); this.pathManager.addLineFrom("center", "left", { x: 200, y: 400 }); - this.pathManager.addLineFrom('center', 'right', { x: 600, y: 400 }); - this.pathManager.addLineFrom('center', 'down', { x: 400, y: 500 }); + this.pathManager.addLineFrom("center", "right", { x: 600, y: 400 }); + this.pathManager.addLineFrom("center", "down", { x: 400, y: 500 }); } createIncrementalCommands() { @@ -120,12 +120,7 @@ export default class Level1 extends Phaser.Scene { } resetLevel() { - LevelHelper.resetLevel( - this, - this.setupLevelCandies.bind(this), - this.animationExecutor, - this.queueManager, - ); + this.levelHelper.resetLevel(); } create() { @@ -136,6 +131,7 @@ export default class Level1 extends Phaser.Scene { this.queueManager = new QueueManager( this.pathManager, this.animationExecutor, + this.levelHelper, ); this.commandManager = new CommandManager( this, @@ -144,6 +140,12 @@ export default class Level1 extends Phaser.Scene { this.queueManager, ); + this.levelHelper = new LevelHelper( + this.setupLevelCandies, + this.animationExecutor, + this.queueManager, + ); + //Set up the level this.createLinesForConveyerBelt(); this.createIncrementalCommands();