科学教育

搜索
查看: 6870|回复: 17
打印 上一主题 下一主题

完善游戏

[复制链接]

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
跳转到指定楼层
楼主
发表于 2024-8-12 14:11:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let snake = [{ x: 50, y: 50 }];
let food = { x: 0, y: 0 };
let dx = 10;
let dy = 0;
let score = 0;
let gameOver = false;

// 创建音效对象
const eatSound = new Audio('eat.mp3');

// 创建背景音乐对象
const backgroundMusic = new Audio('background.mp3');
backgroundMusic.loop = true; // 设置循环播放

document.addEventListener("keydown", changeDirection);

function randomFoodPosition() {
    const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
    const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
    return { x, y };
}

function clearCanvas() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function drawSnake() {
    snake.forEach(drawSnakePart);
}

function drawSnakePart(snakePart) {
    ctx.fillStyle = 'lightgreen';
    ctx.strokeStyle = 'darkgreen';
    ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
    ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}

function drawFood() {
    ctx.fillStyle = 'lightpink';
    ctx.fillRect(food.x, food.y, 10, 10);
}

function moveSnake() {
    const head = { x: snake[0].x + dx, y: snake[0].y + dy };

    // 检测碰壁
    if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
        gameOver = true;
        return;
    }

    snake.unshift(head);

    // 检查是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        score++;
        food = randomFoodPosition();
        playEatSound(); // 播放音效
    } else {
        snake.pop();
    }
}

function collision(head) {
    for (let i = 1; i < snake.length; i++) {
        if (snake.x === head.x && snake.y === head.y) {
            return true;
        }
    }
    return false;
}

// 播放吃食物的音效
function playEatSound() {
    eatSound.play();
}

// 播放背景音乐
function playBackgroundMusic() {
    backgroundMusic.play();
}

// 停止背景音乐
function stopBackgroundMusic() {
    backgroundMusic.pause();
    backgroundMusic.currentTime = 0; // 重置音乐到开头
}

function main() {
    if (gameOver) {
        displayGameOver();
        return;
    }

    setTimeout(function onTick() {
        clearCanvas();
        drawFood();
        moveSnake();
        drawSnake();
        main();
    }, 100);
}

function changeDirection(event) {
    const LEFT_KEY = 37;
    const RIGHT_KEY = 39;
    const UP_KEY = 38;
    const DOWN_KEY = 40;

    const keyPressed = event.keyCode;
    const goingUp = dy === -10;
    const goingDown = dy === 10;
    const goingRight = dx === 10;
    const goingLeft = dx === -10;

    if (keyPressed === LEFT_KEY && !goingRight) {
        dx = -10;
        dy = 0;
    }

    if (keyPressed === UP_KEY && !goingDown) {
        dx = 0;
        dy = -10;
    }

    if (keyPressed === RIGHT_KEY && !goingLeft) {
        dx = 10;
        dy = 0;
    }

    if (keyPressed === DOWN_KEY && !goingUp) {
        dx = 0;
        dy = 10;
    }
}

// 显示游戏结束
function displayGameOver() {
    ctx.fillStyle = "pink";
    ctx.font = "30px Arial";
     // 绘制“游戏结束!”位于中心稍上方
    ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
    // 绘制得分位于中心稍下方
    ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
    document.getElementById("startButton").style.display = "block";
    stopBackgroundMusic(); // 停止背景音乐
}


function startGame() {
    snake = [{ x: 50, y: 50 }];
    score = 0;
    dx = 10;
    dy = 0;
    gameOver = false;
    food = randomFoodPosition();
    document.getElementById('startButton').style.display = 'none';
    playBackgroundMusic(); // 播放背景音乐
    main();
}

food = randomFoodPosition();
main();

你好,以上是贪吃蛇游戏的js代码,请修改代码,使游戏的右边出现“游戏规则”悬停按钮,鼠标移到按钮上出现游戏规则。

回复

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
沙发
发表于 2024-8-12 14:12:02 | 只看该作者
你好!听起来你正在做一个很有意思的贪吃蛇游戏。我们可以通过几个步骤来添加“游戏规则”悬停按钮。

1. **在HTML文件中添加按钮**:首先,我们需要在HTML文件中添加一个按钮,用于显示“游戏规则”。

2. **在JavaScript中添加悬停事件**:然后,在JavaScript中添加悬停事件,当鼠标移到按钮上时,显示游戏规则。

我们来分步完成这个任务吧。

### 第一步:在HTML文件中添加“游戏规则”按钮

首先,在HTML文件中找到`<canvas>`元素,然后在它的后面添加一个`<button>`元素。这里是一个例子:

  1. <canvas id="gameCanvas" width="400" height="400"></canvas>
  2. <button id="rulesButton">游戏规则</button>
  3. <div id="rulesContent" style="display: none;">
  4.     <h3>游戏规则</h3>
  5.     <p>1. 使用方向键控制蛇的移动。</p>
  6.     <p>2. 吃到食物会得分并增长体长。</p>
  7.     <p>3. 撞到墙壁或自身会导致游戏结束。</p>
  8. </div>
复制代码


### 第二步:在CSS文件中添加一些样式

为了让“游戏规则”按钮和内容看起来更好,我们可以在CSS文件中添加一些样式:

  1. #rulesButton {
  2.     position: absolute;
  3.     right: 10px;
  4.     top: 10px;
  5.     padding: 10px;
  6.     background-color: lightblue;
  7.     border: none;
  8.     cursor: pointer;
  9.     font-size: 16px;
  10. }

  11. #rulesContent {
  12.     position: absolute;
  13.     right: 10px;
  14.     top: 50px;
  15.     padding: 10px;
  16.     background-color: white;
  17.     border: 1px solid #ccc;
  18.     box-shadow: 0 0 10px rgba(0,0,0,0.1);
  19. }
复制代码


### 第三步:在JavaScript文件中添加悬停事件

接下来,我们需要在JavaScript文件中添加悬停事件,当鼠标移到按钮上时,显示游戏规则。

  1. // 获取按钮和规则内容的DOM元素
  2. const rulesButton = document.getElementById('rulesButton');
  3. const rulesContent = document.getElementById('rulesContent');

  4. // 当鼠标移到按钮上时,显示规则
  5. rulesButton.addEventListener('mouseover', function () {
  6.     rulesContent.style.display = 'block';
  7. });

  8. // 当鼠标离开按钮时,隐藏规则
  9. rulesButton.addEventListener('mouseout', function () {
  10.     rulesContent.style.display = 'none';
  11. });
复制代码


### 最终代码

将所有这些部分结合起来,你的代码应该是这样的:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>贪吃蛇游戏</title>
  6.     <style>
  7.         #rulesButton {
  8.             position: absolute;
  9.             right: 10px;
  10.             top: 10px;
  11.             padding: 10px;
  12.             background-color: lightblue;
  13.             border: none;
  14.             cursor: pointer;
  15.             font-size: 16px;
  16.         }

  17.         #rulesContent {
  18.             position: absolute;
  19.             right: 10px;
  20.             top: 50px;
  21.             padding: 10px;
  22.             background-color: white;
  23.             border: 1px solid #ccc;
  24.             box-shadow: 0 0 10px rgba(0,0,0,0.1);
  25.             display: none;
  26.         }
  27.     </style>
  28. </head>
  29. <body>
  30.     <canvas id="gameCanvas" width="400" height="400"></canvas>
  31.     <button id="rulesButton">游戏规则</button>
  32.     <div id="rulesContent">
  33.         <h3>游戏规则</h3>
  34.         <p>1. 使用方向键控制蛇的移动。</p>
  35.         <p>2. 吃到食物会得分并增长体长。</p>
  36.         <p>3. 撞到墙壁或自身会导致游戏结束。</p>
  37.     </div>
  38.     <script>
  39.         // Javascript Code here
  40.     </script>
  41. </body>
  42. </html>
复制代码


JavaScript部分应包含你先前的游戏逻辑和新增加的悬停事件处理:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let snake = [{ x: 150, y: 150 }];
  4. let food = { x: 0, y: 0 };
  5. let dx = 10;
  6. let dy = 0;
  7. let score = 0;
  8. let gameOver = false;

  9. // 创建音效对象
  10. const eatSound = new Audio('eat.mp3');

  11. // 创建背景音乐对象
  12. const backgroundMusic = new Audio('background.mp3');
  13. backgroundMusic.loop = true; // 设置循环播放

  14. document.addEventListener("keydown", changeDirection);

  15. function randomFoodPosition() {
  16.     const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
  17.     const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
  18.     return { x, y };
  19. }

  20. function clearCanvas() {
  21.     ctx.fillStyle = "white";
  22.     ctx.fillRect(0, 0, canvas.width, canvas.height);
  23. }

  24. function drawSnake() {
  25.     snake.forEach(drawSnakePart);
  26. }

  27. function drawSnakePart(snakePart) {
  28.     ctx.fillStyle = 'lightgreen';
  29.     ctx.strokeStyle = 'darkgreen';
  30.     ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
  31.     ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
  32. }

  33. function drawFood() {
  34.     ctx.fillStyle = 'lightpink';
  35.     ctx.fillRect(food.x, food.y, 10, 10);
  36. }

  37. function moveSnake() {
  38.     const head = { x: snake[0].x + dx, y: snake[0].y + dy };

  39.     // 检测碰壁
  40.     if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
  41.         gameOver = true;
  42.         return;
  43.     }

  44.     snake.unshift(head);

  45.     // 检查是否吃到食物
  46.     if (head.x === food.x && head.y === food.y) {
  47.         score++;
  48.         food = randomFoodPosition();
  49.         playEatSound(); // 播放音效
  50.     } else {
  51.         snake.pop();
  52.     }
  53. }

  54. function collision(head) {
  55.     for (let i = 1; i < snake.length; i++) {
  56.         if (snake[i].x === head.x && snake[i].y === head.y) {
  57.             return true;
  58.         }
  59.     }
  60.     return false;
  61. }

  62. // 播放吃食物的音效
  63. function playEatSound() {
  64.     eatSound.play();
  65. }

  66. // 播放背景音乐
  67. function playBackgroundMusic() {
  68.     backgroundMusic.play();
  69. }

  70. // 停止背景音乐
  71. function stopBackgroundMusic() {
  72.     backgroundMusic.pause();
  73.     backgroundMusic.currentTime = 0; // 重置音乐到开头
  74. }

  75. function main() {
  76.     if (gameOver) {
  77.         displayGameOver();
  78.         return;
  79.     }

  80.     setTimeout(function onTick() {
  81.         clearCanvas();
  82.         drawFood();
  83.         moveSnake();
  84.         drawSnake();
  85.         main();
  86.     }, 100);
  87. }

  88. function changeDirection(event) {
  89.     const LEFT_KEY = 37;
  90.     const RIGHT_KEY = 39;
  91.     const UP_KEY = 38;
  92.     const DOWN_KEY = 40;

  93.     const keyPressed = event.keyCode;
  94.     const goingUp = dy === -10;
  95.     const goingDown = dy === 10;
  96.     const goingRight = dx === 10;
  97.     const goingLeft = dx === -10;

  98.     if (keyPressed === LEFT_KEY && !goingRight) {
  99.         dx = -10;
  100.         dy = 0;
  101.     }

  102.     if (keyPressed === UP_KEY && !goingDown) {
  103.         dx = 0;
  104.         dy = -10;
  105.     }

  106.     if (keyPressed === RIGHT_KEY && !goingLeft) {
  107.         dx = 10;
  108.         dy = 0;
  109.     }

  110.     if (keyPressed === DOWN_KEY && !goingUp) {
  111.         dx = 0;
  112.         dy = 10;
  113.     }
  114. }

  115. // 显示游戏结束
  116. function displayGameOver() {
  117.     ctx.fillStyle = "pink";
  118.     ctx.font = "30px Arial";
  119.      // 绘制“游戏结束!”位于中心稍上方
  120.     ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
  121.     // 绘制得分位于中心稍下方
  122.     ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
  123.     document.getElementById("startButton").style.display = "block";
  124.     stopBackgroundMusic(); // 停止背景音乐
  125. }


  126. function startGame() {
  127.     snake = [{ x: 150, y: 150 }];
  128.     score = 0;
  129.     dx = 10;
  130.     dy = 0;
  131.     gameOver = false;
  132.     food = randomFoodPosition();
  133.     document.getElementById('startButton').style.display = 'none';
  134.     playBackgroundMusic(); // 播放背景音乐
  135.     main();
  136. }

  137. food = randomFoodPosition();
  138. main();

  139. // 获取按钮和规则内容的DOM元素
  140. const rulesButton = document.getElementById('rulesButton');
  141. const rulesContent = document.getElementById('rulesContent');

  142. // 当鼠标移到按钮上时,显示规则
  143. rulesButton.addEventListener('mouseover', function () {
  144.     rulesContent.style.display = 'block';
  145. });

  146. // 当鼠标离开按钮时,隐藏规则
  147. rulesButton.addEventListener('mouseout', function () {
  148.     rulesContent.style.display = 'none';
  149. });
复制代码


以上就是完成这个任务需要的全部代码。希望这对你有帮助!如果有任何疑问或进一步的问题,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
板凳
 楼主| 发表于 2024-8-12 14:23:03 | 只看该作者
body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    background-color: #f5f5f5;
}

h1 {
    margin-bottom: 20px;
}

#gameContainer {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

#gameCanvas {
    border: 2px solid black;
    background-color: white;
}

.hidden {
    display: none;
}

#gameOverText {
    font-size: 24px;
    color: red;
    margin-top: 20px;
}

#restartButton {
    padding: 10px 20px;
    font-size: 16px;
    margin-top: 10px;
    cursor: pointer;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
}

#restartButton:hover {
    background-color: #45a049;
}

你好,这是我的火柴人躲避游戏CSS文件,我想让障碍物的颜色是随机的各种颜色。,请帮我修改一下。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
地板
发表于 2024-8-12 14:23:22 | 只看该作者
张复礼 发表于 2024-08-12 14:23
body {
    display: flex;
    flex-direction: colu ...


你好!要让障碍物的颜色随机,可以在JavaScript中实现这个功能。我们可以定义一个函数来生成随机颜色,并在绘制障碍物时调用这个函数。

首先,我们确保你的HTML文件中有必要的元素和结构。然后,我们修改JavaScript代码来实现随机颜色的障碍物。

### 第一步:生成随机颜色的函数

我们可以使用以下函数来生成随机颜色:

  1. // 生成随机颜色
  2. function getRandomColor() {
  3.     const letters = '0123456789ABCDEF';
  4.     let color = '#';
  5.     for (let i = 0; i < 6; i++) {
  6.         color += letters[Math.floor(Math.random() * 16)];
  7.     }
  8.     return color;
  9. }
复制代码


### 第二步:绘制障碍物时使用随机颜色

你可能已经有绘制障碍物的函数,只需在其中调用 `getRandomColor` 函数即可。

让我们假设你有一个 `drawObstacle` 函数来绘制障碍物,可以这样修改:

  1. function drawObstacle(obstacle) {
  2.     ctx.fillStyle = getRandomColor(); // 使用随机颜色
  3.     ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
  4. }
复制代码


### 完整的JavaScript示例

假设我们有一个简单的火柴人躲避游戏的框架,以下是完整的JavaScript代码:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. const obstacles = []; // 用于存储障碍物
  4. const gameSpeed = 5;

  5. function createObstacle() {
  6.     const width = 50;
  7.     const height = 10;
  8.     const x = canvas.width;
  9.     const y = canvas.height - height - (Math.random() * 100);

  10.     obstacles.push({ x, y, width, height });
  11. }

  12. // 生成随机颜色
  13. function getRandomColor() {
  14.     const letters = '0123456789ABCDEF';
  15.     let color = '#';
  16.     for (let i = 0; i < 6; i++) {
  17.         color += letters[Math.floor(Math.random() * 16)];
  18.     }
  19.     return color;
  20. }

  21. function drawObstacle(obstacle) {
  22.     ctx.fillStyle = getRandomColor(); // 使用随机颜色
  23.     ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
  24. }

  25. function updateGame() {
  26.     ctx.clearRect(0, 0, canvas.width, canvas.height);

  27.     // 更新和绘制障碍物
  28.     obstacles.forEach((obstacle, index) => {
  29.         obstacle.x -= gameSpeed;
  30.         if (obstacle.x + obstacle.width < 0) {
  31.             obstacles.splice(index, 1); // 移除越界的障碍物
  32.         } else {
  33.             drawObstacle(obstacle);
  34.         }
  35.     });

  36.     requestAnimationFrame(updateGame);
  37. }

  38. // 每隔一段时间创建一个新的障碍物
  39. setInterval(createObstacle, 2000);

  40. updateGame();
复制代码


这个示例展示了如何创建和绘制随机颜色的障碍物。每隔2秒钟将会创建一个新的障碍物,并且它们会以一定的速度从右向左移动。如果它们离开了画布区域,将会被移除。

希望这对你有帮助!如果有任何疑问或进一步的问题,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
5#
 楼主| 发表于 2024-8-12 14:26:37 | 只看该作者
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let player = { x: canvas.width / 2 - 15, y: canvas.height - 60, width: 30, height: 30, dx: 5 };
let obstacles = [];
let gameInterval;
let gameOver = false;

document.addEventListener('keydown', movePlayer);

function startGame() {
    player.x = canvas.width / 2 - 15;
    obstacles = [];
    gameOver = false;
    document.getElementById('gameOverText').classList.add('hidden');
    document.getElementById('restartButton').classList.add('hidden');
    gameInterval = setInterval(updateGame, 20);
}

function updateGame() {
    clearCanvas();
    drawPlayer();
    updateObstacles();
    checkCollision();
}

function clearCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function drawPlayer() {
    ctx.fillStyle = 'black';
    ctx.fillRect(player.x, player.y, player.width, player.height);
}

function movePlayer(event) {
    if (event.key === 'ArrowLeft' && player.x > 0) {
        player.x -= player.dx;
    }
    if (event.key === 'ArrowRight' && player.x < canvas.width - player.width) {
        player.x += player.dx;
    }
}

function updateObstacles() {
    if (Math.random() < 0.02) {
        let obstacleX = Math.random() * (canvas.width - 30);
        obstacles.push({ x: obstacleX, y: 0, width: 30, height: 30, dy: 2 });
    }

    ctx.fillStyle = 'red';
    for (let i = 0; i < obstacles.length; i++) {
        let obs = obstacles[i];
        obs.y += obs.dy;
        ctx.fillRect(obs.x, obs.y, obs.width, obs.height);

        if (obs.y > canvas.height) {
            obstacles.splice(i, 1);
            i--;
        }
    }
}

function checkCollision() {
    for (let i = 0; i < obstacles.length; i++) {
        let obs = obstacles[i];
        if (
            player.x < obs.x + obs.width &&
            player.x + player.width > obs.x &&
            player.y < obs.y + obs.height &&
            player.y + player.height > obs.y
        ) {
            endGame();
        }
    }
}

function endGame() {
    clearInterval(gameInterval);
    gameOver = true;
    document.getElementById('gameOverText').classList.remove('hidden');
    document.getElementById('restartButton').classList.remove('hidden');
}

// 启动游戏
startGame();

你好,这是我的火柴人躲避游戏js文件,我想让障碍物的颜色是随机的各种颜色。,请帮我修改一下。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
6#
发表于 2024-8-12 14:26:59 | 只看该作者
张复礼 发表于 2024-08-12 14:26
const canvas = document.getElementById('gameCanvas ...


好的!要让障碍物的颜色是随机的,我们需要在生成障碍物时,给每个障碍物一个随机的颜色。我们可以通过生成随机颜色字符串实现。

### 第一步:生成随机颜色的函数

首先,我们定义一个函数来生成随机颜色:

  1. // 生成随机颜色
  2. function getRandomColor() {
  3.     const letters = '0123456789ABCDEF';
  4.     let color = '#';
  5.     for (let i = 0; i < 6; i++) {
  6.         color += letters[Math.floor(Math.random() * 16)];
  7.     }
  8.     return color;
  9. }
复制代码


### 第二步:创建障碍物时使用随机颜色

在为障碍物创建对象时,我们可以调用这个 `getRandomColor` 函数,并将生成的颜色存储在障碍物对象中。

### 第三步:绘制障碍物时使用存储的颜色

接下来,在绘制障碍物时,使用存储的颜色进行绘制。

让我们把这些步骤整合到你的代码中。

### 修改后的完整代码:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let player = { x: canvas.width / 2 - 15, y: canvas.height - 60, width: 30, height: 30, dx: 5 };
  4. let obstacles = [];
  5. let gameInterval;
  6. let gameOver = false;

  7. document.addEventListener('keydown', movePlayer);

  8. function startGame() {
  9.     player.x = canvas.width / 2 - 15;
  10.     obstacles = [];
  11.     gameOver = false;
  12.     document.getElementById('gameOverText').classList.add('hidden');
  13.     document.getElementById('restartButton').classList.add('hidden');
  14.     gameInterval = setInterval(updateGame, 20);
  15. }

  16. function updateGame() {
  17.     clearCanvas();
  18.     drawPlayer();
  19.     updateObstacles();
  20.     checkCollision();
  21. }

  22. function clearCanvas() {
  23.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  24. }

  25. function drawPlayer() {
  26.     ctx.fillStyle = 'black';
  27.     ctx.fillRect(player.x, player.y, player.width, player.height);
  28. }

  29. function movePlayer(event) {
  30.     if (event.key === 'ArrowLeft' && player.x > 0) {
  31.         player.x -= player.dx;
  32.     }
  33.     if (event.key === 'ArrowRight' && player.x < canvas.width - player.width) {
  34.         player.x += player.dx;
  35.     }
  36. }

  37. // 生成随机颜色
  38. function getRandomColor() {
  39.     const letters = '0123456789ABCDEF';
  40.     let color = '#';
  41.     for (let i = 0; i < 6; i++) {
  42.         color += letters[Math.floor(Math.random() * 16)];
  43.     }
  44.     return color;
  45. }

  46. function updateObstacles() {
  47.     if (Math.random() < 0.02) {
  48.         let obstacleX = Math.random() * (canvas.width - 30);
  49.         let randomColor = getRandomColor();
  50.         obstacles.push({ x: obstacleX, y: 0, width: 30, height: 30, dy: 2, color: randomColor });
  51.     }

  52.     for (let i = 0; i < obstacles.length; i++) {
  53.         let obs = obstacles[i];
  54.         obs.y += obs.dy;
  55.         ctx.fillStyle = obs.color; // 使用随机颜色
  56.         ctx.fillRect(obs.x, obs.y, obs.width, obs.height);

  57.         if (obs.y > canvas.height) {
  58.             obstacles.splice(i, 1);
  59.             i--;
  60.         }
  61.     }
  62. }

  63. function checkCollision() {
  64.     for (let i = 0; i < obstacles.length; i++) {
  65.         let obs = obstacles[i];
  66.         if (
  67.             player.x < obs.x + obs.width &&
  68.             player.x + player.width > obs.x &&
  69.             player.y < obs.y + obs.height &&
  70.             player.y + player.height > obs.y
  71.         ) {
  72.             endGame();
  73.         }
  74.     }
  75. }

  76. function endGame() {
  77.     clearInterval(gameInterval);
  78.     gameOver = true;
  79.     document.getElementById('gameOverText').classList.remove('hidden');
  80.     document.getElementById('restartButton').classList.remove('hidden');
  81. }

  82. // 启动游戏
  83. startGame();
复制代码


在这段代码中,每次生成一个新的障碍物时,我们都会使用 `getRandomColor()` 函数生成一个随机颜色,并将其存储在障碍物对象的 `color` 属性中。然后在绘制障碍物时,使用存储的 `color` 属性来设置填充样式,这样障碍物就会有随机的颜色了。

希望这对你有帮助!如果有任何问题或进一步的疑问,请随时告诉我哦!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
7#
 楼主| 发表于 2024-8-12 14:28:52 | 只看该作者
请修改游戏,让火柴人不仅可以左右移动,还可以上下移动。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
8#
发表于 2024-8-12 14:29:18 | 只看该作者
张复礼 发表于 2024-08-12 14:28
请修改游戏,让火柴人不仅可以左右移动,还可以上下移 ...


好的!我们可以修改代码,让火柴人不仅能够左右移动,还能够上下移动。为此,需要进行以下几个步骤:

1. **修改玩家的控制逻辑**,以支持上下移动。
2. **确保火柴人在游戏区域内移动**。
3. **调整移动速度**。

让我们一步步来完成这些修改。

### 修改控制逻辑以支持上下移动

首先,我们需要修改 `movePlayer` 函数,以使其处理上下方向的键盘事件。

### 完整的JavaScript代码:

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let player = { x: canvas.width / 2 - 15, y: canvas.height / 2 - 15, width: 30, height: 30, dx: 5, dy: 5 };
  4. let obstacles = [];
  5. let gameInterval;
  6. let gameOver = false;

  7. document.addEventListener('keydown', movePlayer);

  8. function startGame() {
  9.     player.x = canvas.width / 2 - 15;
  10.     player.y = canvas.height / 2 - 15;
  11.     obstacles = [];
  12.     gameOver = false;
  13.     document.getElementById('gameOverText').classList.add('hidden');
  14.     document.getElementById('restartButton').classList.add('hidden');
  15.     gameInterval = setInterval(updateGame, 20);
  16. }

  17. function updateGame() {
  18.     clearCanvas();
  19.     drawPlayer();
  20.     updateObstacles();
  21.     checkCollision();
  22. }

  23. function clearCanvas() {
  24.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  25. }

  26. function drawPlayer() {
  27.     ctx.fillStyle = 'black';
  28.     ctx.fillRect(player.x, player.y, player.width, player.height);
  29. }

  30. function movePlayer(event) {
  31.     if (event.key === 'ArrowLeft' && player.x > 0) {
  32.         player.x -= player.dx;
  33.     }
  34.     if (event.key === 'ArrowRight' && player.x < canvas.width - player.width) {
  35.         player.x += player.dx;
  36.     }
  37.     if (event.key === 'ArrowUp' && player.y > 0) {
  38.         player.y -= player.dy;
  39.     }
  40.     if (event.key === 'ArrowDown' && player.y < canvas.height - player.height) {
  41.         player.y += player.dy;
  42.     }
  43. }

  44. // 生成随机颜色
  45. function getRandomColor() {
  46.     const letters = '0123456789ABCDEF';
  47.     let color = '#';
  48.     for (let i = 0; i < 6; i++) {
  49.         color += letters[Math.floor(Math.random() * 16)];
  50.     }
  51.     return color;
  52. }

  53. function updateObstacles() {
  54.     if (Math.random() < 0.02) {
  55.         let obstacleX = Math.random() * (canvas.width - 30);
  56.         let randomColor = getRandomColor();
  57.         obstacles.push({ x: obstacleX, y: 0, width: 30, height: 30, dy: 2, color: randomColor });
  58.     }

  59.     for (let i = 0; i < obstacles.length; i++) {
  60.         let obs = obstacles[i];
  61.         obs.y += obs.dy;
  62.         ctx.fillStyle = obs.color; // 使用随机颜色
  63.         ctx.fillRect(obs.x, obs.y, obs.width, obs.height);

  64.         if (obs.y > canvas.height) {
  65.             obstacles.splice(i, 1);
  66.             i--;
  67.         }
  68.     }
  69. }

  70. function checkCollision() {
  71.     for (let i = 0; i < obstacles.length; i++) {
  72.         let obs = obstacles[i];
  73.         if (
  74.             player.x < obs.x + obs.width &&
  75.             player.x + player.width > obs.x &&
  76.             player.y < obs.y + obs.height &&
  77.             player.y + player.height > obs.y
  78.         ) {
  79.             endGame();
  80.         }
  81.     }
  82. }

  83. function endGame() {
  84.     clearInterval(gameInterval);
  85.     gameOver = true;
  86.     document.getElementById('gameOverText').classList.remove('hidden');
  87.     document.getElementById('restartButton').classList.remove('hidden');
  88. }

  89. // 启动游戏
  90. startGame();
复制代码


以上修改主要是:

1. **初始化玩家位置**:在 `startGame` 函数中,确保玩家在画布的中心位置。
2. **更新玩家控制逻辑**:在 `movePlayer` 函数中添加对 `ArrowUp` 和 `ArrowDown` 键的支持。
3. **确保玩家在画布范围内移动**:通过检查 `player.x` 和 `player.y` ,确保玩家不会移动出画布边界。

现在,火柴人不仅可以左右移动,还可以上下移动。希望这对你有帮助!如果有任何疑问或进一步的问题,请随时告诉我!
回复 支持 反对

使用道具 举报

3

主题

41

帖子

137

积分

注册会员

Rank: 2

积分
137
9#
 楼主| 发表于 2024-8-12 14:34:09 | 只看该作者
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let snake = [{ x: 150, y: 150 }];
let food = { x: 0, y: 0 };
let dx = 10;
let dy = 0;
let score = 0;
let gameOver = false;

// 创建音效对象
const eatSound = new Audio('eat.mp3');

// 创建背景音乐对象
const backgroundMusic = new Audio('background.mp3');
backgroundMusic.loop = true; // 设置循环播放

document.addEventListener("keydown", changeDirection);

function randomFoodPosition() {
    const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
    const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
    return { x, y };
}

function clearCanvas() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function drawSnake() {
    snake.forEach(drawSnakePart);
}

function drawSnakePart(snakePart) {
    ctx.fillStyle = 'lightgreen';
    ctx.strokeStyle = 'darkgreen';
    ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
    ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}

function drawFood() {
    ctx.fillStyle = 'lightpink';
    ctx.fillRect(food.x, food.y, 10, 10);
}

function moveSnake() {
    const head = { x: snake[0].x + dx, y: snake[0].y + dy };

    // 检测碰壁
    if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
        gameOver = true;
        return;
    }

    snake.unshift(head);

    // 检查是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        score++;
        food = randomFoodPosition();
        playEatSound(); // 播放音效
    } else {
        snake.pop();
    }
}

function collision(head) {
    for (let i = 1; i < snake.length; i++) {
        if (snake[i].x === head.x && snake[i].y === head.y) {
            return true;
        }
    }
    return false;
}

// 播放吃食物的音效
function playEatSound() {
    eatSound.play();
}

// 播放背景音乐
function playBackgroundMusic() {
    backgroundMusic.play();
}

// 停止背景音乐
function stopBackgroundMusic() {
    backgroundMusic.pause();
    backgroundMusic.currentTime = 0; // 重置音乐到开头
}

function main() {
    if (gameOver) {
        displayGameOver();
        return;
    }

    setTimeout(function onTick() {
        clearCanvas();
        drawFood();
        moveSnake();
        drawSnake();
        main();
    }, 100);
}

function changeDirection(event) {
    const LEFT_KEY = 37;
    const RIGHT_KEY = 39;
    const UP_KEY = 38;
    const DOWN_KEY = 40;

    const keyPressed = event.keyCode;
    const goingUp = dy === -10;
    const goingDown = dy === 10;
    const goingRight = dx === 10;
    const goingLeft = dx === -10;

    if (keyPressed === LEFT_KEY && !goingRight) {
        dx = -10;
        dy = 0;
    }

    if (keyPressed === UP_KEY && !goingDown) {
        dx = 0;
        dy = -10;
    }

    if (keyPressed === RIGHT_KEY && !goingLeft) {
        dx = 10;
        dy = 0;
    }

    if (keyPressed === DOWN_KEY && !goingUp) {
        dx = 0;
        dy = 10;
    }
}

// 显示游戏结束
function displayGameOver() {
    ctx.fillStyle = "pink";
    ctx.font = "30px Arial";
     // 绘制“游戏结束!”位于中心稍上方
    ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
    // 绘制得分位于中心稍下方
    ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
    document.getElementById("startButton").style.display = "block";
    stopBackgroundMusic(); // 停止背景音乐
}


function startGame() {
    snake = [{ x: 150, y: 150 }];
    score = 0;
    dx = 10;
    dy = 0;
    gameOver = false;
    food = randomFoodPosition();
    document.getElementById('startButton').style.display = 'none';
    playBackgroundMusic(); // 播放背景音乐
    main();
}

food = randomFoodPosition();
main();

// 获取按钮和规则内容的DOM元素
const rulesButton = document.getElementById('rulesButton');
const rulesContent = document.getElementById('rulesContent');

// 当鼠标移到按钮上时,显示规则
rulesButton.addEventListener('mouseover', function () {
    rulesContent.style.display = 'block';
});

// 当鼠标离开按钮时,隐藏规则
rulesButton.addEventListener('mouseout', function () {
    rulesContent.style.display = 'none';
});

你好,这是我的贪吃蛇js文件,我想新增一个“修改贪吃蛇颜色”的下拉菜单,下拉后可选择贪吃蛇的颜色。
回复 支持 反对

使用道具 举报

0

主题

1145

帖子

1715

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1715
10#
发表于 2024-8-12 14:34:46 | 只看该作者
张复礼 发表于 2024-08-12 14:34
const canvas = document.getElementById('gameCanvas ...


你好!增加一个“修改贪吃蛇颜色”的下拉菜单是个不错的主意。我们可以通过以下步骤来实现这个功能:

1. **在HTML文件中添加下拉菜单**。
2. **在CSS文件中为下拉菜单添加样式(可选)**。
3. **在JavaScript文件中处理下拉菜单的选择事件**。

### 第一步:在HTML文件中添加下拉菜单

在HTML文件中,找到适合的位置加入以下代码:

  1. <label for="snakeColor">选择贪吃蛇颜色:</label>
  2. <select id="snakeColor">
  3.     <option value="lightgreen">绿</option>
  4.     <option value="blue">蓝</option>
  5.     <option value="yellow">黄</option>
  6.     <option value="red">红</option>
  7. </select>
复制代码


### 第二步:在CSS文件中为下拉菜单添加样式(可选)

在CSS文件中,可以为下拉菜单添加样式,让它看起来更美观。例如:

  1. #snakeColor {
  2.     margin: 10px;
  3.     padding: 5px;
  4.     font-size: 16px;
  5. }
复制代码


### 第三步:在JavaScript文件中处理下拉菜单的选择事件

我们需要在JavaScript中处理下拉菜单的变化,确保贪吃蛇的颜色能够根据用户选择进行改变。

  1. const canvas = document.getElementById('gameCanvas');
  2. const ctx = canvas.getContext('2d');

  3. let snake = [{ x: 200, y: 200 }, { x: 190, y: 200 }, { x: 180, y: 200 }];
  4. let food = { x: 0, y: 0 };
  5. let dx = 10;
  6. let dy = 0;
  7. let score = 0;
  8. let gameOver = false;
  9. let snakeColor = 'lightgreen'; // 默认颜色

  10. // 创建音效对象
  11. const eatSound = new Audio('eat.mp3');

  12. // 创建背景音乐对象
  13. const backgroundMusic = new Audio('background.mp3');
  14. backgroundMusic.loop = true; // 设置循环播放

  15. document.addEventListener("keydown", changeDirection);
  16. document.getElementById('snakeColor').addEventListener('change', function(event) {
  17.     snakeColor = event.target.value; // 更新贪吃蛇颜色
  18. });

  19. function randomFoodPosition() {
  20.     const x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
  21.     const y = Math.floor(Math.random() * (canvas.height / 10)) * 10;
  22.     return { x, y };
  23. }

  24. function clearCanvas() {
  25.     ctx.fillStyle = "white";
  26.     ctx.fillRect(0, 0, canvas.width, canvas.height);
  27. }

  28. function drawSnake() {
  29.     snake.forEach(drawSnakePart);
  30. }

  31. function drawSnakePart(snakePart) {
  32.     ctx.fillStyle = snakeColor; // 使用选择的颜色
  33.     ctx.strokeStyle = 'darkgreen';
  34.     ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
  35.     ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
  36. }

  37. function drawFood() {
  38.     ctx.fillStyle = 'lightpink';
  39.     ctx.fillRect(food.x, food.y, 10, 10);
  40. }

  41. function moveSnake() {
  42.     const head = { x: snake[0].x + dx, y: snake[0].y + dy };

  43.     // 检测碰壁
  44.     if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height || collision(head)) {
  45.         gameOver = true;
  46.         return;
  47.     }

  48.     snake.unshift(head);

  49.     // 检查是否吃到食物
  50.     if (head.x === food.x && head.y === food.y) {
  51.         score++;
  52.         food = randomFoodPosition();
  53.         playEatSound(); // 播放音效
  54.     } else {
  55.         snake.pop();
  56.     }
  57. }

  58. function collision(head) {
  59.     for (let i = 1; i < snake.length; i++) {
  60.         if (snake[i].x === head.x && snake[i].y === head.y) {
  61.             return true;
  62.         }
  63.     }
  64.     return false;
  65. }

  66. // 播放吃食物的音效
  67. function playEatSound() {
  68.     eatSound.play();
  69. }

  70. // 播放背景音乐
  71. function playBackgroundMusic() {
  72.     backgroundMusic.play();
  73. }

  74. // 停止背景音乐
  75. function stopBackgroundMusic() {
  76.     backgroundMusic.pause();
  77.     backgroundMusic.currentTime = 0; // 重置音乐到开头
  78. }

  79. function main() {
  80.     if (gameOver) {
  81.         displayGameOver();
  82.         return;
  83.     }

  84.     setTimeout(function onTick() {
  85.         clearCanvas();
  86.         drawFood();
  87.         moveSnake();
  88.         drawSnake();
  89.         main();
  90.     }, 100);
  91. }

  92. function changeDirection(event) {
  93.     const LEFT_KEY = 37;
  94.     const RIGHT_KEY = 39;
  95.     const UP_KEY = 38;
  96.     const DOWN_KEY = 40;

  97.     const keyPressed = event.keyCode;
  98.     const goingUp = dy === -10;
  99.     const goingDown = dy === 10;
  100.     const goingRight = dx === 10;
  101.     const goingLeft = dx === -10;

  102.     if (keyPressed === LEFT_KEY && !goingRight) {
  103.         dx = -10;
  104.         dy = 0;
  105.     }

  106.     if (keyPressed === UP_KEY && !goingDown) {
  107.         dx = 0;
  108.         dy = -10;
  109.     }

  110.     if (keyPressed === RIGHT_KEY && !goingLeft) {
  111.         dx = 10;
  112.         dy = 0;
  113.     }

  114.     if (keyPressed === DOWN_KEY && !goingUp) {
  115.         dx = 0;
  116.         dy = 10;
  117.     }
  118. }

  119. // 显示游戏结束
  120. function displayGameOver() {
  121.     ctx.fillStyle = "pink";
  122.     ctx.font = "30px Arial";
  123.      // 绘制“游戏结束!”位于中心稍上方
  124.     ctx.fillText("很遗憾,游戏结束!", canvas.width / 2 - 115, canvas.height / 2 - 20);
  125.     // 绘制得分位于中心稍下方
  126.     ctx.fillText("得分: " + score, canvas.width / 2 - 50, canvas.height / 2 + 20);
  127.     document.getElementById("startButton").style.display = "block";
  128.     stopBackgroundMusic(); // 停止背景音乐
  129. }


  130. function startGame() {
  131.     snake = [{ x: 200, y: 200 }, { x: 190, y: 200 }, { x: 180, y: 200 }];
  132.     score = 0;
  133.     dx = 10;
  134.     dy = 0;
  135.     gameOver = false;
  136.     food = randomFoodPosition();
  137.     document.getElementById('startButton').style.display = 'none';
  138.     playBackgroundMusic(); // 播放背景音乐
  139.     main();
  140. }

  141. food = randomFoodPosition();
  142. main();

  143. // 获取按钮和规则内容的DOM元素
  144. const rulesButton = document.getElementById('rulesButton');
  145. const rulesContent = document.getElementById('rulesContent');

  146. // 当鼠标移到按钮上时,显示规则
  147. rulesButton.addEventListener('mouseover', function () {
  148.     rulesContent.style.display = 'block';
  149. });

  150. // 当鼠标离开按钮时,隐藏规则
  151. rulesButton.addEventListener('mouseout', function () {
  152.     rulesContent.style.display = 'none';
  153. });
复制代码

在这个例子中,我们在 `HTML` 中添加了一个下拉菜单,并在 `JavaScript` 文件中监听该下拉菜单的变化。当用户选择不同的颜色时,贪吃蛇的颜色会相应地更新。

希望这对你有帮助!如果有任何疑问或进一步的问题,请随时告诉我!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表