海外TECH |
DEV Community |
Let's build a box pushing puzzle game from scratch! 📦🕹️ |
https://dev.to/thormeier/let-s-build-a-box-pushing-puzzle-game-from-scratch-5458
|
Let x s build a box pushing puzzle game from scratch ️When I was a kid I used to play puzzle games a lot One of them was called Sokoban The principle is simple Push boxes around in a maze until all boxes are at their target spot As seen in this animation I found on Wikipedia Gif by Carloseow at English Wikipedia I wanted to play this again for ages now so I figured why not build my own version Let s get right into it BoilerplatingThe usual Some HTML with an empty JS file The HTML is pretty straight forward lt DOCTYPE html gt lt html gt lt head gt lt head gt lt body gt lt canvas width height id canvas gt lt canvas gt lt div id message style font size px font weight bold gt Use arrow keys to move the boxes around lt div gt lt script src blockPushingGame js gt lt script gt lt body gt lt html gt Gathering the texturesSo first I need textures I look through a popular search enginefor a wall texture a sand texture a box texture some red dot to indicate the target and a cat I can use as a player These are the textures I m going to use Player texture Box texture Floor texture Wall texture Target texture I use promises to load all the textures beforehand to not load them every time I want to render something Loads a texture async param texture returns Promise lt unknown gt const loadTexture texture gt new Promise resolve gt const image new Image image addEventListener load gt resolve image image src texture Promise allSettled loadTexture floor jpg loadTexture wall jpg loadTexture target jpg loadTexture box jpg loadTexture cat png then results gt const floorTexture wallTexture targetTexture boxTexture catTexture results map result gt result value more stuff here Defining the playing fieldThere s several different objects in a block pushing game The floorWallsBoxesTargets to move the boxes ontoThe player moving the boxesI define different nested arrays for each of them to be able to render and compare them const floor new Array fill new Array fill X const walls X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X const targets X X X X X X X const boxes X X X X X X X const player X let playerX let playerY With this approach I basically abstracted everything away into a visual approach for the programmer By setting X and at the right coordinates I can either make something be a wall or an empty space I can add boxes and their targets wherever I want and don t have to fiddle around with setting X and Y coordinates of them I can now use these arrays and the textures together A first render of the playing fieldIn order to render for example all the walls I need to loop over the array of arrays and put the texture on the canvas at the coordinates where an X is Since the canvas is by pixels and I ve defined the playing field as by each grid cell of the playing field is pixels in width and height Example If a piece of wall is placed at playing field X Y this means that the texture s top left corner will render at X Y In code this would look like this Renders a grid of blocks with a given texture param blocks param textureImage param canvas returns Promise lt unknown gt const renderBlocks blocks textureImage canvas gt Scale the grid of the nested blocks array to the pixel grid of the canvas const pixelWidthBlock canvas width blocks length const pixelHeightBlock canvas height blocks length const context canvas getContext d blocks forEach row y gt row forEach cell x gt if cell X context drawImage textureImage x pixelWidthBlock y pixelHeightBlock pixelWidthBlock pixelHeightBlock Together with the textures I can now render a playing field for the first time Promise allSettled loadTexture floor jpg loadTexture wall jpg loadTexture target jpg loadTexture box jpg loadTexture cat png then results gt const floorTexture wallTexture targetTexture boxTexture catTexture results map result gt result value const canvas document querySelector canvas const render gt renderBlocks floor floorTexture canvas renderBlocks walls wallTexture canvas renderBlocks targets targetTexture canvas renderBlocks boxes boxTexture canvas renderBlocks player catTexture canvas render Making it interactiveThe next step is to give the player character the ability to move As indicated in the HTML part the player will be able to use the arrow keys to move around I attach the event listener right after rendering the field for the first time window addEventListener keydown event gt let xMovement let yMovement switch event key case ArrowUp yMovement break case ArrowDown yMovement break case ArrowLeft xMovement break case ArrowRight xMovement break const newPlayerX playerX xMovement const newPlayerY playerY yMovement Remove player at old position player playerY playerX Set player at new position player newPlayerY newPlayerX X playerX newPlayerX playerY newPlayerY render The reason I work with two variables and don t update the new player position right away is that it allows me to do all the collision checks later on in a more generalized way Speaking of collision checks let s check if the player is actually jumping off the field first Collision with end of playing field if newPlayerX lt newPlayerY lt newPlayerX gt floor length newPlayerY gt floor length return Pretty straight forward If the new coordinates would be outside of the field don t move Same goes for the walls Wall collision if walls newPlayerY newPlayerX X return The boxes are a bit more complex The rule is that I cannot move a box whose way is blocked by either a wall or a second box I can only push one box at a time To implement that I first need to figure out if the player is colliding with a box If that s the case I need to find out if the boxes way would be blocked I therefore check in the direction of movement if there s a wall or another box in the way If there s none I move the box Box collision if boxes newPlayerY newPlayerX X if boxes newPlayerY yMovement newPlayerX xMovement X walls newPlayerY yMovement newPlayerX xMovement X return boxes newPlayerY newPlayerX boxes newPlayerY yMovement newPlayerX xMovement X The last step is to render the changed field again by calling render Almost done Checking if the player has wonThe game is won if all boxes are placed on targets It doesn t matter which box is on which target though This means that I only need to check if the array of boxes is the same as the array of targets Determines if the game was won param targets param boxes returns boolean const hasWon targets boxes gt for let y y lt targets length y for let x x lt targets length x if targets y x boxes y x Some box is not aligned with a target return false return true To show the player that they ve solved the puzzle I add this to the event listener I added earlier if hasWon targets boxes document querySelector message innerHTML You ve won Let s play Have fun Because I certainly will I hope you enjoyed reading this article as much as I enjoyed writing it If so leave a ️or a I write tech articles in my free time and like to drink coffee every once in a while If you want to support my efforts please consider buying me a coffee or following me on Twitter You can also support me and my writing directly via Paypal |
2021-09-05 19:43:23 |
医療系 |
医療介護 CBnews |
ICU等の稼働率は何に左右されるのか?-先が見えない時代の戦略的病院経営(154) |
https://www.cbnews.jp/news/entry/20210903172615
|
千葉大学医学部附属病院 |
2021-09-06 05:00:00 |
ニュース |
BBC News - Home |
Guinea coup attempt: Soldiers claim to seize power from Alpha Condé |
https://www.bbc.co.uk/news/world-africa-58453778?at_medium=RSS&at_campaign=KARANGA
|
defence |
2021-09-05 19:38:00 |
ニュース |
BBC News - Home |
Grenfell Tower: Families angry at lack of consultation over demolition |
https://www.bbc.co.uk/news/uk-england-london-58447126?at_medium=RSS&at_campaign=KARANGA
|
families |
2021-09-05 19:23:56 |
ニュース |
BBC News - Home |
Brazil-Argentina game halted after confusion over Covid regulations |
https://www.bbc.co.uk/sport/football/58431607?at_medium=RSS&at_campaign=KARANGA
|
Brazil Argentina game halted after confusion over Covid regulationsArgentina players walk off the pitch during their World Cup qualifier against Brazil following confusion over players who may have broken quarantine rules |
2021-09-05 19:51:56 |
ニュース |
BBC News - Home |
England v India: Haseeb Hameed & Rory Burns hold firm to set up intriguing final day |
https://www.bbc.co.uk/sport/av/cricket/58455248?at_medium=RSS&at_campaign=KARANGA
|
England v India Haseeb Hameed amp Rory Burns hold firm to set up intriguing final dayWatch highlights as openers Haseeb Hameed and Rory Burns give England hope after India looked to have batted them out of contention on the penultimate day of the fourth Test |
2021-09-05 19:19:02 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
マッキンゼー流!日本の自動車業界に「大再編」が避けられない、その本質的理由【動画】 - マッキンゼー流!自動車産業 大再編 |
https://diamond.jp/articles/-/281250
|
日本企業 |
2021-09-06 04:55:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
【入山章栄・動画】パーパス経営では「メガトレンド×祖業」が重要な経営学的理由 - 入山章栄の世界標準の経営理論 |
https://diamond.jp/articles/-/281309
|
世界標準 |
2021-09-06 04:50:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
最強の「塾・予備校・家庭教師・教材」の選び方、わが子と相性ピッタリが見つかる! - わが子にピッタリ!塾・予備校&家庭教師・オンライン教材選び |
https://diamond.jp/articles/-/281187
|
小中高の各学校で学期を迎えたが、夏休みぼけが抜けない子どもは多いはず。 |
2021-09-06 04:45:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
FP&税理士、お金の相談で失敗しない「悪質・低レベル」な人の見分け方 - 悪質?使えない?FP&税理士の見分け方! |
https://diamond.jp/articles/-/281230
|
|
2021-09-06 04:40:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
EY・デロイトら会計コンサルに商機!東証市場再編で「ESGビジネス」に妙味 - 東証再編 664社に迫る大淘汰 |
https://diamond.jp/articles/-/280469
|
上場企業 |
2021-09-06 04:35:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
ハーバードがワクチン開発を断念したメルクに注目する2つの理由 - ハーバードの知性に学ぶ「日本論」 佐藤智恵 |
https://diamond.jp/articles/-/281270
|
ハーバードがワクチン開発を断念したメルクに注目するつの理由ハーバードの知性に学ぶ「日本論」佐藤智恵ハーバードビジネススクールのウィリー・シー教授は今年月、米製薬大手メルクの事例を取り上げた教材を出版した。 |
2021-09-06 04:30:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
日銀が気候変動対策に乗り出す「当然」と「限界」そして“根本問題” - 政策・マーケットラボ |
https://diamond.jp/articles/-/281282
|
中央銀行 |
2021-09-06 04:25:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
「三菱電機の検査不正」がメディアの怒りを買った本当の理由 - DOL特別レポート |
https://diamond.jp/articles/-/281170
|
三菱自動車 |
2021-09-06 04:20:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
緊急事態宣言への「免疫」で、リスク高まる日本景気の先行き - 政策・マーケットラボ |
https://diamond.jp/articles/-/281295
|
緊急事態宣言への「免疫」で、リスク高まる日本景気の先行き政策・マーケットラボ第波の感染拡大によって、人口規模との比較で見た日本の感染状況は、世界平均を大きく超える厳しいものとなった。 |
2021-09-06 04:15:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
年収が上がった会社ランキング2021【トップ5】2位松井証券、1位は? - ニッポンなんでもランキング! |
https://diamond.jp/articles/-/281381
|
松井証券 |
2021-09-06 04:10:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
年収が上がった会社ランキング2021【全500社・完全版】 - ニッポンなんでもランキング! |
https://diamond.jp/articles/-/281323
|
駆使 |
2021-09-06 04:10:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
“旧中間階級”は年収127万円減、貧困大国ニッポンの全「階級格差」データを初公開! - 今週の週刊ダイヤモンド ここが見どころ |
https://diamond.jp/articles/-/281185
|
上級国民 |
2021-09-06 04:05:00 |
ビジネス |
東洋経済オンライン |
菅首相が総裁選不出馬、経済対策めぐるシナリオ 問われるコロナ対策、収束後の景気対策も焦点 | 岐路に立つ日本の財政 | 東洋経済オンライン |
https://toyokeizai.net/articles/-/452856?utm_source=rss&utm_medium=http&utm_campaign=link_back
|
日本の財政 |
2021-09-06 04:30:00 |
コメント
コメントを投稿