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 d12d189..c9d3e3d 100644 --- a/src/js/level1.js +++ b/src/js/level1.js @@ -34,9 +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', 'leftDown', { x: 400, y: 500 }); - // this.pathManager.addLineFrom('center', 'rightDown', { x: 600, y: 150 }); + this.pathManager.addLineFrom("center", "right", { x: 600, y: 400 }); + this.pathManager.addLineFrom("center", "down", { x: 400, y: 500 }); } createIncrementalCommands() { @@ -121,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() { @@ -137,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, @@ -145,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();