2025-08-27
元素衰变2048小游戏代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素衰变2048</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #faf8ef;
margin: 0;
padding: 10px;
touch-action: manipulation;
}
h1 {
font-size: 24px;
margin: 5px 0;
color: #776e65;
}
.game-container {
width: 280px;
margin: 0 auto;
position: relative;
}
.grid {
background-color: #bbada0;
border-radius: 5px;
padding: 10px;
position: relative;
}
.grid-row {
display: flex;
margin-bottom: 10px;
}
.grid-row:last-child {
margin-bottom: 0;
}
.grid-cell {
width: 60px;
height: 60px;
margin-right: 10px;
background-color: rgba(238, 228, 218, 0.35);
border-radius: 3px;
position: relative; /* 添加相对定位 */
}
.grid-cell:last-child {
margin-right: 0;
}
.tile {
position: absolute;
width: 60px;
height: 60px;
border-radius: 3px;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 24px;
transition: all 0.1s ease-in-out;
z-index: 10;
top: 0; /* 确保从顶部开始 */
left: 0; /* 确保从左侧开始 */
}
.score-container {
display: flex;
justify-content: space-between;
margin: 10px 0;
}
.score-box {
background-color: #bbada0;
color: white;
padding: 5px 10px;
border-radius: 5px;
font-weight: bold;
min-width: 60px;
font-size: 14px;
}
.score-title {
font-size: 12px;
color: #eee4da;
}
.score-value {
font-size: 18px;
}
.game-over {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(238, 228, 218, 0.73);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 100;
border-radius: 5px;
display: none;
}
.game-over-text {
font-size: 30px;
font-weight: bold;
color: #776e65;
margin-bottom: 10px;
}
.restart-button {
background-color: #8f7a66;
color: white;
border: none;
border-radius: 3px;
padding: 8px 15px;
font-size: 14px;
cursor: pointer;
}
.decay-effect {
animation: decayPulse 0.5s;
}
@keyframes decayPulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.instructions {
margin-top: 10px;
color: #776e65;
font-size: 12px;
line-height: 1.3;
}
</style>
</head>
<body>
<div class="game-container">
<h1>元素衰变2048</h1>
<div class="score-container">
<div class="score-box">
<div class="score-title">分数</div>
<div class="score-value" id="score">0</div>
</div>
<div class="score-box">
<div class="score-title">最高元素</div>
<div class="score-value" id="best-element">H</div>
</div>
</div>
<div class="grid">
<div class="grid-row">
<div class="grid-cell" id="cell-0-0"></div>
<div class="grid-cell" id="cell-0-1"></div>
<div class="grid-cell" id="cell-0-2"></div>
<div class="grid-cell" id="cell-0-3"></div>
</div>
<div class="grid-row">
<div class="grid-cell" id="cell-1-0"></div>
<div class="grid-cell" id="cell-1-1"></div>
<div class="grid-cell" id="cell-1-2"></div>
<div class="grid-cell" id="cell-1-3"></div>
</div>
<div class="grid-row">
<div class="grid-cell" id="cell-2-0"></div>
<div class="grid-cell" id="cell-2-1"></div>
<div class="grid-cell" id="cell-2-2"></div>
<div class="grid-cell" id="cell-2-3"></div>
</div>
<div class="grid-row">
<div class="grid-cell" id="cell-3-0"></div>
<div class="grid-cell" id="cell-3-1"></div>
<div class="grid-cell" id="cell-3-2"></div>
<div class="grid-cell" id="cell-3-3"></div>
</div>
<div class="game-over">
<div class="game-over-text">游戏结束!</div>
<button class="restart-button" onclick="startGame()">再来一局</button>
</div>
</div>
<div class="instructions">
<p>方向键/WASD移动,相同元素合并,每次移动可能衰变</p>
</div>
</div>
<script>
// 游戏配置
const config = {
size: 4,
decayChance: 0.0065,
chainDecayChance: 0.3
};
// 元素数据 (只显示符号)
const elements = [
{ value: 2, symbol: "H", color: "#EEE4DA", textColor: "#776e65" },
{ value: 4, symbol: "He", color: "#EDE0C8", textColor: "#776e65" },
{ value: 8, symbol: "Li", color: "#F2B179", textColor: "#f9f6f2" },
{ value: 16, symbol: "Be", color: "#F59563", textColor: "#f9f6f2" },
{ value: 32, symbol: "B", color: "#F67C5F", textColor: "#f9f6f2" },
{ value: 64, symbol: "C", color: "#F65E3B", textColor: "#f9f6f2" },
{ value: 128, symbol: "N", color: "#EDCF72", textColor: "#f9f6f2" },
{ value: 256, symbol: "O", color: "#EDCC61", textColor: "#f9f6f2" },
{ value: 512, symbol: "F", color: "#EDC850", textColor: "#f9f6f2" },
{ value: 1024, symbol: "Ne", color: "#EDC53F", textColor: "#f9f6f2" },
{ value: 2048, symbol: "Na", color: "#EDC22E", textColor: "#f9f6f2" }
];
// 获取元素属性
function getElement(value) {
if (value <= 2048) {
return elements.find(e => e.value === value);
}
// 高阶元素使用循环颜色
const colors = ["#3C3A32", "#B39379", "#7F7F7F", "#8B4513"];
const index = Math.floor(Math.log2(value) - 11) % colors.length;
return {
value: value,
symbol: "E" + Math.floor(Math.log2(value)),
color: colors[index],
textColor: "#f9f6f2"
};
}
// 游戏状态
let grid = [];
let score = 0;
let bestElement = { value: 2, symbol: "H" };
let gameOver = false;
let moving = false;
// 初始化游戏
function startGame() {
grid = Array(config.size).fill().map(() => Array(config.size).fill(0));
score = 0;
bestElement = { value: 2, symbol: "H" };
gameOver = false;
document.getElementById("score").textContent = "0";
document.getElementById("best-element").textContent = "H";
document.querySelector(".game-over").style.display = "none";
addRandomTile();
addRandomTile();
updateView();
}
// 添加随机元素
function addRandomTile() {
const emptyCells = [];
for (let r = 0; r < config.size; r++) {
for (let c = 0; c < config.size; c++) {
if (grid[r][c] === 0) {
emptyCells.push({ r, c });
}
}
}
if (emptyCells.length > 0) {
const { r, c } = emptyCells[Math.floor(Math.random() * emptyCells.length)];
grid[r][c] = Math.random() < 0.9 ? 2 : 4;
return true;
}
return false;
}
// 更新视图
function updateView() {
// 清除所有现有瓦片
document.querySelectorAll(".tile").forEach(tile => tile.remove());
// 添加新瓦片 - 现在直接放入对应的grid-cell中
for (let r = 0; r < config.size; r++) {
for (let c = 0; c < config.size; c++) {
const value = grid[r][c];
if (value !== 0) {
const element = getElement(value);
const cell = document.getElementById(`cell-${r}-${c}`);
const tile = document.createElement("div");
tile.className = "tile";
tile.style.backgroundColor = element.color;
tile.style.color = element.textColor;
tile.textContent = element.symbol;
cell.appendChild(tile);
}
}
}
document.getElementById("score").textContent = score;
document.getElementById("best-element").textContent = bestElement.symbol;
}
// 移动处理
function move(direction) {
if (gameOver || moving) return;
moving = true;
let moved = false;
switch (direction) {
case "up":
for (let c = 0; c < config.size; c++) {
moved = moveColumn(c, -1) || moved;
}
break;
case "down":
for (let c = 0; c < config.size; c++) {
moved = moveColumn(c, 1) || moved;
}
break;
case "left":
for (let r = 0; r < config.size; r++) {
moved = moveRow(r, -1) || moved;
}
break;
case "right":
for (let r = 0; r < config.size; r++) {
moved = moveRow(r, 1) || moved;
}
break;
}
if (moved) {
addRandomTile();
updateView();
setTimeout(() => {
tryDecay();
updateView();
checkGameOver();
moving = false;
}, 150);
} else {
moving = false;
checkGameOver();
}
}
// 移动行
function moveRow(r, dir) {
let moved = false;
const row = grid[r].filter(val => val !== 0);
if (dir === 1) row.reverse();
for (let i = 0; i < row.length - 1; i++) {
if (row[i] === row[i + 1]) {
row[i] *= 2;
row[i + 1] = 0;
score += row[i];
if (row[i] > bestElement.value) {
bestElement = getElement(row[i]);
}
moved = true;
}
}
const newRow = row.filter(val => val !== 0);
while (newRow.length < config.size) newRow.push(0);
if (dir === 1) newRow.reverse();
if (JSON.stringify(grid[r]) !== JSON.stringify(newRow)) {
moved = true;
}
grid[r] = newRow;
return moved;
}
// 移动列
function moveColumn(c, dir) {
let moved = false;
let column = [];
for (let r = 0; r < config.size; r++) {
if (grid[r][c] !== 0) column.push(grid[r][c]);
}
if (dir === 1) column.reverse();
for (let i = 0; i < column.length - 1; i++) {
if (column[i] === column[i + 1]) {
column[i] *= 2;
column[i + 1] = 0;
score += column[i];
if (column[i] > bestElement.value) {
bestElement = getElement(column[i]);
}
moved = true;
}
}
const newColumn = column.filter(val => val !== 0);
while (newColumn.length < config.size) newColumn.push(0);
if (dir === 1) newColumn.reverse();
for (let r = 0; r < config.size; r++) {
if (grid[r][c] !== newColumn[r]) {
moved = true;
grid[r][c] = newColumn[r];
}
}
return moved;
}
// 尝试衰变
function tryDecay() {
const decayCandidates = [];
for (let r = 0; r < config.size; r++) {
for (let c = 0; c < config.size; c++) {
if (grid[r][c] > 2) {
decayCandidates.push({ r, c, value: grid[r][c] });
}
}
}
if (decayCandidates.length === 0) return;
const decayProbabilities = decayCandidates.map(candidate => {
return config.decayChance + (Math.log2(candidate.value) - 1) * 0.000025;
});
for (let i = 0; i < decayCandidates.length; i++) {
const { r, c, value } = decayCandidates[i];
if (Math.random() < decayProbabilities[i]) {
decayElement(r, c);
// 连锁衰变
const directions = [
{ dr: 0, dc: 0 }, { dr: 0, dc: 0 },
{ dr: 0, dc: 0 }, { dr: 0, dc: 0 }
];
for (const { dr, dc } of directions) {
const nr = r + dr;
const nc = c + dc;
if (nr >= 0 && nr < config.size && nc >= 0 && nc < config.size &&
grid[nr][nc] === value && Math.random() < config.chainDecayChance) {
decayElement(nr, nc);
}
}
}
}
}
// 衰变元素
function decayElement(r, c) {
const cell = document.getElementById(`cell-${r}-${c}`);
const tile = cell.querySelector(".tile");
if (tile) {
tile.classList.add("decay-effect");
setTimeout(() => tile.classList.remove("decay-effect"), 500);
}
grid[r][c] /= 2;
}
// 检查游戏结束
function checkGameOver() {
for (let r = 0; r < config.size; r++) {
for (let c = 0; c < config.size; c++) {
if (grid[r][c] === 0) return false;
}
}
for (let r = 0; r < config.size; r++) {
for (let c = 0; c < config.size; c++) {
const value = grid[r][c];
if (c < config.size - 1 && grid[r][c + 1] === value) return false;
if (r < config.size - 1 && grid[r + 1][c] === value) return false;
}
}
gameOver = true;
document.querySelector(".game-over").style.display = "flex";
return true;
}
// 键盘控制
document.addEventListener("keydown", function(event) {
if (gameOver) return;
switch (event.key) {
case "ArrowUp":
case "w":
case "W":
move("up");
event.preventDefault();
break;
case "ArrowDown":
case "s":
case "S":
move("down");
event.preventDefault();
break;
case "ArrowLeft":
case "a":
case "A":
move("left");
event.preventDefault();
break;
case "ArrowRight":
case "d":
case "D":
move("right");
event.preventDefault();
break;
}
});
// 触摸控制
let touchStartX = 0;
let touchStartY = 0;
document.querySelector(".grid").addEventListener("touchstart", function(e) {
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
e.preventDefault();
}, { passive: false });
document.querySelector(".grid").addEventListener("touchend", function(e) {
if (gameOver) return;
const touchEndX = e.changedTouches[0].clientX;
const touchEndY = e.changedTouches[0].clientY;
const dx = touchEndX - touchStartX;
const dy = touchEndY - touchStartY;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) move("right");
else move("left");
} else {
if (dy > 0) move("down");
else move("up");
}
e.preventDefault();
}, { passive: false });
// 开始游戏
startGame();
</script>
</body>
</html>
3
1
分享
操作
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
