From dee568c51dbf2393aa7bd75f4241602af8022a2c Mon Sep 17 00:00:00 2001 From: Logan Hunt Date: Mon, 4 Apr 2022 18:30:11 -0600 Subject: [PATCH] Fix flickering issue by having singleton sprites; add loading priority; load levels from source --- .DS_Store | Bin 6148 -> 6148 bytes assets/.DS_Store | Bin 8196 -> 8196 bytes assets/image/.DS_Store | Bin 8196 -> 8196 bytes assets/image/hedge.png | Bin 1627 -> 1640 bytes assets/image/wall.png | Bin 1053 -> 1315 bytes index.js | 42 ++++++++++ src/bootstrap.js | 16 +++- src/components/loadPriority.js | 1 + src/entities/bigblue.js | 14 ++-- src/entities/flag.js | 10 +-- src/entities/floor.js | 10 +-- src/entities/grass.js | 10 +-- src/entities/hedge.js | 10 +-- src/entities/liquid.js | 2 + src/entities/rock.js | 14 ++-- src/entities/wall.js | 10 +-- src/entities/wordBigBlue.js | 10 +-- src/entities/wordFlag.js | 10 +-- src/entities/wordIs.js | 10 +-- src/entities/wordKill.js | 10 +-- src/entities/wordLava.js | 10 +-- src/entities/wordPush.js | 10 +-- src/entities/wordRock.js | 10 +-- src/entities/wordSink.js | 10 +-- src/entities/wordStop.js | 10 +-- src/entities/wordWall.js | 10 +-- src/entities/wordWater.js | 10 +-- src/entities/wordWin.js | 10 +-- src/entities/wordYou.js | 10 +-- src/game.js | 28 ++----- src/render/sprites.js | 142 +++++++++++++++++++++++++++++++++ src/systems/gridSystem.js | 16 ++-- src/systems/render.js | 12 ++- src/utils/loadLevel.js | 66 +++++++++++++++ 34 files changed, 339 insertions(+), 194 deletions(-) create mode 100644 src/components/loadPriority.js create mode 100644 src/render/sprites.js create mode 100644 src/utils/loadLevel.js diff --git a/.DS_Store b/.DS_Store index 68b99032edf759e06c9b1c72c03e680d9c539b94..d794b1aa8ebd1e750edca41526dd3db8466ac05d 100644 GIT binary patch delta 432 zcmZoMXfc=|#>B!ku~2NHo+2a9#(>?7iytsEG4f32VRC2OHaUc;P*tqD+C)devQ|f- z+R)O_NJqiYz}URDmXkwNS>HM+K07BjFTZ2*TPAtN&dI#Y@`+pwnGAUhDGaF$6%2X| z84M*1xePg;Ir+&+Ir&Kp3=9Gc42(a4wBCO(0J0buI8gLtF%+Y!XG%v_KUtI6u|AI> zA8bcF&~y;1lpzObBf7q;$ohb6L52c`M22LBY#^BqRIdxvl@I3YF#v4^vhz@FW_Ct1 zfd^v3B)qu~2NHo+2aL#(>?7jBJy6Slk(RP7Yxy)R3&MHa0Lf)lo1qG_2K8 zsJ1jR)KM_AG_S4Y?Xj)K`_4-xat+=4&YHnU57W0^c% Lgnu)K=np0U&qWZO diff --git a/assets/image/.DS_Store b/assets/image/.DS_Store index 9adcaf94708215617b58b7d4f9ab576fd51a24e0..a4819cb9ed2ebd64f550b37fd43fc00255a3d41c 100644 GIT binary patch delta 36 scmZp1XmOa}&nUVvU^hRb=wu!N%gqY~3|ThU%d|32Y~b0@~ delta 89 zcmZp1XmOa}&nUJrU^hRb*km37OGdfL0s>-Y40;U33`q>S49N_}43-Q=3?>X|45kbz sKoL_00|r-y0)}vgOwXMBVp1H6vAKK!lVbujlQ04oh>hAjL*@+b*-rg3^r>`G> z<^%0M7<}XCPqlrYwTt{y#)hd&Ou3EObNwVFGB5a68?Q6_ zvN9Wse%d!)&~$>n2xeckG>>uM3)fDg+R0~%l+%+r$-Jy?58ohCB}agZ#aS7$+VbwKbWIxyO_0gJniX zHI{yQtc7>3`RRSaqY3}8sDm<_XJP7u6O0Z&vn$#uC%WL)PrdWqN1Ob{oDq&Q81Mf2 z2F1|iH1|?3*=0=J3NyaTH#eOXEIMbpM>ApJo)-kk!k#09f9pPT^msD!*aMbo{iJEk z+3v{%YhU=rq6Nc8C65~2^Ix$kD44@+q9-^(UJ4#v@KX*ta;eU7Z#{eQq(-~aTSq^g zpWK(HUC#&hRfzk@7FZy`&JxsQI*7*EfGb~S^a zYI5@Fvt(|Jf1Qo91HR|+f-I(|5qwCVenGtG+X$C!b8$)|;DlS#KWS%P;AG zE$Z2UgiIJ*SMpAtiJvg?;gV0^9P_H;^BG^hK?oAyJ~O8DdEkS?frST4&tpEAHO=8c zLv1`WUaGP9+KX=DI{&&LOc4<13LngU2QqiX6P#Q$f1aa5YaH#JijRti+|2GXue8?% zMRa;PH1mYzFV4n0yAK4v!pTeB<@aB^_{evixM0TLT@YjrO7GD0ehGSO^Z&i=VUEsP z_h?RammiMh&gPtC_iQbi)OQyY(Bky@bf9PJK!!== zu1TzSak_qca?^~i^W5$DnBUD*PtW|5KhMKUJs;>~%tJ2Q^{;_+${c1C?k9g{I_ot{ zoDN2*f9ZU<)F%%|=`~NiI2y3~8zj&Mjdpb%ByU&8?wl7@M^9XB@;OiZgr#RUr`OM< zp8b)RbEYG*Yp{#k)p8i6PCR$!)-<2FC%sxab;>3WU7zXR{`(uWGimN_SbB4AJ$v%b z<}{yvwUZ{fG{6khm8ikJ;W#7=3D)7*IPm-{<2{c3mlsh{S|&lxTGjb+B_+|)4N-yjT4PJ18f z2SvNfn79>|_%1)W>8@hvGBam269)HuAW0AG9id#$?C2@xtn?&)sW1JcX)LpIHdCy9 zfAEc=71L)o&yMc-S8NIb%dj*#8%z+TN1Pq}l%tNGl{q=1@jQF`R{GRAlR>fLquhV| z1}T6mS0ms1_&_Okwi{qi+{5YMf0R0VV|w7HdD5G2X7<)6cgjy*-;W<@z!vpB zU0}jIpu2e|&%{rd`EuktH|M_U`tpuHzCj8I$eCReGbImBCB`hqZ0T`NO>?bDEnMz; z?eNa%C@^cssnK&kkR}9@+2z4o9 zd#dj}wQA@u4+NNEW~u{ohsXCx;i2%@^=J0Pt6TNX>;04bKU}$-9OS=ccK`qY07*qo IM6N<$f(^9mumAu6 diff --git a/assets/image/wall.png b/assets/image/wall.png index 0d15132571ce9824114be5cce236b1e317131f20..772b93d6358bcd07b6f440f550a24908923c09fc 100644 GIT binary patch delta 277 zcmbQsv6yRuiX}_Bqpu?a!^VE@KZ&di3=9g%9znhg3{`3j3=J&|48MRv4KElNN(~qo zUL`OvSj}Ky5HFasE6`@5UK|sX!Nk7H%BdBZX|_rkB_#z``ucgrdWk9dNvV3t`MLTa z8GS=N1O3Uqj4t&co>f3*MQTo@OJ;6rUU6oAo}H124Okh51eXE~*nl-U=jY@X1s5bH qr`j1pwIB(hs|H&Wfw0Eh$VL>&9)!%~R>m|I(H`Y*o8L3)F#!O|_E-`C delta 44 zcmV+{0Mq}Y3Y`d$Bnkm@Qb$4nuFf3kkzHN_0a=l~)04*mFq4-8S_Bzh;Rmzz0xkk# C2M_oF diff --git a/index.js b/index.js index 7b9af6d..c53b521 100644 --- a/index.js +++ b/index.js @@ -1,11 +1,53 @@ const express = require('express'); const path = require('path'); +const fs = require('fs'); + +const MAP_LAYERS=2; const app = express(); app.route('/').get((req, res) => { res.sendFile(path.join(__dirname, 'index.html')); }); +app.route('/levels').get((req, res) => { + fs.readFile(path.join(__dirname, 'level-all.bbiy'), 'utf8', (err, data) => { + if (err) { + console.log(err); + return; + } + + const levels = []; + const lines = data.split('\r\n'); + do { + const levelName = lines.shift(); + if (!levelName) { + break; + } + const [xDim, yDim] = lines.shift().split(' x ').map((x) => parseInt(x)); + + let level = Array(yDim).fill(null).map(() => Array(xDim).fill(null).map(() => [])); + for (let i = 0; i < MAP_LAYERS; i++) { + for (let y = 0; y < yDim; y++) { + const line = lines.shift().split(''); + for (let x = 0; x < xDim; x++) { + if (line[x] !== ' ') { + level[y][x].push(line[x]); + } + } + } + } + levels.push({ + levelName, + gridSize: {xDim, yDim}, + level, + }); + } while (lines.length); + + // Send the array of objects + res.send(levels); + }); +}); + app.use(express.static('.')); app.listen(3000, () => { diff --git a/src/bootstrap.js b/src/bootstrap.js index 65afc17..489ad8d 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,12 +1,13 @@ game.bootstrap = (() => { const scripts = [ - { src: ['src/utils/objectEquivalence.js', 'src/utils/unitizeVector.js', 'src/utils/clamp.js'], id: 'utils'}, - { src: ['src/render/graphics.js'], id: 'graphics' }, + { src: ['src/utils/objectEquivalence.js', 'src/utils/unitizeVector.js', 'src/utils/clamp.js', 'src/utils/loadLevel.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', ], id: 'components' }, @@ -69,6 +70,7 @@ game.bootstrap = (() => { } const loadAssets = function() { + game.assets = {}; const promises = []; for (let key in assets) { promises.push(loadAsset(assets[key], (asset) => { @@ -82,8 +84,14 @@ game.bootstrap = (() => { })); } - game.assets = {}; - loadAssets().then(() => { + const loadLevels = function() { + game.levels = []; + fetch('/levels') + .then((r) => r.json()) + .then((r) => game.levels = r); + } + + Promise.all([loadAssets(), loadLevels()]).then(() => { loadScripts(() => game.initialize()); }) })(); diff --git a/src/components/loadPriority.js b/src/components/loadPriority.js new file mode 100644 index 0000000..35c3887 --- /dev/null +++ b/src/components/loadPriority.js @@ -0,0 +1 @@ +game.components.LoadPriority = ({priority}) => game.Component('loadPriority', {priority}); \ No newline at end of file diff --git a/src/entities/bigblue.js b/src/entities/bigblue.js index 475740e..69593aa 100644 --- a/src/entities/bigblue.js +++ b/src/entities/bigblue.js @@ -1,13 +1,11 @@ game.createBigBlue = () => { const bigBlue = game.Entity(); - bigBlue.addComponent(game.components.Position({x: 0, y: 0})); + bigBlue.addComponent(game.components.LoadPriority({priority: 1})); bigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - bigBlue.sprite = game.graphics.Sprite({ - image: game.assets.bigblue, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + bigBlue.sprite = game.sprites.bigBlue; + + // TODO: Remove this + bigBlue.addComponent(game.components.Controllable({controls: ['left', 'right', 'up', 'down']})); + return bigBlue; } \ No newline at end of file diff --git a/src/entities/flag.js b/src/entities/flag.js index b7115d2..fa10d9f 100644 --- a/src/entities/flag.js +++ b/src/entities/flag.js @@ -1,13 +1,7 @@ game.createFlag = () => { const flag = game.Entity(); - flag.addComponent(game.components.Position({x: 0, y: 0})); + flag.addComponent(game.components.LoadPriority({priority: 2})); flag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - flag.sprite = game.graphics.Sprite({ - image: game.assets.flag, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + flag.sprite = game.sprites.flag; return flag; } diff --git a/src/entities/floor.js b/src/entities/floor.js index 9c2d504..0210f37 100644 --- a/src/entities/floor.js +++ b/src/entities/floor.js @@ -1,13 +1,7 @@ game.createFloor = () => { const floor = game.Entity(); - floor.addComponent(game.components.Position({x: 0, y: 0})); + floor.addComponent(game.components.LoadPriority({priority: 5})); floor.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - floor.sprite = game.graphics.Sprite({ - image: game.assets.floor, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + floor.sprite = game.sprites.floor; return floor; } diff --git a/src/entities/grass.js b/src/entities/grass.js index 7451476..f2a6da2 100644 --- a/src/entities/grass.js +++ b/src/entities/grass.js @@ -1,13 +1,7 @@ game.createGrass = () => { const grass = game.Entity(); - grass.addComponent(game.components.Position({x: 0, y: 0})); + grass.addComponent(game.components.LoadPriority({priority: 6})); grass.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - grass.sprite = game.graphics.Sprite({ - image: game.assets.grass, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + grass.sprite = game.sprites.grass; return grass; } diff --git a/src/entities/hedge.js b/src/entities/hedge.js index 5b4c362..1e5d482 100644 --- a/src/entities/hedge.js +++ b/src/entities/hedge.js @@ -1,13 +1,7 @@ game.createHedge = () => { const hedge = game.Entity(); - hedge.addComponent(game.components.Position({x: 0, y: 0})); + hedge.addComponent(game.components.LoadPriority({priority: 6})); hedge.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - hedge.sprite = game.graphics.Sprite({ - image: game.assets.hedge, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + hedge.sprite = game.sprites.hedge; return hedge; } diff --git a/src/entities/liquid.js b/src/entities/liquid.js index d912ec9..8c7d8ea 100644 --- a/src/entities/liquid.js +++ b/src/entities/liquid.js @@ -1,5 +1,7 @@ game.createLiquid = () => { + // TODO: Split this into two entities: water and lava const liquid = game.Entity(); + 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.sprite = game.graphics.Sprite({ diff --git a/src/entities/rock.js b/src/entities/rock.js index fe9f809..c852f10 100644 --- a/src/entities/rock.js +++ b/src/entities/rock.js @@ -1,13 +1,11 @@ game.createRock = () => { const rock = game.Entity(); - rock.addComponent(game.components.Position({x: 0, y: 0})); + rock.addComponent(game.components.LoadPriority({priority: 2})); rock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - rock.sprite = game.graphics.Sprite({ - image: game.assets.rock, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + rock.sprite = game.sprites.rock; + + //TODO: Remove this + rock.addComponent(game.components.Pushable()); + return rock; } diff --git a/src/entities/wall.js b/src/entities/wall.js index 55226d0..d5167c4 100644 --- a/src/entities/wall.js +++ b/src/entities/wall.js @@ -1,13 +1,7 @@ game.createWall = () => { const wall = game.Entity(); - wall.addComponent(game.components.Position({x: 0, y: 0})); + wall.addComponent(game.components.LoadPriority({priority: 3})); wall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wall.sprite = game.graphics.Sprite({ - image: game.assets.wall, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wall.sprite = game.sprites.wall; return wall; } diff --git a/src/entities/wordBigBlue.js b/src/entities/wordBigBlue.js index c94fa19..b9ebb5e 100644 --- a/src/entities/wordBigBlue.js +++ b/src/entities/wordBigBlue.js @@ -1,13 +1,7 @@ game.createWordBigBlue = () => { const wordBigBlue = game.Entity(); - wordBigBlue.addComponent(game.components.Position({x: 0, y: 0})); + wordBigBlue.addComponent(game.components.LoadPriority({priority: 3})); wordBigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordBigBlue.sprite = game.graphics.Sprite({ - image: game.assets.wordBigBlue, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordBigBlue.sprite = game.sprites.wordBigBlue; return wordBigBlue; } diff --git a/src/entities/wordFlag.js b/src/entities/wordFlag.js index da66406..a2e1ca1 100644 --- a/src/entities/wordFlag.js +++ b/src/entities/wordFlag.js @@ -1,13 +1,7 @@ game.createWordFlag = () => { const wordFlag = game.Entity(); - wordFlag.addComponent(game.components.Position({x: 0, y: 0})); + wordFlag.addComponent(game.components.LoadPriority({priority: 3})); wordFlag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordFlag.sprite = game.graphics.Sprite({ - image: game.assets.wordFlag, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordFlag.sprite = game.sprites.wordFlag; return wordFlag; } diff --git a/src/entities/wordIs.js b/src/entities/wordIs.js index dff0819..41263f4 100644 --- a/src/entities/wordIs.js +++ b/src/entities/wordIs.js @@ -1,13 +1,7 @@ game.createWordIs = () => { const wordIs = game.Entity(); - wordIs.addComponent(game.components.Position({x: 0, y: 0})); + wordIs.addComponent(game.components.LoadPriority({priority: 3})); wordIs.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordIs.sprite = game.graphics.Sprite({ - image: game.assets.wordIs, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordIs.sprite = game.sprites.wordIs; return wordIs; } diff --git a/src/entities/wordKill.js b/src/entities/wordKill.js index a1a19af..1835f59 100644 --- a/src/entities/wordKill.js +++ b/src/entities/wordKill.js @@ -1,13 +1,7 @@ game.createWordKill = () => { const wordKill = game.Entity(); - wordKill.addComponent(game.components.Position({x: 0, y: 0})); + wordKill.addComponent(game.components.LoadPriority({priority: 3})); wordKill.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordKill.sprite = game.graphics.Sprite({ - image: game.assets.wordKill, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordKill.sprite = game.sprites.wordKill; return wordKill; } diff --git a/src/entities/wordLava.js b/src/entities/wordLava.js index e1ad242..8c7780b 100644 --- a/src/entities/wordLava.js +++ b/src/entities/wordLava.js @@ -1,13 +1,7 @@ game.createWordLava = () => { const wordLava = game.Entity(); - wordLava.addComponent(game.components.Position({x: 0, y: 0})); + wordLava.addComponent(game.components.LoadPriority({priority: 3})); wordLava.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordLava.sprite = game.graphics.Sprite({ - image: game.assets.wordLava, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordLava.sprite = game.sprites.wordLava; return wordLava; } diff --git a/src/entities/wordPush.js b/src/entities/wordPush.js index aa24d46..c4294e6 100644 --- a/src/entities/wordPush.js +++ b/src/entities/wordPush.js @@ -1,13 +1,7 @@ game.createWordPush = () => { const wordPush = game.Entity(); - wordPush.addComponent(game.components.Position({x: 0, y: 0})); + wordPush.addComponent(game.components.LoadPriority({priority: 3})); wordPush.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordPush.sprite = game.graphics.Sprite({ - image: game.assets.wordPush, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordPush.sprite = game.sprites.wordPush; return wordPush; } diff --git a/src/entities/wordRock.js b/src/entities/wordRock.js index 2e698b3..66f4efb 100644 --- a/src/entities/wordRock.js +++ b/src/entities/wordRock.js @@ -1,13 +1,7 @@ game.createWordRock = () => { const wordRock = game.Entity(); - wordRock.addComponent(game.components.Position({x: 0, y: 0})); + wordRock.addComponent(game.components.LoadPriority({priority: 3})); wordRock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordRock.sprite = game.graphics.Sprite({ - image: game.assets.wordRock, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordRock.sprite = game.sprites.wordRock; return wordRock; } diff --git a/src/entities/wordSink.js b/src/entities/wordSink.js index 4cec615..604d630 100644 --- a/src/entities/wordSink.js +++ b/src/entities/wordSink.js @@ -1,13 +1,7 @@ game.createWordSink = () => { const wordSink = game.Entity(); - wordSink.addComponent(game.components.Position({x: 0, y: 0})); + wordSink.addComponent(game.components.LoadPriority({priority: 3})); wordSink.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordSink.sprite = game.graphics.Sprite({ - image: game.assets.wordSink, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordSink.sprite = game.sprites.wordSink; return wordSink; } diff --git a/src/entities/wordStop.js b/src/entities/wordStop.js index 0d8aeea..ee43e38 100644 --- a/src/entities/wordStop.js +++ b/src/entities/wordStop.js @@ -1,13 +1,7 @@ game.createWordStop = () => { const wordStop = game.Entity(); - wordStop.addComponent(game.components.Position({x: 0, y: 0})); + wordStop.addComponent(game.components.LoadPriority({priority: 3})); wordStop.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordStop.sprite = game.graphics.Sprite({ - image: game.assets.wordStop, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordStop.sprite = game.sprites.wordStop; return wordStop; } diff --git a/src/entities/wordWall.js b/src/entities/wordWall.js index b973933..ba97cec 100644 --- a/src/entities/wordWall.js +++ b/src/entities/wordWall.js @@ -1,13 +1,7 @@ game.createWordWall = () => { const wordWall = game.Entity(); - wordWall.addComponent(game.components.Position({x: 0, y: 0})); + wordWall.addComponent(game.components.LoadPriority({priority: 3})); wordWall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordWall.sprite = game.graphics.Sprite({ - image: game.assets.wordWall, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordWall.sprite = game.sprites.wordWall; return wordWall; } diff --git a/src/entities/wordWater.js b/src/entities/wordWater.js index b26dc57..a33d8f3 100644 --- a/src/entities/wordWater.js +++ b/src/entities/wordWater.js @@ -1,13 +1,7 @@ game.createWordWater = () => { const wordWater = game.Entity(); - wordWater.addComponent(game.components.Position({x: 0, y: 0})); + wordWater.addComponent(game.components.LoadPriority({priority: 3})); wordWater.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordWater.sprite = game.graphics.Sprite({ - image: game.assets.wordWater, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordWater.sprite = game.sprites.wordWater; return wordWater; } diff --git a/src/entities/wordWin.js b/src/entities/wordWin.js index 1a4f233..67fbc41 100644 --- a/src/entities/wordWin.js +++ b/src/entities/wordWin.js @@ -1,13 +1,7 @@ game.createWordWin = () => { const wordWin = game.Entity(); - wordWin.addComponent(game.components.Position({x: 0, y: 0})); + wordWin.addComponent(game.components.LoadPriority({priority: 3})); wordWin.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordWin.sprite = game.graphics.Sprite({ - image: game.assets.wordWin, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordWin.sprite = game.sprites.wordWin; return wordWin; } diff --git a/src/entities/wordYou.js b/src/entities/wordYou.js index 8dcf587..574ba4d 100644 --- a/src/entities/wordYou.js +++ b/src/entities/wordYou.js @@ -1,13 +1,7 @@ game.createWordYou = () => { const wordYou = game.Entity(); - wordYou.addComponent(game.components.Position({x: 0, y: 0})); + wordYou.addComponent(game.components.LoadPriority({priority: 3})); wordYou.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100})); - wordYou.sprite = game.graphics.Sprite({ - image: game.assets.wordYou, - spriteHeight: 24, - spriteWidth: 24, - numFrames: 3, - timePerFrame: 100, - }); + wordYou.sprite = game.sprites.wordYou; return wordYou; } diff --git a/src/game.js b/src/game.js index 69a91ce..073455a 100644 --- a/src/game.js +++ b/src/game.js @@ -7,37 +7,25 @@ game.loop = (timeStamp) => { game.systems[i].update(elapsedTime, game.entities); }); + if (game.nextLevel) { + game.loadLevel(game.nextLevel); + game.nextLevel = false; + } + requestAnimationFrame(game.loop); } game.initialize = () => { + [game.entities, game.config] = game.loadLevel(game.levels[0]); + game.systemOrder = ["render", "physics", "gridSystem", "keyboardInput"]; game.systems = { render: game.system.Render(game.graphics), physics: game.system.Physics(), - gridSystem: game.system.GridSystem({ - xDim: 15, - yDim: 15, - canvasWidth: game.canvas.width, - canvasHeight: game.canvas.height, - }), + gridSystem: game.system.GridSystem({...game.config}), keyboardInput: game.system.KeyboardInput(), }; - game.entities = {}; - - Array(10).fill(null).forEach((_, i) => { - const bigBlue = game.createBigBlue(); - bigBlue.addComponent(game.components.GridPosition({x: Math.floor(Math.random() * 15), y: Math.floor(Math.random() * 13)})); - bigBlue.addComponent(game.components.Controllable({controls: ['left', 'right', 'up', 'down']})); - game.entities[bigBlue.id] = bigBlue; - }); - - game.rock = game.createRock(); - game.rock.addComponent(game.components.Position({x: 200, y: 200})); - game.rock.addComponent(game.components.GridPosition({x: 0, y: 0})); - game.rock.addComponent(game.components.Pushable()); - game.entities[game.rock.id] = game.rock; lastTimeStamp = performance.now() requestAnimationFrame(game.loop); diff --git a/src/render/sprites.js b/src/render/sprites.js new file mode 100644 index 0000000..286da4c --- /dev/null +++ b/src/render/sprites.js @@ -0,0 +1,142 @@ +game.sprites = { + bigBlue: game.graphics.Sprite({ + image: game.assets.bigblue, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + flag: game.graphics.Sprite({ + image: game.assets.flag, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + floor: game.graphics.Sprite({ + image: game.assets.floor, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + hedge: game.graphics.Sprite({ + image: game.assets.hedge, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 250, + }), + grass: game.graphics.Sprite({ + image: game.assets.grass, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + rock: game.graphics.Sprite({ + image: game.assets.rock, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wall: game.graphics.Sprite({ + image: game.assets.wall, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordBigBlue: game.graphics.Sprite({ + image: game.assets.wordBigBlue, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordFlag: game.graphics.Sprite({ + image: game.assets.wordFlag, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordIs: game.graphics.Sprite({ + image: game.assets.wordIs, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordKill: game.graphics.Sprite({ + image: game.assets.wordKill, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordLava: game.graphics.Sprite({ + image: game.assets.wordLava, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordPush: game.graphics.Sprite({ + image: game.assets.wordPush, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordRock: game.graphics.Sprite({ + image: game.assets.wordRock, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordSink: game.graphics.Sprite({ + image: game.assets.wordSink, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordStop: game.graphics.Sprite({ + image: game.assets.wordStop, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordWall: game.graphics.Sprite({ + image: game.assets.wordWall, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordWater: game.graphics.Sprite({ + image: game.assets.wordWater, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordWin: game.graphics.Sprite({ + image: game.assets.wordWin, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), + wordYou: game.graphics.Sprite({ + image: game.assets.wordYou, + spriteHeight: 24, + spriteWidth: 24, + numFrames: 3, + timePerFrame: 100, + }), +}; diff --git a/src/systems/gridSystem.js b/src/systems/gridSystem.js index b8d49e6..ef5a6e1 100644 --- a/src/systems/gridSystem.js +++ b/src/systems/gridSystem.js @@ -1,11 +1,11 @@ -game.system.GridSystem = ({ xDim, yDim, canvasWidth, canvasHeight }) => { +game.system.GridSystem = ({ xDim, yDim }) => { const entitiesGrid = Array(yDim).fill(null).map(() => Array(xDim).fill(null).map(() => new Map())); - const gridWidth = canvasWidth / xDim; - const gridHeight = canvasHeight / yDim; + let gridWidth = game.canvas.width / xDim; + let gridHeight = game.canvas.height / yDim; const gameCoordsToGrid = ({ x, y }) => { - return { x: Math.floor((x+gridWidth/2) / canvasWidth * xDim), y: Math.floor((y+gridHeight/2) / canvasHeight * yDim) }; + return { x: Math.floor((x+gridWidth/2) / game.canvas.width * xDim), y: Math.floor((y+gridHeight/2) / game.canvas.height * yDim) }; }; const gridCoordsToGame = ({ x, y }) => { @@ -39,8 +39,8 @@ game.system.GridSystem = ({ xDim, yDim, canvasWidth, canvasHeight }) => { rebuildGrid(gridEntities); gridEntities.map((entity) => { if (entity.hasComponent("appearance")) { - entity.components.appearance.width = canvasWidth / xDim; - entity.components.appearance.height = canvasHeight / yDim; + entity.components.appearance.width = gridWidth; + entity.components.appearance.height = gridHeight; } if (entity.hasComponent("position")) { const newGridCoords = gameCoordsToGrid(entity.components.position); @@ -89,7 +89,9 @@ game.system.GridSystem = ({ xDim, yDim, canvasWidth, canvasHeight }) => { entity.components.momentum.dy = 0; } } - } + } else { + entity.addComponent(game.components.Position({...gridCoordsToGame(entity.components.gridPosition)})); + }; }); }; diff --git a/src/systems/render.js b/src/systems/render.js index 0a4c72d..4ec67c7 100644 --- a/src/systems/render.js +++ b/src/systems/render.js @@ -2,12 +2,18 @@ game.system.Render = (graphics) => { const update = (elapsedTime, entities) => { graphics.clear(); - for (let id in entities) { - const entity = entities[id]; + const entitiesArray = Object.keys(entities).map(key => entities[key]); + const sortedEntities = entitiesArray.sort((a, b) => { + const aprior = a.hasComponent("loadPriority") ? a.components.loadPriority.priority : 0; + const bprior = b.hasComponent("loadPriority") ? b.components.loadPriority.priority : 0; + return bprior - aprior; + }); + + sortedEntities.forEach((entity) => { if (entity.sprite && entity.hasComponent("position") && entity.hasComponent("appearance")) { entity.sprite.draw(elapsedTime, {...entity.components.position, ...entity.components.appearance}); } - } + }); } return { update }; }; \ No newline at end of file diff --git a/src/utils/loadLevel.js b/src/utils/loadLevel.js new file mode 100644 index 0000000..4f0c701 --- /dev/null +++ b/src/utils/loadLevel.js @@ -0,0 +1,66 @@ +game.loadLevel = (level) => { + const entities = {}; + const config = {...level.gridSize}; + for (let y = 0; y < level.gridSize.yDim; y++) { + for (let x = 0; x < level.gridSize.xDim; x++) { + const cell = level.level[y][x]; + cell.forEach((letter) => { + let entity; + switch (letter) { + case 'b': + entity = game.createBigBlue(); + break; + case 'h': + entity = game.createHedge(); + break; + case 'r': + entity = game.createRock(); + break; + case 'f': + entity = game.createFlag(); + break; + case 'l': + entity = game.createFloor(); + break; + case 'w': + entity = game.createWall(); + break; + case 'W': + entity = game.createWordWall(); + break; + case 'I': + entity = game.createWordIs(); + break; + case 'S': + entity = game.createWordStop(); + break; + case 'R': + entity = game.createWordRock(); + break; + case 'P': + entity = game.createWordPush(); + break; + case 'B': + entity = game.createWordBigBlue(); + break; + case 'Y': + entity = game.createWordYou(); + break; + case 'F': + entity = game.createWordFlag(); + break; + case 'X': + entity = game.createWordWin(); + break; + default: + break; + } + if (entity) { + entity.addComponent(game.components.GridPosition({x, y})); + entities[entity.id] = entity; + } + }); + } + } + return [entities, config]; +}; \ No newline at end of file