chefCat working

This commit is contained in:
adeliptr 2025-05-06 15:36:17 +09:00
parent f78944727e
commit 2098d6e3f2
9 changed files with 353 additions and 52 deletions

BIN
.DS_Store vendored

Binary file not shown.

62
Cat.js
View File

@ -3,14 +3,38 @@ import { catAnimation, imageAssets } from './sketch.js';
import { cheeses } from './GameScene.js';
export const movingObjects = [];
export const catAniDesc = {
chefCat: {
idle: { row: 0, frames: 4, frameSize: [200, 200], frameDelay: 10 },
action: { row: 0, frames: 4, frameSize: [200, 200], frameDelay: 10 }
},
singleYarnCat: {
idle: { row: 0, frameSize: [200, 200] },
action: {row: 1, frames: 8, frameSize: [200, 200], frameDelay: 5 }
},
doubleYarnCat: {
idle: { row: 0, frameSize: [200, 200] },
action: {row: 1, frames: 8, frameSize: [200, 200], frameDelay: 5 }
},
sleepyCat: {
idle: {row: 0, frameSize: [200, 200] },
action: {row: 0, frameSize: [200, 200] }
},
iceCat: {
idle: { row: 0, frameSize: [200, 200] },
action: {row: 1, frames: 8, frameSize: [200, 200], frameDelay: 5 }
}
}
export class Cat {
constructor(x, y, cost, ani, width) {
constructor(x, y, cost, spriteSheet, ani, width) {
// (x, y) is the center of the grid
this.sprite = createSprite(x, y, width, width);
this.sprite.spriteSheet = spriteSheet;
this.sprite.addAnis(ani);
console.log(this.spriteSheet);
console.log(this.sprite.animation);
this.sprite.changeAni('idle');
this.sprite.scale = width / 200;
this.x = x;
this.y = y;
@ -20,6 +44,14 @@ export class Cat {
this.HP = 200;
}
switchToIdle() {
this.sprite.changeAni('idle');
}
switchToAction() {
this.sprite.changeAni('action');
}
action() {
// TODO:
// - ChefCat: produces cheese every 10 seconds -> cheese.png pop up on top of the ChefCat every 10 seconds
@ -31,8 +63,18 @@ export class Cat {
// delete the snowball sprite when it hit a mouse or get out of gameFrame
}
update() {
// update ani
clear();
if (kb.presses('a')) {
console.log(`a is pressed`)
this.sprite.changeAni('action');
}
}
attacked(mouse) {
this.HP = max(0, this.HP - mouse.AP);
// if HP = 0, remove sprite
}
draw() {
@ -55,16 +97,18 @@ export class Cat {
export class ChefCat extends Cat {
constructor(x, y) {
super(x, y, 50, catAnimation.chefCat, 100);
super(x, y, 50, catAnimation.chefCat, catAniDesc.chefCat, 100);
this.lastProduced = millis();
}
action() {
// Produces 50 cheese every 10 seconds, cheese.png pop in front of the chefCat
// TODO: change it to 25 secs
if (millis() - this.lastProduced > 10000) {
console.log(`produces Cheese!`)
const cheese = createSprite(this.x + 20, this.y + 20, 20, 20);
cheese.addImage(imageAssets.cheese);
const cheese = createSprite(this.x + this.width / 5, this.y + this.width / 5);
cheese.scale = this.width / 300;
cheese.image = imageAssets.cheese;
cheese.mouseActive = true;
cheeses.push(cheese);
this.lastProduced = millis();
@ -74,7 +118,7 @@ export class ChefCat extends Cat {
export class SingleYarnCat extends Cat {
constructor(x, y) {
super(x, y, 100, catAnimation.singleYarnCat, 100);
super(x, y, 100, catAnimation.singleYarnCat, catAniDesc.singleYarnCat, 100);
this.lastShot = millis();
}
@ -93,7 +137,7 @@ export class SingleYarnCat extends Cat {
export class DoubleYarnCat extends Cat {
constructor(x, y) {
super(x, y, 200, catAnimation.doubleYarnCat, 100);
super(x, y, 200, catAnimation.doubleYarnCat, catAniDesc.doubleYarnCat, 100);
this.lastShot = millis();
}
@ -114,7 +158,7 @@ export class DoubleYarnCat extends Cat {
export class SleepyCat extends Cat {
constructor(x, y) {
super(x, y, 150, catAnimation.sleepyCat, 100);
super(x, y, 150, catAnimation.sleepyCat, catAniDesc.sleepyCat, 100);
this.awake = false;
this.wakeStart = undefined;
}
@ -133,7 +177,7 @@ export class SleepyCat extends Cat {
export class IceCat extends Cat {
constructor(x, y) {
super(x, y, 150, catAnimation.iceCat, 100);
super(x, y, 150, catAnimation.iceCat, catAniDesc.iceCat, 100);
this.lastShot = millis();
}

View File

@ -1,13 +1,82 @@
import { prototypeFrame, gameFrame } from './prototype.js';
import { StartScene } from './StartScene.js';
import { imageAssets, catImages, catAnimation, selectedCatType, resetCatType } from './sketch.js';
import { Cat, ChefCat, SingleYarnCat, DoubleYarnCat, SleepyCat, IceCat } from './Cat.js'
const gameParent = document.getElementById('gameFrame');
const upperContainer = document.getElementById('upperContainer');
const controlPanel = document.getElementById('controlPanel');
const cheeseCount = document.getElementById('cheeseCount');
const activeCats = [];
let robotVacuums = [];
let gameSprites = [];
export let cheeses = [];
let grid = Array(5).fill().map(() => Array(9).fill(null));
let isAttacked = Array(5).fill(false);
function createCat(type, x, y) {
switch (type) {
case 'chefCat':
let cat = new ChefCat(x, y);
cat.action();
return cat;
case 'singleYarnCat':
return new SingleYarnCat(x, y);
case 'doubleYarnCat':
return new DoubleYarnCat(x, y);
case 'sleepyCat':
return new SleepyCat(x, y);
case 'iceCat':
return new IceCat(x, y);
default:
return undefined;
}
}
function calculateCell(mouseX, mouseY) {
let col = floor((mouseX - gameFrame.padding_left) / gameFrame.tileWidth)
let row = floor((mouseY - gameFrame.padding_up) / gameFrame.tileHeight)
console.log(`clicked on grid[${row}][${col}]`);
return {row, col};
}
function isCellValid(row, col) {
if (row < 0) return false;
if (row >= gameFrame.rows) return false;
if (col < 0) return false;
if (col >= gameFrame.cols) return false;
return true;
}
export function GameScene() {
this.enter = function() {
select('#controlPanel').show();
select('#upperContainer').show();
select('#menuButton').show();
select('#startButton').hide();
upperContainer.style.width = width + 'px';
const gridHeight = gameFrame.rows * gameFrame.tileHeight;
upperContainer.style.height = (gameFrame.height - gridHeight - gameFrame.border) + 'px';
controlPanel.style.margin = gameFrame.border + 'px';
controlPanel.style.height = (gameFrame.height - gridHeight - 3 * gameFrame.border) + 'px';
gameSprites = []; // kayanya ga butuh, sama kayak allSprites
robotVacuums = [];
for (let row = 0; row < gameFrame.rows; row ++) {
let x = gameFrame.paddingRobot + gameFrame.robotSize / 2;
let y = gameFrame.padding_up + row * gameFrame.tileHeight + gameFrame.tileHeight / 2;
let vacuum = createSprite(x, y, gameFrame.robotSize, gameFrame.robotSize);
vacuum.image = imageAssets.robotVacuum;
vacuum.image.scale = gameFrame.tileWidth / 1000;
// vacuum.vel.x = 1;
gameSprites.push(vacuum);
robotVacuums.push(vacuum);
}
}
this.setup = function() {
@ -16,35 +85,107 @@ export function GameScene() {
gameFrame.height = height;
const ratio = width / prototypeFrame.width;
gameFrame.tileWidth = ratio * prototypeFrame.tileWidth
gameFrame.tileHeight = ratio * prototypeFrame.tileHeight
gameFrame.padding_left = ratio * prototypeFrame.padding_left
Object.keys(prototypeFrame).forEach(key => {
if (key != 'width' && key != 'height') {
gameFrame[key] = ratio * prototypeFrame[key];
}
})
gameFrame.catRatio = 1.2 * gameFrame.tileWidth/200;
}
this.draw = function() {
console.log(`lets draw the gameScene`)
background(255);
textAlign(CENTER, CENTER);
textSize(40);
fill(0);
text("this is the game", width/2, height/2 - 50);
drawGrid()
clear();
image(imageAssets.gameBackground, 0, gameFrame.padding_up - gameFrame.border, gameFrame.width, gameFrame.height - gameFrame.padding_up + gameFrame.border);
noFill();
stroke('#B09472');
strokeWeight(gameFrame.border);
// fix the border radius --> create a ratio for it
rect(gameFrame.border / 2, gameFrame.border / 2, width - gameFrame.border, height - gameFrame.border, 35);
drawGrid();
activeCats.forEach((cat) => cat.action());
}
this.exit = function() {
console.log(`i exit gameScene`);
gameSprites.forEach((sprite) => sprite.remove());
activeCats.forEach((cat) => cat.remove()); // idk if it is needed or not
}
this.mousePressed = function() {
this.sceneManager.showScene(StartScene);
const {row, col} = calculateCell(mouseX, mouseY);
if (isCellValid(row, col) && selectedCatType === 'petCage') {
const cat = grid[row][col];
if (cat) {
cat.remove();
// TODO: need to remove from activeCats too
grid[row][col] = null;
}
}
else if (isCellValid(row, col) && selectedCatType != null) {
let x = gameFrame.padding_left + col * gameFrame.tileWidth + gameFrame.tileWidth / 2;
let y = gameFrame.padding_up + row * gameFrame.tileHeight + gameFrame.tileHeight / 2;
const newCat = createCat(selectedCatType, x, y);
if (newCat) {
newCat.sprite.scale = gameFrame.catRatio;
grid[row][col] = newCat;
activeCats.push(newCat);
gameSprites.push(newCat.sprite); // Is this redundant? kedouble2
resetCatType();
}
// grid[row][col] = selectedCatType;
// console.log(`after click, grid[${row}][${col}] = ${grid[row][col]}`)
}
for (let i = 0; i < cheeses.length; i++) {
console.log(`there are ${cheeses.length} cheeses`)
// Calculate boundaries
let left = cheeses[i].x - cheeses[i].width / 2;
let right = cheeses[i].x + cheeses[i].width / 2;
let top = cheeses[i].y - cheeses[i].height / 2;
let bottom = cheeses[i].y + cheeses[i].height / 2;
if (mouseX >= left && mouseX <= right && mouseY >= top && mouseY <= bottom) {
console.log(`cheese ${i} is pressed`)
updateCheeseCount(25);
cheeses[i].remove();
cheeses.splice(i, 1);
break;
}
}
}
function drawGrid() {
for (let row = 0; row < gameFrame.rows; row++) {
for (let col = 0; col < gameFrame.cols; col++) {
let x = gameFrame.padding_left + col * gameFrame.tileWidth;
let y = gameFrame.padding_left + row * gameFrame.tileHeight;
fill((row + col) % 2 === 0 ? '#fceecf' : '#fff6e9');
stroke(0);
// console.log(`rect(${x}, ${y}, ${gameFrame.tileWidth}, ${gameFrame.tileHeight})`)
let y = gameFrame.padding_up + row * gameFrame.tileHeight;
let isHovering = (
mouseX > x && mouseX < x + gameFrame.tileWidth &&
mouseY > y && mouseY < y + gameFrame.tileHeight
);
if (isHovering && selectedCatType) {
fill('red');
}
else {
fill((row + col) % 2 === 0 ? '#F7E7BE' : '#FDF4E5');
}
noStroke();
rect(x, y, gameFrame.tileWidth, gameFrame.tileHeight);
}
}
}
}
function updateCheeseCount(n) {
console.log(`update cheeseCount by ${n}`)
let currCheese = int(cheeseCount.textContent);
currCheese += n;
cheeseCount.textContent = currCheese;
// TODO: handle if n is negative and currCheese < -n somewhere else
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 82 KiB

BIN
assets/ica_cat_ani.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -8,7 +8,8 @@
<script src="js/p5.dom.min.js"></script>
<script src="js/p5.sound.min.js"></script>
<script src="js/scenemanager.js"></script>
<!-- <script src='https://cdnjs.cloudflare.com/ajax/libs/p5play/3.26.5/p5play.js' integrity='sha512-/U7V9+DgHiG8HVEtlGUYBRudMHgNB05AtyKOG2e4BduF4XogG4inVXPvEI5NE/I7R28a8K7gAgI7msqIzzBt4Q==' crossorigin='anonymous'></script> -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/planck-js/1.3.0/planck.js' integrity='sha512-OpFl/oyutfMxRHH9jnD7DwC14TmOzCsE/2l8Uf2PCGuLtUxX+qAhX/TNSV/rf24XZfANLoa10lmM40BlLMmRwg==' crossorigin='anonymous'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5play/3.26.5/p5play.js' integrity='sha512-/U7V9+DgHiG8HVEtlGUYBRudMHgNB05AtyKOG2e4BduF4XogG4inVXPvEI5NE/I7R28a8K7gAgI7msqIzzBt4Q==' crossorigin='anonymous'></script>
<script type="module" src="sketch.js"></script>
@ -20,19 +21,46 @@
<body>
<h1 id="title">Cats vs Mice</h1>
<div id="gameFrame">
<div id="controlPanel">
<div id="catToolbar">
<button class="catButton" id="cheeseButton">🧀<span>250</span></button>
<button class="catButton" id="chefButton">🧑‍🍳<span>50</span></button>
<button class="catButton" id="singleYarnButton">🧶<span>100</span></button>
<button class="catButton" id="doubleYarnButton">🧶🧶<span>200</span></button>
<button class="catButton" id="sleepyButton">💤<span>150</span></button>
<button class="catButton" id="iceButton">❄️<span>150</span></button>
</div>
<div id="gameProgressWrapper">
<progress id="gameProgress" value="30" max="100"></progress>
<label>Game Progress</label>
<div id="upperContainer">
<div id="controlPanel">
<!-- <img src="assets/cheeseLabel.png" alt="Cheese Label" id="cheeseLabel"> -->
<label>CH</label>
<div id="cheeseDisplay">
<img src="assets/cheese.png" alt="cheeseIcon" class="buttonIcon" id="cheeseIcon">
<span id="cheeseCount">50</span>
</div>
<!-- <img src="assets/catsLabel.png" alt="Cat Label" id="cheeseLabel"> -->
<label>CA</label>
<div id="catToolbar">
<button class="catButton" id="chefCat">
<img src="assets/chef_cat_icon.png" alt="Chef Cat" class="catIcon" />
<span>50</span>
</button>
<button class="catButton" id="singleYarnCat">
<img src="assets/single_yarn_cat_icon.png" alt="Single Yarn Cat" class="catIcon" />
<span>100</span>
</button>
<button class="catButton" id="doubleYarnCat">
<img src="assets/double_yarn_cat_icon.png" alt="Double Yarn Cat" class="catIcon" />
<span>200</span>
</button>
<button class="catButton" id="sleepyCat">
<img src="assets/sleepy_cat_icon.png" alt="Sleepy Cat" class="catIcon" />
<span>150</span>
</button>
<button class="catButton" id="iceCat">
<img src="assets/ice_cat_icon.png" alt="Ice Cat" class="catIcon" />
<span>150</span>
</button>
</div>
<button class="catButton" id="petCage">
<img src="assets/petCage.png" alt="Pet Cage" class="catIcon" />
<span>200</span>
</button>
<!-- <div id="gameProgressWrapper">
<progress id="gameProgress" value="30" max="100"></progress>
<label>Game Progress</label>
</div> -->
</div>
</div>
</div>

11
prototype.js vendored
View File

@ -1,11 +1,16 @@
export const prototypeFrame = {
border: 10,
width: 800,
height: 569,
tileWidth: 60,
tileHeight: 75,
tileWidth: 72,
tileHeight: 90,
itemWidth: 54,
itemHeight: 64,
padding_left: 160
padding_left: 92,
padding_up: 109,
paddingRobot: 38,
robotSize: 64,
controlPanelGap: 8
}
export const gameFrame = {

103
sketch.js
View File

@ -1,18 +1,59 @@
import { StartScene } from './StartScene.js';
import { GameScene } from './GameScene.js';
let mgr;
export let mgr;
const gameParent = document.getElementById('gameFrame');
export let startPageImage;
const catImages = {};
const controlPanel = document.getElementById('controlPanel');
const startButton = document.getElementById('startButton');
export let startPageAni, robotVacuum, gameBackground;
export let imageAssets = {};
export const catImages = {};
export const catAnimation = {};
export let selectedCatType = null;
function preload() {
startPageImage = loadImage('assets/start_page.jpg');
// catImages.chefCat = loadImage('assets/ChefCat.png');
// catImages.singleYarnCat = loadImage('assets/SingleYarnCat.png');
// catImages.doubleYarnCat = loadImage('assets/DoubleYarnCat.png');
// catImages.sleepyCat = loadImage('assets/SleepyCat.png');
// catImages.iceCat = loadImage('assets/IceCat.png');
startPageAni = loadAni('assets/start_page_ani.png', {
width: 1440, height: 1024, frames: 5
});
startPageAni.frameDelay = 10;
robotVacuum = loadImage('assets/robot_vacuum.png');
gameBackground = loadImage('assets/gamebg3.png');
imageAssets.cheese = loadImage('assets/cheese.png');
// imageAssets.yarn = loadImage('assets/yarn.png');
// imageAssets.snowball = loadImage('assets/snowball.png');
imageAssets.robotVacuum = loadImage('assets/robot_vacuum.png');
imageAssets.gameBackground = loadImage('assets/gamebg3.png');
catImages.chefCat = loadImage('assets/chef_cat_icon.png');
catImages.singleYarnCat = loadImage('assets/single_yarn_cat_icon.png');
catImages.doubleYarnCat = loadImage('assets/double_yarn_cat_icon.png');
catImages.sleepyCat = loadImage('assets/sleepy_cat_icon.png');
catImages.iceCat = loadImage('assets/ice_cat_icon.png');
catAnimation.chefCat = loadImage('assets/chef_cat_ani.png');
catAnimation.singleYarnCat = loadImage('assets/single_yarn_cat_ani.png');
catAnimation.doubleYarnCat = loadImage('assets/double_yarn_cat_ani.png');
catAnimation.sleepyCat = loadImage('assets/sleepy_cat_icon.png');
catAnimation.iceCat = loadImage('assets/ice_cat_ani.png');
// catAnimation.chefCat = loadAni('assets/chef_cat_ani.png', {
// width: 200, height: 200, frames: 4
// });
// catAnimation.singleYarnCat = loadAni('assets/single_yarn_cat_ani.png', {
// width: 200, height:200, frames: 8
// });
// catAnimation.doubleYarnCat = loadAni('assets/double_yarn_cat_ani.png', {
// width: 200, height: 200, frames: 8
// });
// catAnimation.iceCat = loadAni('assets/ice_cat_ani.png', {
// width: 200, height: 200, frames: 8
// });
// catAnimation.chefCat.frameDelay = 10;
// catAnimation.singleYarnCat.frameDelay = 5;
// catAnimation.doubleYarnCat.frameDelay = 30;
// catAnimation.iceCat.frameDelay = 5;
}
function setup() {
@ -26,7 +67,7 @@ function setup() {
mgr.addScene(GameScene);
// mgr.addScene(PauseScene);
mgr.showScene(StartScene);
mgr.showScene(GameScene);
}
function draw() {
@ -37,6 +78,48 @@ function mousePressed() {
mgr.handleEvent("mousePressed");
}
export function resetCatType() {
console.log(`reset is called`)
selectedCatType = null;
document.querySelectorAll('.catButton').forEach(button =>
button.classList.remove('activeButton')
);
}
startButton.addEventListener('click', function (event) {
event.preventDefault();
mgr.showScene(GameScene);
});
menuButton.addEventListener('click', function (event) {
event.preventDefault();
mgr.showScene(StartScene);
});
document.querySelectorAll('.catButton').forEach(button => {
button.addEventListener('click', () => {
if (selectedCatType === button.id) {
selectedCatType = null;
button.classList.remove('activeButton');
// document.body.style.cursor = 'default';
}
else {
selectedCatType = button.id;
document.querySelectorAll('.catButton').forEach(btn =>
btn.classList.remove('activeButton')
);
button.classList.add('activeButton');
// const img = button.querySelector('img');
// if (img) {
// document.body.style.cursor = `url(${img.src}) 32 32, auto`;
// }
}
console.log('Selected cat type:', selectedCatType);
});
});
window.preload = preload;
window.setup = setup;
window.draw = draw;