手起刀落-一起来写经典的贪吃蛇游戏

回味

小时候玩的经典贪吃蛇游戏我们印象仍然深刻,谋划了几天,小时候喜欢玩的游戏,长大了终于有能力把他做出来(从来都没有通关过,不知道自己写的程序,是不是能通关了...),好了,闲话不多谈,先来看一下效果吧!!

功能和小时候玩的贪吃蛇一样,

1、选择速度 
    slow
    normal
    fast
2、选择是否有墙作为障碍物
    on
    off

看完效果就先附上地址喽:大山深处修炼的小龙虾,欢迎fork.

结构分解

如果构建一个简单的经典贪吃蛇游戏呢?我们根据面板可以分解出如下结构:

因为其他面板比较简单,我们重点来看一下游戏面板

游戏面板

游戏面板是核心,在游戏面板中,我们来分解一下游戏面板我们需要的因素:

场景、snake、食物

首先我们需要一个游戏场景、snake、食物这些基础设施 这里使用canvas作为我们的整个游戏的场景:

<canvas class="wrap" id="snake" width="400" height="400" tabindex="1"></canvas>

需要一只snake,后面初始化他的位置

var activeDot = function (x, y) {
    ctx.fillStyle = "#eee";
    ctx.fillRect(x * 10, y * 10, 10, 10);
}

需要食物作为对象(关于食物我们需要定义一些规则,如食物的产生)

var food = {
    x: 0,
    y: 0
};

规则

规则是游戏的核心

1、关于游戏的规则

snake的方向控制:(使用键盘的上下左右键控制蛇的方向)

 // changer dir
    var changeDir = function (key) {
        if (key == 38 && snake_dir != 2) {
            snake_next_dir = 0;
        } else {
            if (key == 39 && snake_dir != 3) {
                snake_next_dir = 1;
            } else {
                if (key == 40 && snake_dir != 0) {
                    snake_next_dir = 2;
                } else {
                    if (key == 37 && snake_dir != 1) {
                        snake_next_dir = 3;
                    }
                }
            }
        }
    }

关于食物,如果食物被吃掉,我们就需要产生新的食物

  // add food
    var addFood = function () {
        food.x = Math.floor(Math.random() * ((canvas.width / 10) - 1));
        food.y = Math.floor(Math.random() * ((canvas.height / 10) - 1));
        for (var i = 0; i < snake.length; i++) {
            // 如果食物被吃就增加食物
            if (checkBlock(food.x, food.y, snake[i].x, snake[i].y)) {
                addFood();
            }
        }
    }

    var checkBlock = function (x, y, _x, _y) {
        return (x == _x && y == _y) ? true : false;
    }

接下来是核心的函数,根据选择的速度和是否有墙体作为障碍物的设置,让蛇运动起来,并且实现

1、根据选择slow、norma、fast决定蛇运动速度速度 2、如果蛇碰到自己==自杀,游戏结束 3、有墙模式碰到墙体,游戏结束 4、无墙模式蛇穿过墙体,从另一侧出现 5、使蛇碰到食物就加入自身身体的一部分,执行增加食物函数

 var mainLoop = function () {
        var _x = snake[0].x;
        var _y = snake[0].y;
        snake_dir = snake_next_dir;
        //  0 — up  1 — right   2 — down  3 — left
        switch (snake_dir) {
            case 0:
                _y--;
                break;
            case 1:
                _x++;
                break;
            case 2:
                _y++;
                break;
            case 3:
                _x--;
                break;
        }
        snake.pop();
        snake.unshift({
            x: _x,
            y: _y
        })

        // --wall
        if (wall == 1) {
            if (snake[0].x < 0 || snake[0].x == canvas.width / 10 || snake[0].y < 0 || snake[0].y == canvas.height / 10) {
                showScreen(3);
                return;
            }
        } else {
            //  off 无墙
            for (var i = 0, x = snake.length; i < x; i++) {
                if (snake[i].x < 0) {
                    snake[i].x = snake[i].x + (canvas.width / 10);
                }
                if (snake[i].x == canvas.width / 10) {
                    snake[i].x = snake[i].x - (canvas.width / 10);
                }
                if (snake[i].y < 0) {
                    snake[i].y = snake[i].y + (canvas.height / 10);
                }
                if (snake[i].y == canvas.height / 10) {
                    snake[i].y = snake[i].y - (canvas.height / 10);
                }
            }
        }

        //  Autophagy death
        for (var i = 1; i < snake.length; i++) {
            if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
                showScreen(3);
                return;
            }
        }

        // Eat food
        if (checkBlock(snake[0].x, snake[0].y, food.x, food.y)) {
            snake[snake.length] = {
                x: snake[0].x,
                y: snake[0].y
            };
            score += 1;
            altScore(score);
            addFood();
            activeDot(food.x, food.y);
        }

        // --------------------

        ctx.beginPath();
        ctx.fillStyle = "#111";
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // --------------------

        for (var i = 0; i < snake.length; i++) {
            activeDot(snake[i].x, snake[i].y);
        }

        // --------------------

        activeDot(food.x, food.y);

        setTimeout(mainLoop, snake_speed);
    }

ok以上展示出一些核心部分,构建出一个舞台中一只小蛇的故事.

小时候爸妈手机里有一款小游戏叫贪吃蛇。就是一条小蛇,不停地在屏幕上游走,吃各个方向出现的蛋,越吃越长。只要蛇头碰到屏幕四周,或者碰到自己的身子,小蛇就立即毙命。方寸的舞台间,亦有无限精彩;PS:到现在也没有通关过..现在不知道能不能通关了...

最后在附上次源码,欢迎fork交流:okaychen... 因为自己测试用的服务器被占用,目前只有做的效果图供大家参考喽. 掘金地址:手起刀落-一起来写经典的贪吃蛇游戏

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏知晓程序

周末福利!这份我私藏已久的「养眼」大礼包,今天忍痛送给你

但不管你是看天气看新闻,还是刷微博,看到的第一眼总是自己的手机壁纸。由此看来,挑一张自己心水的照片做壁纸,是多么的重要。

873
来自专栏华章科技

用 Python 20 秒画完小猪佩奇“社会人”!附效果视频+完整代码

导读:今年社交平台上最火的带货女王是谁?范冰冰?杨幂?Angelababy?不,是猪猪女孩小猪佩奇。

735
来自专栏IT派

7月Python最佳开源项目Top 10

【导读】七月就要结束了,小编为大家整理了本月 Python 最受欢迎的十大开源项目。他山之石,可以攻玉,爱好Python的朋友们一起学习Github上的优秀项目...

553
来自专栏大数据文摘

小白学数据之常用Python库“小抄表”(附小抄表PDF下载)

1353
来自专栏人工智能头条

七夕前,我用AI做了个撩妹工具!程序员,只能帮你到这了...

我用Python爬遍网上所有表白情话,得出以下出镜率最高的,然后用AI做了一个智能问答,根据你的选择来帮你梳理最适合你性格的情况!

522
来自专栏Python疯子

Python强大的pyecharts绘画优美图形<四>

支持保存做种格式 对象.render(path='snapshot.html') 对象.render(path='snapshot.png') 对象.re...

541
来自专栏数据小魔方

墨迹人物图片合成!

今天给大家分享利用PPT合成墨迹人物的技巧! ▽ 利用墨迹素材与人物图像合成墨迹人物 这种风格的图片既充满古典韵味 由不乏现代气息 通常网上的做法都是利用PS或...

3056
来自专栏生信技能树

【直播】我的基因组51:画全基因范围内的染色体reads覆盖度图

前面我们已经详细讲解过如何根据窗口来统计每条染色体的每个片段的GC含量,还有平均测序深度,请大家自行前往前面查看脚本及实现方式!【直播】我的基因组47:测序深度...

3136
来自专栏九彩拼盘的叨叨叨

2016 新年计划

本文遵守创作共享CC BY-NC-SA 4.0协议 网络平台如需转载必须与本人联系确认。

742
来自专栏数据结构与算法

P1372 又是毕业季I

题目背景 “叮铃铃铃”,随着高考最后一科结考铃声的敲响,三年青春时光顿时凝固于此刻。毕业的欣喜怎敌那离别的不舍,憧憬着未来仍毋忘逝去的歌。1000多个日夜的欢笑...

3044

扫码关注云+社区