当前位置: 首页 > news >正文

用HTML.CSS.JavaScript实现一个贪吃蛇小游戏

目录

    • 一、引言
    • 二、实现思路
      • 1. HTML 结构
      • 2. CSS 样式
      • 3. JavaScript 逻辑
    • 三、代码实现
    • 四、效果展示

一、引言

贪吃蛇是一款经典的小游戏,曾经风靡一时。今天,我们将使用 HTML、CSS 和 JavaScript 来实现一个简单的贪吃蛇小游戏。通过这个项目,可以了解到如何使用 HTML5 的画布元素(<canvas>)来绘制图形,以及如何使用 JavaScript 来处理游戏逻辑。

二、实现思路

1. HTML 结构

我们首先创建一个基本的 HTML 结构,包含一个 <canvas> 元素用于绘制游戏画面,以及一些必要的 <script><style> 标签。

2. CSS 样式

使用 CSS 对 <canvas> 元素进行简单的样式设置,使其具有边框,并居中显示。

3. JavaScript 逻辑

  • 初始化游戏元素:定义蛇的初始位置、食物的初始位置、分数等。
  • 处理用户输入:监听键盘事件,根据用户按下的方向键来改变蛇的移动方向。
  • 绘制游戏画面:使用 requestAnimationFramesetInterval 函数来不断更新游戏画面,包括蛇的移动、食物的生成和绘制、分数的显示等。
  • 处理碰撞检测:检测蛇是否撞到墙壁或自己的身体,如果是,则游戏结束。
  • 处理食物的生成和消耗:当蛇吃到食物时,分数增加,并且生成新的食物。

三、代码实现

上述代码中,我们使用了 HTML5 的 <canvas> 元素来绘制游戏画面,通过 JavaScript 来处理游戏逻辑。具体实现步骤如下:

  1. 初始化游戏元素:定义蛇的初始位置、食物的初始位置、分数等。
  2. 监听键盘事件:根据用户按下的方向键来改变蛇的移动方向。
  3. 绘制游戏画面:使用 setInterval 函数来不断更新游戏画面,包括蛇的移动、食物的生成和绘制、分数的显示等。
  4. 处理碰撞检测:检测蛇是否撞到墙壁或自己的身体,如果是,则游戏结束。
  5. 处理食物的生成和消耗:当蛇吃到食物时,分数增加,并且生成新的食物。
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
  <title>贪吃蛇小游戏</title>
  <style>
    #game-board {
      border: 2px solid #333;
      display: block;
      margin: 20px auto;
    }
  </style>
</head>

<body class="bg-gray-100 flex flex-col items-center justify-center h-screen">
  <h1 class="text-3xl font-bold mb-4">贪吃蛇小游戏</h1>
  <canvas id="game-board" width="400" height="400"></canvas>
  <script>
    const canvas = document.getElementById('game-board');
    const ctx = canvas.getContext('2d');

    const box = 20;
    let snake = [];
    snake[0] = {
      x: 9 * box,
      y: 10 * box
    };
    let food = {
      x: Math.floor(Math.random() * 19) * box,
      y: Math.floor(Math.random() * 19) * box
    };
    let score = 0;
    let d;

    document.addEventListener('keydown', direction);

    function direction(event) {
      if (event.keyCode === 37 && d!== 'RIGHT') {
        d = 'LEFT';
      } else if (event.keyCode === 38 && d!== 'DOWN') {
        d = 'UP';
      } else if (event.keyCode === 39 && d!== 'LEFT') {
        d = 'RIGHT';
      } else if (event.keyCode === 40 && d!== 'UP') {
        d = 'DOWN';
      }
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      for (let i = 0; i < snake.length; i++) {
        ctx.fillStyle = (i === 0)? 'green' : 'lightgreen';
        ctx.fillRect(snake[i].x, snake[i].y, box, box);
        ctx.strokeStyle = 'darkgreen';
        ctx.strokeRect(snake[i].x, snake[i].y, box, box);
      }
      ctx.fillStyle = 'red';
      ctx.fillRect(food.x, food.y, box, box);
      let snakeX = snake[0].x;
      let snakeY = snake[0].y;
      if (d === 'LEFT') snakeX -= box;
      if (d === 'UP') snakeY -= box;
      if (d === 'RIGHT') snakeX += box;
      if (d === 'DOWN') snakeY += box;
      if (snakeX === food.x && snakeY === food.y) {
        score++;
        food = {
          x: Math.floor(Math.random() * 19) * box,
          y: Math.floor(Math.random() * 19) * box
        };
      } else {
        snake.pop();
      }
      let newHead = {
        x: snakeX,
        y: snakeY
      };
      if (snakeX < 0 || snakeX >= canvas.width || snakeY < 0 || snakeY >= canvas.height || collision(newHead, snake)) {
        clearInterval(game);
        alert(`游戏结束!你的最终得分是: ${score}`);
      }
      snake.unshift(newHead);
      ctx.fillStyle = 'white';
      ctx.font = '20px Arial';
      ctx.fillText('Score: '+ score, 10, 30);
    }

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

    let game = setInterval(draw, 100);
  </script>
</body>

</html>
    

四、效果展示

初始界面

在这里插入图片描述
小蛇吃到自己,死亡结算

在这里插入图片描述

http://www.dtcms.com/a/112704.html

相关文章:

  • 基于Go语言实现一个网络聊天室(连接Redis版)
  • Kubernetes集群管理详解:从入门到精通
  • Eliet Chat开发日志:信令服务器注册与通信过程
  • JAVA单例模式
  • 2023-2024总结记录
  • leetcode二叉树刷题调试不方便的解决办法
  • 【Redis】服务端高并发分布式结构
  • 使用Scrapy官方开发的爬虫部署、运行、管理工具:Scrapyd
  • 网安小白筑基篇五:web后端基础之PHP
  • Springboot----@Role注解的作用
  • C++设计模式-解释器模式:从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
  • 【Python使用】嘿马推荐系统全知识和项目开发教程第2篇:1.4 案例--基于协同过滤的电影推荐,1.5 推荐系统评估【附代码
  • 【Android】界面布局-线性布局LinearLayout-例子
  • 编程能力的跃迁时刻:技术革命与认知重构的交响曲
  • MySQL索引原理:从B+树手绘到EXPLAIN
  • 合肥京东运营服务商TOP5推荐
  • Axure数据可视化科技感大屏设计资料——赋能多领域,展示无限价值
  • C# 类库生成后自动复制到指定目录
  • Mysql 集群架构 vs 主从复制架构
  • PostgreSQL LIKE 操作符详解
  • 如何在windows 环境、且没有显卡的情况下用python跑通从ModelScope下载的大模型的调用
  • FPGA状态机思想实现流水灯及HDLBits学习
  • 02.unity各个面板说明
  • JSON Crack:简化数据可视化的参数编辑器
  • 【Guava】新集合 - BiMapMultimapMultiset
  • JavaScript中左键单击(click)与双击(dblclick)事件的关系解析地图操作避坑
  • vue项目data functions should return an object
  • Linux的 `/proc` 目录 笔记250404
  • 【kubernetes】BusyBox
  • 试用thymeleaf引入vue-element-admin(一)