summaryrefslogtreecommitdiff
path: root/src/entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/entities')
-rw-r--r--src/entities/boshy.js51
-rw-r--r--src/entities/boshyblood.js25
-rw-r--r--src/entities/boshybullet.js15
-rw-r--r--src/entities/entity.js13
-rw-r--r--src/entities/game_over.js60
-rw-r--r--src/entities/hello_kitty.js75
-rw-r--r--src/entities/hello_kitty_background.js41
-rw-r--r--src/entities/hp_bar.js32
-rw-r--r--src/entities/portal.js28
9 files changed, 329 insertions, 11 deletions
diff --git a/src/entities/boshy.js b/src/entities/boshy.js
index ea6068d..9a2b589 100644
--- a/src/entities/boshy.js
+++ b/src/entities/boshy.js
@@ -3,11 +3,17 @@ import { Vector } from "../engine/vector.js"
import { Engine } from "../engine.js"
import { BoshyBullet } from "./boshybullet.js"
import { Entity } from "./entity.js"
+import { SCENES, currentScene } from "../scenes.js"
+import { boshyDied } from "../main.js"
+import { Blood } from "./boshyblood.js"
export class Boshy extends Entity {
reloadTime = 6
lastShot = 0
- speed = 5
+ speed = 4
+
+ canmove = true
+ dead = false
constructor() {
super({
@@ -16,10 +22,19 @@ export class Boshy extends Entity {
sprite: BOSHY.NORMAL,
})
- Engine.playSound(BOSHY.SOUNDS.INTRO)
+ switch (currentScene) {
+ case SCENES.PREQUEL:
+ Engine.radio.playSound(BOSHY.SOUNDS.INTRO2)
+ break;
+
+ case SCENES.HELLO_KITTY:
+ Engine.radio.playSound(BOSHY.SOUNDS.INTRO)
+ break;
+ }
}
update() {
+ if (!this.canmove) return
let keys = Engine.keys
let viewport = Engine.screen.viewport
@@ -60,6 +75,36 @@ export class Boshy extends Entity {
new BoshyBullet(bullet_a_position)
new BoshyBullet(bullet_b_position)
- Engine.playSound(BOSHY.SOUNDS.SHOOT)
+ // new BoshyBullet(this.position.clone())
+ Engine.radio.playSound(BOSHY.SOUNDS.SHOOT)
+ }
+
+ die() {
+ if (this.dead) return
+ this.dead = true
+ this.playDeathSounds()
+ this.spawnBlood()
+
+ this.position.x = 0
+ this.position.y = Engine.screen.viewport.y
+ this.remove()
+ boshyDied()
+ }
+
+ playDeathSounds() {
+ Engine.radio.playSound(BOSHY.SOUNDS.DEAD)
+
+ switch (Engine.random(1, 4)) {
+ case 1: Engine.radio.playSound(BOSHY.SOUNDS.DEADQUOTE1); break;
+ case 2: Engine.radio.playSound(BOSHY.SOUNDS.DEADQUOTE2); break;
+ case 3: Engine.radio.playSound(BOSHY.SOUNDS.DEADQUOTE3); break;
+ case 4: Engine.radio.playSound(BOSHY.SOUNDS.DEADQUOTE4); break;
+ }
+ }
+
+ spawnBlood() {
+ for (let i = 0; i<20; i++) {
+ new Blood(this.position.clone().floor())
+ }
}
}
diff --git a/src/entities/boshyblood.js b/src/entities/boshyblood.js
new file mode 100644
index 0000000..af4a97d
--- /dev/null
+++ b/src/entities/boshyblood.js
@@ -0,0 +1,25 @@
+import { BOSHY } from "../assets.js"
+import { Vector } from "../engine/vector.js"
+import { Engine } from "../engine.js"
+import { Entity } from "./entity.js"
+
+export class Blood extends Entity {
+ constructor(position) {
+ super({
+ size: new Vector(6, 6),
+ position: position,
+ sprite: BOSHY.BLOOD,
+ })
+
+ let max_speed = 20
+ this.velocity = new Vector(Engine.random(-max_speed, max_speed),Engine.random(-max_speed, max_speed))
+ this.gravity = 1
+ }
+
+
+ update() {
+ this.position.add(this.velocity)
+ if (Engine.screen.isOffLimits(this.position, this.size)) this.remove()
+ this.velocity.y += this.gravity
+ }
+}
diff --git a/src/entities/boshybullet.js b/src/entities/boshybullet.js
index ed91ede..a87e159 100644
--- a/src/entities/boshybullet.js
+++ b/src/entities/boshybullet.js
@@ -1,7 +1,8 @@
import { BOSHY } from "../assets.js"
import { Vector } from "../engine/vector.js"
-import { bullets } from "../main.js"
import { Entity } from "./entity.js"
+import { enemy } from "../main.js"
+import { Engine } from "../engine.js"
export class BoshyBullet extends Entity {
speed = 20
@@ -12,19 +13,17 @@ export class BoshyBullet extends Entity {
position: position.floor(),
sprite: BOSHY.BULLET,
})
-
- bullets.list.push(this)
}
update() {
this.position.y -= this.speed
if (this.position.y < 0) {
- this.span.remove()
- bullets.remove(this)
+ this.remove()
}
- }
- remove() {
- this.span.remove()
+ if (Engine.collision.collidingWithEnemy(this.position, this.hitbox)) {
+ enemy.hit()
+ this.remove()
+ }
}
}
diff --git a/src/entities/entity.js b/src/entities/entity.js
index ac14d4b..9d27508 100644
--- a/src/entities/entity.js
+++ b/src/entities/entity.js
@@ -1,5 +1,6 @@
import { Vector } from "../engine/vector.js"
import { Engine } from "../engine.js"
+import { entities } from "../main.js"
export class Entity {
constructor({
@@ -7,6 +8,7 @@ export class Entity {
hitbox = size,
sprite,
position = new Vector(0,0),
+ pixelated = false,
}) {
this.size = size
this.hitbox = hitbox
@@ -15,9 +17,20 @@ export class Entity {
this.span = document.createElement("img")
this.span.src = sprite
Engine.screen.append(this.span)
+
+ entities.list.push(this)
+ if (pixelated) this.span.className = "pixelated"
}
+ update() {}
+
draw() {
Engine.screen.draw(this.span, this.position, this.size)
}
+
+
+ remove() {
+ this.span.remove()
+ entities.remove(this)
+ }
}
diff --git a/src/entities/game_over.js b/src/entities/game_over.js
new file mode 100644
index 0000000..fc35938
--- /dev/null
+++ b/src/entities/game_over.js
@@ -0,0 +1,60 @@
+import { Vector } from "../engine/vector.js"
+import { Entity } from "./entity.js"
+import { GAME_OVER } from "../assets.js"
+
+export class GameOver extends Entity {
+ fadeWaitTime = 40
+ opacity = 0
+ stage = 0
+
+ zoomDelay = 7
+ zoomWaitTime = this.zoomDelay
+ zoomGrowth = 10
+ zoomedIn = false
+ initialSize = 400
+ maxSize = 550
+
+ constructor() {
+ super({
+ size: new Vector(400, 400),
+ position: new Vector(325, 250),
+ sprite: GAME_OVER,
+ pixelated: true,
+ })
+
+ this.span.style.zIndex = 5
+ this.span.style.opacity = 0
+ }
+
+ update() {
+ if (this.stage == 0) this.fadeIn()
+ this.zoomAnimation()
+ }
+
+ fadeIn() {
+ if (this.fadeWaitTime > 0) { this.fadeWaitTime--; return; }
+ if (this.opacity < 1) {
+ this.opacity += 0.05
+ this.span.style.opacity = this.opacity
+ return
+ }
+ this.stage = 1
+ }
+
+ zoomAnimation() {
+ if (this.zoomWaitTime > 0) { this.zoomWaitTime--; return; }
+ console.log("hi")
+ if (this.zoomedIn) this.size.add(new Vector(-this.zoomGrowth, -this.zoomGrowth))
+ else this.size.add(new Vector(this.zoomGrowth, this.zoomGrowth))
+ console.log(this.size)
+ if (
+ this.size.x == this.initialSize ||
+ this.size.x == this.maxSize
+ ) {
+ this.zoomedIn = !this.zoomedIn
+ this.zoomWaitTime = this.zoomDelay
+ }
+
+ }
+}
+
diff --git a/src/entities/hello_kitty.js b/src/entities/hello_kitty.js
new file mode 100644
index 0000000..eb7552a
--- /dev/null
+++ b/src/entities/hello_kitty.js
@@ -0,0 +1,75 @@
+import { Vector } from "../engine/vector.js"
+import { Engine } from "../engine.js"
+import { Entity } from "./entity.js"
+import { HELLO_KITTY } from "../assets.js"
+import { setEnemy, boshy } from "../main.js"
+
+export class HelloKitty extends Entity {
+ max_hp = 500
+ hp = this.max_hp
+ previous = 0
+ moveInterval = 30
+
+ justGotHit = false
+ turningRight = false
+
+ constructor() {
+ super({
+ size: new Vector(200, 200),
+ hitbox: new Vector(100, 200),
+ position: new Vector(325, 140),
+ sprite: HELLO_KITTY.MAIN[0],
+ pixelated: true,
+ })
+
+ this.span.style.zIndex = 1
+ setEnemy(this)
+ }
+
+ update() {
+ this.move()
+ if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) {
+ boshy.die()
+ }
+ }
+
+ move() {
+ /* get position */
+ let localscale = Math.sin((Engine.frame - this.previous) / this.moveInterval)
+ let viewport = Engine.screen.viewport
+ let newPos = (viewport.x / 2) + (localscale * viewport.x / 2) * 0.6
+
+ this.turningRight = this.position.x < newPos
+ this.position.x = newPos
+ // this.position.x += this.speed
+ // if (this.position.x > 325) this.speed -= this.acceleration
+ // else this.speed += this.acceleration
+ }
+
+ draw() {
+ /* hit effect */
+ if (this.justGotHit) {
+ this.span.style.filter = "brightness(500%)"
+ this.justGotHit = false
+ } else {
+ this.span.style.filter = "brightness(100%)"
+ }
+
+ if (this.turningRight) this.span.style.transform = "scaleX(-1)"
+ else this.span.style.transform = "scaleX(1)"
+
+ /* frame */
+ this.span.src = (Math.floor(Engine.frame / 10 % 2) == 0) ?
+ HELLO_KITTY.MAIN[0] :
+ HELLO_KITTY.MAIN[1]
+
+ /* draw */
+ super.draw()
+ }
+
+ hit() {
+ this.hp--
+ if (!this.justGotHit) Engine.radio.playSound(HELLO_KITTY.HIT_SOUND)
+ this.justGotHit = true
+ }
+}
diff --git a/src/entities/hello_kitty_background.js b/src/entities/hello_kitty_background.js
new file mode 100644
index 0000000..4d9a81f
--- /dev/null
+++ b/src/entities/hello_kitty_background.js
@@ -0,0 +1,41 @@
+import { Vector } from "../engine/vector.js"
+import { BACKGROUND } from "../assets.js"
+import { Entity } from "../entities/entity.js"
+import { Engine } from "../engine.js"
+
+export class HelloKittyBackground extends Entity {
+ speed = 20
+ stage = 0
+
+ constructor(position = null) {
+ let size = new Vector(1300, 2080)
+ let x_margin = 0
+ if (position == null) position = new Vector(
+ size.x / 2 + Engine.screen.viewport / 2 - x_margin,
+ - (size.y / 2) + Engine.screen.viewport.y,
+ )
+ super({
+ //size: new Vector(650, 1040),
+ size: size,
+ position: position,
+ sprite: BACKGROUND.KITTY,
+ })
+ this.span.style.zIndex = -3
+ this.max_down = (this.size.y / 2)
+ this.x_margin = x_margin
+ }
+
+ update() {
+ this.position.y += this.speed
+ if (this.stage == 0 && this.position.y > this.max_down) {
+ let margin = this.position.y - this.max_down
+ let newPos = new Vector(
+ this.size.x / 2 - this.x_margin,
+ - (this.size.y / 2) + margin
+ )
+
+ new HelloKittyBackground(newPos)
+ this.stage++
+ }
+ }
+}
diff --git a/src/entities/hp_bar.js b/src/entities/hp_bar.js
new file mode 100644
index 0000000..d6e68bb
--- /dev/null
+++ b/src/entities/hp_bar.js
@@ -0,0 +1,32 @@
+import { WHITE } from "../assets.js"
+import { Vector } from "../engine/vector.js"
+import { Engine } from "../engine.js"
+import { Entity } from "./entity.js"
+import { enemy } from "../main.js"
+
+export class HPBar extends Entity {
+ constructor() {
+ let size = new Vector(Engine.screen.viewport.x, 20)
+ super({
+ size: new Vector(Engine.screen.viewport.x, 20),
+ position: new Vector(size.x / 2, size.y / 2),
+ sprite: WHITE,
+ pixelated: true,
+ })
+
+ this.lasthp = enemy.hp
+ }
+
+ update() {
+ if (enemy.hp != this.lasthp) {
+ this.lasthp = enemy.hp
+
+ let hpScale = enemy.hp / enemy.max_hp
+ let viewport = Engine.screen.viewport
+
+ this.size.x = hpScale * viewport.x
+ this.position.x = (viewport.x / 2) - (1 - hpScale) / 2 * viewport.x
+ }
+ }
+}
+
diff --git a/src/entities/portal.js b/src/entities/portal.js
new file mode 100644
index 0000000..8e3c6c9
--- /dev/null
+++ b/src/entities/portal.js
@@ -0,0 +1,28 @@
+import { Entity } from "./entity.js"
+import { PORTAL } from "../assets.js"
+import { Vector } from "../engine/vector.js"
+import { Engine } from "../engine.js"
+import { SCENE, SCENES } from "../scenes.js"
+
+export class Portal extends Entity {
+ constructor() {
+ super({
+ size: new Vector(150, 150),
+ position: new Vector(325, 100),
+ sprite: PORTAL[0],
+ })
+
+ frames = PORTAL.length
+ }
+
+ update() {
+ if (Engine.collision.collidingWithBoshy(this.position, this.hitbox)) {
+ SCENE.load(SCENES.HELLO_KITTY)
+ }
+ }
+
+ draw() {
+ this.span.src = PORTAL[Math.floor(Engine.frame / 2) % frames]
+ super.draw()
+ }
+}