原生js+canvas實現類貪喫蛇的小遊戲

寫在前面

這是一個類貪喫蛇的小遊戲,因爲最近又翻到了canvas,想着寫一些東西來鞏固下,剛好就看到博主寫的demo,不過我在其基礎上進行了一定的規則限制,下面附上鍊接:博主原文

設計初衷

此次這個遊戲加入了
1、積分規則,
2、碰壁死亡規則,
3、調用requestAnimationFrame方法實現循環。
遊戲的截圖效果如下:
使用鍵盤的方向鍵來控制遊戲人物的移動
死亡效果截圖如下:
死亡截圖

設計步驟

1、在HTML文檔中創建canvas的節點,以便DOM操作。

代碼如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>使用canvas和js來實現一個小遊戲</title>
        <script type="text/javascript" src = "canvas.js"></script>
    </head>
    <body>
        <canvas id = "drawing" width = "512" height = "480" style="border: 1px solid lightblue;">
        </canvas>
    </body> 
</html>

2、獲取對canvas元素以及canvas上下文的引用。

var drawing = document.getElementById("drawing");
var context = drawing.getContext("2d");

3、將遊戲人物、怪物、背景圖加載進去

因爲圖片是異步加載的,所以我使用了onload加載函數,並且設置了標記量,以免圖片加載的過程中出現錯誤,顯示不了畫布上。

//在畫布上獲取對背景的引用
    var bgReady = false;  //布爾值用於確保何時可以正確的引用圖片
    var bgImage = new Image();
    bgImage.onload = function () //圖片的加載是異步加載
    {
        bgReady = true;
    };
    bgImage.src = "image/bg.png";
    //在畫布上獲取對英雄的引用
    var heroReady = false;
    var heroImage = new Image();
    heroImage.onload = function ()
    {
        heroReady = true;
    };
    heroImage.src = "image/hero.png";
    //在畫布上獲取對怪獸的引用
    var monsterReady = false;
    var monsterImage = new Image();
    monsterImage.onload = function ()
    {
        monsterReady = true;
    };
    monsterImage.src = "image/monster.png";

4、定義遊戲對象,定義分數變量

在這個遊戲裏面,怪物是靜止不動且隨機出現的,當鍵盤上控制人物移動時,需要一個速度,即:speed,創建對象來保存他們的變量。

//定義遊戲對象(英雄和怪獸的畫布座標)
    var hero = {
        speed : 256,
        x : 0,
        y : 0
    };
    var monster = {
        x : 0,
        y : 0
    };
    var score = 0;

5、當遊戲失敗後重置網頁或得分後怪物的位置隨機出現

在這個函數中使用了隨機數來確保怪物位置出現的隨機性,確保了遊戲的可玩性。

var reset = function ()
    {
        if(over == true)
        {
            hero.x = drawing.width/2;
            hero.y = drawing.height/2;
            over = false;
        }
        monster.x = 32 + Math.floor((Math.random() * (drawing.width - 64)));
        monster.y = 32 + Math.floor((Math.random() * (drawing.height - 64)));
    };

6、採用鍵盤事件的監聽,保持稍後存儲用戶輸入

這個部分我們旨在用addEventListener()方法、採用“keydown”、“keyup”來對鍵盤設置事件的監聽,以此來獲取用戶鍵盤的輸入。addEventListener()方法接受三個參數,即:
1)event,必選,注意: 不要使用 “on” 前綴。 例如,使用 “click” ,而不是使用 “onclick”。
2)必選。指定要事件觸發時執行的函數, 當事件對象會作爲第一個參數傳入函數。 事件對象的類型取決於特定的事件。
3) 可選。布爾值,指定事件是否在捕獲或冒泡階段執行。

var keyDown = {};
    addEventListener("keydown", function(e){
        keyDown[e.keyCode] = true;
    },false);

    addEventListener("keyup", function(e){
        delete keyDown[e.keyCode];
    },false);

7、遊戲的更新

在這部分的函數中,前四個if語句說明了,當四個方向鍵被按下的時候,遊戲人物會朝着相應的方向移動;第五個if語句用來判斷怪獸和遊戲人物是否相撞,相撞的話則得一分,因爲遊戲人物和怪獸都是32 * 32 像素的,所以判斷語句才這麼寫的。

//Dom操作實現英雄和怪獸碰撞加分
    var update = function (modifier)
    {
        if(38 in keyDown)
        {
            hero.y -= hero.speed * modifier;
        }
        if (40 in keyDown) 
        { 
            hero.y += hero.speed * modifier;
        }
        if (37 in keyDown) 
        { 
            hero.x -= hero.speed * modifier;
        }
        if (39 in keyDown) 
        { 
            hero.x += hero.speed * modifier;
        }

        if(
            hero.x <= (monster.x + 32) && 
            hero.y <= (monster.y + 32)  && 
            monster.x <= (hero.x + 32)  && 
            monster.y <= (hero.y + 32)  
          )
        {
            score = score + 1;
            reset();
        }
    };

8、繪製圖像

在這個部分中,我們就用到了之前的標誌量,使得可以確保圖片在加載時候可以正常的顯示在畫布中,因爲圖片是異步加載的;並且將得分情況寫在了左上角。

//繪製圖像(英雄、怪獸、背景、分數)
    var render = function ()
    {
        if(bgReady)
        {
             context.drawImage(bgImage,0,0);
        }
        if(heroReady)
        {
            context.drawImage(heroImage,hero.x,hero.y);
        }
        if(monsterReady)
        {
            context.drawImage(monsterImage,monster.x,monster.y);
        }
        context.fillStyle = "#fff";
        context.font = "24px Helvetica";
        context.textAlign = "left";
        context.textBaseline = "top";
        context.fillText("你的得分: " + score, 32,32);
    };

9、設置當英雄碰撞到畫布上的邊界時,遊戲結束或者重置遊戲

var over = false;
    var gameOver = function ()
    {
        if(
            hero.x <= 0 ||
            hero.x >= drawing.width ||
            hero.y <= 0 ||
            hero.y >=drawing.height
          )
        {
            over = true;
            score = 0;
            alert("很遺憾,你不小心結束了比賽!");
            reset();
        }
    };

Tips

1、圖片的加載方式是異步,必須使用onload加載函數才能夠正確的顯示
2、我們獲取canvas是通過getElementById獲取的,其所返回對象的寬和高就是我們所要獲取的canvas的寬和高。
3、在設置遊戲結束函數時,over必須是提前聲明的,且在reset中要有判斷over布爾值的語句。

如果大家獲取源碼的話,請點擊這裏:遊戲源碼地址

如果有什麼問題還要深究的話,歡迎大家提問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章