主要实现
1.使用WASD
或方向按钮
控制游戏
2.最高值4096
,玩到4096视为胜利
3.随机生成2、4、8
方块
4.移动方块
5.合并方块
JS代码干了什么
初始化游戏界面:创建游戏板和控制按钮。
定义游戏相关变量:如棋盘大小、棋盘状态、得分等。
初始化棋盘:创建棋盘元素并添加到页面。
生成新的方块:根据一定概率生成 2、4 或 8 的方块。
更新棋盘显示:根据方块的值设置背景颜色。移动方块:根据用户操作或键盘按键,实现方块的上、下、左、右移动。
合并方块:在移动过程中,相同值的方块会合并。
处理游戏结束:判断是否无法再进行移动。
监听用户操作:通过点击按钮或键盘按键触发移动操作。
HTML布局
`game-container`游戏板块
|`game-board`游戏棋盘板块
|`controls`游戏控制按钮版块
不同数字的配色
数字 | 颜色 |
---|---|
2 | #eee4da |
4 | #ede0c8 |
8 | #f2b179 |
16 | #f59563 |
32 | #f67c5f |
64 | #f65e3b |
128 | #edcf72 |
256 | #edcc61 |
512 | #edc850 |
1024 | #edc53f |
2048 | #edc22e |
4096 | #ed9e1f |
效果图
源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>4096 Game</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Arial', sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #faf8ef;
}
#game-container {
display: flex;
flex-direction: column;
align-items: center;
}
#game-board {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: 10px;
background-color: #bbada0;
padding: 10px;
border-radius: 10px;
margin-bottom: 20px;
}
.tile {
width: 80px;
height: 80px;
background-color: #cdc1b4;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
border-radius: 10px;
transition: all 0.2s ease-in-out;
}
#controls {
display: flex;
gap: 10px;
}
button {
width: 60px;
height: 60px;
font-size: 20px;
border-radius: 10px;
background-color: #8f7a66;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #9f8b76;
}
</style>
</head>
<body>
<div id="game-container">
<div id="game-board"></div>
<div id="controls">
<button id="up">W</button>
<button id="left">A</button>
<button id="down">S</button>
<button id="right">D</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const boardSize = 4;
let board = [];
let score = 0;
const gameBoard = document.getElementById('game-board');
const buttons = {
up: document.getElementById('up'),
down: document.getElementById('down'),
left: document.getElementById('left'),
right: document.getElementById('right')
};
function initBoard() {
for (let i = 0; i < boardSize * boardSize; i++) {
const tile = document.createElement('div');
tile.classList.add('tile');
gameBoard.appendChild(tile);
}
board = Array.from(document.querySelectorAll('.tile'));
generateTile();
generateTile();
updateBoard();
}
function generateTile() {
let emptyTiles = board.filter(tile =>!tile.textContent);
if (emptyTiles.length > 0) {
let randomTile = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
let randomValue = Math.random() < 0.9? '2' : Math.random() < 0.1? '4' : '8';
randomTile.textContent = randomValue;
}
}
function updateBoard() {
board.forEach(tile => {
const value = tile.textContent;
tile.style.backgroundColor = getTileColor(value);
});
}
function getTileColor(value) {
switch (value) {
case '2':
return '#eee4da';
case '4':
return '#ede0c8';
case '8':
return '#f2b179';
case '16':
return '#f59563';
case '32':
return '#f67c5f';
case '64':
return '#f65e3b';
case '128':
return '#edcf72';
case '256':
return '#edcc61';
case '512':
return '#edc850';
case '1024':
return '#edc53f';
case '2048':
return '#edc22e';
case '4096':
return '#ed9e1f';
default:
return '#cdc1b4';
}
}
function move(direction) {
switch (direction) {
case 'up':
moveUp();
break;
case 'down':
moveDown();
break;
case 'left':
moveLeft();
break;
case 'right':
moveRight();
break;
}
generateTile();
updateBoard();
}
function moveUp() {
for (let i = 0; i < boardSize; i++) {
let column = [];
for (let j = 0; j < boardSize; j++) {
column.push(board[i + j * boardSize].textContent);
}
let newColumn = slideTiles(column);
for (let j = 0; j < boardSize; j++) {
board[i + j * boardSize].textContent = newColumn[j];
}
}
}
function moveDown() {
for (let i = 0; i < boardSize; i++) {
let column = [];
for (let j = 0; j < boardSize; j++) {
column.push(board[i + j * boardSize].textContent);
}
let newColumn = slideTiles(column.reverse()).reverse();
for (let j = 0; j < boardSize; j++) {
board[i + j * boardSize].textContent = newColumn[j];
}
}
}
function moveLeft() {
for (let i = 0; i < boardSize; i++) {
let row = [];
for (let j = 0; j < boardSize; j++) {
row.push(board[i * boardSize + j].textContent);
}
let newRow = slideTiles(row);
for (let j = 0; j < boardSize; j++) {
board[i * boardSize + j].textContent = newRow[j];
}
}
}
function moveRight() {
for (let i = 0; i < boardSize; i++) {
let row = [];
for (let j = 0; j < boardSize; j++) {
row.push(board[i * boardSize + j].textContent);
}
let newRow = slideTiles(row.reverse()).reverse();
for (let j = 0; j < boardSize; j++) {
board[i * boardSize + j].textContent = newRow[j];
}
}
}
function slideTiles(tiles) {
let newTiles = tiles.filter(tile => tile);
for (let i = 0; i < newTiles.length - 1; i++) {
if (newTiles[i] === newTiles[i + 1]) {
newTiles[i] = (parseInt(newTiles[i]) * 2).toString();
newTiles[i + 1] = '';
}
}
newTiles = newTiles.filter(tile => tile);
while (newTiles.length < boardSize) {
newTiles.push('');
}
return newTiles;
}
buttons.up.addEventListener('click', () => move('up'));
buttons.down.addEventListener('click', () => move('down'));
buttons.left.addEventListener('click', () => move('left'));
buttons.right.addEventListener('click', () => move('right'));
document.addEventListener('keydown', (e) => {
switch (e.key) {
case 'w':
move('up');
break;
case's':
move('down');
break;
case 'a':
move('left');
break;
case 'd':
move('right');
break;
}
});
initBoard();
});
</script>
</body>
</html>