PHP 怎么PHP贪吃蛇

wen PHP项目 2

本文目录导读:

PHP 怎么PHP贪吃蛇

  1. 方案1:命令行版本(终端运行)
  2. 方案2:Web版本(浏览器运行)
  3. 方案3:AJAX版本(智能自动移动)
  4. 使用说明
  5. 功能特点
  6. 改进建议

我来给你写一个完整的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版本

  1. 将代码保存为 web_snake.phpajax_snake.php
  2. 放到PHP服务器目录,如 htdocspublic_html
  3. 通过浏览器访问:
    • 方案2:http://localhost/web_snake.php
    • 方案3:http://localhost/ajax_snake.php?game=true

功能特点

完整游戏逻辑:移动、碰撞检测、得分系统
多种操作方式:键盘、按钮点击
实时更新:AJAX异步更新游戏状态
漂亮界面:CSS美化,游戏元素可视化
状态保持:使用Session保存游戏进度

改进建议

  1. 添加音效:吃食物时播放声音
  2. 障碍物:增加墙壁或障碍物
  3. AI模式:实现自动寻路算法
  4. 排行榜:保存最高分记录
  5. 多关卡:不同难度等级

这个贪吃蛇游戏涵盖了PHP核心功能:会话管理、数组操作、DOM操作、AJAX通信等,是一个很好的学习项目!

上一篇PHP 怎么PHP扫雷

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!