简单实现贪吃蛇小游戏效果图
文章底部有案例中的背景图
这是简单的html结构和样式部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.map {
width: 1000px;
height: 600px;
border: 5px solid #333;
margin: 50px auto;
position: relative;
background-image: url(./imgs/bg.png);
background-repeat: repeat;
background-size: 20px 20px;
}
.map>div {
width: 20px;
height: 20px;
position: absolute;
background-size: 20px 20px;
background-repeat: no-repeat;
}
.map>.food {
background-image: url(./imgs/food.png);
}
.map>.head {
background-image: url(./imgs/head.png);
}
.map>.body {
background-image: url(./imgs/body.png);
}
button{
width: 150px;
text-align: center;
height: 50px;
font-size: 30px;
}
</style>
</head>
<body>
<button id="btn1">开始</button>
<button id="btn2">暂停</button>
<button id="btn3">重新开始</button>
<div class="map" id="map"></div>
//我们在html 底部 书写的一部分 js
<script type="module">
// 导入js2
import Game from './贪吃蛇2.js'
const g = new Game('#map')
// 三个按钮的点击事件
document.querySelector('#btn1').onclick = function(){
g.start()
}
document.querySelector('#btn2').onclick = function(){
g.pause()
}
document.querySelector('#btn3').onclick = function(){
g.reload()
}
//当按下方向键盘的时候 控制蛇的移动方向
document.onkeydown = function(e){
// 事件委托的方式 拿到键盘上的上下左右的code 编码
if(e.keyCode == 37){
//left
g.setDes('left')
}else if(e.keyCode == 38){
//top
g.setDes('top')
}else if(e.keyCode == 39){
//right
g.setDes('right')
}else if(e.keyCode == 40){
// bottom
g.setDes('bottom')
}
}
</script>
</body>
</html>
单独的./贪吃蛇.js' js文件
export default class food{
constructor(ele){
//获取到地图范围
this.map = document.querySelector(ele)
//新建一个食物的div
this.Food = document.createElement('div')
//新建一个头部的div
this.Head = document.createElement('div')
//新建一个身体的div
this.Body = document.createElement('div')
//给食物DIV 添加一个类名
this.Food.classList.add('food')
// 将新建的食物div插入到地图中
this.map.appendChild(this.Food)
//记录食物的坐标
this.x = 0
this.y = 0
// 调用改变食物位置的方法
this.changeFood()
}
// 原型内容部分
changeFood(){
//0 拿到地图的高度和宽度
const w = parseInt(window.getComputedStyle(this.map).width)
const h = parseInt(window.getComputedStyle(this.map).height)
// 1.1计算每行多少个小格子
// 1.2计算每列多少个小格子
const row = w / 20
const col = h / 20
// 2求食物在第几个格子上
// const posX = (Math.floor(Math.random()*(row-1))+1)*20
const posX = Math.floor(Math.random()*row)*20
const posY = Math.floor(Math.random()*col)*20
// 3求出随机数后 赋值给坐标
this.x = posX
this.y = posY
// 4修改食物的坐标
this.Food.style.left = this.x + "px"
this.Food.style.top = this.y + "px"
}
}
单独的./贪吃蛇.js1' js文件
export default class Snake{
constructor(ele){
//1 拿到范围地图
this.map = document.querySelector(ele)
// 2方向
this.des = 'right'
// 数组来存储一条蛇
this.Snake = []
// 4. 创建一条蛇
this.makeSnake();
this.isDie()
}
addSnake(){
// 1. 当前 this.snake 为空数组, 此时只需要创建一节蛇头即可
// 2. 当前 this.snake 数组已经有值了, 除了要创建一节蛇头意外, 还要把原本的蛇头更改蛇身
// 0 拿到数组的第一项定位蛇头
const head = this.Snake[0]
//首次判断 是否 为空数组
// 不为空 有内容 将之更改为蛇身
if(head !== undefined){
head.className = 'body'
}
//3 创建蛇头
const oHaed = document.createElement('div')
// 添加类名
oHaed.className = 'head'
// 再地图页面生成蛇头
this.map.appendChild(oHaed)
//并且插入在数组的开头
this.Snake.unshift(oHaed)
//4 调整蛇头的走位
const pos = {
x : 0,
y : 0,
}
if(head !== undefined){
/**
* 如果当前方向是 向 右, left += 20 top 不变
* 左, left -= 20 top 不变
* 下, left 不变 top += 20
* 上, left 不变 top -= 20
*/
// 先获取蛇头原本的偏移量
pos.x = head.offsetLeft
pos.y = head.offsetTop
switch(this.des){
case "right": pos.x += 20; break;
case "left": pos.x -= 20; break;
case "bottom": pos.y += 20; break;
case "top": pos.y -= 20; break;
}
}
oHaed.style.left = pos.x + "px";
oHaed.style.top = pos.y + "px";
}
makeSnake(){
// 调用五次 生成长度为 5 一条的蛇
for (let i = 0; i < 10; i++) {
this.addSnake();
}
}
//走一步
move(){
// 删除末尾的元素
// 删除对应的dom 节点
// 新增一个蛇头
const body = this.Snake.pop()
body.remove()
this.addSnake()
}
// 判断食物重叠
isEat(footX,footY){
//定义第一项为蛇头
const head = this.Snake[0]
if(head.offsetLeft == footX && head.offsetTop == footY){
return true
}
return false
}
//判断是失败 条件 超界
isDie(){
const head =this.Snake[0]
if(
head.offsetLeft < 0 |
head.offsetTop < 0 |
head.offsetLeft > this.map.clientWidth |
head.offsetTop > this.map.clientHeight
){
return true
}
return false
}
}
单独的./贪吃蛇.js2' js文件
必须在贪吃蛇js2中 按顺序先导入 这如下两个js
import food from './贪吃蛇.js'
import Snake from './贪吃蛇1.js'
export default class Game{
constructor(ele){
this.food = new food(ele)
this.Snake = new Snake(ele)
this.timer = 0
this.sum = 0
this.level = 1
}
//开始游戏
start(){
// let newTime = 1800 - this.leve * 100;
this.timer = setInterval(()=>{
this.Snake.move()
// this.up()
// 判断是否吃到了食物
if(this.Snake.isEat(this.food.x,this.food.y)){
this.food.changeFood()
this.Snake.addSnake()
this.sum ++
}
// 判断蛇头是否超界
if(this.Snake.isDie()){
clearInterval(this.timer)
alert('小菜鸟!还敢继续挑战吗?')
}
},100)
}
//暂停游戏
pause(){
clearInterval(this.timer)
}
//重新开始
reload(){
window.location.reload()
}
//修改蛇的方向
setDes(type){
this.Snake.des = type
}
}
案例中的背景图
背景
蛇的身体
蛇的食物
蛇的头部