用JavaScript实现一个贪吃蛇游戏

原理如下,贪吃蛇的蛇身就是一个数组,数组中的每个元素都是一个坐标,蛇身每次移动时都会在数组前插入一个新坐标,并在数组尾部删掉一条记录,吃到食物后数组的尾部记录就不删。如果移到屏幕边缘会从屏幕的另一边出现。好!接下来直接上代码!

<!DOCTYPE html>
<html lang="CN">
<head><meta charset="UTF-8"><title>贪吃蛇</title><style>canvas {border: 1px solid black;}</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<h3 id="score">分数:0</h3>
<script>const canvas = document.getElementById('gameCanvas');const ctx = canvas.getContext('2d');const gridSize = 20;const snake = [{x: 160, y: 160}, {x: 140, y: 160}, {x: 120, y: 160}];let direction = 'right';let food = {x: 80, y: 80};let score = 0;let gameOver = false;function drawSnakePart(snakePart) {ctx.fillStyle = 'lightgreen';ctx.strokeStyle = 'darkgreen';ctx.fillRect(snakePart.x, snakePart.y, gridSize, gridSize);ctx.strokeRect(snakePart.x, snakePart.y, gridSize, gridSize);}function drawSnake() {snake.forEach(drawSnakePart);}function moveSnake() {const head = {x: snake[0].x, y: snake[0].y};//根据方向生成新的蛇头位置const width = canvas.width - gridSizeconst height = canvas.height - gridSizeif (direction === 'right') head.x = head.x === width ? 0 : head.x + gridSize;if (direction === 'left') head.x = head.x <= 0 ? width : head.x - gridSize;if (direction === 'up') head.y = head.y <= 0 ? height : head.y - gridSize;if (direction === 'down') head.y = head.y === height ? 0 : head.y + gridSize;//根据蛇头位置判断是否和蛇身碰撞const collision = snake.find(s => s.x === head.x && s.y === head.y)if (collision) {gameOver = trueshowGameOver()}//将蛇头位置插入数组的首位snake.unshift(head);//判断蛇是否吃到食物,如果没吃到则从数组末尾删除一个以保持数组的总长不变if (head.x === food.x && head.y === food.y) {score += 10;document.getElementById("score").innerHTML = "分数:" + scorecreateFood();} else {snake.pop();}}function changeDirection(event) {const keyPressed = event.keyCode;const goingUp = direction === 'up';const goingDown = direction === 'down';const goingRight = direction === 'right';const goingLeft = direction === 'left';if (keyPressed === 37 && !goingRight) {direction = 'left';}if (keyPressed === 38 && !goingDown) {direction = 'up';}if (keyPressed === 39 && !goingLeft) {direction = 'right';}if (keyPressed === 40 && !goingUp) {direction = 'down';}}function randomTen(min, max) {return Math.round((Math.random() * (max - min) + min) / gridSize) * gridSize;}function createFood() {food = {x: randomTen(0, canvas.width - gridSize),y: randomTen(0, canvas.height - gridSize)};}function drawFood() {ctx.fillStyle = 'red';ctx.fillRect(food.x, food.y, gridSize, gridSize);}function clearCanvas() {ctx.fillStyle = 'white';ctx.fillRect(0, 0, canvas.width, canvas.height);}function showGameOver() {const h1 = document.createElement("h1")const text = document.createTextNode("Game Over,按F5重新开始")h1.appendChild(text)document.body.appendChild(h1)}function gameLoop() {if (gameOver) returnclearCanvas();drawFood();moveSnake();drawSnake();setTimeout(gameLoop, 100);}document.addEventListener('keydown', changeDirection);gameLoop();
</script>
</body>
</html>

功能简单,所以截图也简单。

源代码下载

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

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

相关文章

Unity RectTransUtility工具类

这个工具主要是用于动态生成UI的情况。项目中我们通过配置UI的锚点、位置以及大小(位置、大小都是通过蓝湖看到的)&#xff0c;然后通过代码动态生成UI。 大部分情况下只要合理设置锚点&#xff0c;那么生成出来的UI就已经满足了适配的要求。 using UnityEngine;public static…

红日靶场vulnstack 4靶机的测试报告[细节](一)

目录 一、测试环境 1、系统环境 2、注意事项 3、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、漏洞利用Getshell ①Struts 2 s2-045漏洞 手工利用s2-45漏洞 Msf综合利用 ②Tomcat框架(CVE-2017-12615) ③phpMyAdmin(CVE-2018-12613) 构造语句写入冰蝎木…

Springboot使用纪要

一、配置文件的加载顺序 1、不同配置文件类型的加载顺序 springboot支持三种类型的配置文件 .yml .yaml .properties当这三种配置文件处于同一目录下时&#xff0c;springboot会优先加载properties文件&#xff0c;如果.properties文件和.yml文件都有某一配置&#xff0c;而…

Unity协程机制详解

Unity的协程&#xff08;Coroutine&#xff09;是一种异步编程的机制&#xff0c;允许在多个帧之间分割代码的执行&#xff0c;而不阻塞主线程。与传统的多线程不同&#xff0c;Unity的协程在主线程中运行&#xff0c;并不会开启新的线程。 什么是协程&#xff1f; 协程是一种…

electron 打包 webview 嵌入需要调用电脑摄像头拍摄失败问题

electron 打包 webview 嵌入需要调用电脑摄像头拍摄失败问题 这篇文章是接我cocos专栏的上一篇文章继续写的&#xff0c;我上一篇文章写的是 cocos 开发触摸屏项目&#xff0c;需要嵌入一个网页用来展示&#xff0c;最后通过 electron 打包成 exe 程序&#xff0c;而且网页里面…

Android 开发者选项-模拟辅助显示设备

目录 概述使用开关的代码实现方式系统部分的处理:参考 概述 在Android开发中&#xff0c;模拟辅助显示设备通常指的是通过Android开发者选项来设置的一种虚拟显示设备&#xff0c;它允许开发者在一个设备上模拟另一个设备的显示特性。这种功能对于测试应用程序在不同屏幕尺寸、…

android 常用三方框架

说实话&#xff0c; 我是比较讨厌三方框架的&#xff0c; 比如一个eventbus 底层逻辑就是个观察者模式&#xff0c;当然他的场景涵盖的比较丰富&#xff0c; 单从 单一原则来说&#xff0c; 还是一个简单的观察者模式就能解决问题&#xff0c; 何必要添加那么多文件到我们的项目…

[COLM 2024] V-STaR: Training Verifiers for Self-Taught Reasoners

本文是对 STaR 的改进方法&#xff0c;COLM 是 Conference On Language Models&#xff0c;大模型领域新出的会议&#xff0c;在国际上很知名&#xff0c;不过目前还没有被列入 ccf list&#xff08;新会议一般不会列入&#xff09;&#xff1b;作者来自高校、微软研究院和 Goo…

从C#中的结构体和类的区别中看引用和值的问题

在 C#中&#xff0c;结构体&#xff08;struct&#xff09;和类&#xff08;class&#xff09;都是用于创建自定义数据类型的方式&#xff0c;但它们在很多方面存在着显著的区别。掌握他们的区别至少不会产生一些我们不了解情况下发生的错误。 文章目录 一、作为参数传递时的差…

Spann3R:基于DUSt3R的密集捕获数据增量式重建方法

来自作者Hengyi Wang在b站3D视觉工坊中对于该论文透彻的讲解&#xff0c;这里是相关重要部分的截屏。这篇博客的用途主要是自己做记录&#xff0c;其次分享给感兴趣的同学&#xff0c;最后谢谢作者大佬的认真讲解。 作者是按照这样的次序来介绍的&#xff1a; 首先从传统的三…

Python4-分支与循环

记录python学习&#xff0c;直到学会基本的爬虫&#xff0c;使用python搭建接口自动化测试就算学会了&#xff0c;在进阶webui自动化&#xff0c;app自动化 python基础3-分支与循环语句 python中 有哪些基本值是被当作true或者false的呢?if语句示例被视为 False 的情况被视为…

SAP-ABAP开发学习-面向对象OOALV(1)

本文目录 一、概述 面向对象开发特点 二、类与对象 程序中类的创建 Class构成要素 对象 方法 一、概述 随着SAP R/3 4.0版本的开发&#xff0c;ABAP语言开始引入了面向对象的开发概念。这在ABAP语言的发展过程中&#xff0c;面向对象&#xff08;Object-oriented&#…

【实用技能】如何在 .NET C# 中的邮件合并过程中操作表格单元格

TX Text Control 中的邮件合并 类是一个强大的库&#xff0c;旨在通过将数据合并到模板中来自动创建文档。它充当结构化数据&#xff08;例如来自数据库、JSON 或 XML&#xff09;和动态文档生成之间的桥梁&#xff0c;对于需要自动化文档工作流程的应用程序来说非常有用。 TX…

有源模拟滤波器的快速设计

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时&#xff0c;也能帮助其他需要参考的朋友。如有谬误&#xff0c;欢迎大家进行指正。 一、概述 几乎所有电子电路中都能看到有源模拟滤波器的身影。音频系统使用滤波器进行频带限制和平衡。通信系统设计使用滤波…

如何使用Python库连接Redis

1、redis-py 库封装一个 Redis 工具类可以帮助我们简化 Redis 的操作并提高代码的复用性和可维护性。 安装redis pip install redisimport redis import logginglogging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__)class RedisUtils:def __init__(s…

【代码随想录day57】【C++复健】 53. 寻宝(prim算法);53. 寻宝(kruskal算法)

53. 寻宝&#xff08;prim算法&#xff09; 好像在研究生的算法课上学过prim算法和kruskal算法&#xff0c;不过当时只是了解了一下大致的概念和流程&#xff0c;并没有涉及到如何去写代码的部分&#xff0c;今天也算是学习了一下这两个算法的代码应该如何去实现&#xff0c;还…

使用OpenTK展示3D点云图像(C#)

最近在研究3D显示&#xff0c;找到一款在winform上展示3D点云的控件&#xff0c;并且实现了点线面的展示&#xff0c;及光照渲染纹理贴图等功能&#xff0c;如下面几张图所展示。 一些基础知识可以在LearnOpenTK - OpenTK 这个网站上学习到。 我这边使用的是openTK3.3.3版本&a…

MetaGPT源码 (Memory 类)

目录 MetaGPT源码&#xff1a;Memory 类例子 MetaGPT源码&#xff1a;Memory 类 这段代码定义了一个名为 Memory 的类&#xff0c;用于存储和管理消息(Message)对象。Memory 提供了多种操作消息的功能&#xff0c;包括添加单条或批量消息、按角色或内容筛选消息、删除最新消息…

pythonOpenCV篇:0基础带你python入门之常用函数

① 二值化函数 功能&#xff1a;将图像转换为二值图像&#xff08;黑白图像&#xff09;&#xff0c;将像素值分为两种类别&#xff1a;前景&#xff08;白&#xff09;和背景&#xff08;黑&#xff09;。函数&#xff1a;cv2.threshold()参数&#xff1a; src&#xff1a;输…

小发现,如何高级的顺序输出,逆序输出整数的每一位(栈,队列)

当我还是初学者的时候&#xff0c;我经常思考有没有比慢慢求每一位数字然后考虑正序&#xff0c;逆序输出要快的办法...长期琢磨&#xff0c;必有所获&#xff01; 我刚学数据结构的时候还没意识到栈&#xff0c;队列还能这样用&#xff0c;虽然说有点杀鸡用牛刀的感觉&#x…