手起刀落-一塊兒來寫經典的貪吃蛇遊戲

回味

小時候玩的經典貪吃蛇遊戲咱們印象仍然深入,謀劃了幾天,小時候喜歡玩的遊戲,長大了終於有能力把他作出來(歷來都沒有通關過,不知道本身寫的程序,是否是能通關了...),好了,閒話很少談,先來看一下效果吧!!javascript

效果圖

功能和小時候玩的貪吃蛇同樣,java

一、選擇速度 
    slow
    normal
    fast
二、選擇是否有牆做爲障礙物
    on
    off

看完效果就先附上地址嘍:Github,歡迎fork.git

結構分解

若是構建一個簡單的經典貪吃蛇遊戲呢?咱們根據面板能夠分解出以下結構:github

面板結構分解

由於其餘面板比較簡單,咱們重點來看一下游戲面板canvas

遊戲面板

遊戲面板是核心,在遊戲面板中,咱們來分解一下游戲面板咱們須要的因素:服務器

場景、snake、食物

首先咱們須要一個遊戲場景、snake、食物這些基礎設施
這裏使用canvas做爲咱們的整個遊戲的場景:dom

<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);
}

須要食物做爲對象(關於食物咱們須要定義一些規則,如食物的產生)oop

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

規則

規則是遊戲的核心post

一、關於遊戲的規則

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;
    }

接下來是核心的函數,根據選擇的速度和是否有牆體做爲障礙物的設置,讓蛇運動起來,而且實現

一、根據選擇slow、norma、fast決定蛇運動速度速度
二、若是蛇碰到本身==自殺,遊戲結束
三、有牆模式碰到牆體,遊戲結束
四、無牆模式蛇穿過牆體,從另外一側出現
五、使蛇碰到食物就加入自身身體的一部分,執行增長食物函數

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... 由於本身測試用的服務器被佔用,目前只有作的效果圖供你們參考嘍.
掘金地址:手起刀落-一塊兒來寫經典的貪吃蛇遊戲

相關文章
相關標籤/搜索