diff options
author | niliara-edu <nil.jimeno@estudiant.fjaverianas.com> | 2024-12-27 18:30:10 +0100 |
---|---|---|
committer | niliara-edu <nil.jimeno@estudiant.fjaverianas.com> | 2024-12-27 18:30:10 +0100 |
commit | 0696b94962a0571fad54844f137dca025df4563b (patch) | |
tree | 8aeff72e8fc46a7dab2b2f556febd962e3f67e4b | |
parent | 474a7253b6b67e2ed33936f6b633587d5d304b66 (diff) |
game finished, only assets left
-rw-r--r-- | assets/sounds/kirbydaance.ogg | bin | 0 -> 103719 bytes | |||
-rw-r--r-- | src/anticheese.js | 2 | ||||
-rw-r--r-- | src/assets.js | 11 | ||||
-rw-r--r-- | src/engine/radio.js | 18 | ||||
-rw-r--r-- | src/entities/bigdump.js | 7 | ||||
-rw-r--r-- | src/entities/entity.js | 14 | ||||
-rw-r--r-- | src/entities/hello_kitty.js | 268 | ||||
-rw-r--r-- | src/entities/hello_kitty/bullet.js | 12 | ||||
-rw-r--r-- | src/entities/hello_kitty/falling_kitten.js | 59 | ||||
-rw-r--r-- | src/entities/hello_kitty/laser.js | 7 | ||||
-rw-r--r-- | src/entities/hello_kitty/walking_kitten.js | 80 | ||||
-rw-r--r-- | todo | 7 |
12 files changed, 424 insertions, 61 deletions
diff --git a/assets/sounds/kirbydaance.ogg b/assets/sounds/kirbydaance.ogg Binary files differnew file mode 100644 index 0000000..11156a1 --- /dev/null +++ b/assets/sounds/kirbydaance.ogg diff --git a/src/anticheese.js b/src/anticheese.js index fc88b8f..ce294d2 100644 --- a/src/anticheese.js +++ b/src/anticheese.js @@ -2,7 +2,7 @@ import { boshy } from "./main.js" import { Engine } from "./engine.js" import { BigDump } from "./entities/bigdump.js" -const maxTime = 200 +const maxTime = 300 const margin = 30 let timeH = 0 let timeV = 0 diff --git a/src/assets.js b/src/assets.js index bf63044..6becf4e 100644 --- a/src/assets.js +++ b/src/assets.js @@ -57,8 +57,15 @@ export const HELLO_KITTY = { './assets/sprites/hello_kitty_small2.png', ], BULLET : './assets/sprites/hello_kitty_heart.png', - HIT_SOUND : './assets/sounds/exciteshoot.ogg', - LASER_SOUND : './assets/sounds/BLAAHLouder.ogg', + SOUNDS : { + HIT : './assets/sounds/exciteshoot.ogg', + LASER : './assets/sounds/BLAAHLouder.ogg', + SHOOT : './assets/sounds/Solgryn_shoot (2).ogg', + SHOOT_LOUD : './assets/sounds/alien explosion.ogg', + DEATH : './assets/sounds/nooooooooooooooooooooooooooooooooo (2).ogg', + BLOOD_RIP : './assets/sounds/blood rip.ogg', + WIN : './assets/sounds/kirbydaance.ogg', + }, } export const WHITE = './assets/sprites/white.png' diff --git a/src/engine/radio.js b/src/engine/radio.js index d39524a..0e2abba 100644 --- a/src/engine/radio.js +++ b/src/engine/radio.js @@ -1,4 +1,17 @@ export class Radio { + playSound(file) { + let audio = new Audio(file) + audio.play() + } + + playSoundUntilEnd(file) { + let audio = new Audio(file) + return new Promise(res => { + audio.play() + audio.onended = res + }) + } + bgm playMusic(file) { if (this.bgm != undefined) this.bgm.pause() @@ -7,8 +20,7 @@ export class Radio { this.bgm.loop = true } - playSound(file) { - let audio = new Audio(file) - audio.play() + stopMusic() { + this.bgm.pause() } } diff --git a/src/entities/bigdump.js b/src/entities/bigdump.js index 90b4a57..d7a20ba 100644 --- a/src/entities/bigdump.js +++ b/src/entities/bigdump.js @@ -28,11 +28,8 @@ export class BigDump extends Entity { if (this.bottom) this.position.x += this.speed else this.position.y += this.speed - console.log("dump", this.position) - - if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) { - boshy.die() - } + this.updateAsHazard() + this.checkBounds() if (Engine.screen.isOffLimits(this.position, this.size)) { this.remove() } diff --git a/src/entities/entity.js b/src/entities/entity.js index 0dbe00c..2b3ab71 100644 --- a/src/entities/entity.js +++ b/src/entities/entity.js @@ -1,6 +1,6 @@ import { Vector } from "../engine/vector.js" import { Engine } from "../engine.js" -import { entities } from "../main.js" +import { entities, boshy } from "../main.js" export class Entity { rotation = 0 @@ -37,4 +37,16 @@ export class Entity { this.span.remove() entities.remove(this) } + + updateAsHazard() { + if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) { + boshy.die() + } + } + + checkBounds() { + if (Engine.screen.isOffLimits(this.position, this.size)) { + this.remove() + } + } } diff --git a/src/entities/hello_kitty.js b/src/entities/hello_kitty.js index 65fa30b..a7d5f68 100644 --- a/src/entities/hello_kitty.js +++ b/src/entities/hello_kitty.js @@ -5,14 +5,16 @@ import { HELLO_KITTY } from "../assets.js" import { setEnemy, boshy } from "../main.js" import { Bullet } from "./hello_kitty/bullet.js" import { Laser } from "./hello_kitty/laser.js" +import { WalkingKitten } from "./hello_kitty/walking_kitten.js" +import { FallingKitten } from "./hello_kitty/falling_kitten.js" +import { Blood } from "./boshyblood.js" export class HelloKitty extends Entity { - max_hp = 300 + max_hp = 200 hp = this.max_hp - moveInterval = 26 + alive = true - previous = 0 - stage = 1 + stage = 0 justGotHit = false turningRight = false @@ -30,23 +32,29 @@ export class HelloKitty extends Entity { this.span.style.zIndex = 1 setEnemy(this) + this.nextStage() } update() { + if (!this.alive) { + this.deathAnimation() + return + } switch (this.stage) { - case 0: this.stage0() case 1: this.stage1(); break - case 2: this.stage2(); break - } - if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) { - boshy.die() + case 2: this.stage2Lasers(); break + case 3: this.stage3Kittens(); break + case 4: this.stage4Touhou(); break + default: this.nextStage() } + this.updateAsHazard() } delayBetweenFrames = 10 timeUntilNextFrame = this.delayBetweenFrames frameAlternator = false draw() { + if (!this.alive) { super.draw(); return } /* hit effect */ if (this.justGotHit) { this.span.style.filter = "brightness(500%)" @@ -78,32 +86,51 @@ export class HelloKitty extends Entity { super.draw() } - attacksUntilNextStage = 6 normalAttackDelay = 100 attackWaitTime = this.normalAttackDelay - stage0() { - this.innerStage = 0 - this.timeUntilNextInnerStage = 0 - this.attackWaitTime = this.normalAttackDelay - // this.prepareMoving() + nextStage() { this.stage++ + + switch (this.stage) { + case 1: + this.attacksUntilNextStage = 6 + this.attackWaitTime = this.normalAttackDelay + this.prepareMoving() + break + case 2: + this.innerStage = 0 + this.timeUntilNextInnerStage = 0 + this.attacksUntilNextStage = 4 + break + case 3: + this.attacksUntilNextStage = 12 + break + case 4: + this.innerStage = 0 + this.timeUntilNextInnerStage = 120 + break + default: + this.stage = 0 + this.nextStage() + } } + /* single shoots stage */ stage1() { this.move() if (!this.attackWaitTime) { if (!this.attacksUntilNextStage) { - this.stage++ - this.attacksUntilNextStage = 4 - } else { - this.normalAttack() - this.attackWaitTime = this.normalAttackDelay - this.attacksUntilNextStage-- + this.nextStage() + return } - } + this.normalAttack() + this.attackWaitTime = this.normalAttackDelay + this.attacksUntilNextStage-- + + } this.attackWaitTime-- } @@ -112,7 +139,7 @@ export class HelloKitty extends Entity { timeUntilNextInnerStage = 0 /* laser stage */ - stage2() { + stage2Lasers() { switch (this.innerStage) { case 0: /*(preparation)*/ this.laserAttackDelay = 120 @@ -142,19 +169,105 @@ export class HelloKitty extends Entity { this.move() if (!this.attackWaitTime) { if (!this.attacksUntilNextStage) { - this.stage = 0 - this.attacksUntilNextStage = 6 - } else { - this.laserAttack() + this.nextStage() + return + } + + this.laserAttack() + + this.attackWaitTime = this.laserAttackDelay + this.laserAttackDelay -= 30 + this.attacksUntilNextStage-- + } + this.attackWaitTime-- + } + + kittenAttackDelay = 40 + stage3Kittens() { + this.move() - this.attackWaitTime = this.laserAttackDelay - this.laserAttackDelay -= 20 - this.attacksUntilNextStage-- + if (!this.attackWaitTime) { + if (!this.attacksUntilNextStage) { + this.nextStage() + return } + this.kittenAttack() + this.attackWaitTime = this.kittenAttackDelay + this.attacksUntilNextStage-- } this.attackWaitTime-- } + /* bullets!!! */ + stage4Touhou() { + switch (this.innerStage) { + case 0: /*(still moving)*/ + this.move() + + this.timeUntilNextInnerStage-- + if (!this.timeUntilNextInnerStage) { + this.innerStage++ + this.timeUntilNextInnerStage = 30 + } + return + + case 1: /*(go to center)*/ + this.moveToCenter() + this.timeUntilNextInnerStage-- + if (!this.timeUntilNextInnerStage) { + this.position.x = 325 /*(center of the screen)*/ + this.innerStage++ + this.attacksUntilNextInnerStage = 5 + this.attackReload = 40 + this.attackWaitTime = 20 + } + return + + case 2: /*(circle attacks)*/ + this.attackWaitTime-- + if (this.attackWaitTime > 0) return + + this.circleAttack() + this.attackWaitTime = this.attackReload + + this.attacksUntilNextInnerStage-- + if (!this.attacksUntilNextInnerStage) { + this.innerStage++ + this.attacksUntilNextInnerStage = 8 + this.attackReload = 30 + this.extraAttackReload = 10 + this.isNextAttackNormal = true + } + return + + case 3: /*(circle attacks + kaboom)*/ + this.attackWaitTime-- + if (this.attackWaitTime > 0) return + + if (this.isNextAttackNormal) { + this.circleAttack() + this.attackWaitTime = this.extraAttackReload + } else { + this.circleAttackFaster() + this.attackWaitTime = this.attackReload + } + this.isNextAttackNormal = !this.isNextAttackNormal + + this.attacksUntilNextInnerStage-- + if (!this.attacksUntilNextInnerStage) { + this.innerStage++ + this.attacksUntilNextInnerStage = 6 + this.attackReload = 30 + this.extraAttackReload = 10 + } + return + + default: + this.nextStage() + return + } + } + speed = 9 acceleration = 0.2 @@ -164,6 +277,7 @@ export class HelloKitty extends Entity { this.speed = 9 } + moveInterval = 26 move() { this.position.x += this.speed if (this.position.x > 325) this.speed -= this.acceleration @@ -185,6 +299,21 @@ export class HelloKitty extends Entity { this.position.x += this.speed } + moveToCenter() { + let distance = this.position.x - 325 /*(viewport.y / 2)*/ + if (distance < 2 && distance > -2) return + + switch (true) { + case (distance < -50): this.speed = 10; break + case (distance < -20): this.speed = 5; break + case (distance < 0): this.speed = 2; break + case (distance > 50): this.speed = -10; break + case (distance > 20): this.speed = -5; break + case (distance > 0): this.speed = -2; break + } + this.position.x += this.speed + } + normalAttack() { let angleToPlayer = this.getBulletAngleToPlayer() let bulletCenter = this.position.clone() @@ -197,11 +326,55 @@ export class HelloKitty extends Entity { Engine.screen.shake() } - + laserAttack(delayed = false) { new Laser(boshy.position.x, delayed) } + kittenAttack() { + new WalkingKitten() + new FallingKitten() + } + + circleAttack() { + let bulletCenter = this.position.clone() + bulletCenter.y += this.bulletMarginY + let bullets = 10 + let interval = 360 / bullets + let initialAngle = this.getBulletAngleToPlayer() + + for (let i = 0; i < bullets; i++) { + new Bullet({ + position: bulletCenter.clone(), + speed: 3, + degrees: initialAngle + interval * i, + spinning: true, + }) + } + + Engine.radio.playSound(HELLO_KITTY.SOUNDS.SHOOT) + } + + circleAttackFaster() { + let bulletCenter = this.position.clone() + bulletCenter.y += this.bulletMarginY + let bullets = 12 + let interval = 360 / bullets + let initialAngle = Engine.random(0, 360) + + for (let i = 0; i < bullets; i++) { + new Bullet({ + position: bulletCenter.clone(), + speed: 7, + degrees: initialAngle + interval * i, + spinning: true, + }) + } + + Engine.radio.playSound(HELLO_KITTY.SOUNDS.SHOOT_LOUD) + Engine.screen.shake() + } + getBulletAngleToPlayer() { let v1 = this.position.clone() v1.y += this.bulletMarginY @@ -212,8 +385,39 @@ export class HelloKitty extends Entity { } hit() { + if (!this.alive) return + this.hp-- - if (!this.justGotHit) Engine.radio.playSound(HELLO_KITTY.HIT_SOUND) + + if (this.hp == 0) { this.die(); return } + + if (!this.justGotHit) Engine.radio.playSound(HELLO_KITTY.SOUNDS.HIT) this.justGotHit = true } + + async die() { + this.alive = false + Engine.radio.stopMusic() + await Engine.radio.playSoundUntilEnd(HELLO_KITTY.SOUNDS.DEATH) + this.explode() + } + + deathAnimationDelay = 60 + deathAnimation() { + if (this.deathAnimationDelay) { + this.deathAnimationDelay-- + return + } + + this.size.x += 1 + } + + async explode() { + for (let i = 0; i < 40; i++) { + new Blood(this.position.clone()) + } + this.remove() + await Engine.radio.playSoundUntilEnd(HELLO_KITTY.SOUNDS.BLOOD_RIP) + Engine.radio.playSound(HELLO_KITTY.SOUNDS.WIN) + } } diff --git a/src/entities/hello_kitty/bullet.js b/src/entities/hello_kitty/bullet.js index 1caeb7c..80ad2dd 100644 --- a/src/entities/hello_kitty/bullet.js +++ b/src/entities/hello_kitty/bullet.js @@ -1,8 +1,6 @@ import { HELLO_KITTY } from "../../assets.js" import { Vector } from "../../engine/vector.js" -import { Engine } from "../../engine.js" import { Entity } from "../entity.js" -import { boshy } from "../../main.js" import { BulletParticle } from "./bullet_particles.js" export class Bullet extends Entity { @@ -23,7 +21,7 @@ export class Bullet extends Entity { this.spinning = spinning this.velocity = Vector.fromDeg(degrees) this.velocity.multiply(speed) - this.velocity.floor() + // this.velocity.floor() this.gravity = gravity @@ -48,11 +46,7 @@ export class Bullet extends Entity { if (this.spinning) this.rotation += this.spinSpeed - if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) { - boshy.die() - } - if (Engine.screen.isOffLimits(this.position, this.size)) { - this.remove() - } + this.updateAsHazard() + this.checkBounds() } } diff --git a/src/entities/hello_kitty/falling_kitten.js b/src/entities/hello_kitty/falling_kitten.js new file mode 100644 index 0000000..2404183 --- /dev/null +++ b/src/entities/hello_kitty/falling_kitten.js @@ -0,0 +1,59 @@ +import { HELLO_KITTY } from "../../assets.js" +import { Vector } from "../../engine/vector.js" +import { Engine } from "../../engine.js" +import { Entity } from "../entity.js" + +export class FallingKitten extends Entity { + constructor() { + let direction = Engine.random(0, 1) + super({ + size: new Vector(40, 40), + hitbox: new Vector(20, 40), + position: new Vector(Engine.random(0 + 22, Engine.screen.viewport.x - 22), 0), + sprite: HELLO_KITTY.SMALL[0], + pixelated: true, + }) + + this.velocity = new Vector(direction ? 1 : -1, 2) + + this.pointRightDirection() + this.maxBottomPosition = Engine.screen.viewport.y + this.size.y / 2 + } + + update() { + this.position.add(this.velocity) + if ( + this.position.x - this.size.x / 2 < 0 || + this.position.x > Engine.screen.viewport.x - this.size.x / 2 + ) { + this.velocity.x *= -1 + this.pointRightDirection() + } + + if (this.position.y > this.maxBottomPosition) this.remove() + this.updateAsHazard() + } + + + delayBetweenFrames = 20 + timeUntilNextFrame = this.delayBetweenFrames + frameAlternator = false + + draw() { + if (!this.timeUntilNextFrame) { + this.timeUntilNextFrame = this.delayBetweenFrames + this.span.src = this.frameAlternator ? + HELLO_KITTY.SMALL[0] : + HELLO_KITTY.SMALL[1] + this.frameAlternator = !this.frameAlternator + } + this.timeUntilNextFrame-- + + super.draw() + } + + pointRightDirection() { + if (this.velocity.x > 0) this.span.style.transform = "scaleX(-1)" + else this.span.style.transform = "scaleX(1)" + } +} diff --git a/src/entities/hello_kitty/laser.js b/src/entities/hello_kitty/laser.js index b8e480d..8cf576a 100644 --- a/src/entities/hello_kitty/laser.js +++ b/src/entities/hello_kitty/laser.js @@ -2,7 +2,6 @@ import { WHITE, HELLO_KITTY } from "../../assets.js" import { Vector } from "../../engine/vector.js" import { Engine } from "../../engine.js" import { Entity } from "../entity.js" -import { boshy } from "../../main.js" import { Bullet } from "./bullet.js" export class Laser extends Entity { @@ -34,7 +33,7 @@ export class Laser extends Entity { if (!this.loadingTimeLeft) { this.attacking = true this.size.x = 100 - Engine.radio.playSound(HELLO_KITTY.LASER_SOUND) + Engine.radio.playSound(HELLO_KITTY.SOUNDS.LASER) Engine.screen.shake() this.spawnBullets() } @@ -45,9 +44,7 @@ export class Laser extends Entity { if (this.size.x == this.attackSize) this.size.x += 10 else this.size.x = this.attackSize this.attackTimeLeft-- - if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) { - boshy.die() - } + this.updateAsHazard() return } diff --git a/src/entities/hello_kitty/walking_kitten.js b/src/entities/hello_kitty/walking_kitten.js new file mode 100644 index 0000000..b027622 --- /dev/null +++ b/src/entities/hello_kitty/walking_kitten.js @@ -0,0 +1,80 @@ +import { HELLO_KITTY } from "../../assets.js" +import { Vector } from "../../engine/vector.js" +import { Engine } from "../../engine.js" +import { Entity } from "../entity.js" + +export class WalkingKitten extends Entity { + constructor() { + let direction = Engine.random(0, 1) + super({ + size: new Vector(40, 40), + hitbox: new Vector(20, 40), + position: new Vector(direction ? 0 : Engine.screen.viewport.x, Engine.screen.viewport.y - 20), + sprite: HELLO_KITTY.SMALL[0], + pixelated: true, + }) + + this.velocity = new Vector(direction ? 1 : -1, 0) + if (direction) this.span.style.transform = "scaleX(-1)" + this.bottomPosition = Engine.screen.viewport.y - 20 + } + + update() { + this.updateJump() + this.position.add(this.velocity) + this.checkBounds() + this.updateAsHazard() + } + + jumping = true + timeUntilNextJump = 0 + gravity = 0.1 + + updateJump() { + if (this.jumping) { + if (this.position.y >= this.bottomPosition) { + this.velocity.y = 0 + this.velocity.x *= 3 + this.position.y = this.bottomPosition + this.jumping = false + this.timeUntilNextJump = Engine.random(-30, 300) + return + } + this.velocity.y += this.gravity + return + } + + this.timeUntilNextJump-- + if (!this.timeUntilNextJump) { + this.velocity.x /= 3 + this.velocity.y = -7 + this.jumping = true + } + } + + delayBetweenFrames = 20 + timeUntilNextFrame = this.delayBetweenFrames + frameAlternator = false + + draw() { + if (!this.timeUntilNextFrame) { + this.timeUntilNextFrame = this.delayBetweenFrames + this.span.src = this.frameAlternator ? + HELLO_KITTY.SMALL[0] : + HELLO_KITTY.SMALL[1] + this.frameAlternator = !this.frameAlternator + } + this.timeUntilNextFrame-- + + super.draw() + } + + checkBounds() { + if ( + this.position.x + this.size.x / 2 < 0 || + this.position.x - this.size.x / 2 > Engine.screen.viewport.x + ) { + this.remove() + } + } +} @@ -1,4 +1,5 @@ -[ ] - implement anti-cheesing poop -[ ] - mini-spamton like attack with raining hearts (stage 3) +[X] - implement anti-cheesing poop +[X] - mini-spamton like attack with raining hearts (stage 3) [ ] - touhou-like attack (stage 4) -[ ] - make lasers shoot hearts, shoot extra hearts when low hp +[X] - make lasers shoot hearts --shoot extra hearts when low hp-- +[ ] - implement game won thingy |