❤️创意网页:贪吃蛇游戏 - 创造一个经典的小游戏

news2024/9/24 23:21:14

博主:命运之光 

🌸专栏:Python星辰秘典

🐳专栏:web开发(简单好用又好看)

❤️专栏:Java经典程序设计

☀️博主的其他文章:点击进入博主的主页

前言:欢迎踏入我的Web项目专栏,一段神奇而令人陶醉的数字世界!

🌌在这里,我将带您穿越时空,揭开属于Web的奥秘。通过HTML、CSS和JavaScript的魔力,我创造了一系列令人惊叹的Web项目,它们仿佛是从梦境中涌现而出。

🌌在这个专栏中,您将遇到华丽的界面,如流星划过夜空般迷人;您将感受到动态的交互,如魔法般让您沉浸其中;您将探索响应式设计的玄妙,让您的屏幕变幻出不同的绚丽景象。

🌌无论您是一个探险家还是一位嗜血的代码巫师,这个专栏将成为您的魔法书。我将分享每个项目的秘密,解开编码的谜题,让您也能够拥有制作奇迹的力量。

🌌准备好了吗?拿起您的键盘,跟随我的指引,一起进入这个神秘而充满惊喜的数字王国。在这里,您将找到灵感的源泉,为自己创造出一段奇幻的Web之旅!

目录

简介

动态图展示

准备工作

创造贪吃蛇游戏

运行游戏

完整代码

代码的使用方法(超简单什么都不用下载)

🍓1.打开记事本 

🍓2.将上面的源代码复制粘贴到记事本里面将文件另存为HTML文件点击保存即可

🍓3.打开html文件(大功告成(●'◡'●))

总结


简介

欢迎来到本篇技术博客!今天,我们将一起学习如何使用HTML5 Canvas和JavaScript创造一个经典的小游戏 - 贪吃蛇游戏。我们将会为您提供代码解析以及游戏玩法说明。让我们开始吧!


动态图展示


准备工作

在开始之前,我们需要做一些准备工作:

  1. 确保您有一个支持HTML5的现代web浏览器(如Chrome、Firefox、Safari等)。
  2. 创建一个HTML文件,并复制以下代码作为基础:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>贪吃蛇游戏</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
    }
    canvas {
      border: 2px solid black;
    }
  </style>
</head>
<body>
  <canvas id="gameCanvas" width="400" height="400"></canvas>
  <script>
    // JavaScript代码将在下面添加
  </script>
</body>
</html>

创造贪吃蛇游戏

我们已经有了一个基本的HTML结构,其中包含一个Canvas元素用于绘制游戏画面。接下来,我们将添加JavaScript代码来创造贪吃蛇游戏。

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

const boxSize = 20;
const canvasSize = 400;
const snake = [];
let direction = 'right';
let food = {};

function drawSnakePart(x, y) {
  // ... 绘制蛇身体的代码 ...
}

function drawFood(x, y) {
  // ... 绘制食物的代码 ...
}

function generateFood() {
  // ... 生成新食物的代码 ...
}

function checkCollision(x, y, array) {
  // ... 检查碰撞的代码 ...
}

function draw() {
  // ... 游戏循环的代码 ...
}

// 监听方向键事件,控制蛇的移动方向
document.addEventListener('keydown', (event) => {
  // ... 控制方向的代码 ...
});

// 初始化蛇身体,创建三个蛇身体部分
snake.push({ x: boxSize * 2, y: boxSize });
snake.push({ x: boxSize, y: boxSize });
snake.push({ x: 0, y: boxSize });

generateFood();
draw();

在这段代码中,我们定义了一些变量和函数用于创建和控制贪吃蛇游戏。

首先,我们定义了一些常量,包括每个格子的大小boxSize、画布的大小canvasSize、蛇的身体snake、蛇的运动方向direction以及食物的位置food

然后,我们定义了两个绘制函数drawSnakePartdrawFood,用于在画布上绘制蛇的身体和食物。

接着,我们定义了一个generateFood函数,用于在画布上随机生成新的食物。

我们还定义了一个checkCollision函数,用于检查蛇头是否与蛇身体或画布边界发生碰撞。

接下来,我们定义了一个draw函数,用于控制游戏的主循环。在该函数中,我们会根据蛇的运动方向更新蛇的位置,并检查蛇是否吃到了食物或碰到了边界或自身。

最后,我们通过监听方向键事件,来控制蛇的运动方向。初始化时,我们将蛇的身体设置为三个部分,并在画布上生成新的食物。


运行游戏

现在,将上述HTML代码保存为一个HTML文件,并在浏览器中打开它。您将会看到一个黑色边框的画布,即游戏的主界面。使用方向键控制蛇的运动,吃掉食物,并尝试不要碰到画布边界或自身。


完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>贪吃蛇游戏</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
    }
    canvas {
      border: 2px solid black;
    }
  </style>
</head>
<body>
  <canvas id="gameCanvas" width="400" height="400"></canvas>
  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    const boxSize = 20;
    const canvasSize = 400;
    const snake = [];
    let direction = 'right';
    let food = {};

    function drawSnakePart(x, y) {
      ctx.fillStyle = 'green';
      ctx.fillRect(x, y, boxSize, boxSize);
      ctx.strokeStyle = 'black';
      ctx.strokeRect(x, y, boxSize, boxSize);
    }

    function drawFood(x, y) {
      ctx.fillStyle = 'red';
      ctx.fillRect(x, y, boxSize, boxSize);
      ctx.strokeStyle = 'black';
      ctx.strokeRect(x, y, boxSize, boxSize);
    }

    function generateFood() {
      food = {
        x: Math.floor(Math.random() * (canvasSize / boxSize)) * boxSize,
        y: Math.floor(Math.random() * (canvasSize / boxSize)) * boxSize,
      };
    }

    function checkCollision(x, y, array) {
      // Check if the given position collides with the snake's body
      for (let i = 0; i < array.length; i++) {
        if (x === array[i].x && y === array[i].y) {
          return true;
        }
      }
      return false;
    }

    function draw() {
      ctx.clearRect(0, 0, canvasSize, canvasSize);

      // Update snake position based on direction
      const headX = snake[0].x + (direction === 'right' ? boxSize : direction === 'left' ? -boxSize : 0);
      const headY = snake[0].y + (direction === 'down' ? boxSize : direction === 'up' ? -boxSize : 0);

      // Check if the snake hits the canvas boundaries or collides with its body
      if (
        headX < 0 ||
        headX >= canvasSize ||
        headY < 0 ||
        headY >= canvasSize ||
        checkCollision(headX, headY, snake)
      ) {
        // Game over
        alert('游戏结束!');
        snake.length = 0; // Clear the snake array
        direction = 'right'; // Reset direction
        snake.push({ x: boxSize * 2, y: boxSize }); // Reset snake position
        generateFood(); // Generate new food
      }

      // Check if the snake eats the food
      if (headX === food.x && headY === food.y) {
        generateFood();
      } else {
        // If not, remove the tail segment
        snake.pop();
      }

      // Add new head segment to the beginning
      const newHead = { x: headX, y: headY };
      snake.unshift(newHead);

      for (let i = 0; i < snake.length; i++) {
        const { x, y } = snake[i];
        drawSnakePart(x, y);
      }

      drawFood(food.x, food.y);

      setTimeout(draw, 100); // Control snake speed (100ms)
    }

    // Listen for arrow key presses to control the snake
    document.addEventListener('keydown', (event) => {
      const key = event.key;
      if (key === 'ArrowUp' && direction !== 'down') {
        direction = 'up';
      } else if (key === 'ArrowDown' && direction !== 'up') {
        direction = 'down';
      } else if (key === 'ArrowLeft' && direction !== 'right') {
        direction = 'left';
      } else if (key === 'ArrowRight' && direction !== 'left') {
        direction = 'right';
      }
    });

    // Initialize the snake with 3 parts
    snake.push({ x: boxSize * 2, y: boxSize });
    snake.push({ x: boxSize, y: boxSize });
    snake.push({ x: 0, y: boxSize });

    generateFood();
    draw();
  </script>
</body>
</html>

代码的使用方法(超简单什么都不用下载)

🍓1.打开记事本 

🍓2.将上面的源代码复制粘贴到记事本里面将文件另存为HTML文件点击保存即可

🍓3.打开html文件(大功告成(●'◡'●))


总结

在本篇博客中,我们学习了如何使用HTML5 Canvas和JavaScript创造一个经典的小游戏 - 贪吃蛇游戏。通过绘制蛇的身体和食物,并监听方向键事件,我们成功地实现了一个简单而有趣的游戏。

希望您享受了本次贪吃蛇游戏的创作过程,并对游戏开发产生了兴趣。感谢您的阅读,祝您编程愉快!


本章的内容就到这里了,觉得对你有帮助的话就支持一下博主把~

🌌点击下方个人名片,交流会更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/810325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++的函数定义中,只提供形参类型,不提供形参名

如上图所示&#xff0c;显示了 c 语法里的一种不常见的应用。若没有对某个形参的后续使用的要求&#xff0c;可以不提供形参名的&#xff0c;也能编译通过。这么写法的作用&#xff0c;可以以第一个参数的类型不同&#xff0c;来实现函数的重载。在阅读源码&#xff0c;在vs201…

【Linux】UDP协议

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;传输层&a…

目标检测应用场景—数据集【NO.14】行人跌倒测试

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

什么是线程?线程和进程的关系?如何创建/查看线程?

文章目录 一. 认识线程(Thread)1.1 概念1.1.1 什么是线程1.1.2 线程存在的意义1.1.3 进程和线程之间的区别和联系1.1.4 Java的线程和操作系统的线程 1.2 创建线程① 继承Thread类② 实现Runnable 接口对比两种方法③ 变形写法④ 其他写法 1.3 查看线程 一. 认识线程(Thread) 1…

C++之科学技术法e使用(一百七十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

阿里云服务器全方位介绍_性能功能优势和租用费用

阿里云服务器全方位介绍包括云服务器ECS优势、云服务器租用价格、云服务器使用场景及限制说明&#xff0c;阿里云服务器网分享云服务器ECS介绍、个人和企业免费试用、云服务器活动、云服务器ECS规格、优势、功能及应用场景详细说明&#xff1a; 目录 什么是云服务器ECS&#…

学习笔记22 set

一、概述 Set是一种集合类型&#xff0c;可以快速在大量数据中查找特定值。 Set存储无序序列中的元素&#xff0c;并且不允许重复。与列表不同&#xff0c;列表中的数据可以通过索引访问&#xff0c;但是在集合中&#xff0c;元素没有与集合中的位置相关联。 Set是优化了搜索…

消息队列总结(4)- RabbitMQ Kafka RocketMQ高性能方案

1.RabbitMQ的高性能解决方案 1.1 发布确认机制 RabbitMQ提供了3种生产者发布确认的模式&#xff1a; 简单模式&#xff08;Simple Mode&#xff09;&#xff1a;生产者发送消息后&#xff0c;等待服务器确认消息已经被接收。这种模式下&#xff0c;生产者发送消息后会阻塞&am…

M5ATOMS3基础03给ROS1发一个问候(rosserial)

引出问题 关于之前2020年的博客&#xff1a; 01. ESP8266和ROS调试一些问题汇总 02. ESP8266和ESP32配置&#xff08;需使用ROS1和ROS2&#xff09; 效果展示 使用M5ATOMS3与ROS1&#xff08;kinetic&#xff0c;melodic&#xff0c;noetic&#xff09;版本通信比较通用的是…

BUU [网鼎杯 2020 朱雀组]phpweb

BUU [网鼎杯 2020 朱雀组]phpweb 众生皆懒狗。打开题目&#xff0c;只有一个报错&#xff0c;不知何从下手。 翻译一下报错&#xff0c;data()函数:,还是没有头绪&#xff0c;中国有句古话说的好“遇事不决抓个包” 抓个包果然有东西&#xff0c;仔细一看这不就分别是函数和参…

【算法基础:贪心】6. 贪心

文章目录 区间问题905. 区间选点&#xff08;排序 贪心&#xff09;908. 最大不相交区间数量&#xff08;排序 贪心&#xff09;906. 区间分组&#xff08;排序 优先队列 贪心&#xff09;⭐907. 区间覆盖&#xff08;排序 贪心&#xff09; Huffman树148. 合并果子&#…

【LeetCode 75】第十四题(643)子数组最大平均数

题目: 示例: 分析: 给一个数组,问数组里长度为k的连续数组中的最大平均值是多少. 这题已经把意思说的很明白了,并且连子数组的长度都固定了,并且是连续的,这里可以直接使用固定长度的滑动窗口来计算. 用两个指针来在数组里划定一个长度为k的范围,然后计算指针范围内的平均数…

数组传参,指针传参

文章目录 一维数组传参二维数组传参一级指针传参二级指针传参 一维数组传参 二维数组传参 一级指针传参 二级指针传参

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其轻量级和高效能而广受欢迎。在本教程中&#xff0c;我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1&#xff1a;更新系统 在安装任何软件之前&#xff0c;让我们先更新系统的软件包列表和已安…

【树链剖分+MST】CF609E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 先把全局的MST求出来&#xff0c;然后对于一条边&#xff0c;如果它本来就在MST中&#xff0c;说明代价就是MST的权值和&#xff0c;否则它加入MST中&#xff0c;此时MST形成了环&#xff0c;我们把环中最大的那…

深入探究Java面向对象的三大特征:封装、继承、多态

文章目录 1. 封装&#xff08;Encapsulation&#xff09;2. 继承&#xff08;Inheritance&#xff09;3. 多态&#xff08;Polymorphism&#xff09;结语 导语&#xff1a;Java是一门面向对象的编程语言&#xff0c;其核心思想是将现实世界中的事物抽象成对象&#xff0c;并通过…

Python(五十二)列表元素的判断及遍历

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

自己整理的JAVA集合

概括&#xff1a; 数组&#xff0c;链表&#xff0c;散列表&#xff0c;二分查找树&#xff0c;红黑树是五种不同的数据结构&#xff0c;它们有各自的特点和用途。ArrayList&#xff0c;LinkedList&#xff0c;HashTable&#xff0c;LinkedHashMap&#xff0c;HashMap 是 Java…

Camera组件

Clear Flags&#xff1a; Skybox&#xff1a;天空盒 Solid Color&#xff1a;填充颜色&#xff0c;当有空白处时填充背景颜色 Depth Only&#xff1a;只渲染想要渲染的层级 Dont Clear&#xff1a;不清除上一帧所留下来的数据&#xff0c;可以做类似残影的效果 Culling Mas…

Unity Addressable

Unity重要目录 工程中的几个重要目录 Assets存放资源、代码、配置Library大部分的资源导入到Assets目录之后&#xff0c;会转化成Unity认可的文件&#xff0c;转化后的文件会存储在这个目录Logs日志文件Packages第三方插件ProjectSettings存放各种项目设定UserSettings用户偏好…