Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/js/SceneClasses/AnimationExecutor.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export default class AnimationExecutor {
originalPosition = { x: 400, y: 300 };
constructor(scene, pathManager) {
this.scene = scene;
this.pathManager = pathManager;
Expand Down Expand Up @@ -126,6 +127,8 @@ export default class AnimationExecutor {
//TODO: Implement loading the sprites.
//RN, we just draw follower as a colored circle
//The code below is to demonstrate how we could switch the candy view

// TODO: Make sure the same candy doesn't show up after success
let color = 0xff0000; // Default red
if (candyType.includes('blue')) color = 0x0000ff;
else if (candyType.includes('green')) color = 0x00ff00;
Expand All @@ -138,6 +141,8 @@ export default class AnimationExecutor {
reset() {
this.commandQueue = [];
this.isAnimating = false;
this.followerPosition = this.pathManager.getCurrentPosition();
this.followerPosition = this.originalPosition
// console.log(this.followerPosition)
// console.log("testing from reset")
}
}
234 changes: 87 additions & 147 deletions src/js/level1.js
Original file line number Diff line number Diff line change
@@ -1,175 +1,115 @@
import Candy, {Colors, Shapes, Patterns } from './candy.js';
export default class Level1 extends Phaser.Scene {
import PathManager from "./SceneClasses/PathManager.js";
import AnimationExecutor from "./SceneClasses/AnimationExecutor.js";
import CommandManager from "./SceneClasses/CommandManager.js";

export default class Level1 extends Phaser.Scene {
graphics;
path1;
path2;
path3;
follower;
isMoving = false;
pathManager;
animationExecutor;
commandManager;
currentLevel = "Level2";

preload() {
// Load the background image
//TO-DO: Add Texture manager: https://docs.phaser.io/phaser/concepts/textures
//Example candy implementation
const blueStripedCircle = new Candy(Colors.BLUE, Shapes.CIRCLE, Patterns.STRIPED, '../assets/candy_photos/blue_circle_striped.png');
//console.log(blueStripedCircle.imagePath === '../assets/blue_circle_striped.png');
this.load.image('background', 'assets/background.png');
this.load.image('follower', blueStripedCircle.imagePath); // Load the candy image
//this.load.image('follower', 'assets/follower.png'); // Optional: Load a follower sprite
console.log(`[${this.currentLevel}] Preloading background image.`);
}

create() {
// Initialize the editor window
C4C.Editor.Window.init(this); // Scene is passed in to this init function!
initializeEditorWindow() {
C4C.Editor.Window.init(this);
C4C.Editor.Window.open();
console.log("Text editor initialized.");

// Define interpreter commands
C4C.Interpreter.define("moveleft", () => {
//console.log("moveleft in text editor");
this.moveLeft();
});

C4C.Interpreter.define("moveright", () => {
this.moveRight();
});

document.getElementById("enableCommands").addEventListener("click", (event) => {
let programText = C4C.Editor.getText();
console.log("Program text: ", programText);
C4C.Interpreter.run(programText);
runner.setProgram(programText);
});
//C4C.Editor.setText('moveleft');
console.log(`[${this.currentLevel}] Text editor initialized.`);
}

// Add the background image
this.add.image(400, 300, 'background'); // Center the background
initializeBackgroundGraphics() {
this.add.image(400, 300, 'background');
console.log(`[${this.currentLevel}] Background image added.`);

this.graphics = this.add.graphics();
this.initializePaths();
this.initializeFollower();

// Add event listener to the button
document.getElementById("enableCommands").addEventListener("click", this.startTween);
console.log(`[${this.currentLevel}] Graphics object created.`);
}

initializePaths() {
// Create the path using 3 separate lines
const startline = new Phaser.Curves.Line([400, 0, 400, 300]);
const leftline = new Phaser.Curves.Line([400, 300, 300, 500]);
const rightline = new Phaser.Curves.Line([400, 300, 500, 500]);

this.path1 = this.add.path();
this.path1.add(startline);
/**
* idea is to move the candy to the location (from current to goal coord)
* we have something to keep track of where we are and check if we are in a valid coordinate
* - valid coordinates are defined in a data structure (map, where coords are keys and values determined if visitied)
*
*/

// Initialize map values in the constructor
constructor() {
super("Level1");
this.map = new Map();
this.key1 = [{x: 400, y: 100}];
this.val1 = [{x: 400, y: 200}];
this.key2 = [{x: 400, y: 200}];
this.val2 = [{x: 300, y: 400}];
this.map.set(this.key1, this.val1);
this.map.set(this.key2, this.val2);
}



this.path2 = this.add.path();
this.path2.add(leftline);

this.path3 = this.add.path();
this.path3.add(rightline);
createLinesForConveyerBelt() {
this.pathManager.addLine('center', { x: 400, y: 100 }, { x: 400, y: 200 });
this.pathManager.addLineFrom('left', 'center', { x: 300, y: 400 });
this.pathManager.addLineFrom('right', 'center', { x: 500, y: 400 });
this.pathManager.addLineFrom('right2', 'right', { x:600, y:500})
this.pathManager.addLineFrom('rightleft', 'right', {x:400, y:500})
}

initializeFollower() {
this.follower = { t: 0, vec: new Phaser.Math.Vector2() };
createPathsFromLines() {
this.pathManager.definePath('moveleft', ['center', 'left']);
this.pathManager.definePath('moveright', ['center', 'right']);
this.pathManager.definePath('moveright1', ['right2']);
this.pathManager.definePath('moveleft1', ['rightleft']);
}

startTween = () => {
this.follower.t = 0;
this.isMoving = true;
console.log("isMoving: ", this.isMoving);
this.tweens.add({
targets: this.follower,
t: 1,
ease: 'Linear',
duration: 1000,
onUpdate: () => {
this.path1.getPoint(this.follower.t, this.follower.vec);
},
onComplete: () => {
console.log("Start Path complete!");
this.handlePathCompletion();
}
defineInterpreterCommands() {
this.commandManager.defineCommandForPath('moveleft');
this.commandManager.defineCommandForPath('moveright');
this.commandManager.defineCommandForPath('moveright1');
this.commandManager.defineCommandForPath('moveleft1');
this.commandManager.defineCustomCommand('sampleCommand', () => {
console.log("This is an example custom command, should run immediately");
});
};

handlePathCompletion() {
// //Logic to determine the next move based on user input or pseudo code
// const nextMove = this.getNextMove(); // Implement this function to determine the next move
// if (nextMove === "left") {
// this.moveLeft();
// } else if (nextMove === "right") {
// this.moveRight();
// } else {
// this.isMoving = false;
// }
}

// getNextMove() {
// }

moveLeft = () => {
console.log("Move left function called");
this.follower.t = 1;
this.tweens.add({
targets: this.follower,
t: 2,
ease: 'Linear',
duration: 1000,
onUpdate: () => {
this.path2.getPoint(this.follower.t - 1, this.follower.vec);
},
onComplete: () => {
console.log("Left Path complete!");
this.handlePathCompletion();
}
this.commandManager.defineQueuedCustomCommand('queuedCommand', () => {
console.log("This is an example custom command that is queued according to animation, should run in animation sequence");
});
};

moveRight = () => {
console.log("Move right function called");
this.follower.t = 2.001;
this.tweens.add({
targets: this.follower,
t: 3,
ease: 'Linear',
duration: 1000,
onUpdate: () => {
this.path3.getPoint(this.follower.t - 2, this.follower.vec);
},
onComplete: () => {
console.log("Right Path complete!");
this.handlePathCompletion();
}
}

initializeRunCodeButton() {
document.getElementById("enableCommands").addEventListener("click", () => {
let programText = C4C.Editor.getText();
console.log(`[${this.currentLevel}] Run button clicked. Program text: ${programText}`);
this.animationExecutor.reset();

C4C.Interpreter.run(programText);
this.animationExecutor.executeNextCommand();
});
};
}

create() {
this.initializeEditorWindow();
this.initializeBackgroundGraphics();
this.pathManager = new PathManager(this);
this.animationExecutor = new AnimationExecutor(this, this.pathManager);
this.commandManager = new CommandManager(this, this.pathManager, this.animationExecutor);

// Set up the level
this.createLinesForConveyerBelt();
this.createPathsFromLines();
this.defineInterpreterCommands();
this.initializeRunCodeButton();
}

update() {
//Clear the graphics object
this.graphics.clear();
this.graphics.lineStyle(2, 0xffffff, 1);

//Draw the paths
this.path1.draw(this.graphics);
this.path2.draw(this.graphics);
this.path3.draw(this.graphics);

//Get the position of the follower on the path
if (this.isMoving) {
if (this.follower.t <= 1) {
this.path1.getPoint(this.follower.t, this.follower.vec);
} else if (this.follower.t > 1 && this.follower.t <= 2) {
this.path2.getPoint(this.follower.t - 1, this.follower.vec);
} else if (this.follower.t > 2 && this.follower.t <= 3) {
this.path3.getPoint(this.follower.t - 2, this.follower.vec);
}
}

//Draw the follower as a red square
this.graphics.fillStyle(0xff0000, 1);
this.graphics.fillRect(this.follower.vec.x - 8, this.follower.vec.y - 8, 16, 16);
this.graphics.lineStyle(4, 0xffffff, 1);

this.pathManager.drawAll(this.graphics);
this.animationExecutor.drawFollower(this.graphics);
}
}

//For debugging for casey later...
// const canvas = document.getElementById('my-custom-canvas');
// if (canvas) {console.log("Found?");} else { console.log("Not found?"); }
15 changes: 11 additions & 4 deletions src/js/level2.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default class Level2 extends Phaser.Scene {
initializeEditorWindow() {
C4C.Editor.Window.init(this);
C4C.Editor.Window.open();
C4C.Editor.setText('moveLeft\ndumpCandy');
C4C.Editor.setText('moveDown\nmoveLeft\nmoveLeft\ndumpCandy');
console.log(`[${this.currentLevel}] Text editor initialized.`);
}

Expand All @@ -32,7 +32,7 @@ export default class Level2 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', 'right', { x: 600, y: 400 });
// this.pathManager.addLineFrom('center', 'leftDown', { x: 200, y: 350 });
// this.pathManager.addLineFrom('center', 'rightDown', { x: 600, y: 150 });
}
Expand Down Expand Up @@ -94,7 +94,13 @@ export default class Level2 extends Phaser.Scene {
console.log(`[${this.currentLevel}] Candy ${candy.type} failed! Position:`, position);
alert(`Candy ${candy.type} is not in the correct position! Try again.`);
//TODO: We should replace this with something better- this alert popup is hideous
//Make something simialr to the animationExecutor.reset() method
// we want to reset the candies position and the level too

// should reset the candy
this.animationExecutor.reset();
//console.log("testing onCandyFailed")


}

defineInterpreterCommands() {
Expand All @@ -118,7 +124,6 @@ export default class Level2 extends Phaser.Scene {
let programText = C4C.Editor.getText();
console.log(`[${this.currentLevel}] Run button clicked. Program text: ${programText}`);

this.setupLevelCandies();
this.animationExecutor.reset();

C4C.Interpreter.run(programText);
Expand All @@ -139,6 +144,8 @@ export default class Level2 extends Phaser.Scene {
this.setupLevelCandies();
this.defineInterpreterCommands();
this.initializeRunCodeButton();

console.log(this.pathManager);
}

update() {
Expand Down
2 changes: 1 addition & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ document.getElementById('level-select').addEventListener('change', (event) => {
// Add more cases for additional levels later when added
default:
scene = 'DemoLevel';
game.scene.start(scene, Level2);
game.scene.start(scene, Level1);
break;
}
});
Expand Down