HTML實現的2048游戲

以下是一個純HTML實現的2048游戲代碼,包含CSS和JavaScript:
在這里插入圖片描述

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>2048 Game</title><style>body {font-family: Arial, sans-serif;text-align: center;background-color: #faf8ef;}.container {width: 450px;margin: 0 auto;}.header {display: flex;justify-content: space-between;margin-bottom: 20px;}h1 {font-size: 80px;margin: 0;color: #776e65;}.score-container {background: #bbada0;padding: 15px 25px;border-radius: 6px;color: white;font-weight: bold;text-align: center;}.score-title {font-size: 13px;display: block;}.score-value {font-size: 25px;}.game-container {background: #bbada0;border-radius: 6px;width: 450px;height: 450px;padding: 15px;position: relative;margin: 0 auto;}.grid {display: grid;grid-template-columns: repeat(4, 1fr);grid-gap: 15px;width: 100%;height: 100%;}.cell {background: rgba(238, 228, 218, 0.35);border-radius: 3px;display: flex;justify-content: center;align-items: center;font-size: 45px;font-weight: bold;color: #776e65;position: relative;}.tile-2 {background: #eee4da;}.tile-4 {background: #ede0c8;}.tile-8 {background: #f2b179;color: white;}.tile-16 {background: #f59563;color: white;}.tile-32 {background: #f67c5f;color: white;}.tile-64 {background: #f65e3b;color: white;}.tile-128 {background: #edcf72;color: white;font-size: 40px;}.tile-256 {background: #edcc61;color: white;font-size: 40px;}.tile-512 {background: #edc850;color: white;font-size: 40px;}.tile-1024 {background: #edc53f;color: white;font-size: 35px;}.tile-2048 {background: #edc22e;color: white;font-size: 35px;}.game-message {display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: rgba(238, 228, 218, 0.73);z-index: 100;flex-direction: column;align-items: center;justify-content: center;border-radius: 6px;}.game-message.game-won {background: rgba(237, 194, 46, 0.5);color: white;}.game-message.game-over {background: rgba(238, 228, 218, 0.73);color: #776e65;}.game-message p {font-size: 60px;font-weight: bold;margin: 0;}.game-message .lower {margin-top: 30px;}.game-message button {background: #8f7a66;color: white;border: none;border-radius: 3px;padding: 10px 20px;font-size: 18px;cursor: pointer;}.game-message button:hover {background: #9f8b77;}.instructions {margin-top: 30px;color: #776e65;}</style>
</head>
<body><div class="container"><div class="header"><h1>2048</h1><div class="score-container"><span class="score-title">SCORE</span><span class="score-value" id="score">0</span></div></div><div class="game-container"><div class="grid" id="grid"></div><div class="game-message" id="game-message"><p id="message-text"></p><div class="lower"><button id="keep-going-button">Keep going</button><button id="retry-button">Try again</button></div></div></div><div class="instructions"><p>Join the numbers and get to the <strong>2048 tile!</strong></p><p>Use <strong>arrow keys</strong> to move the tiles.</p></div></div><script>document.addEventListener('DOMContentLoaded', () => {const grid = document.getElementById('grid');const scoreDisplay = document.getElementById('score');const gameMessage = document.getElementById('game-message');const messageText = document.getElementById('message-text');const retryButton = document.getElementById('retry-button');const keepGoingButton = document.getElementById('keep-going-button');let board = [];let score = 0;let gameWon = false;// Initialize the gamefunction initGame() {// Create empty boardboard = [[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]];score = 0;gameWon = false;updateScore();// Clear the gridgrid.innerHTML = '';// Create cellsfor (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {const cell = document.createElement('div');cell.className = 'cell';cell.id = `cell-${i}-${j}`;grid.appendChild(cell);}}// Hide game messagegameMessage.style.display = 'none';// Add two initial tilesaddRandomTile();addRandomTile();// Render the boardrenderBoard();}// Add a random tile (2 or 4) to an empty cellfunction addRandomTile() {const emptyCells = [];// Find all empty cellsfor (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (board[i][j] === 0) {emptyCells.push({row: i, col: j});}}}// If there are empty cells, add a new tileif (emptyCells.length > 0) {const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];board[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4;return true;}return false;}// Render the boardfunction renderBoard() {for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {const cell = document.getElementById(`cell-${i}-${j}`);const value = board[i][j];// Clear the cellcell.className = 'cell';cell.textContent = '';// If the cell has a value, add the appropriate class and contentif (value > 0) {cell.textContent = value;cell.classList.add(`tile-${value}`);}}}}// Update the score displayfunction updateScore() {scoreDisplay.textContent = score;}// Check if the game is overfunction isGameOver() {// Check if there are any empty cellsfor (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (board[i][j] === 0) {return false;}}}// Check if any adjacent cells have the same valuefor (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (j < 3 && board[i][j] === board[i][j + 1]) {return false;}if (i < 3 && board[i][j] === board[i + 1][j]) {return false;}}}return true;}// Check if the player has won (reached 2048)function checkWin() {for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (board[i][j] === 2048) {return true;}}}return false;}// Show game message (win or lose)function showGameMessage(won) {if (won) {messageText.textContent = 'You Win!';gameMessage.classList.add('game-won');gameMessage.classList.remove('game-over');keepGoingButton.style.display = 'inline-block';} else {messageText.textContent = 'Game Over!';gameMessage.classList.add('game-over');gameMessage.classList.remove('game-won');keepGoingButton.style.display = 'none';}gameMessage.style.display = 'flex';}// Move tiles leftfunction moveLeft() {let moved = false;for (let i = 0; i < 4; i++) {// Remove zeroslet row = board[i].filter(val => val !== 0);// Merge adjacent equal valuesfor (let j = 0; j < row.length - 1; j++) {if (row[j] === row[j + 1]) {row[j] *= 2;score += row[j];row[j + 1] = 0;moved = true;if (row[j] === 2048) {gameWon = true;}}}// Remove zeros again after mergingrow = row.filter(val => val !== 0);// Add zeros to the endwhile (row.length < 4) {row.push(0);}// Check if the row has changedif (JSON.stringify(board[i]) !== JSON.stringify(row)) {moved = true;}board[i] = row;}return moved;}// Move tiles rightfunction moveRight() {let moved = false;for (let i = 0; i < 4; i++) {// Remove zeroslet row = board[i].filter(val => val !== 0);// Merge adjacent equal values (from right)for (let j = row.length - 1; j > 0; j--) {if (row[j] === row[j - 1]) {row[j] *= 2;score += row[j];row[j - 1] = 0;moved = true;if (row[j] === 2048) {gameWon = true;}}}// Remove zeros again after mergingrow = row.filter(val => val !== 0);// Add zeros to the beginningwhile (row.length < 4) {row.unshift(0);}// Check if the row has changedif (JSON.stringify(board[i]) !== JSON.stringify(row)) {moved = true;}board[i] = row;}return moved;}// Move tiles upfunction moveUp() {let moved = false;for (let j = 0; j < 4; j++) {// Get columnlet column = [board[0][j], board[1][j], board[2][j], board[3][j]];// Remove zeroscolumn = column.filter(val => val !== 0);// Merge adjacent equal valuesfor (let i = 0; i < column.length - 1; i++) {if (column[i] === column[i + 1]) {column[i] *= 2;score += column[i];column[i + 1] = 0;moved = true;if (column[i] === 2048) {gameWon = true;}}}// Remove zeros again after mergingcolumn = column.filter(val => val !== 0);// Add zeros to the endwhile (column.length < 4) {column.push(0);}// Check if the column has changedfor (let i = 0; i < 4; i++) {if (board[i][j] !== column[i]) {moved = true;board[i][j] = column[i];}}}return moved;}// Move tiles downfunction moveDown() {let moved = false;for (let j = 0; j < 4; j++) {// Get columnlet column = [board[0][j], board[1][j], board[2][j], board[3][j]];// Remove zeroscolumn = column.filter(val => val !== 0);// Merge adjacent equal values (from bottom)for (let i = column.length - 1; i > 0; i--) {if (column[i] === column[i - 1]) {column[i] *= 2;score += column[i];column[i - 1] = 0;moved = true;if (column[i] === 2048) {gameWon = true;}}}// Remove zeros again after mergingcolumn = column.filter(val => val !== 0);// Add zeros to the beginningwhile (column.length < 4) {column.unshift(0);}// Check if the column has changedfor (let i = 0; i < 4; i++) {if (board[i][j] !== column[i]) {moved = true;board[i][j] = column[i];}}}return moved;}// Handle keyboard eventsfunction handleKeyPress(event) {if (gameMessage.style.display === 'flex' && !gameWon) {return;}let moved = false;switch (event.key) {case 'ArrowLeft':moved = moveLeft();break;case 'ArrowRight':moved = moveRight();break;case 'ArrowUp':moved = moveUp();break;case 'ArrowDown':moved = moveDown();break;default:return;}if (moved) {addRandomTile();renderBoard();updateScore();if (gameWon) {showGameMessage(true);} else if (isGameOver()) {showGameMessage(false);}}}// Event listenersdocument.addEventListener('keydown', handleKeyPress);retryButton.addEventListener('click', initGame);keepGoingButton.addEventListener('click', () => {gameMessage.style.display = 'none';gameWon = false;});// Start the gameinitGame();});</script>
</body>
</html>

功能說明

這個2048游戲實現包含以下功能:

  • 4×4的游戲棋盤
  • 使用箭頭鍵控制方塊移動
  • 分數計算和顯示
  • 游戲勝利檢測(達到2048方塊)
  • 游戲結束檢測(無法移動)
  • 重新開始游戲選項
  • 達到2048后可以選擇繼續游戲
  • 響應式設計,適應不同屏幕

使用方法

  1. 將上述代碼復制到一個HTML文件中
  2. 用瀏覽器打開該文件即可開始游戲
  3. 使用鍵盤方向鍵(↑↓←→)移動方塊
  4. 相同數字的方塊碰撞時會合并
  5. 目標是得到2048方塊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83261.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83261.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83261.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Python 構建支持主流大模型與 Ollama 的統一接口平臺

?? 背景概述 近年來,隨著大語言模型(LLM)的蓬勃發展,OpenAI 的 GPT 系列、Google 的 Gemini、Anthropic 的 Claude、以及開源的 Ollama 本地模型等,逐漸成為自然語言處理、智能問答、AI 助手等應用的基礎組件。 開發者在使用這些模型時常面臨如下問題: 各模型接口不統…

計算機系統概述(4)

計算機系統層次結構&#xff1a;硬件層、系統層、應用層。 計算機的基本硬件系統由運算器、控制器、存儲器、輸入設備和輸出設備5大部件組成。 運算器、控制器等部件被集成在一起統稱為中央處理單元CPU。 存儲器是計算機系統中的記憶設備&#xff0c;分為內部存儲器和外部存…

Linux 下的COW機制(copy-on-write)

Linux通過MMU進行虛擬地址到物理地址的轉換&#xff0c;當進程執行fork()后&#xff0c;會把頁中的權限設置為RD-ONLY&#xff08;只讀&#xff09;。 MMU&#xff08;內存管理單元&#xff09; MMU本質是一個集成在CPU核心的硬件電路模塊&#xff0c;其核心任務是實現…

客戶案例 | 短視頻點播企業海外視頻加速與成本優化:MediaPackage+Cloudfront 技術重構實踐

01技術背景與業務挑戰 某短視頻點播企業深耕國內用戶市場&#xff0c;但其后臺應用系統部署于東南亞印尼 IDC 機房。 隨著業務規模擴大&#xff0c;傳統架構已較難滿足當前企業發展的需求&#xff0c;企業面臨著三重挑戰&#xff1a; ① 業務&#xff1a;國內用戶訪問海外服…

開發Vue.js組件的二三事

Vue.js作為一款漸進式JavaScript框架&#xff0c;其組件化開發模式是其核心優勢之一。在多年的Vue開發實踐中&#xff0c;我積累了一些組件開發的經驗和思考&#xff0c;在此與大家分享。 組件設計原則 單一職責原則 每個組件應該只關注一個特定的功能或UI部分。如果一個組件…

實現多路視頻截圖預覽之后上傳到后臺系統

********************父組件********************** <div class"camera-box" v-loading"i.loading"> <div class"camera-box-inner" v-for"(x, y) in i.children" :key"y children x.featureCode" v-show"…

分布式鎖-Redisson實現

目錄 本地鎖的局限性 Redisson解決分布式鎖問題 在分布式環境下&#xff0c;分布式鎖可以保證在多個節點上的并發操作時數據的一致性和互斥性。分布式鎖有多種實現方案&#xff0c;最常用的兩種方案是&#xff1a;zookeeper和redis&#xff0c;本文介紹redis實現分布式鎖方案…

【辦公類-48-04】202506每月電子屏臺賬匯總成docx-5(問卷星下載5月范圍內容,自動獲取excel文件名,并轉移處理)

背景需求&#xff1a; 1-4月電子屏表格&#xff0c;都是用這個代碼將EXCEL數據整理成分類成3個WORD表格。 【辦公類-48-04】20250118每月電子屏臺賬匯總成docx-4&#xff08;提取EXCLE里面1月份的內容&#xff0c;自制月份文件夾&#xff09;-CSDN博客文章瀏覽閱讀1.2k次&…

【websocket】安裝與使用

websocket安裝與使用 1. 介紹2. 安裝3. websocketpp常用接口4. Websocketpp使用4.1 服務端4.2 客戶端 1. 介紹 WebSocket 是從 HTML5 開始支持的一種網頁端和服務端保持長連接的 消息推送機制。 傳統的 web 程序都是屬于 “一問一答” 的形式&#xff0c;即客戶端給服務器發送…

微算法科技(NASDAQ:MLGO)基于信任的集成共識和灰狼優化(GWO)算法,搭建高信任水平的區塊鏈網絡

隨著數字化轉型的加速&#xff0c;區塊鏈技術作為去中心化、透明且不可篡改的數據存儲與交換平臺&#xff0c;正逐步滲透到金融、供應鏈管理、物聯網等多個領域&#xff0c;探索基于信任的集成共識機制&#xff0c;并結合先進的優化算法來提升區塊鏈網絡的信任水平&#xff0c;…

【項目實戰】通過多模態+LangGraph實現PPT生成助手

PPT自動生成系統 基于LangGraph的PPT自動生成系統&#xff0c;可以將Markdown文檔自動轉換為PPT演示文稿。 功能特點 Markdown解析&#xff1a;自動解析Markdown文檔結構PPT模板分析&#xff1a;分析PPT模板的布局和風格智能布局決策&#xff1a;匹配內容與合適的PPT布局自動…

貝葉斯優化+LSTM+時序預測=Nature子刊!

貝葉斯優化與LSTM的融合在時間序列預測領域取得了顯著成效&#xff0c;特別是在處理那些涉及眾多超參數調整的復雜問題時。 1.這種結合不僅極大提高了預測的精確度&#xff0c;還優化了模型訓練流程&#xff0c;提升了效率和成本效益。超參數優化的新篇章&#xff1a;LSTM因其…

AWSLambda之設置時區

目標 希望Lambda運行的時區是東八區。 解決 只需要設置lambda的環境變量TZ為東八區時區即可&#xff0c;即Asia/Shanghai。 參考 使用 Lambda 環境變量

RAG系統向量數據庫選型與Prompt Engineering魯棒性測試實踐

引言 在AI應用不斷落地的今天&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff0c;檢索增強生成&#xff09;和Prompt Engineering&#xff08;提示工程&#xff09;成為大模型工程師和測試工程師的核心武器。 一方面&#xff0c;RAG系統依賴強大的向量數據…

2.Socket 編程 UDP

1.UDP網絡編程 0.背景知識 自實現IP轉化 相關函數理解 IP相關理解 1. V2版本 - DictServer封裝版 實現一個簡單的英譯漢的網絡字典 Dict.hpp dictionary.txt InetAddr.hpp ? 在 InetAddr 中&#xff0c;重載一下方便對用戶是否是同一個進行比較 Log.hpp makefile Mutex.hpp…

數據可視化交互

目錄 【實驗目的】 【實驗原理】 【實驗環境】 【實驗步驟】 一、安裝 pyecharts 二、下載數據 三、實驗任務 實驗 1&#xff1a;AQI 橫向對比條形圖 代碼說明&#xff1a; 運行結果&#xff1a; 實驗 2&#xff1a;AQI 等級分布餅圖 實驗 3&#xff1a;多城市 AQI…

【MATLAB去噪算法】基于CEEMDAN聯合小波閾值去噪算法(第四期)

CEEMDAN聯合小波閾值去噪算法相關文獻 一、EMD 與 EEMD 的局限性 &#xff08;1&#xff09;EMD (經驗模態分解) 旨在自適應地將非線性、非平穩信號分解成一系列 本征模態函數 (IMFs)&#xff0c;這些 IMFs 從高頻到低頻排列。 核心問題&#xff1a;模態混合 (Mode Mixing) 同…

大話軟工筆記—架構模型

1. 架構模型1—拓撲圖 &#xff08;1&#xff09;拓撲圖概念 拓撲圖&#xff0c;將多個軟件系統用網絡圖連接起來的表達方式。 &#xff08;2&#xff09;拓撲圖分類 總線型結構 比較普遍采用的方式&#xff0c;將所有的系統接到一條總線上。 星狀結構 各個系統通過點到…

24-Oracle 23 ai ?Lock-Free Reservations?(無鎖列值保留)

數據庫領域為了解決ACID的平衡&#xff0c;嘗試了各種鎖、各種模式&#xff0c; 引擎技術特性、廠家實現方式各放異彩&#xff0c;被各種鎖折磨的小伙伴&#xff0c;是不是感同身受。 一、數據庫鎖 1. 鎖的類型與特點 ?全局鎖?&#xff1a;鎖定整個數據庫實例&#xff0c;備…

OpenPrompt 和直接對提示詞的嵌入向量進行訓練有什么區別

OpenPrompt 和直接對提示詞的嵌入向量進行訓練有什么區別 直接訓練提示詞嵌入向量的核心區別 您提到的代碼: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding