寫在前面
這是一個類貪喫蛇的小遊戲,因爲最近又翻到了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布爾值的語句。
如果大家獲取源碼的話,請點擊這裏:遊戲源碼地址
如果有什麼問題還要深究的話,歡迎大家提問。