summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorniliara-edu <nil.jimeno@estudiant.fjaverianas.com>2024-12-27 18:30:10 +0100
committerniliara-edu <nil.jimeno@estudiant.fjaverianas.com>2024-12-27 18:30:10 +0100
commit0696b94962a0571fad54844f137dca025df4563b (patch)
tree8aeff72e8fc46a7dab2b2f556febd962e3f67e4b
parent474a7253b6b67e2ed33936f6b633587d5d304b66 (diff)
game finished, only assets left
-rw-r--r--assets/sounds/kirbydaance.oggbin0 -> 103719 bytes
-rw-r--r--src/anticheese.js2
-rw-r--r--src/assets.js11
-rw-r--r--src/engine/radio.js18
-rw-r--r--src/entities/bigdump.js7
-rw-r--r--src/entities/entity.js14
-rw-r--r--src/entities/hello_kitty.js268
-rw-r--r--src/entities/hello_kitty/bullet.js12
-rw-r--r--src/entities/hello_kitty/falling_kitten.js59
-rw-r--r--src/entities/hello_kitty/laser.js7
-rw-r--r--src/entities/hello_kitty/walking_kitten.js80
-rw-r--r--todo7
12 files changed, 424 insertions, 61 deletions
diff --git a/assets/sounds/kirbydaance.ogg b/assets/sounds/kirbydaance.ogg
new file mode 100644
index 0000000..11156a1
--- /dev/null
+++ b/assets/sounds/kirbydaance.ogg
Binary files differ
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()
+ }
+ }
+}
diff --git a/todo b/todo
index 7acbe6b..a1af75e 100644
--- a/todo
+++ b/todo
@@ -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