使用原生js编写贪吃蛇小游戏

贪吃蛇小游戏大家都不陌生,基本上都玩过,而使用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看看,里面不但有很多小游戏源码,还有很多的工具软件和网站模板,个人来讲,这个网站还是不错的,感兴趣的小伙伴可以去转一转。

posted @ 2021-07-22 11:14  我超凶的  阅读(520)  评论(0编辑  收藏  举报