网页小游戏之贪吃蛇

702 阅读2分钟

我正在参加 码上掘金体验活动,详情:show出你的创意代码块

前言

今天给大家分享一个网页小游戏贪吃蛇,相当经典的一款童年游戏,从零开始,构建一个完整的游戏应用,接下来开始吧。

代码

正文

1、画图

首先我们做的是一个游戏,要知道他具体包含什么,然后再逐个的列出来,最后在使用html代码组装起来。我大概设计了一下页面,具体包括得分框、贪吃蛇身体、贪吃蛇头部、要吃掉的道具、各个控制开始暂停的按钮以及控制上下左右的按键。

1.1 把整个布局画出来

html代码如下

<div class="content">
  <div class="left-box">
  <div class="score">
    得分:
    <span id="score">
            0
    </span>
</div>

<div id="gameBox"class="gameBox">
    <div class="bg-img-box">
        <div id="head"class="head snake">
            <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fis5.mzstatic.com%2Fimage%2Fthumb%2FPurple122%2Fv4%2F34%2F95%2F80%2F34958089-1d33-a766-84f8-f060a85728ca%2Fsource%2F1024x1024bb.jpeg&refer=http%3A%2F%2Fis5.mzstatic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652539374&t=8fcd0bcd14b49c9a6bf9e45e3b1efc95">
        </div>
    </div>
</div>
</div>

再加css 的修饰,得到效果如下:

image.png

1.2把初始值的身体放上去

上面我们把贪吃蛇的头部已经放出来了,那么我们要在它的后面增加初始长度身体,我们设置了25px的身体,后面将会用到这个值。因为身体都是动态的,因为要吃了道具就会增加身体长度,所以我们使用js代码进行增加身体,方法如下:

function addBody(x, y, type) {
    type = type || " snakeBody";
    var html = "<div class='" + type + " snake'></div>";
    var $snakeBody = $(html);
    $snakeBody.css("left", x + "px");
    $snakeBody.css("top", y + "px");
    $gameBox.append($snakeBody);
    if(type != "egg") {
            bodyArry.push($snakeBody);
    } else {
            $egg = $snakeBody;
    }
}

我们设置了addBody方法,进行身体及道具(我这里叫它蛋蛋)的添加,原理就是在游戏页面容器进行传入x/y坐标,添加一个身体或者蛋。我们开始的时候先加两个身体的长度,这两个坐标需要跟头部连在一起代码及效果图如下:

addBody(180, 200);
addBody(160, 200);

image.png

2、添加随机道具

贪吃蛇游戏就是要在图上随机显示一个道具,然后操作贪吃蛇去吃它进而增加身体长度,所以我们要用js代码进行随机生成渲染,代码如下:

    function addEgg() {
        eggX = Math.round(Math.random() * gameGround.x / 25) * step;
        eggY = Math.round(Math.random() * gameGround.y / 25) * step;
        addBody(eggX, eggY, "egg");
    }

以上代码我们设置了一个addEgg的方法,来对随机道具的生成,就是整个图的高度和宽度除25(这个是之前说身体的宽度),再成step(这个变量是每操作一步走的宽度),这样就得到了道具的随机坐标,然后使用之前的addBody进行增加在游戏界面上,就完成了蛋蛋的添加,效果如下:

image.png

3、操作贪吃蛇

3.1设置移动函数

游戏就是需要人为的操作,我们要让它动起来就是需要按钮或者按键进行整条贪吃蛇的移动。 首先我们使用先定义移动的方法,代码如下:

function move(key) {
    if(key == 37) {
            typeY = 0; //左
            typeX = -1;
    } else if(key == 38) { //上
            typeX = 0;
            typeY = -1;
    } else if(key == 39) {
            typeY = 0; //右
            typeX = 1;
    } else if(key == 40) { //下
            typeY = 1;
            typeX = 0;
    } else if(key == 32) { //下
            clearInterval(timer);
    } else if(key == 13) { //下
            snakeRun();
    } else {
            if(key) {
                    return;
            }
    }
    var oldHeadX = +$head.css('left').split("px")[0];
    var oldHeadY = +$head.css('top').split("px")[0];
    var moveX = typeX * step;
    var moveY = typeY * step;
    $head.css("left", "+=" + moveX + "px");
    $head.css("top", "+=" + moveY + "px");
    bodyArry[bodyArry.length - 1].css("left", oldHeadX + "px");
    bodyArry[bodyArry.length - 1].css("top", oldHeadY + "px");
    if(bodyArry.length > 1) {
            bodyArry.unshift(bodyArry[bodyArry.length - 1]);
            bodyArry.pop();
    }

    if(gameOver()) {
            myAlert();
    }
    eatEgg();
    gameOver();
}

以上代码定义了move方法,用来移动贪吃蛇以及其他逻辑的判断。具体思路是依据每个按键的值来判断是向哪边移动,然后没执行一次整体的移动就乘以step(每一步移动的距离),然后拿到距离再让整个贪吃蛇各个部分一起移动。

3.2设置其他方法

上面代码我们看到了调用了gameOver、eatEgg、myAlert等方法,下面我来解释一下他们的作用及具体代码。 gameOver方法用判断游戏是否结束,我设计了只要蛇头撞到了游戏页面边缘或者撞到了自己的身体,就让游戏结束,代码如下:

function gameOver() {
    //撞墙
    var headX = +$head.css("left").split("px")[0];
    var headY = +$head.css("top").split("px")[0];
    if(headX > gameGround.x - 21 || headX < 0 || headY > gameGround.y - 30 || headY < 0) {
        return true;
    }
    //撞自己
    for(var i = 0; i < bodyArry.length; i++) {
        if(headX == bodyArry[i].css("left").split("px")[0] && headY == bodyArry[i].css("top").split("px")[0]) {
            return true;
        }
    };
    return false;
}

要洗结束了,我们就要有所提升,所以写了个alert方法,代码如下;

function myAlert() {
    bgm1.pause();
    bgm2.pause();
    bgm3.pause();
    $("#myAlert-bk").show();
    $("#myAlert").show();
    clearInterval(timer);
    overAudio.play();
}

接下来就是eatEgg方法,吃到道具之后就让身体增加一个长度,代码如下:

function eatEgg() {
    if($head.css("left") == $egg.css("left") &&
        $head.css("top") == $egg.css("top")) {
        eatAudio.play();
        $egg.removeClass("egg").addClass("snakeBody");
        bodyArry.push($egg);
        addEgg();
        $("#score").html(++score);
        if(score == 3) {
            clearInterval(timer);
            colorRun();
            snakeRun(150);
            bgm1.pause();
            bgm2.play();
        } else if(score == 8) {
            clearInterval(timer);
            clearInterval(colorTimer);
            $(".score").css("background-color", "#F5D994");
            snakeRun(300);
            bgm2.pause();
            bgm3.play();
        } else if(score == 12) {
            clearInterval(timer);
            clearInterval(colorTimer);
            $(".score").css("background-color", "#C8C6CA");
            $(".gameBox").css("background-color", "#AFACB1");
            snakeRun(100);
            bgm3.pause();
            bgm2.play();
        }
    }
}

3.3 自己动

看了上面的代码,会发现我有很大清理定时器的东西,是因为我用定时器让贪吃蛇自己动起来,如果我们不改变方向,它就会往一个方向移动,直到游戏结束,代码如下:

 function snakeRun(speed) {
    timer = setInterval(function() {
        move();
    }, speed);
}

3.4其他乐趣体验

看了3.2的代码我们还发现我设计了其他的方法,判断分数然后进行不一样的界面及声音的操作,我用了不同的bgm(都是拿了超级玛丽的声音)和得分表的颜色变化,来表示得分情况及紧张感,同时进行了贪吃蛇的加速增加难度。(具体可以体验一下游戏,或者看下具体代码。)

3.5手机操作

为了让手机可以直接操作,我设计点击游戏界面中间点到上下左右的地方,进行移动。具体代码如下:

$("#gameBox").bind("touchend", function(evt) {
    var touch = evt.originalEvent.changedTouches[0];
    var snake = {
        x: $("#head").offset().left + step / 2,
        y: $("#head").offset().top + step / 2
    }
    var x = touch.clientX - snake.x;
    var y = touch.clientY - snake.y;
    if(Math.abs(y) > Math.abs(x)) {
        //上下移动
        if(y > 0) {
                move(40);
        } else {
                move(38);
        }
    } else {
        //左右移动
        if(x > 0) {
                move(39);
        } else {
                move(37);
        }
    }
})

4、最后效果

1651322655250_.gif

结语

本次分享了一个贪吃蛇小游戏的制作,其实主要是整个游戏的逻辑理解,然后和前端知识进行整合。