diff --git a/public/js/Entity.js b/public/js/Entity.js index d5c220d9..b8878bd2 100644 --- a/public/js/Entity.js +++ b/public/js/Entity.js @@ -44,6 +44,7 @@ export default class Entity { constructor() { this.audio = new AudioBoard(); this.sounds = new Set(); + this.pos = new Vec2(0, 0); this.vel = new Vec2(0, 0); this.size = new Vec2(0, 0); diff --git a/public/js/entities.js b/public/js/entities.js index 5a1f6174..265e00c8 100644 --- a/public/js/entities.js +++ b/public/js/entities.js @@ -1,24 +1,25 @@ -import {loadBulletBill} from './entities/BulletBill.js'; import {loadMario} from './entities/Mario.js'; import {loadGoomba} from './entities/Goomba.js'; import {loadKoopa} from './entities/Koopa.js'; +import {loadBullet} from './entities/Bullet.js'; import {loadCannon} from './entities/Cannon.js'; -export async function loadEntities(audioContext) { + +export function loadEntities(audioContext) { const entityFactories = {}; function addAs(name) { return factory => entityFactories[name] = factory; } - await Promise.all([ + + return Promise.all([ loadMario(audioContext).then(addAs('mario')), loadGoomba(audioContext).then(addAs('goomba')), loadKoopa(audioContext).then(addAs('koopa')), - loadBulletBill(audioContext).then(addAs('bulletBill')), - ]); - - await loadCannon(entityFactories, audioContext).then(addAs('cannon')); + loadBullet(audioContext).then(addAs('bullet')), + loadCannon(audioContext, entityFactories).then(addAs('cannon')), - return entityFactories; -} + ]) + .then(() => entityFactories); +} \ No newline at end of file diff --git a/public/js/entities/Cannon.js b/public/js/entities/Cannon.js index d6886eaf..1cd182c0 100644 --- a/public/js/entities/Cannon.js +++ b/public/js/entities/Cannon.js @@ -1,32 +1,41 @@ -import {findPlayers} from '../player.js'; -import Entity, {Trait} from '../Entity.js'; +import Entity from '../Entity.js'; import Emitter from '../traits/Emitter.js'; +import {findPlayers} from '../player.js'; import {loadAudioBoard} from '../loaders/audio.js'; -export function loadCannon(entityFactory, audioContext) { +const HOLD_FIRE_THRESHOLD = 30; + +export function loadCannon(audioContext, entityFactories) { return loadAudioBoard('cannon', audioContext) .then(audio => { - return createCannonFactory(entityFactory, audio); + return createCannonFactory(audio, entityFactories); }); } -function createCannonFactory(entityFactory, audio) { - const createBullet = entityFactory.bulletBill; +function createCannonFactory(audio, entityFactories) { - const bulletEmitter = (entity, level) => { + + function emitBullet(cannon, level) { + let dir = 1; for (const player of findPlayers(level)) { - if (player.pos.x > entity.pos.x - 30 && player.pos.x < entity.pos.x + 30) { + if (player.pos.x > cannon.pos.x - HOLD_FIRE_THRESHOLD + && player.pos.x < cannon.pos.x + HOLD_FIRE_THRESHOLD) { return; } + + if (player.pos.x < cannon.pos.x) { + dir = -1; + } } - entity.sounds.add('shoot'); + const bullet = entityFactories.bullet(); + + bullet.pos.copy(cannon.pos); + bullet.vel.set(80 * dir, 0); - const bullet = createBullet(); - bullet.vel.set(80, 0); - bullet.pos.copy(entity.pos); + cannon.sounds.add('shoot'); level.entities.add(bullet); - }; + } return function createCannon() { const cannon = new Entity(); @@ -34,10 +43,8 @@ function createCannonFactory(entityFactory, audio) { const emitter = new Emitter(); emitter.interval = 4; - emitter.emitters.push(bulletEmitter); - + emitter.emitters.push(emitBullet); cannon.addTrait(emitter); - return cannon; - }; + } } diff --git a/public/js/main.js b/public/js/main.js index 3d76ae74..637d89f9 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -3,11 +3,12 @@ import Timer from './Timer.js'; import {createLevelLoader} from './loaders/level.js'; import {loadFont} from './loaders/font.js'; import {loadEntities} from './entities.js'; +import {createPlayer, createPlayerEnv} from './player.js'; import {setupKeyboard} from './input.js'; -import {createPlayerEnv, createPlayer} from './player.js'; import {createCollisionLayer} from './layers/collision.js'; import {createDashboardLayer} from './layers/dashboard.js'; + async function main(canvas) { const context = canvas.getContext('2d'); const audioContext = new AudioContext(); @@ -24,11 +25,12 @@ async function main(canvas) { const camera = new Camera(); - const mario = createPlayer(entityFactory.mario); + const mario = createPlayer(entityFactory.mario()); const playerEnv = createPlayerEnv(mario); level.entities.add(playerEnv); + level.comp.layers.push(createCollisionLayer(level)); level.comp.layers.push(createDashboardLayer(font, playerEnv)); diff --git a/public/js/math.js b/public/js/math.js index 82f475d2..f5a37571 100644 --- a/public/js/math.js +++ b/public/js/math.js @@ -34,7 +34,8 @@ export class Vec2 { } copy(vec2) { - this.set(vec2.x, vec2.y); + this.x = vec2.x; + this.y = vec2.y; } set(x, y) { diff --git a/public/js/player.js b/public/js/player.js index 93b45c8b..13049854 100644 --- a/public/js/player.js +++ b/public/js/player.js @@ -1,6 +1,6 @@ import Entity from './Entity.js'; -import PlayerController from './traits/PlayerController.js'; import Player from './traits/Player.js'; +import PlayerController from './traits/PlayerController.js'; export function createPlayerEnv(playerEntity) { const playerEnv = new Entity(); @@ -11,13 +11,12 @@ export function createPlayerEnv(playerEntity) { return playerEnv; } -export function createPlayer(factory) { - const entity = factory(); +export function createPlayer(entity) { entity.addTrait(new Player()); return entity; } -export function* findPlayers (level) { +export function* findPlayers(level) { for (const entity of level.entities) { if (entity.player) { yield entity; diff --git a/public/js/traits/Emitter.js b/public/js/traits/Emitter.js index 39b86d8e..09fe4e3a 100644 --- a/public/js/traits/Emitter.js +++ b/public/js/traits/Emitter.js @@ -3,9 +3,9 @@ import {Trait} from '../Entity.js'; export default class Emitter extends Trait { constructor() { super('emitter'); - this.emitters = []; this.interval = 2; this.coolDown = this.interval; + this.emitters = []; } emit(entity, level) { diff --git a/public/js/traits/Physics.js b/public/js/traits/Physics.js index c06f4126..7246b761 100644 --- a/public/js/traits/Physics.js +++ b/public/js/traits/Physics.js @@ -1,21 +1,17 @@ import {Trait} from '../Entity.js'; -import Gravity from './Gravity.js'; export default class Physics extends Trait { constructor() { super('physics'); - this.gravity = new Gravity(); } - update(entity, gameContext, level) { - const {deltaTime} = gameContext; - + update(entity, {deltaTime}, level) { entity.pos.x += entity.vel.x * deltaTime; level.tileCollider.checkX(entity); entity.pos.y += entity.vel.y * deltaTime; level.tileCollider.checkY(entity); - this.gravity.update(entity, gameContext, level); + entity.vel.y += level.gravity * deltaTime; } } diff --git a/public/js/traits/Player.js b/public/js/traits/Player.js index 16c46de0..daa771ef 100644 --- a/public/js/traits/Player.js +++ b/public/js/traits/Player.js @@ -1,5 +1,4 @@ import {Trait} from '../Entity.js'; -import {Vec2} from '../math.js'; export default class Player extends Trait { constructor() { diff --git a/public/js/traits/Stomper.js b/public/js/traits/Stomper.js index 0d5417bb..7d15a060 100644 --- a/public/js/traits/Stomper.js +++ b/public/js/traits/Stomper.js @@ -7,10 +7,8 @@ export default class Stomper extends Trait { } bounce(us, them) { - this.queue(() => { - us.bounds.bottom = them.bounds.top; - us.vel.y = -this.bounceSpeed; - }); + us.bounds.bottom = them.bounds.top; + us.vel.y = -this.bounceSpeed; } collides(us, them) { @@ -19,7 +17,7 @@ export default class Stomper extends Trait { } if (us.vel.y > them.vel.y) { - this.bounce(us, them); + this.queue(() => this.bounce(us, them)); us.sounds.add('stomp'); this.events.emit('stomp', us, them); } diff --git a/public/levels/1-1.json b/public/levels/1-1.json index acef9db0..c4728bb9 100644 --- a/public/levels/1-1.json +++ b/public/levels/1-1.json @@ -128,6 +128,7 @@ } ] }, + "cannon-2h": { "tiles": [ { @@ -399,7 +400,7 @@ }, { "name": "cannon", - "pos": [104, 112] + "pos": [96, 112] } ] } diff --git a/public/sprites/overworld.json b/public/sprites/overworld.json index f9e75248..1dcfeb48 100644 --- a/public/sprites/overworld.json +++ b/public/sprites/overworld.json @@ -105,4 +105,4 @@ ] } ] -} +} \ No newline at end of file