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

JS做贪吃蛇小游戏(源码)

一、HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="./../css/index.css">
</head>
<body>
	<div class="container">
		<!-- 开始按钮 -->
		<button class="start"></button>
		<!-- 暂停按钮 -->
		<button class="pause"></button>
	</div>
	<script src="../js/config.js"></script>
	<script src="../js/index.js"></script>
</body>
</html>

二、css代码

html,body{
	margin: 0;
	padding:0 ;
}
/*容器样式*/
.container{
	width: 600px;
	height: 600px;
	background: #225675;
	border: 20px solid #7dd9ff;
	margin: 100px auto;
	position: relative;
}
/*按钮公共样式*/
button{
	border:none;
	outline: none;
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%,-50%);
}
/*开始按钮*/
.start{
	width: 200px;
	height: 200px;
	background: url(./../img/start.webp) center no-repeat;
	background-size: 100% 100%;
	display: block;
}
/*暂停按钮*/
.pause{
	width: 80px;
	height: 80px;
	background: url(./../img/b.webp) center no-repeat;
	background-size: 100% 100%;
	display: none;
}

三、JS代码

1.index.js

//绘制蛇的方法
function drawSnake(snake){
	for(var i=0;i<snake.snakePos.length;i++){
		if(!snake.snakePos[i].domConent){
			// 如果进入此if,说明是第一次创建蛇
			snake.snakePos[i].domConent=document.createElement("div");
			snake.snakePos[i].domConent.style.position="absolute";
			snake.snakePos[i].domConent.style.width=snakeBody+"px";
			snake.snakePos[i].domConent.style.height=snakeBody+"px";
			snake.snakePos[i].domConent.style.left=snake.snakePos[i].x*snakeBody+"px";
			snake.snakePos[i].domConent.style.top=snake.snakePos[i].y*snakeBody+"px";
			if(snake.snakePos[i].flag==='head'){
				//进入此if说明是蛇头
				snake.snakePos[i].domConent.style.background=`
					url("../img/a.webp") center/contain no-repeat
				`;
				//根据方向进行旋转
				switch(snake.direction.flag){
					case "top":{
						snake.snakePos[i].domConent.style.transform=`rotate(-90deg)`;
						break;
					}
					case "bottom":{
						snake.snakePos[i].domConent.style.transform=`rotate(90deg)`;
						break;
					}
					case "left":{
						snake.snakePos[i].domConent.style.transform=`rotate(180deg)`;
						break;
					}
					case "right":{
						snake.snakePos[i].domConent.style.transform=`rotate(0deg)`;
						break;
					}
				}
			}else{
				//说明是蛇身
				snake.snakePos[i].domConent.style.background="#e69009";
				snake.snakePos[i].domConent.style.borderRadius="50%"
			}
		}
		//需要将创建的DOM 元素添加到容器当中
		document.querySelector(".container").append(snake.snakePos[i].domConent)
	}
}

//绘制食物的方法
function drawFood(){
	//1.食物是随机的
	//2.食物不能再蛇头或蛇身的位置
	while(true){
		//构成一个死循环,直到生成符合要求的食物坐标才能退出
		var isRepeat=false//默认生成的坐标是符合要求的
		//随机生成一个坐标
		food.x=Math.floor(Math.random()*tr+0)
		food.y=Math.floor(Math.random()*tr+0)
		//查看是否符合要求
		for(var i=0;i<snake.snakePos.length;i++){
			if(snake.snakePos[i].x===food.x&&snake.snakePos[i].y===food.y){
				//当前生成的食物,和蛇的坐标冲突了
				isRepeat = true;
				break; //跳出for循环
			}
		}
		if(!isRepeat){
			break;//跳出while循环
		}
	}
	//整个while循环跳出来以后u,食物的坐标一定是ok的
	if(!food.domConent){
		food.domConent = document.createElement("div")
		food.domConent.style.width = snakeBody+"px";
		food.domConent.style.height = snakeBody+"px";
		food.domConent.style.position = "absolute";
		food.domConent.style.background=`
			url("../img/apple.webp") center/contain no-repeat
		`;
		document.querySelector(".container").append(food.domConent);
	}
	food.domConent.style.left = food.x * snakeBody + "px";
	food.domConent.style.top = food.y * snakeBody + "px";
}


// 初始化游戏
function initGame(){
	// 1.初始化地图
	for(var i=0;i<tr;i++){
		for(var j=0;j<td;j++){
			gridData.push({
				x:j,
				y:i
			})
		}
	}
	// console.log(gridData) 
	//2.绘制蛇
	drawSnake(snake);
	//3.绘制食物 
	drawFood()
}
// 碰撞检测
function isCollide(newHead){
	var collideCheckInfo={
		isCollide:false,  //是否碰撞墙壁蛇身
		isEat:false       //是否迟到食物
	}
	// 是否碰到墙壁
	if(newHead.x<0||newHead.x>=td||newHead.y<0||newHead.y>=tr){
		collideCheckInfo.isCollide =true;
		return collideCheckInfo;
	}
	//检测是否碰到自己
	for(var i=0 ; i<snake.snakePos.length;i++){
		if(snake.snakePos[i].x === newHead.x && snake.snakePos[i].y===newHead.y){
			collideCheckInfo.isCollide=true;
			return collideCheckInfo;
		}
	}
	// 检测是否吃到东西
	if(newHead.x === food.x&&newHead.y===food.y){
		collideCheckInfo.isEat =true;
		score++;  //分数自增
	}
	return collideCheckInfo;
}

// 蛇的移动
function snakeMove(){
	
	var oldHead =snake.snakePos[snake.snakePos.length-1]
	//根据方向计算出新的蛇头坐标
	var newHead ={
		domConent:"",
		x : oldHead.x + snake.direction.x,
		y : oldHead.y + snake.direction.y,
		flag:"head",
	}
	// 首先先进行碰撞检测,看计算出来的新的蛇头有没有碰上食物,蛇身体,墙壁
	var collideCheckResult= isCollide(newHead);
	if(collideCheckResult.isCollide){
		//说明碰墙le
		// console.log("碰墙")
		if(window.confirm(`游戏结束,您当前的得分为${score}分,是否要重新开始游戏`)){
			//重新开始游戏
			// console.log("重新开始游戏")
			document.querySelector(".container").innerHTML=`
				<!-- 开始按钮 -->
				<button class="start" style="display:none"></button>
				<!-- 暂停按钮 -->
				<button class="pause" style="display:none"></button>
			`;
			score =0;
			snake ={
				//设一开始移动的方向
				direction:directionNumber.right,
				//蛇的初始位置
				snakePos:[
					{x:0,y:0,domConent:"",flag:"body"},
					{x:1,y:0,domConent:"",flag:"body"},
					{x:2,y:0,domConent:"",flag:"body"},
					{x:3,y:0,domConent:"",flag:"head"}
				]
			};
			food = {
				x:0 , y:0  ,domConent:""
			};
			initGame();
		}else{
			//结束游戏
			document.onkeydown = null;
			clearInterval(timerStop)
			// console.log("取消游戏")
		}
		return;
	}

	//将旧的头修改为身体
	oldHead.flag = "body";
	oldHead.domConent.style.background ="#e69009";
	oldHead.domConent.style.borderRadius ="50%";
	snake.snakePos.push(newHead);
	// 判段是否吃到东西
	if(collideCheckResult.isEat){
		//重新生成新的食物
		drawFood();
	}else{
		//没有吃到,移除最后一个
		document.querySelector(".container").removeChild(snake.snakePos[0].domConent)
		snake.snakePos.shift();
	}
	// 重新绘制蛇
	drawSnake(snake);
}

//
function startGame(){
	timerStop = setInterval(function(){
		snakeMove()
	},time)
}

// 绑定事件
function bindEvent(){
	// 首先是键盘事件,用户按上下左右,蛇可以移动
	document.onkeydown = function(e){
		// console.log(e.key)
		if((e.key === "ArrowUp" || e.key.toLocaleLowerCase() === "w")&&snake.direction.flag !== "bottom"){
			//用户按下上建
			snake.direction=directionNumber.top;
			 event.preventDefault(); // 阻止方向键默认行为(如页面滚动)
		}
		if((e.key === "ArrowDown" || e.key.toLocaleLowerCase() === "s")&&snake.direction.flag !=="top"){
			//用户按下下建
			snake.direction=directionNumber.bottom;
			 event.preventDefault(); // 阻止方向键默认行为(如页面滚动)

		}
		if((e.key === "ArrowLeft" || e.key.toLocaleLowerCase() === "a")&&snake.direction.flag !== "right"){
			//用户按下左建
			snake.direction=directionNumber.left;
			 event.preventDefault(); // 阻止方向键默认行为(如页面滚动)

		}
		if((e.key === "ArrowRight" || e.key.toLocaleLowerCase() === "d")&&snake.direction.flag !== "lefts"){
			//用户按下右建
			snake.direction=directionNumber.right;
			 event.preventDefault(); // 阻止方向键默认行为(如页面滚动)
		}
		// snakeMove();
	}
	//2.计时器自动调用蛇移动的方法
	startGame();
	//3.点击整个容器的时候可以暂停和重新开始游戏
	document.querySelector(".container").onclick = function(e){
		//这里是通过事件委托的形式,判断用户究竟点击的时候container容器还是暂停按钮,从而做出不同的操作
		if(e.target.className === "container"){
			//做暂停操作
			document.querySelector(".pause").style.display = 'block';
			clearInterval(timerStop);
		}else{
			//恢复游戏操作
			document.querySelector(".pause").style.display = 'none';
			startGame();
		}	
	}
}
// 主方法
function main(){
	//用户点击了开始游戏之后,再做后续的工作
	document.querySelector(".start").onclick= function(e){
		e.stopPropagation();
		document.querySelector(".start").style.display="none"
		//1.初始化游戏
		initGame();
		// 2.绑定事件
		bindEvent();
	}
	
}
main();

2.config.js(游戏相关设置)

// 游戏相关的配置


var gridData = [];//存储地图对象
// 整个网格的行与列
var tr = 30;
var td = 30;

//蛇的身体大小
var snakeBody = 20;

// 新的蛇头和旧的蛇头之间的关系
var directionNumber={
	// 我们在确定新的蛇头的时候,会拿下面的对象和旧蛇头做一个计算,从而得出新蛇头的位置
	left:{x:-1,y:0,flag:"left"},
	right:{x:1,y:0,flag:"right"},
	top:{x:0,y:-1,flag:"top"},
	bottom:{x:0,y:1,flag:"bottom"}
}

//蛇相关的配置信息
var snake ={
	//设一开始移动的方向
	direction:directionNumber.right,
	//蛇的初始位置
	snakePos:[
		{x:0,y:0,domConent:"",flag:"body"},
		{x:1,y:0,domConent:"",flag:"body"},
		{x:2,y:0,domConent:"",flag:"body"},
		{x:3,y:0,domConent:"",flag:"head"}
	]
}
//食物的相关配置信息
var food = {
	x:0 , y:0  ,domConent:""
}
//游戏分数
var  score= 0
//停止计时器
var timerStop = null
//计时器事件
var time=100
原文地址:https://blog.csdn.net/weixin_65450681/article/details/146342951
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/592686.html

相关文章:

  • uni-app——计时器和界面交互API
  • 【笔记】深度学习模型训练的 GPU 内存优化之旅:重计算篇
  • 人工智能中神经网络是如何进行预测的
  • 涨薪技术|Kubernetes(k8s)之yaml语法大全
  • AI实干家:HK深度体验-【第3篇-香港、新加坡、深圳、上海、首尔五座城市在金融数据维度的对比分析】
  • 31天Python入门——第5天:循环那些事儿
  • 【Go每日一练】随机密码生成器
  • 大语言模型黑盒越狱攻击之模板补全
  • Android retrofit 接口请求,提示CLEARTEXT communication处理
  • PostgreSQL:语言基础与数据库操作
  • 苹果电脑mac M1 15.0 安装虚拟机以及Debian系统 |Debian优化汉化中文 |Debian换阿里下载源 |Debian新建用户
  • 【简单有效!】Gradio利用html插件实现video视频流循环播放
  • Java面试黄金宝典3
  • 【Linux】手动部署并测试内网穿透
  • 并发编程面试题三
  • 2000-2016年各省地方财政营业税数据
  • 【人工智能】【Python】在Scikit-Learn中使用网格搜索对决策树调参
  • ROS合集(三)RTAB-Map + EuRoC 数据格式概述
  • 上取整,下取整,四舍五入
  • LS-NET-001-什么是承载网,核心网和接入网