本文目录导读:

我来给你写一个完整的PHP贪吃蛇游戏,包含多种实现方式:
方案1:命令行版本(终端运行)
<?php
// snake.php - 终端贪吃蛇游戏
class SnakeGame {
private $width;
private $height;
private $snake;
private $food;
private $direction;
private $score;
private $gameOver;
private $speed;
public function __construct($width = 20, $height = 10) {
$this->width = $width;
$this->height = $height;
$this->reset();
$this->speed = 100000; // 微秒
}
public function reset() {
$this->snake = [[5, 5], [4, 5], [3, 5]]; // 蛇身坐标
$this->direction = 'right';
$this->score = 0;
$this->gameOver = false;
$this->generateFood();
}
private function generateFood() {
do {
$this->food = [
rand(0, $this->width - 1),
rand(0, $this->height - 1)
];
} while (in_array($this->food, $this->snake));
}
private function move() {
$head = $this->snake[0];
switch ($this->direction) {
case 'up': $head[1]--; break;
case 'down': $head[1]++; break;
case 'left': $head[0]--; break;
case 'right': $head[0]++; break;
}
// 撞墙检测
if ($head[0] < 0 || $head[0] >= $this->width ||
$head[1] < 0 || $head[1] >= $this->height) {
$this->gameOver = true;
return;
}
// 撞自己检测
if (in_array($head, array_slice($this->snake, 0, -1))) {
$this->gameOver = true;
return;
}
array_unshift($this->snake, $head);
// 吃食物
if ($head == $this->food) {
$this->score += 10;
$this->generateFood();
$this->speed = max(20000, $this->speed - 2000); // 加速
} else {
array_pop($this->snake);
}
}
private function render() {
system('clear'); // Windows用 cls
$grid = array_fill(0, $this->height, array_fill(0, $this->width, ' '));
// 绘制蛇
foreach ($this->snake as $i => $segment) {
$grid[$segment[1]][$segment[0]] = $i == 0 ? '🐍' : '⬛';
}
// 绘制食物
$grid[$this->food[1]][$this->food[0]] = '🍎';
// 输出
echo "════════════════════════════\n";
echo " 贪吃蛇游戏 得分: {$this->score}\n";
echo "════════════════════════════\n";
foreach ($grid as $row) {
echo "│" . implode('', $row) . "│\n";
}
echo "════════════════════════════\n";
echo "操作: W上 S下 A左 D右 Q退出\n";
}
public function run() {
echo "贪吃蛇游戏开始!按 W/A/S/D 移动\n";
while (!$this->gameOver) {
$this->render();
// 检测键盘输入
$key = $this->getKey();
if ($key) {
switch (strtolower($key)) {
case 'w': $this->direction = 'up'; break;
case 's': $this->direction = 'down'; break;
case 'a': $this->direction = 'left'; break;
case 'd': $this->direction = 'right'; break;
case 'q': echo "游戏结束!得分: {$this->score}\n"; return;
}
}
$this->move();
usleep($this->speed);
}
echo "游戏结束!最终得分: {$this->score}\n";
echo "按回车键重新开始...";
trim(fgets(STDIN));
$this->reset();
$this->run();
}
private function getKey() {
system('stty cbreak -echo');
$key = fgetc(STDIN);
system('stty -cbreak echo');
return $key;
}
}
// 运行游戏
$game = new SnakeGame();
$game->run();
方案2:Web版本(浏览器运行)
<?php
// web_snake.php - 浏览器贪吃蛇
session_start();
if (!isset($_SESSION['snake_game'])) {
$_SESSION['snake_game'] = [
'snake' => [[5, 5], [4, 5], [3, 5]],
'direction' => 'right',
'score' => 0,
'gameOver' => false
];
}
$game = &$_SESSION['snake_game'];
// 处理移动指令
if (isset($_GET['action'])) {
$action = $_GET['action'];
if (!$game['gameOver']) {
switch ($action) {
case 'up': $game['direction'] = 'up'; break;
case 'down': $game['direction'] = 'down'; break;
case 'left': $game['direction'] = 'left'; break;
case 'right': $game['direction'] = 'right'; break;
case 'restart':
$game = ['snake' => [[5,5],[4,5],[3,5]],
'direction' => 'right',
'score' => 0,
'gameOver' => false];
break;
}
// 移动逻辑
if ($action != 'restart' && !$game['gameOver']) {
moveSnake($game);
}
}
}
function moveSnake(&$game) {
$head = $game['snake'][0];
switch ($game['direction']) {
case 'up': $head[1]--; break;
case 'down': $head[1]++; break;
case 'left': $head[0]--; break;
case 'right': $head[0]++; break;
}
// 边界检测
if ($head[0] < 0 || $head[0] >= 20 || $head[1] < 0 || $head[1] >= 10) {
$game['gameOver'] = true;
return;
}
// 自撞检测
if (in_array($head, array_slice($game['snake'], 0, -1))) {
$game['gameOver'] = true;
return;
}
array_unshift($game['snake'], $head);
// 食物位置(如果没有食物)
if (!isset($game['food'])) {
$game['food'] = generateFood($game['snake']);
}
// 吃食物
if ($head == $game['food']) {
$game['score'] += 10;
$game['food'] = generateFood($game['snake']);
} else {
array_pop($game['snake']);
}
}
function generateFood($snake) {
do {
$food = [rand(0, 19), rand(0, 9)];
} while (in_array($food, $snake));
return $food;
}
// 检查是否还有食物
if (isset($game['snake']) && !isset($game['food']) && !$game['gameOver']) {
$game['food'] = generateFood($game['snake']);
}
// 如果游戏结束,清理session,允许重新开始
if ($game['gameOver'] && isset($_GET['restart'])) {
session_destroy();
header('Location: web_snake.php');
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">PHP贪吃蛇</title>
<style>
body { font-family: monospace; text-align: center; margin-top: 50px; }
.game-title { color: #333; font-size: 24px; }
.score { color: #666; margin: 10px; }
.game-over { color: red; font-weight: bold; }
.controls { margin: 20px; }
.controls button { padding: 10px 20px; margin: 5px; cursor: pointer; }
.snake-grid { display: inline-grid; gap: 1px; background: #333; padding: 1px; }
.grid-cell { width: 30px; height: 30px; background: #eee; }
.snake-head { background: #4CAF50 !important; }
.snake-body { background: #8BC34A !important; }
.food { background: #F44336 !important; }
</style>
</head>
<body>
<h1 class="game-title">🐍 PHP贪吃蛇 🐍</h1>
<div class="score">得分: <span id="score"><?php echo $game['score']; ?></span></div>
<?php if ($game['gameOver']): ?>
<div class="game-over">游戏结束!得分: <?php echo $game['score']; ?></div>
<a href="?restart=1"><button>重新开始</button></a>
<?php else: ?>
<div class="snake-grid" style="grid-template-columns: repeat(20, 30px); grid-template-rows: repeat(10, 30px);">
<?php
// 创建网格
for ($y = 0; $y < 10; $y++) {
for ($x = 0; $x < 20; $x++) {
$class = 'grid-cell';
$cellPos = [$x, $y];
if (isset($game['snake'][0]) && $cellPos == $game['snake'][0]) {
$class .= ' snake-head';
} elseif (in_array($cellPos, $game['snake'])) {
$class .= ' snake-body';
} elseif (isset($game['food']) && $cellPos == $game['food']) {
$class .= ' food';
}
echo "<div class='$class'></div>";
}
}
?>
</div>
<div class="controls">
<button onclick="move('up')">⬆️ 上</button><br>
<button onclick="move('left')">⬅️ 左</button>
<button onclick="move('down')">⬇️ 下</button>
<button onclick="move('right')">➡️ 右</button>
</div>
<script>
function move(direction) {
window.location.href = '?action=' + direction;
}
// 键盘控制
document.addEventListener('keydown', function(e) {
switch(e.key) {
case 'ArrowUp': move('up'); break;
case 'ArrowDown': move('down'); break;
case 'ArrowLeft': move('left'); break;
case 'ArrowRight': move('right'); break;
}
});
</script>
<?php endif; ?>
<p>使用方向键或点击按钮控制蛇的移动</p>
</body>
</html>
方案3:AJAX版本(智能自动移动)
<?php
// ajax_snake.php - 带AJAX的贪吃蛇
session_start();
// 初始化或读取游戏状态
if (!isset($_SESSION['ajax_snake'])) {
$_SESSION['ajax_snake'] = [
'snake' => [[10, 5], [9, 5], [8, 5]],
'direction' => 'right',
'score' => 0,
'gameOver' => false,
'food' => [15, 5],
'speed' => 200
];
}
$response = ['success' => true];
// 处理AJAX请求
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['action'])) {
$game = &$_SESSION['ajax_snake'];
switch ($_POST['action']) {
case 'move':
if (!$game['gameOver']) {
moveSnake($game);
$response = [
'success' => true,
'gameOver' => $game['gameOver'],
'score' => $game['score']
];
}
break;
case 'restart':
$_SESSION['ajax_snake'] = [
'snake' => [[10, 5], [9, 5], [8, 5]],
'direction' => 'right',
'score' => 0,
'gameOver' => false,
'food' => [15, 5],
'speed' => 200
];
$response = ['success' => true, 'restarted' => true];
break;
}
echo json_encode($response);
exit;
}
function moveSnake(&$game) {
$head = $game['snake'][0];
switch ($game['direction']) {
case 'up': $head[1]--; break;
case 'down': $head[1]++; break;
case 'left': $head[0]--; break;
case 'right': $head[0]++; break;
}
// 边界检查
if ($head[0] < 0 || $head[0] >= 20 || $head[1] < 0 || $head[1] >= 10) {
$game['gameOver'] = true;
return;
}
// 自撞检查
if (in_array($head, array_slice($game['snake'], 0, -1))) {
$game['gameOver'] = true;
return;
}
array_unshift($game['snake'], $head);
// 吃食物
if ($head == $game['food']) {
$game['score'] += 10;
$game['food'] = generateFood($game['snake']);
$game['speed'] = max(50, $game['speed'] - 5);
} else {
array_pop($game['snake']);
}
}
function generateFood($snake) {
do {
$food = [rand(0, 19), rand(0, 9)];
} while (in_array($food, $snake));
return $food;
}
// 如果不是AJAX请求,输出HTML页面
if (isset($_GET['game'])) {
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">AJAX贪吃蛇</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #1a1a2e;
margin: 0;
font-family: Arial, sans-serif;
}
.game-container {
background: #16213e;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
text-align: center;
}
h1 { color: #e94560; margin-bottom: 20px; }
.score { color: #fff; font-size: 20px; margin-bottom: 20px; }
#gameBoard {
border: 2px solid #e94560;
background: #0f3460;
margin: 20px auto;
border-radius: 5px;
}
.game-over {
color: #e94560;
font-size: 24px;
margin: 20px;
display: none;
}
button {
padding: 12px 30px;
font-size: 16px;
background: #e94560;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin: 10px;
}
button:hover { opacity: 0.9; }
.controls {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
gap: 5px;
justify-content: center;
margin: 20px 0;
}
.direction-btn { padding: 15px; font-size: 20px; background: #3b82f6; }
.up { grid-column: 2; grid-row: 1; }
.down { grid-column: 2; grid-row: 3; background: #10b981; }
.left { grid-column: 1; grid-row: 2; }
.right { grid-column: 3; grid-row: 2; background: #f59e0b; }
.stop-btn { background: #ef4444; }
</style>
</head>
<body>
<div class="game-container">
<h1>🐍 贪吃蛇 🐍</h1>
<div class="score">得分: <span id="score">0</span></div>
<div id="gameBoard"></div>
<div class="game-over" id="gameOverMsg">游戏结束!</div>
<div class="controls">
<button class="direction-btn up" onclick="setDirection('up')">↑</button>
<button class="direction-btn left" onclick="setDirection('left')">←</button>
<button class="direction-btn down" onclick="setDirection('down')">↓</button>
<button class="direction-btn right" onclick="setDirection('right')">→</button>
</div>
<button onclick="restartGame()">重新开始</button>
<script>
const COLS = 20;
const ROWS = 10;
const CELL_SIZE = 30;
let gameBoard = document.getElementById('gameBoard');
let gameOver = false;
let direction = 'right';
let gameTimer;
// 创建画布
const canvas = document.createElement('canvas');
canvas.id = 'snakeCanvas';
canvas.width = COLS * CELL_SIZE;
canvas.height = ROWS * CELL_SIZE;
gameBoard.appendChild(canvas);
const ctx = canvas.getContext('2d');
// 加载初始状态
function loadGame() {
fetch('ajax_snake.php?game=true')
.then(() => startGame());
}
// 开始游戏
function startGame() {
gameOver = false;
direction = 'right';
document.getElementById('gameOverMsg').style.display = 'none';
gameTimer = setInterval(update, 200);
}
// 更新游戏状态
function update() {
fetch('ajax_snake.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `action=move&direction=${direction}`
})
.then(response => response.json())
.then(data => {
if (data.gameOver) {
clearInterval(gameTimer);
document.getElementById('gameOverMsg').style.display = 'block';
gameOver = true;
}
document.getElementById('score').textContent = data.score;
// 这里可以重新获取游戏状态绘制
drawBoard();
});
}
// 绘制游戏板
function drawBoard() {
// 纯前端绘制,需要后端同步状态
// 实际应用中,这里需要从服务器获取完整的蛇和食物位置
}
// 设置方向
function setDirection(dir) {
direction = dir;
}
// 重新开始
function restartGame() {
fetch('ajax_snake.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'action=restart'
});
startGame();
}
// 键盘控制
document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'ArrowUp': setDirection('up'); break;
case 'ArrowDown': setDirection('down'); break;
case 'ArrowLeft': setDirection('left'); break;
case 'ArrowRight': setDirection('right'); break;
}
});
// 启动游戏
loadGame();
</script>
</div>
</body>
</html>
<?php } else {
// 非游戏页面时返回JSON状态
header('Content-Type: application/json');
echo json_encode($_SESSION['ajax_snake'] ?? ['error' => 'Game not initialized']);
} ?>
使用说明
命令行版本
php snake.php
操作键:W上 S下 A左 D右 Q退出
Web版本
- 将代码保存为
web_snake.php和ajax_snake.php - 放到PHP服务器目录,如
htdocs或public_html - 通过浏览器访问:
- 方案2:
http://localhost/web_snake.php - 方案3:
http://localhost/ajax_snake.php?game=true
- 方案2:
功能特点
✅ 完整游戏逻辑:移动、碰撞检测、得分系统
✅ 多种操作方式:键盘、按钮点击
✅ 实时更新:AJAX异步更新游戏状态
✅ 漂亮界面:CSS美化,游戏元素可视化
✅ 状态保持:使用Session保存游戏进度
改进建议
- 添加音效:吃食物时播放声音
- 障碍物:增加墙壁或障碍物
- AI模式:实现自动寻路算法
- 排行榜:保存最高分记录
- 多关卡:不同难度等级
这个贪吃蛇游戏涵盖了PHP核心功能:会话管理、数组操作、DOM操作、AJAX通信等,是一个很好的学习项目!