贪吃蛇小游戏大家都不陌生,基本上都玩过,而使用js,也能够编写出各种各样的小游戏,今天就写一下贪吃蛇这个经典小游戏
效果图:
html代码
代码没啥可说的,两个下拉框分别对应着游戏棋盘大小和贪吃的速度
css代码
原本还用弹性布局将#box居中的,但截不了那么长的图,就省略了,如果感觉不好看,可以自己编写样式
下面是加上代码,提醒一句,js代码太多了(两百多行),最好单独写一个文件,这里为了方便,就不更改了,一篇文章写下来了
js代码
`// 第一步写的东西 把游戏中的 一些公共的数据值 封装在一个公共的对象里
var Common = new function () {
this.width = 20; //x方向的格子数 默认是20 可以根据后面的程序中需要改变
this.height = 20;
// speed 速度
this.speed = 250; //这个值越小 蛇跑的越快
this.workThread = null;
}
// 对蛇的行走方向进行封装
var Direction = new function () {
// 左键
this.LEFT = 37;
// 上键
this.UP = 38;
// 右键
this.RIGHT = 39;
// 下键
this.DOWN = 40;
}
// 把位置封装为一个构造函数
var Position = function (x, y) {
this.X = 0;
this.Y = 0;
if (arguments.length >= 1) this.X = x;
if (arguments.length >= 2) this.Y = y;
}
// 食物的构造函数
function Food() {
// 食物的位置
this.pos = new Position(); //初始化 食物的位置 在0.0; 在后面的程序中要实现位置是随机的
// 下面的是真正的实现创造食物,创建的过程中必须要考虑三个限制
// 食物的位置是随机的
// 食物的位置不能出界
// 食物的位置不能在蛇的身上
this.Create = function (snakePos) { //蛇的身体占据的位置参数的形式传进来
// 创建食物的第一个步骤 消除上一个食物 消除上一个食物的背景颜色
document.getElementById('box_' + this.pos.X + '' + this.pos.Y).className = '';
var x = 0;
var y = 0;
var flag = false;
// 生成的食物不能在蛇的身上出现
do {
// 搞两个随机数坐标值
x = Math.round(Math.random() * (Common.width - 1));
y = Math.round(Math.random() * (Common.height - 1));
// 把上面生成的随机数排除出蛇的身体
if (snakePos instanceof Array) {
for (var i = 0; i < snakePos.length; i++) {
if (x == snakePos[i].X && y == snakePos[i].Y) {
flag = true;
break // 这里结束的是for循环
}
}
}
} while (flag);
// 最后跳出了do while 循环得到的x y值就一定不是蛇身上的位置 坐标 也是随机的 也是不出界的
this.pos = new Position(x, y);
document.getElementById('box' + x + '' + y).className = 'food';
}
}
// 定义蛇的构造函数
function Snake() {
// 判断蛇动的过程中 还是刚刚动完
this.isDone = false;
// 默认蛇移动方向是右边
this.dir = Direction.RIGHT;
// 默认蛇初始的情况 身体长度为1个格子 位置(0,0)
this.pos = new Array(new Position());
// 实现蛇的移动
this.Move = function () {
// 第一步擦屁股
document.getElementById('box' + this.pos[0].X + '_' + this.pos[0].Y).className = '';
// 第二步 除了蛇头野外 每一个蛇的身体部分 向前蠕动一步
for (var i = 0; i < this.pos.length - 1; i++) {
console.log(this.pos);
this.pos[i].X = this.pos[i + 1].X;
this.pos[i].Y = this.pos[i + 1].Y;
}
var head = this.pos[this.pos.length - 1]
// 第三步重新给蛇整一个头
switch (this.dir) {
case Direction.LEFT:
head.X--;
break;
case Direction.RIGHT:
head.X++;
break;
case Direction.UP:
head.Y--;
break;
case Direction.DOWN:
head.Y++;
break;
}
this.pos[this.pos.length - 1] = head;
// 画蛇 如果蛇在上一步的移动中死掉了 就没有画的必要了
// 在画蛇之前 判断蛇死没死
// 1.蛇跑出界 2.咬到自己
for (var i = 0; i < this.pos.length; i++) {
var idExits = false; //蛇有没有 有没有咬到自己的标记 true 表示咬到了
for (var j = i + 1; j < this.pos.length; j++) {
if (this.pos[i].X == this.pos[j].X && this.pos[i].Y == this.pos[j].Y) {
idExits = true;
break;
}
}
if (idExits) {
// game over 蛇咬到自己 游戏结束
this.Over();
break;
}
// 再循环中 游戏没有结束 证明蛇没有咬到自己
// 继续判断 蛇有没有跑出界
var std = document.getElementById('box_' + this.pos[i].X + '_' + this.pos[i].Y);
if (std) {
// 表示蛇没有出界
// 画出蛇的身体
std.className = "snake";
} else {
// 蛇出界了
this.Over();
break
}
}
this.isDone = true;
}
// 此方法表示游戏结束
this.Over = function () {
clearInterval(Common.workThread);
alert('游戏结束')
}
this.isDone = true;
// 设置蛇新的方向
this.setDir = function (dir) {
switch (dir) {
case Direction.UP:
if (this.isDone && this.dir != Direction.DOWN) {
this.dir = Direction.UP;
this.isDone = false;
}
break;
case Direction.DOWN:
if (this.isDone && this.dir != Direction.UP) {
this.dir = Direction.DOWN;
this.isDone = false;
}
break;
case Direction.LEFT:
if (this.isDone && this.dir != Direction.RIGHT) {
this.dir = Direction.LEFT;
this.isDone = false;
}
break;
case Direction.RIGHT:
if (this.isDone && this.dir != Direction.LEFT) {
this.dir = Direction.RIGHT;
this.isDone = false;
}
break;
}
}
this.Eat = function (food) {
var head = this.pos[this.pos.length - 1];
var isEat = false; //false 表示蛇没得吃 true 表示 蛇有的吃
switch (this.dir) {
case Direction.UP:
console.log(head.X);
console.log(food.pos);
if (head.X == food.pos.X && head.Y == food.pos.Y + 1) {
// console.log(000);
isEat = true;
}
break;
case Direction.RIGHT:
if (head.X == food.pos.X - 1 && head.Y == food.pos.Y) {
// console.log(000);
isEat = true;
console.log(true);
}
break;
case Direction.DOWN:
if (head.X == food.pos.X && head.Y == food.pos.Y - 1) {
// console.log(000);
isEat = true;
console.log(true);
}
break;
case Direction.LEFT:
if (head.X - 1 == food.pos.X && head.Y == food.pos.Y) {
// console.log(000);
isEat = true;
console.log(true);
}
break;
}
if (isEat) {
// 实现吃的动作
// console.log(0);
this.pos[this.pos.length] = new Position(food.pos.X, food.pos.Y)
food.Create(this.pos)
}
}
}
function init() {
var html = [];
html.push("");
for (var y = 0; y < Common.height; y++) {
html.push('')
for (var x = 0; x < Common.width; x++) {
html.push('<td id=box_' + x + '_' + y + '> ');
}
html.push('')
}
html.push('
var tableStr = html.join('')
var panel = document.getElementById('panel');
panel.innerHTML = tableStr
}
// window.onload 函数在页面以及页面资源刚刚加载完成后立即执行的函数体
window.onload = function () {
// addEventListener() 方法用于向指定元素添加事件句柄。
// document.addEventListener('keydown', function (ev) {
// var evt = window.event || ev;
// })
// 初始化格子
init();
document.getElementById('btnSart').onclick = function () {
var snakePos = [new Position(0, 0)];
var food = new Food();
food.Create(snakePos);
var snake = new Snake();
Common.workThread = setInterval(function () {
snake.Eat(food);
snake.Move();
document.addEventListener('keydown', function (evt) {
var evnt = window.event || evt;
snake.setDir(evnt.keyCode);
}, false)
}, Common.speed)
}
document.getElementById('selSize').onchange = function () {
Common.width = this.value;
Common.height = this.value;
init()
}
document.getElementById('selSpeed').onchange = function () {
Common.speed = this.value;
init()
}
}`
全部代码就这些了,写完就能完成贪吃蛇游戏了,另外,如果想研究更多的小游戏源码,可以去源码之家(https://www.mycodes.net)看看,里面不但有很多小游戏源码,还有很多的工具软件和网站模板,个人来讲,这个网站还是不错的,感兴趣的小伙伴可以去转一转。