194 lines
5.8 KiB
JavaScript
194 lines
5.8 KiB
JavaScript
import { gameFrame } from '../constants/Prototype.js';
|
|
import { mouseAnimation } from '../sketch.js';
|
|
import { activeMice, mouseGroup, gameSprites } from '../GameScene.js';
|
|
import { updateGameProgress } from '../Controller.js';
|
|
import { Snowball } from './Throwable.js';
|
|
|
|
const mouseAniDesc = {
|
|
idle: { row: 0, frameSize: [200, 200] },
|
|
walk: {row: 1, frames: 6, frameSize: [200, 200], frameDelay: 10 }
|
|
}
|
|
|
|
/**
|
|
* Mouse class representing a mouse character in the game
|
|
*/
|
|
class Mouse {
|
|
/**
|
|
* Creates an instance of a Mouse
|
|
*
|
|
* @param {number} row - The row the mouse belongs to
|
|
* @param {number} speed - The speed of the mouse's movement
|
|
* @param {number} HP - The health points of the mouse
|
|
* @param {number} AP - The attack power of the mouse
|
|
* @param {p5.SpriteSheet} spriteSheet - The sprite sheet for the mouse animation
|
|
* @param {number} size - The size of the mouse sprite
|
|
*/
|
|
constructor(row, speed, HP, AP, spriteSheet, size) {
|
|
const y = gameFrame.padding_up + row * gameFrame.tileHeight + gameFrame.tileHeight / 2;
|
|
|
|
this.sprite = createSprite(width, y, size, size);
|
|
this.sprite.spriteSheet = spriteSheet;
|
|
this.sprite.scale = gameFrame.catRatio * size / gameFrame.tileWidth;
|
|
this.sprite.overlaps(mouseGroup)
|
|
this.sprite.addAnis(mouseAniDesc);
|
|
this.sprite.changeAni('walk');
|
|
this.sprite.layer = 3;
|
|
this.sprite.vel.x = speed;
|
|
|
|
this.row = row;
|
|
this.HP = HP;
|
|
this.AP = AP;
|
|
this.targetCat = undefined;
|
|
this.lastAttack = 0;
|
|
this.defaultSpeed = speed;
|
|
this.defaultHP = HP;
|
|
this.isAlive = true;
|
|
}
|
|
|
|
/**
|
|
* Removes the mouse from the game and updates the progress
|
|
*/
|
|
remove() {
|
|
this.sprite.remove();
|
|
let index = activeMice[this.row].indexOf(this);
|
|
if (index != -1) {
|
|
activeMice[this.row].splice(index, 1);
|
|
}
|
|
|
|
if (this.defaultHP = 1000) {
|
|
if (this.row - 1 >= 0) {
|
|
index = activeMice[this.row - 1].indexOf(this);
|
|
if (index != -1) activeMice[this.row - 1].splice(index, 1);
|
|
}
|
|
if (this.row + 1 < gameFrame.rows) {
|
|
index = activeMice[this.row + 1].indexOf(this);
|
|
if (index != -1) activeMice[this.row + 1].splice(index, 1);
|
|
}
|
|
}
|
|
|
|
index = gameSprites.indexOf(this);
|
|
if (index !== -1) {
|
|
gameSprites.splice(index, 1);
|
|
}
|
|
|
|
if (this.isAlive) {
|
|
this.isAlive = false;
|
|
updateGameProgress();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Makes the mouse attack the target cat if one exists
|
|
*/
|
|
attack() {
|
|
if (this.targetCat != undefined) {
|
|
this.sprite.vel.x = 0;
|
|
this.sprite.changeAni('idle');
|
|
if (this.lastAttack == 0 || millis() - this.lastAttack > 3000) {
|
|
this.targetCat.attacked(this);
|
|
this.lastAttack = millis();
|
|
}
|
|
}
|
|
else {
|
|
this.sprite.vel.x = this.defaultSpeed;
|
|
this.sprite.changeAni('walk');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles when the mouse is attacked and reduces its health
|
|
* @param {number} point - The damage taken by the mouse
|
|
*/
|
|
attacked(throwable) {
|
|
this.HP -= throwable.point;
|
|
if (this.HP <= 0) this.remove();
|
|
else {
|
|
this.sprite.opacity = (this.HP / this.defaultHP) * 0.5 + 0.5;
|
|
}
|
|
|
|
if (throwable instanceof Snowball) {
|
|
this.defaultSpeed = min(-0.05, this.defaultSpeed + 0.02);
|
|
this.sprite.vel.x = this.defaultSpeed;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Basic type of mouse
|
|
*/
|
|
class BasicMouse extends Mouse {
|
|
constructor(row) {
|
|
super(row, -0.15, 100, 20, mouseAnimation.basicMouse, gameFrame.tileWidth);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helmet-wearing mouse
|
|
* Has a higher HP compared to BasicMouse
|
|
*/
|
|
class HelmetMouse extends Mouse {
|
|
constructor(row) {
|
|
super(row, -0.15, 150, 20, mouseAnimation.helmetMouse, gameFrame.tileWidth);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sporty type of mouse
|
|
* Has a higher speed compared to Basic Mouse
|
|
*/
|
|
class SportyMouse extends Mouse {
|
|
constructor(row) {
|
|
super(row, -0.3, 85, 20, mouseAnimation.sportyMouse, gameFrame.tileWidth);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Boss mouse is 3 times bigger than other mice
|
|
* Has a higher HP and AP compared to the other types
|
|
* Has a slower speed compared to the other types
|
|
*/
|
|
class BossMouse extends Mouse {
|
|
constructor(row) {
|
|
super(row, -0.05, 1000, 50, mouseAnimation.bossMouse, 3 * gameFrame.tileWidth);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Factory function to create different types of cats
|
|
*
|
|
* @param {string} type - The type of mouse to create
|
|
* @param {number} row - The row the mouse belongs to
|
|
* @returns @returns {Mouse|undefined} The created mouse instance or undefined if type is invalid
|
|
*/
|
|
function createMouse(type, row) {
|
|
switch (type) {
|
|
case 'basicMouse':
|
|
return new BasicMouse(row);
|
|
case 'helmetMouse':
|
|
return new HelmetMouse(row);
|
|
case 'sportyMouse':
|
|
return new SportyMouse(row);
|
|
case 'bossMouse':
|
|
return new BossMouse(row);
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Spawns a mouse of a specified type and adds it to the game
|
|
* @param {string} type - The type of mouse to spawn
|
|
* @param {number} row - The row to spawn the mouse in
|
|
*/
|
|
export function spawnMouse(type, row) {
|
|
let newMouse = new createMouse(type, row);
|
|
if (newMouse) {
|
|
activeMice[row].push(newMouse);
|
|
if (type == 'bossMouse') {
|
|
if (row - 1 >= 0) activeMice[row - 1].push(newMouse);
|
|
if (row + 1 < gameFrame.rows) activeMice[row + 1].push(newMouse);
|
|
}
|
|
mouseGroup.add(newMouse.sprite);
|
|
gameSprites.push(newMouse.sprite);
|
|
}
|
|
} |