html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>贪吃蛇</title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background-color: #000000;
}
div {
width: 1000px;
height: 500px;
margin: 20px auto;
}
canvas {
border: 1px solid #800080;
background-color: #000;
}
#startGame {
width: 120px;
height: 40px;
text-align: center;
line-height: 40px;
font-size: 20px;
color: #0000FF;
background-color: #FFC0CB;
margin: 20px 40%;
}
span {
display: inline-block;
color: red;
}
</style>
<body>
<div>
<canvas id="cvs" width="1000" height="500"></canvas>
<span id="span">0分</span>
<button id="startGame">开始游戏</button>
</div>
</body>
<script src="GluttonousSnake.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
let ctx = cvs.getContext('2d')
let x = 60
let y = 20 //初始移动位置
let f = {} //食物
let speed = 150 //定时器速度 移动速度 游戏难度
let a = 20 //每次移动的距离
// 蛇身
let arr = [{
x: 20,
y: 20
},
{
x: 40,
y: 20
},
{
x: 60,
y: 20
}
]
let gluttonous_snake = new GluttonousSnake(ctx, x, y, f, speed, arr, a)
gluttonous_snake.maps()
gluttonous_snake.initial()
// 开始游戏
startGame.onclick = function() {
if (this.innerHTML == '开始游戏') {
this.innerHTML = '暂停游戏'
gluttonous_snake.timeX = setInterval(gluttonous_snake.moveX.bind(gluttonous_snake), gluttonous_snake.speed)
gluttonous_snake.food()
// 键盘事件
gluttonous_snake.a = 20
document.addEventListener('keydown', function(e) {
let event = e || window.event
let ke = event.keyCode
// 右
if (gluttonous_snake.timeX == false) {
if (ke == 39) {
clearInterval(gluttonous_snake.timeY)
gluttonous_snake.timeY = 0
clearInterval(gluttonous_snake.timeX)
gluttonous_snake.timeX = 0
gluttonous_snake.a = 20
gluttonous_snake.timeX = setInterval(gluttonous_snake.moveX.bind(gluttonous_snake), gluttonous_snake.speed)
}
// 左
if (ke == 37) {
clearInterval(gluttonous_snake.timeY)
gluttonous_snake.timeY = 0
clearInterval(gluttonous_snake.timeX)
gluttonous_snake.timeX = 0
gluttonous_snake.a = -20
gluttonous_snake.timeX = setInterval(gluttonous_snake.moveX.bind(gluttonous_snake), gluttonous_snake.speed)
}
}
if (gluttonous_snake.timeY == false) {
// 上
if (ke == 38) {
clearInterval(gluttonous_snake.timeX)
gluttonous_snake.timeX = 0
gluttonous_snake.a = -20
gluttonous_snake.timeY = setInterval(gluttonous_snake.moveY.bind(gluttonous_snake), gluttonous_snake.speed)
}
// 下
if (ke == 40) {
clearInterval(gluttonous_snake.timeY)
gluttonous_snake.timeY = 0
clearInterval(gluttonous_snake.timeX)
gluttonous_snake.timeX = 0
gluttonous_snake.a = 20
gluttonous_snake.timeY = setInterval(gluttonous_snake.moveY.bind(gluttonous_snake), gluttonous_snake.speed)
}
}
})
return
}
this.innerHTML = '开始游戏'
clearInterval(gluttonous_snake.timeX)
clearInterval(gluttonous_snake.timeY)
gluttonous_snake.timeX = 0
gluttonous_snake.timeY = 0
}
</script>
</html>
GluttonousSnake.js
class GluttonousSnake {
constructor(ctx, x, y, f, speed, arr, a) {
this.x = x;
this.y = y; //初始移动位置
this.f = {}; //食物
this.speed = speed;
this.a = a //每次移动的距离
this.arr = arr;
this.ctx = ctx;
this.timeX = false
this.timeY = false
}
//线
gridding(x, y, x1, y1) {
this.ctx.beginPath()
this.ctx.lineWidth = 0.2
this.ctx.strokeStyle = '#800080'
this.ctx.moveTo(x, y)
this.ctx.lineTo(x1, y1)
this.ctx.closePath()
this.ctx.stroke()
}
//网格
maps() {
for (let i = 20; i <= cvs.width; i += 20) {
this.gridding(i, 0, i, cvs.height)
}
for (let i = 20; i <= cvs.height; i += 20) {
this.gridding(0, i, cvs.width, i)
}
}
//填充矩形
fillRects(x, y) {
this.ctx.fillStyle = this.getRandomColor()
this.ctx.fillRect(x, y, 20, 20);
this.ctx.stroke();
}
//绘制蛇身位置
initial() {
for (let i = 0; i < this.arr.length; i++) {
this.fillRects(this.arr[i].x, this.arr[i].y)
}
}
//随机颜色
getRandomColor() {
return '#' + Math.random().toString(16).substr(2, 6).toUpperCase();
}
// 清除画布
cler(x, y) {
this.ctx.clearRect(0, 0, cvs.width, cvs.height)
}
//X移动
moveX() {
this.x += this.a
this.fillRects(this.x, this.y)
this.cler()
this.maps()
this.fillRects(this.f.x, this.f.y)
this.arr.push({
x: this.x,
y: this.y
})
this.arr = this.arr.slice(1)
this.initial()
this.gameOver()
this.Decide()
if (this.x == this.f.x && this.y == this.f.y) {
this.arr.push({
x: this.f.x,
y: this.f.y
})
this.food()
}
span.innerHTML = this.arr.length - 3 + '分'
}
//Y移动
moveY() {
this.y += this.a
this.fillRects(this.x, this.y)
this.cler()
this.maps()
this.fillRects(this.f.x, this.f.y)
this.arr.push({
x: this.x,
y: this.y
})
this.arr = this.arr.slice(1)
this.initial()
this.gameOver()
this.Decide()
if (this.x == this.f.x && this.y == this.f.y) {
this.arr.push({
x: this.f.x,
y: this.f.y
})
this.food()
}
span.innerHTML = this.arr.length - 3 + '分'
}
//食物
food() {
this.f = {
x: (Math.floor(Math.random() * 49 + 1)) * 20,
y: (Math.floor(Math.random() * 24 + 1)) * 20
}
this.fillRects(this.f.x, this.f.y)
this.difficulty()
}
//游戏规则
gameOver() {
if (this.x > cvs.width - 20) {
this.jiesu()
}
if (this.x < 0) {
this.jiesu()
}
if (this.y > cvs.height - 20) {
this.jiesu()
}
if (this.y < 0) {
this.jiesu()
}
}
//判断是否撞到自己了
Decide() {
for (let i = 0; i < this.arr.length - 1; i++) {
if (this.arr[i].x == this.arr[this.arr.length - 1].x && this.arr[i].y == this.arr[this.arr.length - 1].y) {
this.jiesu()
}
}
}
// 结束规则
jiesu() {
clearInterval(this.timeX)
clearInterval(this.timeY)
this.timeY = 0
this.timeX = 0
alert('游戏结束')
this.cler()
this.maps()
this.arr = [{
x: 20,
y: 20
},
{
x: 40,
y: 20
},
{
x: 60,
y: 20
}
]
this.x = 60
this.y = 20
this.initial()
startGame.innerHTML = '开始游戏'
}
//每吃五个提高一次难度
difficulty() {
let len = this.arr.length - 3
let difficulty_n = len / 5
if (len % 5 == 0) {
if (len <= 10) {
this.speed -= 20
}
if (len > 10 && len <= 20) {
this.speed -= 15
}
if (len > 20 && len < 30) {
this.speed -= 10
}
if (len > 30) {
this.speed -= 5
}
}
}
}