JavaScript贪吃蛇的实现代码
作者:777885 发布时间:2023-08-31 04:41:44
标签:js,贪吃蛇
本文实例为大家分享了JavaScript实现贪吃蛇的具体代码,供大家参考,具体内容如下
首先我们要确定贪吃蛇应有的功能
1.通过键盘的上下左右控制蛇的移动方向
2.边界判定,即蛇头超出边界则游戏结束
3.碰撞判定,即蛇头和食物块发生触碰
4.吃到食物积分加1
具体实现
一.html代码
<div class="container">
<!--小蛇移动的操场-->
<div id="playground">
<!--小蛇-->
<div id="snake"></div>
<!--食物-->
<div id="food"></div>
</div>
<!--记录得分-->
<div id="menu">
<div>得分<span id="score"></span></div>
</div>
</div>
二.css代码
<style>
* {
padding: 0;
margin: 0;
}
.container {
width: 800px;
height: 600px;
margin: 0 auto;
}
#playground {
width: 650px;
height: 100%;
background-color: cadetblue;
float: left;
position: relative;
}
#menu {
width: 150px;
height: 100%;
background-color: darkcyan;
float: left;
}
#snake {
width: 20px;
height: 20px;
background-color: #d3e0d7;
position: absolute;
left: 0;
top: 0;
}
#food {
width: 20px;
height: 20px;
background-color: #027766;
position: absolute;
}
.body {
width: 20px;
height: 20px;
background-color: #178b9a;
position: absolute;
;
top: 0;
left: 0;
}
#score {
font-size: 30px;
font-weight: bold;
color: black;
}
#menu div {
font-size: 20px;
font-weight: bold;
margin-left: 20px;
}
#hqx {
width: 100px;
height: 50px;
margin: 0 auto;
}
#inp {
border: 0;
width: 100px;
height: 50px;
background-color: coral;
}
</style>
三.开始实现具体功能
1.先获取节点,设置全局变量
//获取节点
var snake = document.getElementById("snake");
var food = document.getElementById("food");
var playground = document.getElementById("playground");
var score = document.getElementById('score');
// var inp = document.getElementById('inp')
/*设置全局变量*/
var timer;
var arr = []; //存放蛇的位置的数组
var num = 0; //数组的长度
var snakeBody; //每次吃调一个食物,增加的身体
2.设置按键事件,并判断边界碰撞,碰撞时游戏结束。这一块代码我遇到了一个问题,就是当我用if(){return}跳出事件,会结束所有代码,后面的代码就不会执行了,然后我换成了switch(){ case: break;}就实现效果了
//设置按键事件
document.onkeydown = function (e) {
var evt = window.evnet || e;
switch (evt.keyCode) {
case 37: //左
clearInterval(timer);
timer = window.setInterval(runLeft, 10); //向左移动的时间器
function runLeft() {
if (snake.offsetLeft > 0) {
snake.style.left = snake.offsetLeft - 1 + 'px'; //实现自己动
snake.style.top = snake.offsetTop + 'px'; //高度不变
arr.push([snake.offsetLeft, snake.offsetTop]); //每移动1px,就将位置存进数组中
num++; //相应的数组长度加1
} else {
clearInterval(timer); //清除定时器
alert('you die') //弹出失败信息
document.onkeydown = null //结束按键
}
}
break; //结束当前按键
case 38: //上
clearInterval(timer);
timer = window.setInterval(runTop, 10);
function runTop() {
if (snake.offsetTop > 0) {
snake.style.top = snake.offsetTop - 1 + 'px';
snake.style.left = snake.offsetLeft + 'px';
arr.push([snake.offsetLeft, snake.offsetTop]);
num++;
} else {
clearInterval(timer);
alert('you die')
document.onkeydown = null
}
}
break;
case 39: //右
clearInterval(timer);
timer = window.setInterval(runRight, 10);
function runRight() {
if (snake.offsetLeft < 630) {
snake.style.left = snake.offsetLeft + 1 + 'px';
snake.style.top = snake.offsetTop + 'px';
arr.push([snake.offsetLeft, snake.offsetTop]);
num++;
} else {
clearInterval(timer);
alert('you die')
document.onkeydown = null
}
}
break;
case 40: //下
clearInterval(timer);
timer = window.setInterval(runBottom, 10);
function runBottom() {
if (snake.offsetTop < 580) {
snake.style.top = snake.offsetTop + 1 + 'px';
snake.style.left = snake.offsetLeft + 'px';
arr.push([snake.offsetLeft, snake.offsetTop]);
num++;
} else {
clearInterval(timer);
alert('you die')
document.onkeydown = null
}
}
break;
}
3.封装一个函数,随机生成食物位置,第一次粗心忘记加单位,看网页没效果,才知道忘记加单位了
function pos() {
food.style.left = parseInt(Math.random() * 630) + 'px';
food.style.top = parseInt(Math.random() * 580) + 'px';
}
4.封装一个碰撞判定函数,使其碰撞时,食物消失,蛇的身体增加一块。这里遇到一个定时器问题,第一次写的时候,我的定时器清除标识和之前的定时器标识一致,导致蛇会上下左右抖动,经过后面不停的修改,最终找到错误。
var timer1 = setInterval(eat, 10); //设置一个碰撞的时间器
function eat() {
snakeCrashFood(snake, food); //传入参数
function snakeCrashFood(obj1, obj2) {
var obj1Left = obj1.offsetLeft;
var obj1Width = obj1.offsetWidth + obj1.offsetLeft;
var obj1Top = obj1.offsetTop;
var obj1Height = obj1.offsetHeight + obj1.offsetTop;
var obj2Left = obj2.offsetLeft;
var obj2Width = obj2.offsetWidth + obj2.offsetLeft;
var obj2Top = obj2.offsetTop;
var obj2Height = obj2.offsetHeight + obj2.offsetTop;
if (!((obj1Width < obj2Left) || (obj2Width < obj1Left) || (obj1Height < obj2Top) || (
obj2Height < obj1Top))) {
snakeBody = document.createElement("div"); //生成新的div
snakeBody.setAttribute("class", "body"); //给新的div添加类名
playground.appendChild(snakeBody); //添加一节新的身体
pos(); //让食物重新随机出现
setInterval(follow, 10); //动态地改变新的身体的位置
}
}
}
5.设置蛇的身体跟随,获得蛇身体的数组,新的身体相对于上一个身体的第20个数组的位置。这里我遇到了一个数组越界问题。最开始初始num值为0,place=20,所以第一次身体的增加arr[num-place][0]前面的索引是从负数开始,在通过老师的指导,增加一个判定,解决了这个问题。
function follow() {
/*获得增加的身体的数组*/
var bodyNum = document.getElementsByClassName("body");
score.innerHTML = bodyNum.length;
var place = 0;
/*数组每移动1px,新的身体的位置就是相对于前一个身体的第20个数组的位置,后面依次加等*/
// console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1")
// console.log("arr : ==" + arr)
// console.log("num : ==" + num) //2
for (var i = 0; i < bodyNum.length; i++) {
// console.log("bodyNum.length : ==" + bodyNum.length)
place += 20;
// console.log("place : ==" + place)//20
// console.log("num - place : ==" + (num - place))//-18
// bodyNum[i].style.left = arr[num - place][0] + 'px';
// bodyNum[i].style.top = arr[num - place][1] + 'px';
if (num - place > 0) {
bodyNum[i].style.left = arr[num - place][0] + 'px';
bodyNum[i].style.top = arr[num - place][1] + 'px';
}
}
// console.log("num555 : ==" + num)
// console.log("===========================================")
}
来源:https://blog.csdn.net/qq_56206082/article/details/120142874


猜你喜欢
- 序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态(存在内存中)写入到临时或持久性存储区(硬盘)。以后
- 一,什么是mycat一个彻底开源的,面向企业应用开发的大数据库集群支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL
- Anaconda简介Anaconda是一个方便的python包管理和环境管理软件,一般用来配置不同的项目环境。我们常常会遇到这样的情况,正在
- 使用echart卡在引入包的问题上了。到github下载的js一直引入不了。注意是引入dirt文件夹下的echarts.js把这个文件夹放入
- binascii模块用法binascii模块用于在二进制和ASCII之间转换>> import binascii# 将binar
- 获取指定日期月份的第一天,你可以使用DATEADD函数,减去指定日期的月份过去了的天数,即可。 代码如下:CREATE FUNC
- Pytest使用的断言是使用python内置的断言assert。Python assert(断言)用于判断一个表达式,在表达式条件为 fal
- 最近发现现有框架的通用查询存储过程的性能慢,于是仔细研究了下代码:Alter PROCEDURE [dbo].[AreaSelect]&nb
- 简介虽然使用Explain不能够马上调优我们的SQL,它也不能给予我们一些调整建议,但是它能够让我们了解MySQL 优化器是如何执行SQL
- --sql基本操作--创建数据库create database Studets--创建表create table student ( sno
- 1、XML 是什么?XML仅仅是一种数据存放格式,这种格式是一种文本(虽然XML规范中也提供了存放二进制数据的解决方案)。事实上有很多文本格
- python 2.7.11django 1.8.4错误内容:related Field has invalid lookup: iconta
- 出自: 编程中国 http://www.bc-cn.net作者: 天涯听雨 &nbs
- 1. 前言上一篇介绍了 Go并发控制--Channel使用channel来控制子协程的优点是实现简单,缺点是当需要大量创建协程时就需要有相同
- props传值时子组件检测不到我们在Vue项目开发的过程中,经常会需要在父子组件传值,我们都知道,父子组件传值的时候是通过 props 来进
- 线程进程和线程什么是进程?进程就是正在运行的程序, 一个任务就是一个进程, 进程的主要工作是管理资源, 而不是实现功能什么是线程?线程的主要
- 参考官网地址:Windows端:https://tensorflow.google.cn/install/source_windowsCPU
- 本文实例为大家分享了Python端口扫描的实现代码,供大家参考,具体内容如下获取本机的IP和端口号:import socket def ge
- 贪食蛇是一个非常经典的游戏, 在游戏中, 玩家操控一条细长的直线(俗称蛇或虫), 它会不停前进, 玩家只能操控蛇的头部朝向(上下左右), 一
- if (arr[i]){ &nb