前端搭建小人逃脱游戏(内附源码)
The sand accumulates to form a pagoda
- ? 寫在前面
- ? 功能介紹
- ? 頁面搭建
- ? 樣式設(shè)置
- ? 邏輯部分
? 寫在前面
上周我們實通過前端基礎(chǔ)實現(xiàn)了打字通,當(dāng)然很多伙伴再評論區(qū)提出了想法,后續(xù)我們會考慮實現(xiàn)的,今天還是繼續(xù)按照我們原定的節(jié)奏來帶領(lǐng)大家完成一個小人逃脫游戲,功能也比較簡單簡單,也是想借助這樣一個簡單的功能,然后來幫助大家了解我們JavaScript在前端中的作用, 在前面的文章當(dāng)中我們也提及到我們在本系列的專欄是循序漸進(jìn)從簡單到復(fù)雜的過程,后續(xù)會帶領(lǐng)大家用前端實現(xiàn)翻卡片、掃雷、貪吃蛇等有趣的小游戲,純前端語言實現(xiàn),都會陸續(xù)帶給大家。歡迎大家訂閱我們這份前端小游戲的專欄。
? 功能介紹
白色方塊為我們游戲中的主角,游戲開始后回隨機(jī)墜落紅色方塊,我們可以通過鍵盤的左右鍵來控制白色方塊的移動,來躲避白色方塊,被撞擊到游戲結(jié)束匯算分?jǐn)?shù),每次成功躲避都加一分,60秒自動結(jié)束匯算得分;你可以通過修改游戲的參數(shù)來控制難度等級!
? 頁面搭建
創(chuàng)建文件
首先呢我們創(chuàng)建我們的HTML文件,這里我就直接命名為 小人逃脫.html 了,大家可以隨意命名, 文件創(chuàng)建生成后我們通過編輯器打開,這里我用的是VScode, 然后初始化我們的代碼結(jié)構(gòu),那在這里告訴大家一個快捷鍵,就是我們敲上我們英文的一個 ! 我們敲擊回車直接就會給我們生成基礎(chǔ)版本的前端代碼結(jié)構(gòu)。
文檔聲明和編碼設(shè)置: 在HTML文檔的頭部,使用<!DOCTYPE>聲明HTML文檔類型,確保瀏覽器以正確的方式渲染網(wǎng)頁內(nèi)容。同時,設(shè)置UTF-8編碼,以確保瀏覽器能夠正確地解析和顯示中文字符。下面我就開始搭建我們的DOM結(jié)構(gòu)了!
DOM結(jié)構(gòu)搭建
這段代碼定義了一個 HTML 游戲頁面,包含了三個 <div> 元素。<div id="game"> 表示游戲主界面,游戲中的元素都將顯示在這個 <div> 元素中。<div id="player"></div> 表示玩家的角色,即小人,將顯示在游戲主界面中央的底部。<div id="score">分?jǐn)?shù): 0</div> 表示游戲得分,將顯示在游戲主界面的頂部。<div id="message"></div> 表示游戲結(jié)束時彈出的提示框,將顯示在游戲主界面中央。
<div id="game"><div id="player"></div><div id="score">分?jǐn)?shù): 0</div><div id="message"></div> </div>? 樣式設(shè)置
我們看到了上面的的DOM已經(jīng)搭建好了,但是很顯然樣式比較隨意了,我們簡單的來配置一下樣式吧,其實我們本專欄也是想帶領(lǐng)大家掌握一些邏輯所以樣式方面我們就一切從簡;其中,body 元素的樣式設(shè)置了外邊距、內(nèi)邊距和隱藏滾動條。#game 元素是整個游戲的容器,設(shè)置了寬度、高度、背景顏色和相對定位。#player 元素是玩家,設(shè)置了寬度、高度、背景顏色、絕對定位、底部對齊、左側(cè)距離容器中心點的距離,并通過 transform 屬性將其水平居中。.obstacle 類表示障礙物,設(shè)置了寬度、高度、背景顏色、絕對定位、頂部距離為負(fù)數(shù)(使其從游戲容器頂部開始落下)、左側(cè)距離容器中心點的距離,并通過 transform 屬性將其水平居中。#score 元素是得分標(biāo)簽,設(shè)置了絕對定位、頂部距離和左側(cè)距離,并設(shè)置了顏色和字體大小。#message 元素是游戲結(jié)束提示信息,設(shè)置了絕對定位、上、左偏移和顏色、字體大小,并通過 display 屬性將其隱藏。
body {margin: 0;padding: 0;overflow: hidden; }#game {width: 100vw;height: 100vh;background-color: #222;position: relative;overflow: hidden; }#player {width: 50px;height: 50px;background-color: white;position: absolute;bottom: 0;left: 50%;transform: translateX(-50%); }.obstacle {width: 50px;height: 50px;background-color: red;position: absolute;top: -50px;left: 50%;transform: translateX(-50%); }#score {position: absolute;top: 10px;left: 10px;color: white;font-size: 24px; }#message {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: white;font-size: 48px;display: none; }? 邏輯部分
首先,通過 document.getElementById 方法獲取了 game、player、score 和 message 等 DOM 元素對象。這些元素分別對應(yīng)游戲區(qū)域、玩家方塊、得分標(biāo)簽和游戲結(jié)束提示信息。在游戲參數(shù)部分,定義了一些游戲的參數(shù),包括得分、游戲是否結(jié)束、障礙物下落間隔、障礙物下落速度、障礙物寬度、障礙物高度和玩家移動速度等。
// 獲取DOM元素 const game = document.getElementById('game'); const player = document.getElementById('player'); const score = document.getElementById('score'); const message = document.getElementById('message');// 初始化游戲參數(shù) let scoreValue = 0; // 得分 let isGameOver = false; // 游戲是否結(jié)束 let obstacleInterval; // 障礙物下落間隔 let gameTimer; // 游戲計時器 const obstacleSpeed = 5; // 障礙物下落速度 const obstacleWidth = 50; // 障礙物寬度 const obstacleHeight = 50; // 障礙物高度 const playerSpeed = 10; // 玩家移動速度接著,通過 document.addEventListener 監(jiān)聽鍵盤事件,控制玩家方塊左右移動。在 dropObstacle 函數(shù)中,創(chuàng)建障礙物并添加到游戲區(qū)域中,并設(shè)置障礙物下落動畫,同時進(jìn)行碰撞檢測,如果玩家方塊與障礙物相撞,游戲結(jié)束。
// 監(jiān)聽鍵盤事件,控制玩家左右移動 document.addEventListener('keydown', event => {if (event.key === 'ArrowLeft') {player.style.left = Math.max(0, player.offsetLeft - playerSpeed) + 'px';} else if (event.key === 'ArrowRight') {player.style.left = Math.min(game.clientWidth - player.offsetWidth, player.offsetLeft + playerSpeed) + 'px';} });// 檢測碰撞 function detectCollision() {// 玩家和每個障礙物都進(jìn)行碰撞檢測const obstacles = document.querySelectorAll('.obstacle');obstacles.forEach(obstacle => {if (isCollided(player, obstacle)) {endGame();}}); }// 碰撞檢測函數(shù) function isCollided(element1, element2) {const rect1 = element1.getBoundingClientRect();const rect2 = element2.getBoundingClientRect();return !(rect1.bottom < rect2.top || rect1.top > rect2.bottom || rect1.right < rect2.left || rect1.left > rect2.right); }// 障礙物下落 function dropObstacle() {// 創(chuàng)建障礙物const obstacle = document.createElement('div');obstacle.classList.add('obstacle');obstacle.style.width = obstacleWidth + 'px';obstacle.style.height = obstacleHeight + 'px';obstacle.style.top = -obstacleHeight + 'px';obstacle.style.left = Math.floor(Math.random() * (game.clientWidth - obstacleWidth)) + 'px';game.appendChild(obstacle);// 障礙物下落動畫const obstacleDrop = setInterval(() => {if (!isGameOver) {obstacle.style.top = obstacle.offsetTop + obstacleSpeed + 'px';if (obstacle.offsetTop >= game.clientHeight) {game.removeChild(obstacle);clearInterval(obstacleDrop);scoreValue++;score.innerHTML = 'Score: ' + scoreValue;}detectCollision();}}, 10); }// 開始游戲 function startGame() {scoreValue = 0;isGameOver = false;obstacleInterval = setInterval(dropObstacle, 1000);gameTimer = setTimeout(() => {endGame();}, 60000); }// 結(jié)束游戲 function endGame() {isGameOver = true;clearInterval(obstacleInterval);clearTimeout(gameTimer);message.innerHTML = 'Game Over! Your score is ' + scoreValue;message.style.display = 'block'; }// 監(jiān)聽重新開始按鈕 message.addEventListener('click', () => {message.style.display'none';while (game.firstChild) {game.removeChild(game.firstChild);}startGame(); });// 開始游戲 startGame();通過 setInterval 定時器循環(huán)調(diào)用 dropObstacle 函數(shù),實現(xiàn)障礙物不斷下落。同時,通過 setTimeout 定時器設(shè)置游戲時間,如果游戲時間到了,則游戲結(jié)束。最后,在 endGame 函數(shù)中,設(shè)置游戲結(jié)束的一些行為,包括清除障礙物下落定時器、游戲時間定時器,顯示游戲結(jié)束信息等。同時,在 message 元素上添加點擊事件,用于重新開始游戲。當(dāng)然這里大家可以通過自己配置參數(shù)來增加游戲的難度!你也可以將元素替換成圖片讓游戲更加生動!
完整代碼
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小人逃脫</title><style>body {margin: 0;padding: 0;overflow: hidden;}#game {width: 100vw;height: 100vh;background-color: #222;position: relative;overflow: hidden;}#player {width: 50px;height: 50px;background-color: white;position: absolute;bottom: 0;left: 50%;transform: translateX(-50%);}.obstacle {width: 50px;height: 50px;background-color: red;position: absolute;top: -50px;left: 50%;transform: translateX(-50%);}#score {position: absolute;top: 10px;left: 10px;color: white;font-size: 24px;}#message {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: white;font-size: 48px;display: none;}</style> </head><body><div id="game"><div id="player"></div><div id="score">分?jǐn)?shù): 0</div><div id="message"></div></div></body> <script>// 獲取DOM元素const game = document.getElementById('game');const player = document.getElementById('player');const score = document.getElementById('score');const message = document.getElementById('message');// 初始化游戲參數(shù)let scoreValue = 0; // 得分let isGameOver = false; // 游戲是否結(jié)束let obstacleInterval; // 障礙物下落間隔let gameTimer; // 游戲計時器const obstacleSpeed = 5; // 障礙物下落速度const obstacleWidth = 50; // 障礙物寬度const obstacleHeight = 50; // 障礙物高度const playerSpeed = 10; // 玩家移動速度// 監(jiān)聽鍵盤事件,控制玩家左右移動document.addEventListener('keydown', event => {if (event.key === 'ArrowLeft') {player.style.left = Math.max(0, player.offsetLeft - playerSpeed) + 'px';} else if (event.key === 'ArrowRight') {player.style.left = Math.min(game.clientWidth - player.offsetWidth, player.offsetLeft + playerSpeed) + 'px';}});// 檢測碰撞function detectCollision() {// 玩家和每個障礙物都進(jìn)行碰撞檢測const obstacles = document.querySelectorAll('.obstacle');obstacles.forEach(obstacle => {if (isCollided(player, obstacle)) {endGame();}});}// 碰撞檢測函數(shù)function isCollided(element1, element2) {const rect1 = element1.getBoundingClientRect();const rect2 = element2.getBoundingClientRect();return !(rect1.bottom < rect2.top || rect1.top > rect2.bottom || rect1.right < rect2.left || rect1.left > rect2.right);}// 障礙物下落function dropObstacle() {// 創(chuàng)建障礙物const obstacle = document.createElement('div');obstacle.classList.add('obstacle');obstacle.style.width = obstacleWidth + 'px';obstacle.style.height = obstacleHeight + 'px';obstacle.style.top = -obstacleHeight + 'px';obstacle.style.left = Math.floor(Math.random() * (game.clientWidth - obstacleWidth)) + 'px';game.appendChild(obstacle);// 障礙物下落動畫const obstacleDrop = setInterval(() => {if (!isGameOver) {obstacle.style.top = obstacle.offsetTop + obstacleSpeed + 'px';if (obstacle.offsetTop >= game.clientHeight) {game.removeChild(obstacle);clearInterval(obstacleDrop);scoreValue++;score.innerHTML = 'Score: ' + scoreValue;}detectCollision();}}, 10);}// 開始游戲function startGame() {scoreValue = 0;isGameOver = false;obstacleInterval = setInterval(dropObstacle, 1000);gameTimer = setTimeout(() => {endGame();}, 60000);}// 結(jié)束游戲function endGame() {isGameOver = true;clearInterval(obstacleInterval);clearTimeout(gameTimer);message.innerHTML = 'Game Over! Your score is ' + scoreValue;message.style.display = 'block';}// 監(jiān)聽重新開始按鈕message.addEventListener('click', () => {message.style.display'none';while (game.firstChild) {game.removeChild(game.firstChild);}startGame();});// 開始游戲startGame(); </script></html>本期推薦
? 原創(chuàng)不易,還希望各位大佬支持一下 \textcolor{blue}{原創(chuàng)不易,還希望各位大佬支持一下} 原創(chuàng)不易,還希望各位大佬支持一下
👍 點贊,你的認(rèn)可是我創(chuàng)作的動力! \textcolor{green}{點贊,你的認(rèn)可是我創(chuàng)作的動力!} 點贊,你的認(rèn)可是我創(chuàng)作的動力!
?? 收藏,你的青睞是我努力的方向! \textcolor{green}{收藏,你的青睞是我努力的方向!} 收藏,你的青睞是我努力的方向!
?? 評論,你的意見是我進(jìn)步的財富! \textcolor{green}{評論,你的意見是我進(jìn)步的財富!} 評論,你的意見是我進(jìn)步的財富!
總結(jié)
以上是生活随笔為你收集整理的前端搭建小人逃脱游戏(内附源码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【入门2】分支结构 P1422 小玉家的
- 下一篇: 汇编语言 王爽第二版 总结