This commit is contained in:
nadiarvi 2025-05-08 18:44:08 +09:00
parent b4ddfaa6be
commit f0a7f3357b
5 changed files with 234 additions and 67 deletions

View File

@ -1,5 +1,5 @@
export class Cat {
constructor(x, y, targetSize) {
constructor(x, y, targetSize, groundRef, obstacleRefs) {
this.x = x;
this.y = y;
this.size = 171;
@ -7,6 +7,8 @@ export class Cat {
this.sprite = null;
this.loaded = false;
this.velocity = 24;
this.ground = groundRef;
this.obstacles = obstacleRefs;
this.steps = [];
@ -15,10 +17,14 @@ export class Cat {
this.stepTimer = 0;
this.stepDuration = 40; // frames to complete one movement
this.moveDirection = null;
this.lastDirection = null;
this.hasJumped = false;
loadImage('assets/cat.webp', (img) => {
this.sprite = new Sprite(this.x, this.y, this.size, this.size);
this.sprite = new Sprite(this.x, this.y, this.size, this.size, 'dynamic');
this.sprite.rotationLock = true;
this.sprite.bounciness = 0.1;
this.sprite.spriteSheet = img;
this.sprite.anis.offset.y = 3;
this.sprite.anis.frameDelay = 8;
@ -39,7 +45,6 @@ export class Cat {
}
update() {
// if (!this.sprite) return;
if (!this.sprite || this.steps.length === 0) return;
console.log(`updating sprite...`);
@ -49,27 +54,18 @@ export class Cat {
this._startMovement(this.steps[this.currentStepIndex]);
}
this.sprite.position.x = this.x;
this.sprite.position.y = this.y;
// console.log(`steps to run: ${this.steps}`);
this._handleInput();
};
update() {
if (!this.sprite || this.steps.length === 0) return;
// update() {
// if (!this.sprite || this.steps.length === 0) return;
if (this.isMoving) {
this._continueMovement();
} else if (this.currentStepIndex < this.steps.length) {
this._startMovement(this.steps[this.currentStepIndex]);
}
this.sprite.position.x = this.x;
this.sprite.position.y = this.y;
}
// if (this.isMoving) {
// this._continueMovement();
// } else if (this.currentStepIndex < this.steps.length) {
// this._startMovement(this.steps[this.currentStepIndex]);
// }
// }
run(steps) {
@ -79,33 +75,177 @@ export class Cat {
}
_startMovement(direction) {
const blockSize = 100;
this.moveDirection = direction;
this.stepTimer = 0;
this.isMoving = true;
if (direction === 'right') {
this.targetX = this.sprite.x + blockSize;
this.sprite.vel.x = this.velocity;
this.lastDirection = 'right';
this.changeAni('w');
} else if (direction === 'up' || direction === 'down') {
this.changeAni('j');
} else if (direction === 'left') {
this.targetX = this.sprite.x - blockSize;
this.sprite.vel.x = -this.velocity;
this.lastDirection = 'left';
this.changeAni('w');
} else if (direction === 'up') {
this.targetY = this.sprite.y - blockSize;
this.hasJumped = false;
// Check platform
let isOnPlatform = this._checkPlatform();
if (isOnPlatform) {
this.sprite.vel.y = -10;
if (this.lastDirection === 'right') this.sprite.vel.x = this.velocity;
else if (this.lastDirection === 'left') this.sprite.vel.x = -this.velocity;
else this.sprite.vel.x = 0;
this.changeAni('j');
}
}
}
_checkPlatform() {
if (!this.sprite) return false;
// if (this.ground && this.sprite.colliding(this.ground)) return true;
if (this.ground && Array.isArray(this.ground)) {
for (let block of this.ground) {
if (this.sprite.colliding(block)) return true;
}
}
if (this.obstacles && Array.isArray(this.obstacles)) {
for (let block of this.obstacles) {
if (this.sprite.colliding(block)) return true;
}
}
return false;
}
// _continueMovement() {
// this.stepTimer++;
// // let isOnPlatform = false;
// let isOnPlatform = this._checkPlatform(); // Use existing _checkPlatform method instead
// if (this.ground && this.sprite.colliding(this.ground)) {
// isOnPlatform = true;
// }
// if (this.obstacles && Array.isArray(this.obstacles)) {
// for (let block of this.obstacles) {
// if (this.sprite.colliding(block)) {
// isOnPlatform = true;
// break;
// }
// }
// }
// if (this.moveDirection === 'right') {
// this.sprite.vel.x = 3;
// this.lastDirection = 'right';
// }
// if (this.moveDirection === 'left') {
// this.sprite.vel.x = -3;
// this.lastDirection = 'left';
// }
// if (this.moveDirection === 'up' && isOnPlatform && !this.hasJumped) {
// this.sprite.vel.y = -20;
// // use lastDirection to add horizontal push
// if (this.lastDirection === 'right') {
// this.sprite.vel.x = 3;
// } else if (this.lastDirection === 'left') {
// this.sprite.vel.x = -3;
// } else {
// this.sprite.vel.x = 0; // jump straight up
// }
// }
// this.hasJumped = true;
// if (this.stepTimer >= this.stepDuration) {
// this.isMoving = false;
// this.currentStepIndex++;
// this.sprite.vel.x = 0;
// this.changeAni('i');
// }
// }
_continueMovement() {
this.stepTimer++;
const delta = this.velocity / this.stepDuration;
let isOnPlatform = this._checkPlatform(); // ✅ use this only
if (this.moveDirection === 'right') this.x += delta;
if (this.moveDirection === 'up') this.y -= delta;
if (this.moveDirection === 'down') this.y += delta;
if (this.moveDirection === 'right') {
this.sprite.vel.x = 3;
this.lastDirection = 'right';
}
if (this.moveDirection === 'left') {
this.sprite.vel.x = -3;
this.lastDirection = 'left';
}
if (this.moveDirection === 'up' && isOnPlatform && !this.hasJumped) {
this.sprite.vel.y = -20;
if (this.lastDirection === 'right') {
this.sprite.vel.x = 3;
} else if (this.lastDirection === 'left') {
this.sprite.vel.x = -3;
} else {
this.sprite.vel.x = 0;
}
}
this.hasJumped = true;
if (this.stepTimer >= this.stepDuration) {
this.isMoving = false;
this.currentStepIndex++;
this.changeAni('i'); // back to idle after each move
this.sprite.vel.x = 0;
this.changeAni('i');
}
}
restart() {
console.log('resetting initial position.....');
if (!this.sprite) return null;
// Reset position to initial coordinates (from constructor)
this.sprite.x = this.x;
this.sprite.y = this.y;
// Reset velocities
this.sprite.vel.x = 0;
this.sprite.vel.y = 0;
// Reset movement states
this.steps = [];
this.currentStepIndex = 0;
this.isMoving = false;
this.stepTimer = 0;
this.moveDirection = null;
this.targetX = null;
this.targetY = null;
// Reset animation
this.changeAni('i');
setTimeout(() => {
console.log('finish resetting...')
}, 1000);
}
keyPressed(key) {
console.log(`receiving keyboard input: ${key}`);
@ -154,11 +294,6 @@ export class Cat {
this.sprite = null;
}
moveUp(){
console.log(`sprite should move up...`);
this.changeAni('j')
}
// helper
_getSpritePosition(){
console.log(`sprite's actual position: ${this.sprite.x}, ${this.sprite.y}`);

View File

@ -12,7 +12,6 @@ export class ClickableArrow {
}
constructor(direction, clickable = false) {
console.log(`constructing a new clickable arrow....`);
this.direction = direction;
this.image = ClickableArrow.images[direction];
this.clickable = clickable;

View File

@ -8,7 +8,7 @@ let mgr;
function setup(){
createCanvas(windowWidth, windowHeight);
console.log(`window size: ${windowWidth}x${windowHeight}`);
world.gravity.y = 50;
textFont('Pixelify Sans', 'sans-serif');
textAlign(CENTER);
textSize(128);

View File

@ -2,16 +2,33 @@ import { colors } from '../utils/theme.js';
import { Cat } from '../cat.js';
import { buttonS } from '../utils/theme.js';
import { MyButton } from '../utils/components.js';
import { Arrow } from '../components/Arrow.js';
import { ClickableArrow } from '../components/ClickableArrow.js';
import { ControlPanel } from '../components/controlPanel.js';
export default function GameScene() {
const groundHeight = 100;
const worldHeight = windowHeight - groundHeight;
// for ground
let ground;
let blocksGround = [];
let blockSprites = [];
let restart = false;
const catSize = 150;
const worldBlockSize = 100;
const groundHeight = worldBlockSize;
// const worldHeight = windowHeight - groundHeight;
const maxIdx = {
x: Math.ceil(windowWidth / worldBlockSize),
y: Math.floor(windowHeight / worldBlockSize)
}
const obstacle = [
...Array(maxIdx.y - 3 - 1).fill(...Array(maxIdx.x).fill(0)),
[...Array(9).fill(0), ...Array(maxIdx.x - 9).fill(1)],
[...Array(8).fill(0), ...Array(maxIdx.x - 8).fill(1)],
[...Array(7).fill(0), ...Array(maxIdx.x - 7).fill(1)],
];
let cat;
let runButton;
@ -45,15 +62,13 @@ export default function GameScene() {
this.name = "GameScene";
this.setup = () => {
cat = new Cat(width / 4, height - 175 - 2, catSize);
runButton = new MyButton({
x: width / 32 * 28.5,
x: (width / 32) * 28.5,
y: height / 32,
text: "run >>",
mode: "CORNER",
style: buttonS,
onPress: () => cat.run(steps.contents),
onPress: () => this.startGame(),
});
blocks = new ControlPanel({
@ -78,6 +93,42 @@ export default function GameScene() {
// y: height / 32,
// numBoxes: 4
// });
for (let i = 0; i < width; i += worldBlockSize) {
let b = new Sprite(
i + worldBlockSize / 2, // x position for each block
height - groundHeight / 2, // y position
worldBlockSize, // width of each block
worldBlockSize, // height of each block
'static'
);
const i_cnt = Math.floor(i / worldBlockSize);
b.color = (i_cnt % 2) === 0 ? color(colors.secondary) : color(colors.darkRed);
b.strokeWeight = 5;
b.stroke = (i_cnt % 2) === 0 ? color(colors.darkRed) : color(colors.darkRed);
blocksGround.push(b);
}
// Obstacles (physical)
for (let y = windowHeight - groundHeight - 2; y > 0; y -= worldBlockSize) {
for (let x = 0; x < width; x += worldBlockSize) {
const x_cnt = Math.floor(x / worldBlockSize);
const y_cnt = Math.floor(y / worldBlockSize);
const isObs = obstacle[y_cnt] && obstacle[y_cnt][x_cnt];
if (isObs) {
let b = new Sprite(x + worldBlockSize / 2, y + worldBlockSize / 2, worldBlockSize, worldBlockSize, 'static');
b.color = (x_cnt + y_cnt) % 2 === 0 ? color(colors.tertiary) : color(colors.accent);
b.strokeWeight = 0;
blockSprites.push(b);
}
}
}
// Cat sprite
// cat = new Cat(width / 4, height - catSize * 13/12, catSize, blocksGround, blockSprites);
cat = new Cat(3.5 * worldBlockSize, height - catSize * 13/12, catSize, blocksGround, blockSprites);
};
this.draw = () => {
@ -90,35 +141,10 @@ export default function GameScene() {
textAlign(LEFT, TOP);
text('lvl.1', width / 32, height /32 - 4);
// Ground
rectMode(CORNER);
fill(colors.secondary);
rect(0, height - groundHeight, width, groundHeight);
console.log(`ground is drawn at (0, ${height - groundHeight}) with size of ${width}x${groundHeight}`)
// Obstacle
console.log(`world size: ${windowWidth}, ${windowHeight}`);
for (let y = windowHeight - groundHeight - 2; y > 0; y -= worldBlockSize) {
for (let x = 0; x < width ; x += worldBlockSize) {
stroke(0)
strokeWeight(1)
noFill()
rect(x, y, worldBlockSize, worldBlockSize);
textSize(24);
const x_cnt = Math.floor(x / worldBlockSize);
const y_cnt = Math.floor(y / worldBlockSize);
const txt = `${x_cnt}, ${y_cnt}`;
text(txt, x + 8, y + 8);
}
}
runButton.draw();
blocks.draw();
steps.draw();
// loops.draw();
// Sprite
cat.draw();
};
@ -171,4 +197,10 @@ export default function GameScene() {
});
};
this.startGame = () => {
if (restart) cat.restart();
cat.run(steps.contents);
this.restart = true;
}
}

View File

@ -3,6 +3,7 @@ const colors = {
secondary: "#ff4f64",
tertiary: "#fff29d",
accent: "#a4e4b6",
darkRed: "#C0404F"
};
const button = {