Skip to content

Commit

Permalink
refactor(events): modularize enemy states
Browse files Browse the repository at this point in the history
  • Loading branch information
remarkablemark committed Jan 24, 2025
1 parent 1a0df01 commit 0384a36
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/constants/animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export enum Animation {
Attack = 'Attack',
Cooldown = 'Cooldown',
Idle = 'Idle',
Move = 'Move',
Stunned = 'Stunned',
}
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './music'
export * from './scenes'
export * from './sounds'
export * from './sprites'
export * from './states'
export * from './tags'
1 change: 1 addition & 0 deletions src/constants/states.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Animation as State } from './animations'
1 change: 1 addition & 0 deletions src/events/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './attack'
export * from './cursors'
export * from './states'
59 changes: 59 additions & 0 deletions src/events/states.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Animation, Sprite, State } from '../constants'
import { addProjectile, getPlayer } from '../gameobjects'
import type { Enemy } from '../types'

export function addEnemyState(enemy: Enemy) {
enemy.onStateEnter(State.Idle, async () => {
enemy.play(Animation.Idle)
await wait(rand(0.3, 1))
enemy.enterState(State.Move)
})

enemy.onStateEnter(State.Move, () => {
enemy.play(Animation.Move)
})

enemy.onStateEnter(State.Attack, async () => {
const player = getPlayer()

if (!player?.exists()) {
return
}

enemy.play(Animation.Attack)

if (enemy.sprite === Sprite.Pokey) {
addProjectile(enemy, player)
}

await wait(0.2)
enemy.enterState(State.Cooldown)
})

enemy.onStateEnter(State.Cooldown, async () => {
enemy.play(Animation.Cooldown)
await wait(rand(1, 3))
enemy.enterState(State.Move)
})

enemy.onStateEnter(State.Stunned, async () => {
enemy.play(Animation.Stunned)
await wait(rand(0.3, 1))
enemy.enterState(State.Move)
})

enemy.onStateUpdate(State.Move, async () => {
const player = getPlayer()

if (!player?.exists()) {
return
}

if (enemy.sprite === Sprite.Pokey && Number(rand()) < 0.005) {
return enemy.enterState(State.Attack)
}

const direction = player.pos.sub(enemy.pos).unit()
enemy.move(direction.scale(enemy.speed))
})
}
55 changes: 8 additions & 47 deletions src/gameobjects/enemy.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Animation, Sound, Sprite, Tag } from '../constants'
import type { Player } from '../types'
import { addProjectile } from './projectile'
import { Sound, Sprite, State, Tag } from '../constants'
import { addEnemyState } from '../events'
import { getPlayer } from './player'
import { incrementScore } from './score'

enum Health {
Min = 20,
Max = 100,
}

const State = Animation

export function addEnemy(x: number, y: number, player: Player) {
export function addEnemy(x: number, y: number) {
const sprites = [
Sprite.Bubbie,
Sprite.Gooba,
Expand All @@ -31,57 +29,20 @@ export function addEnemy(x: number, y: number, player: Player) {
area(),
body(),
scale(0.75),
state(State.Attack, Object.values(State)),
state(State.Move, Object.values(State)),
Tag.Enemy,
{ damage, speed },
])

enemy.onStateEnter(State.Idle, async () => {
enemy.play(State.Idle)
await wait(rand(0, 1))
enemy.enterState(State.Attack)
})

enemy.onStateEnter(State.Stunned, async () => {
enemy.play(State.Stunned)
await wait(rand(0, 1))
enemy.enterState(State.Attack)
})

enemy.onStateEnter(State.Cooldown, async () => {
enemy.play(State.Cooldown)
await wait(rand(1, 3))
enemy.enterState(State.Attack)
})

enemy.onStateEnter(State.Attack, async () => {
enemy.play(State.Attack)
if (enemy.sprite === Sprite.Pokey) {
addProjectile(enemy, player)
}
})

enemy.onStateUpdate(State.Attack, async () => {
if (!player.exists()) {
return
}

if (enemy.sprite === Sprite.Pokey && Number(rand()) < 0.005) {
return enemy.enterState(State.Idle)
}

const direction = player.pos.sub(enemy.pos).unit()
enemy.move(direction.scale(enemy.speed))
})
addEnemyState(enemy)

enemy.onCollide(Tag.Player, async () => {
enemy.enterState(State.Cooldown)
player.hurt(enemy.damage)
enemy.enterState(State.Attack)
getPlayer()?.hurt(enemy.damage)
})

enemy.onHurt(() => {
enemy.enterState(State.Stunned)
enemy.play(State.Stunned)
})

enemy.onDeath(() => {
Expand Down
5 changes: 5 additions & 0 deletions src/gameobjects/player.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Scene, Sound, Sprite, Tag } from '../constants'
import { addAttack, addCursorKeys } from '../events'
import { stopMusic } from '../gameobjects'
import type { Player } from '../types'

const HEALTH = 100

Expand Down Expand Up @@ -35,3 +36,7 @@ export function addPlayer(x = center().x, y = center().y) {

return player
}

export function getPlayer() {
return get(Tag.Player)[0] as Player | undefined
}
2 changes: 1 addition & 1 deletion src/scenes/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ scene(Scene.Game, () => {

loop(5, () => {
const { x, y } = outsideCoordinates(player.pos.x, player.pos.y)
addEnemy(x, y, player)
addEnemy(x, y)
})
})
9 changes: 5 additions & 4 deletions src/scenes/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ scene(Scene.Preload, () => {
sliceX: 4,
anims: {
[Animation.Idle]: 0,
[Animation.Move]: 0,
[Animation.Attack]: 1,
[Animation.Cooldown]: 2,
[Animation.Stunned]: 3,
Expand All @@ -21,14 +22,13 @@ scene(Scene.Preload, () => {
loadSprite(Sprite.Pokey, 'sprites/pokey.png', {
sliceX: 5,
anims: {
[Animation.Idle]: 3,
[Animation.Move]: 0,
[Animation.Attack]: {
from: 1,
to: 2,
loop: true,
speed: 1,
},
[Animation.Cooldown]: 0,
[Animation.Idle]: 3,
[Animation.Stunned]: 4,
},
})
Expand All @@ -43,9 +43,10 @@ scene(Scene.Preload, () => {
sprites.forEach(([name, src]) => {
loadSprite(name, src, {
anims: {
[Animation.Idle]: 0,
[Animation.Move]: 0,
[Animation.Attack]: 0,
[Animation.Cooldown]: 0,
[Animation.Idle]: 0,
[Animation.Stunned]: 0,
},
})
Expand Down

0 comments on commit 0384a36

Please sign in to comment.