diff --git a/index.html b/index.html index dfaff35..f0ec376 100644 --- a/index.html +++ b/index.html @@ -9,9 +9,11 @@
+
diff --git a/level-all.bbiy b/level-all.bbiy index ee3c273..46f736a 100644 --- a/level-all.bbiy +++ b/level-all.bbiy @@ -29,8 +29,8 @@ hhhhhhhhhhhhhhhhhhhh wwwwwwwwwwww r - b r f - r + r f + b r wwwwwwwwwwww BIY FIX diff --git a/src/bootstrap.js b/src/bootstrap.js index b1fd62e..7a7d809 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,13 +1,19 @@ game.bootstrap = (() => { const scripts = [ - { src: ['src/utils/objectEquivalence.js', 'src/utils/unitizeVector.js', 'src/utils/clamp.js', 'src/utils/loadLevel.js'], id: 'utils'}, + { + src: [ + 'src/utils/objectEquivalence.js', 'src/utils/unitizeVector.js', 'src/utils/clamp.js', 'src/utils/loadLevel.js', + 'src/utils/randInRange.js' + ], + id: 'utils' + }, { src: ['src/render/graphics.js', 'src/render/sprites.js'], id: 'graphics' }, { src: ['src/components/component.js'], id: 'component' }, { src: [ 'src/components/position.js', 'src/components/momentum.js', 'src/components/gridPosition.js', 'src/components/appearence.js', 'src/components/controllable.js', 'src/components/pushable.js', - 'src/components/loadPriority.js', 'src/components/stop.js' + 'src/components/loadPriority.js', 'src/components/stop.js', 'src/components/alive.js', ], id: 'components' }, @@ -18,7 +24,8 @@ game.bootstrap = (() => { 'src/entities/liquid.js', 'src/entities/rock.js', 'src/entities/wall.js', 'src/entities/wordBigBlue.js', 'src/entities/wordFlag.js', 'src/entities/wordIs.js', 'src/entities/wordKill.js', 'src/entities/wordLava.js', 'src/entities/wordPush.js', 'src/entities/wordRock.js', 'src/entities/wordSink.js', 'src/entities/wordStop.js', - 'src/entities/wordWall.js', 'src/entities/wordWater.js', 'src/entities/wordWin.js', 'src/entities/wordYou.js' + 'src/entities/wordWall.js', 'src/entities/wordWater.js', 'src/entities/wordWin.js', 'src/entities/wordYou.js', + 'src/entities/borderParticles.js' ], id: 'entities' }, diff --git a/src/components/alive.js b/src/components/alive.js new file mode 100644 index 0000000..08b0890 --- /dev/null +++ b/src/components/alive.js @@ -0,0 +1 @@ +game.components.Alive = () => game.Component('alive'); \ No newline at end of file diff --git a/src/entities/bigblue.js b/src/entities/bigblue.js index 69593aa..02029a5 100644 --- a/src/entities/bigblue.js +++ b/src/entities/bigblue.js @@ -2,6 +2,7 @@ game.createBigBlue = () => { const bigBlue = game.Entity(); bigBlue.addComponent(game.components.LoadPriority({priority: 1})); bigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + bigBlue.addComponent(game.components.Alive()); bigBlue.sprite = game.sprites.bigBlue; // TODO: Remove this diff --git a/src/entities/borderParticles.js b/src/entities/borderParticles.js new file mode 100644 index 0000000..a8d7036 --- /dev/null +++ b/src/entities/borderParticles.js @@ -0,0 +1,55 @@ +game.createBorderParticles = ({colors, maxAmount, minAmount, minLife, maxLife, minRadius, maxRadius, maxSpeed}) => { + const particles = game.Entity(); + let particleSpecs = Array(randomInRange(minAmount, maxAmount)).fill(0).map(() => { + const particle = { + x: Math.random(), + y: Math.random(), + dx: Math.random() * maxSpeed - maxSpeed / 2, + dy: Math.random() * maxSpeed - maxSpeed / 2, + radius: randomInRange(minRadius, maxRadius), + color: colors[randomInRange(0, colors.length-1)], + lifetime: randomInRange(minLife, maxLife), + elapsed: 0, + }; + switch (Math.floor(Math.random() * 4)) { + case 0: + particle.y = 0; + particle.dy = -Math.abs(particle.dy); + break; + case 1: + particle.x = 1; + particle.dx = Math.abs(particle.dx); + break; + case 2: + particle.y = 1; + particle.dy = Math.abs(particle.dy); + break; + case 3: + particle.x = 0; + particle.dx = -Math.abs(particle.dx); + break; + } + return particle; + }); + particles.addComponent(game.components.LoadPriority({priority: 1})); + particles.addComponent(game.components.Alive()); + particles.sprite = game.graphics.Sprite({ + drawFunction: (elapsedTime, {x, y, width, height}, context) => { + particleSpecs.map((spec) => spec.elapsed += elapsedTime); + particleSpecs = particleSpecs.filter((spec) => spec.lifetime > spec.elapsed); + if (particleSpecs.length === 0) { + particles.removeComponent("alive"); + } + particleSpecs.map((spec) => { + const position = {x: (spec.x * width) + x + spec.dx * spec.elapsed, y: (spec.y * height) + y + spec.dy * spec.elapsed}; + const fill = context.fillStyle; + context.fillStyle = spec.color; + context.beginPath(); + context.arc(position.x, position.y, spec.radius, 0, 2 * Math.PI); + context.fill(); + context.fillStyle = fill; + }); + } + }) + return particles; +} \ No newline at end of file diff --git a/src/entities/entity.js b/src/entities/entity.js index 1eb5223..3da032c 100644 --- a/src/entities/entity.js +++ b/src/entities/entity.js @@ -13,7 +13,6 @@ game.Entity = (id=game.nextId++) => { } }; - return { id, components, diff --git a/src/entities/flag.js b/src/entities/flag.js index fa10d9f..87daeb7 100644 --- a/src/entities/flag.js +++ b/src/entities/flag.js @@ -2,6 +2,7 @@ game.createFlag = () => { const flag = game.Entity(); flag.addComponent(game.components.LoadPriority({priority: 2})); flag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + flag.addComponent(game.components.Alive()); flag.sprite = game.sprites.flag; return flag; } diff --git a/src/entities/floor.js b/src/entities/floor.js index 0210f37..d16392e 100644 --- a/src/entities/floor.js +++ b/src/entities/floor.js @@ -2,6 +2,7 @@ game.createFloor = () => { const floor = game.Entity(); floor.addComponent(game.components.LoadPriority({priority: 5})); floor.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + floor.addComponent(game.components.Alive()); floor.sprite = game.sprites.floor; return floor; } diff --git a/src/entities/grass.js b/src/entities/grass.js index f2a6da2..f731ef1 100644 --- a/src/entities/grass.js +++ b/src/entities/grass.js @@ -2,6 +2,7 @@ game.createGrass = () => { const grass = game.Entity(); grass.addComponent(game.components.LoadPriority({priority: 6})); grass.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + grass.addComponent(game.components.Alive()); grass.sprite = game.sprites.grass; return grass; } diff --git a/src/entities/hedge.js b/src/entities/hedge.js index ab5ef35..03ecb0f 100644 --- a/src/entities/hedge.js +++ b/src/entities/hedge.js @@ -3,6 +3,7 @@ game.createHedge = () => { hedge.addComponent(game.components.LoadPriority({priority: 6})); hedge.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); hedge.addComponent(game.components.Stop({stop: true})); + hedge.addComponent(game.components.Alive()); hedge.sprite = game.sprites.hedge; return hedge; } diff --git a/src/entities/liquid.js b/src/entities/liquid.js index 8c7d8ea..27026d6 100644 --- a/src/entities/liquid.js +++ b/src/entities/liquid.js @@ -4,6 +4,7 @@ game.createLiquid = () => { liquid.addComponent(game.components.LoadPriority({priority: 5})); liquid.addComponent(game.components.Position({x: 0, y: 0})); liquid.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + liquid.addComponent(game.components.Alive()); liquid.sprite = game.graphics.Sprite({ image: game.assets.liquid, spriteHeight: 24, diff --git a/src/entities/rock.js b/src/entities/rock.js index c852f10..7602ab6 100644 --- a/src/entities/rock.js +++ b/src/entities/rock.js @@ -2,6 +2,7 @@ game.createRock = () => { const rock = game.Entity(); rock.addComponent(game.components.LoadPriority({priority: 2})); rock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); + rock.addComponent(game.components.Alive()); rock.sprite = game.sprites.rock; //TODO: Remove this diff --git a/src/entities/wall.js b/src/entities/wall.js index 73c3adb..84c9a91 100644 --- a/src/entities/wall.js +++ b/src/entities/wall.js @@ -3,6 +3,7 @@ game.createWall = () => { wall.addComponent(game.components.LoadPriority({priority: 3})); wall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wall.addComponent(game.components.Stop({stop: true})); + wall.addComponent(game.components.Alive()); wall.sprite = game.sprites.wall; return wall; } diff --git a/src/entities/wordBigBlue.js b/src/entities/wordBigBlue.js index d21e15c..537c523 100644 --- a/src/entities/wordBigBlue.js +++ b/src/entities/wordBigBlue.js @@ -3,6 +3,7 @@ game.createWordBigBlue = () => { wordBigBlue.addComponent(game.components.LoadPriority({priority: 3})); wordBigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordBigBlue.addComponent(game.components.Pushable({pushable: true})); + wordBigBlue.addComponent(game.components.Alive()); wordBigBlue.sprite = game.sprites.wordBigBlue; return wordBigBlue; } diff --git a/src/entities/wordFlag.js b/src/entities/wordFlag.js index 0a23da4..dd95845 100644 --- a/src/entities/wordFlag.js +++ b/src/entities/wordFlag.js @@ -3,6 +3,7 @@ game.createWordFlag = () => { wordFlag.addComponent(game.components.LoadPriority({priority: 3})); wordFlag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordFlag.addComponent(game.components.Pushable({pushable: true})); + wordFlag.addComponent(game.components.Alive()); wordFlag.sprite = game.sprites.wordFlag; return wordFlag; } diff --git a/src/entities/wordIs.js b/src/entities/wordIs.js index 02b31bd..a32bfa1 100644 --- a/src/entities/wordIs.js +++ b/src/entities/wordIs.js @@ -3,6 +3,7 @@ game.createWordIs = () => { wordIs.addComponent(game.components.LoadPriority({priority: 3})); wordIs.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordIs.addComponent(game.components.Stop({stop: true})); + wordIs.addComponent(game.components.Alive()); wordIs.sprite = game.sprites.wordIs; return wordIs; } diff --git a/src/entities/wordKill.js b/src/entities/wordKill.js index 7bc0972..283ce90 100644 --- a/src/entities/wordKill.js +++ b/src/entities/wordKill.js @@ -3,6 +3,7 @@ game.createWordKill = () => { wordKill.addComponent(game.components.LoadPriority({priority: 3})); wordKill.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordKill.addComponent(game.components.Pushable({pushable: true})); + wordKill.addComponent(game.components.Alive()); wordKill.sprite = game.sprites.wordKill; return wordKill; } diff --git a/src/entities/wordLava.js b/src/entities/wordLava.js index 573dd29..dc50bf3 100644 --- a/src/entities/wordLava.js +++ b/src/entities/wordLava.js @@ -3,6 +3,7 @@ game.createWordLava = () => { wordLava.addComponent(game.components.LoadPriority({priority: 3})); wordLava.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordLava.addComponent(game.components.Pushable({pushable: true})); + wordLava.addComponent(game.components.Alive()); wordLava.sprite = game.sprites.wordLava; return wordLava; diff --git a/src/entities/wordPush.js b/src/entities/wordPush.js index bd4c267..20a4b8e 100644 --- a/src/entities/wordPush.js +++ b/src/entities/wordPush.js @@ -3,6 +3,7 @@ game.createWordPush = () => { wordPush.addComponent(game.components.LoadPriority({priority: 3})); wordPush.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordPush.addComponent(game.components.Pushable({pushable: true})); + wordPush.addComponent(game.components.Alive()); wordPush.sprite = game.sprites.wordPush; return wordPush; } diff --git a/src/entities/wordRock.js b/src/entities/wordRock.js index be303c4..96d8982 100644 --- a/src/entities/wordRock.js +++ b/src/entities/wordRock.js @@ -3,6 +3,7 @@ game.createWordRock = () => { wordRock.addComponent(game.components.LoadPriority({priority: 3})); wordRock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordRock.addComponent(game.components.Pushable({pushable: true})); + wordRock.addComponent(game.components.Alive()); wordRock.sprite = game.sprites.wordRock; return wordRock; } diff --git a/src/entities/wordSink.js b/src/entities/wordSink.js index 298778d..2da3e07 100644 --- a/src/entities/wordSink.js +++ b/src/entities/wordSink.js @@ -3,6 +3,7 @@ game.createWordSink = () => { wordSink.addComponent(game.components.LoadPriority({priority: 3})); wordSink.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordSink.addComponent(game.components.Pushable({pushable: true})); + wordSink.addComponent(game.components.Alive()); wordSink.sprite = game.sprites.wordSink; return wordSink; } diff --git a/src/entities/wordStop.js b/src/entities/wordStop.js index 30907d8..0f6f97a 100644 --- a/src/entities/wordStop.js +++ b/src/entities/wordStop.js @@ -3,6 +3,7 @@ game.createWordStop = () => { wordStop.addComponent(game.components.LoadPriority({priority: 3})); wordStop.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordStop.addComponent(game.components.Pushable({pushable: true})); + wordStop.addComponent(game.components.Alive()); wordStop.sprite = game.sprites.wordStop; return wordStop; } diff --git a/src/entities/wordWall.js b/src/entities/wordWall.js index 6d4678b..4dac235 100644 --- a/src/entities/wordWall.js +++ b/src/entities/wordWall.js @@ -3,6 +3,7 @@ game.createWordWall = () => { wordWall.addComponent(game.components.LoadPriority({priority: 3})); wordWall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordWall.addComponent(game.components.Pushable({pushable: true})); + wordWall.addComponent(game.components.Alive()); wordWall.sprite = game.sprites.wordWall; return wordWall; } diff --git a/src/entities/wordWater.js b/src/entities/wordWater.js index ae4bb7c..e6272d1 100644 --- a/src/entities/wordWater.js +++ b/src/entities/wordWater.js @@ -3,6 +3,7 @@ game.createWordWater = () => { wordWater.addComponent(game.components.LoadPriority({priority: 3})); wordWater.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordWater.addComponent(game.components.Pushable({pushable: true})); + wordWater.addComponent(game.components.Alive()); wordWater.sprite = game.sprites.wordWater; return wordWater; } diff --git a/src/entities/wordWin.js b/src/entities/wordWin.js index f6386b9..a3830b9 100644 --- a/src/entities/wordWin.js +++ b/src/entities/wordWin.js @@ -3,6 +3,7 @@ game.createWordWin = () => { wordWin.addComponent(game.components.LoadPriority({priority: 3})); wordWin.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordWin.addComponent(game.components.Pushable({pushable: true})); + wordWin.addComponent(game.components.Alive()); wordWin.sprite = game.sprites.wordWin; return wordWin; } diff --git a/src/entities/wordYou.js b/src/entities/wordYou.js index 2fe97d3..49a0044 100644 --- a/src/entities/wordYou.js +++ b/src/entities/wordYou.js @@ -3,6 +3,7 @@ game.createWordYou = () => { wordYou.addComponent(game.components.LoadPriority({priority: 3})); wordYou.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); wordYou.addComponent(game.components.Pushable({pushable: true})); + wordYou.addComponent(game.components.Alive()); wordYou.sprite = game.sprites.wordYou; return wordYou; } diff --git a/src/game.js b/src/game.js index 073455a..60d2a27 100644 --- a/src/game.js +++ b/src/game.js @@ -3,10 +3,17 @@ game.loop = (timeStamp) => { let elapsedTime = timeStamp - lastTimeStamp; lastTimeStamp = timeStamp; + game.systemOrder.map((i) => { game.systems[i].update(elapsedTime, game.entities); }); + for (let id in game.entities) { + if (!game.entities[id].hasComponent("alive")) { + delete game.entities[id]; + } + } + if (game.nextLevel) { game.loadLevel(game.nextLevel); game.nextLevel = false; @@ -26,7 +33,6 @@ game.initialize = () => { keyboardInput: game.system.KeyboardInput(), }; - lastTimeStamp = performance.now() requestAnimationFrame(game.loop); } diff --git a/src/systems/gridSystem.js b/src/systems/gridSystem.js index e8a6c82..d9c8a6b 100644 --- a/src/systems/gridSystem.js +++ b/src/systems/gridSystem.js @@ -52,6 +52,8 @@ game.system.GridSystem = ({ xDim, yDim }) => { }); const proposed = {...newGridCoords}; + let wall = false; + let entitiesToPush = []; if (entity.hasComponent("controllable")) { let found = false; do { @@ -60,7 +62,12 @@ game.system.GridSystem = ({ xDim, yDim }) => { for (let entity of entitiesInCell.values()) { if (entity.hasComponent("pushable")) { found = true; - entity.addComponent(game.components.Momentum({...momentumVector})); + entitiesToPush.push(entity); + } + if (entity.hasComponent("stop")) { + wall = true; + found = false; + break; } } proposed.x += momentumVector.dx; @@ -72,17 +79,28 @@ game.system.GridSystem = ({ xDim, yDim }) => { } while (found); } - if (entity.hasComponent("pushable") || entity.hasComponent("controllable")) { - for (let e of entitiesGrid[newGridCoords.y][newGridCoords.x].values()) { - if (e.hasComponent("stop")) { - newGridCoords = oldGridCoords; - break; - } + if (entity.hasComponent("controllable")) { + if (!wall) { + entity.components.gridPosition = {...entity.components.gridPosition, ...newGridCoords}; + entitiesToPush.map((e) => e.addComponent(game.components.Momentum({...momentumVector}))); } - entity.addComponent(game.components.Momentum({...momentumVector})); + const particles = game.createBorderParticles({ + colors: ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"], + maxAmount: 100, + minAmount: 25, + minLife: 100, + maxLife: 300, + minRadius: 1, + maxRadius: 3, + maxSpeed: 0.15, + }); + particles.addComponent(game.components.Position(gridCoordsToGame(oldGridCoords))); + particles.addComponent(game.components.Appearance({width: 50, height: 50})); + game.entities[particles.id] = particles; + } else { + entity.components.gridPosition = {...entity.components.gridPosition, ...newGridCoords}; } - entity.components.gridPosition = {...entity.components.gridPosition, ...newGridCoords}; entity.components.position = { ...entity.components.position, diff --git a/src/utils/randInRange.js b/src/utils/randInRange.js new file mode 100644 index 0000000..528221a --- /dev/null +++ b/src/utils/randInRange.js @@ -0,0 +1,4 @@ +const randomInRange = (min, max) => { + // min <= random number <= max + return Math.floor(Math.random() * (max - min + 1)) + min; +} \ No newline at end of file