Demo 連結
程式碼
這次要來實作貪吃蛇小遊戲,因為程式較多,會將JS檔案拆分再用export 、import來匯入和匯出,方便做程式碼管理。
繪製網格
在遊戲畫面中的格子,我們可以用 grid 來繪製。用 grid 製作的好處是方便我們在js中取得每個格子的座標將蛇繪製到網格上,網格數量則使用css變數來帶入。
1 2 3 4 5 6 7 8 9 10 11 12
| .game-board { --col-num: 28; --row-num: 16; width: 100%; height: 640px; background-color: var(--color-primary); border: 1px solid var(--color-primary); display: grid; gap: 1px; grid-template-columns: repeat(var(--col-num), 1fr); grid-template-rows: repeat(var(--row-num), 1fr); }
|
建立動畫 loop 函式
要讓貪吃蛇不停地在畫面上移動,我們需要一個可以每秒更新的函式,以往可以用 setInterval來達成。但 setInterval 可能會有時間誤差的問題,所以我們改用 requestAnimationFrame 來製作。
1 2 3 4 5 6 7 8 9 10 11 12 13
| let lastRenderTime = 0; let speed = 2; function animate(currentTime) { const currentPage = getCurrentPage(); const requestId = window.requestAnimationFrame(animate); const secondSinceLastRender = (currentTime - lastRenderTime) / 1000; if (secondSinceLastRender < 1 / speed) return; lastRenderTime = currentTime; update(); draw(); if (currentPage !== 'game-page') cancelAnimationFrame(requestId); } window.requestAnimationFrame(animate);
|
requestAnimationFrame 會在我們設定的時間到後自動執行函式,讓貪吃蛇能持續移動。
繪製貪吃蛇
貪吃蛇的身體是由不同格子組成,我們可以用物件帶入x 跟y的值,代表該節身體的位置。之後我們在操作蛇的移動和增加身體時,都是在操作這個陣列。
1 2 3 4 5
| let snakeBody = [ { x: 14, y: 6 }, { x: 14, y: 7 }, { x: 14, y: 8 }, ];
|
移動身體的部分,概念是將每節身體的位置,設定成上一節身體的位置,這樣每次繪製影格時,蛇就會移動。
1 2 3 4 5
| for (let i = snakeBody.length - 2; i >= 0; i--) { snakeBody[i + 1] = { ...snakeBody[i] }; } snakeBody[0].x += direction.x; snakeBody[0].y += direction.y;
|
那有了蛇的 x y 座標後,剩下的就是在html中將對應的座標選起來,並加上對應的class。
如蛇的頭部 index 是 0,就加上head的class。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export function drawSnake(gameBoard, boardSet) { const gridItems = document.querySelectorAll('.grid-item'); gridItems.forEach((item) => item.className = 'grid-item'); snakeBody.forEach((body, index) => { const gridItem = getGridItemByXY({ gameBoard, boardSet, postion: body }); gridItem.className = 'grid-item'; if (index === 0) gridItem.classList.add('head'); if (index === 1) gridItem.classList.add('gray-100'); if (index === 2) gridItem.classList.add('gray-200'); if (index === 3) gridItem.classList.add('gray-300'); if (index === 4) gridItem.classList.add('gray-400'); if (index > 4) gridItem.classList.add('body'); }) }
|
以上就是製作的貪吃蛇遊戲的方法囉。