摘要:它是基于開始且隨時間變化的一個因子。最后調用函數并且將本次的時間保存下來。這個現象的出現主要是因為在函數中將和寫死了,所以一個最簡單的方法就是在中傳入參數然后在調用的時候傳入捕獲時位置的參數最后在開始游戲的時候將放在最中間即可大功告成
先上效果圖 開始之前的準備
game.html
js/ 里面創建game.js
images/ 里面放三張圖片,一張背景圖片(background.png),一張英雄圖片(hero.png),一張怪物的圖片(monster.png)
在game.html里面寫上以下幾行簡單的HTML代碼:
Simple Canvas Game
我們在game.html引入了game.js文件,沒錯,剩下的所有工作都是在操作game.js,為其添加游戲的js代碼。
創建畫布在game.js 里面,我們首先需要為游戲的舞臺創建一張畫布(canvas):
var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas);
這里通過js來創建了一個元素并設置canvas的寬和高,最后將其添加到
標簽后。var ctx = canvas.getContext("2d");中的ctx變量是我們后面會用到的,具體的canvas用法查看這里的鏈接:https://developer.mozilla.org/en/canvas_tutorial
準備圖片游戲需要加載我們之前存放在images文件夾下面的三張圖片:
// Background image var bgReady = false; var bgImage = new Image(); bgImage.onload = function () { bgReady = true; }; bgImage.src = "images/background.png"; // Hero image var heroReady = false; var heroImage = new Image(); heroImage.onload = function () { heroReady = true; }; heroImage.src = "images/hero.png"; // Monster image var monsterReady = false; var monsterImage = new Image(); monsterImage.onload = function () { monsterReady = true; }; monsterImage.src = "images/monster.png";
以上三張圖片都是通過創建簡單的圖片對象來實現加載的,類似bgReady的三個變量用來標識圖片是否已經加載完成,如果如果在圖片加載未完成情況下進行繪制是會報錯的。如果你不太確定new Image()到底是個什么東西,你可以在bgImage.src = "images/background.png";之后使用console.log(bgImage);來查看,你看到的將是類似:
游戲對象
我們需要定義一些對象,以便我們在后面會用到:
var hero = { speed: 256 // movement in pixels per second }; var monster = {}; var monstersCaught = 0;
既然是英雄抓獲怪物,我們得要有一個英雄和怪物的對象。而英雄有一個speed屬性用來控制他每秒移動多少像素。怪物游戲過程中不會移動,所以暫時不用設置屬性。monstersCaught則用來存儲怪物被捉住的次數,初始值當然為0了。
處理用戶的輸入游戲是給人玩的,那么我們怎么知道用戶到底在這個過程中干了什么?按了鍵盤?點了鼠標?這些都是用戶在玩游戲的時候的輸入,所以我們一旦捕獲到這些輸入,我們就可以根據游戲的邏輯對用戶的輸入進行處理了:
// Handle keyboard controls var keysDown = {}; addEventListener("keydown", function (e) { keysDown[e.keyCode] = true; }, false); addEventListener("keyup", function (e) { delete keysDown[e.keyCode]; }, false);
這里我們只是監聽兩個用戶的輸入:
keydown
keyup
然后我們將用戶的輸入先保存起來,并沒有立即響應。為此,我們用keysDown這個對象來保存用戶按下的鍵值(keyCode),如果按下的鍵值在這個對象里,那么我們就做相應處理。
開始一輪游戲在前端開發中,一般是用戶觸發了點擊事件然后才去執行動畫或發起異步請求之類的
游戲在結束的時候,我們需要開始新的一輪游戲,所以在game.js添加reset函數
// Reset the game when the player catches a monster var reset = function () { hero.x = canvas.width / 2; hero.y = canvas.height / 2; // Throw the monster somewhere on the screen randomly monster.x = 32 + (Math.random() * (canvas.width - 64)); monster.y = 32 + (Math.random() * (canvas.height - 64)); };
reset()函數用于開始新一輪和游戲,在這個方法里我們將英雄放回畫布中心同時將怪物放到一個隨機的地方。
更新對象在游戲的過程中,不管是用戶在玩(有正確輸入的狀態)還是游戲結束,我們都是需要及時更新游戲的對象:
var update = function (modifier) { if (38 in keysDown) { // Player holding up hero.y -= hero.speed * modifier; } if (40 in keysDown) { // Player holding down hero.y += hero.speed * modifier; } if (37 in keysDown) { // Player holding left hero.x -= hero.speed * modifier; } if (39 in keysDown) { // Player holding right hero.x += hero.speed * modifier; } // Are they touching? if ( hero.x <= (monster.x + 32) && monster.x <= (hero.x + 32) && hero.y <= (monster.y + 32) && monster.y <= (hero.y + 32) ) { ++monstersCaught; reset(); } };
update函數負責更新游戲的各個對象,會被規律地重復調用。首先它負責檢查用戶當前按住的是中方向鍵,然后將英雄往相應方向移動。
有點費腦力的或許是這個傳入的modifier 變量。你可以后面將要實現的main 方法里看到它的來源,但這里還是有必要詳細解釋一下。它是基于1開始且隨時間變化的一個因子。例如1秒過去了,它的值就是1,英雄的速度將會乘以1,也就是每秒移動256像素;如果半秒鐘則它的值為0.5,英雄的速度就乘以0.5也就是說這半秒內英雄以正常速度一半的速度移動。理論上說因為這個update函數被調用的非常快且頻繁,所以modifier的值會很小,但有了這一因子后,不管我們的代碼跑得快慢,都能夠保證英雄的移動速度是恒定的。
這里需要說明一下下面的判斷怪物和英雄是什么根據:
if ( hero.x <= (monster.x + 31) && monster.x <= (hero.x + 31) && hero.y <= (monster.y + 32) && monster.y <= (hero.y + 32) )
上面的31,32是由hero和monster圖片的大小決定的,我們的hero圖片是32x32,monster圖片是30x32,所以根據坐標的位于圖片中心的法制,就可以得到上面的判斷條件。
現在英雄的移動已經是基于用戶的輸入(按下上,下,左,右鍵)了,接下來該檢查移動過程中所觸發的事件了,也就是英雄與怪物相遇。這就是本游戲的勝利點,monstersCaught +1然后重新開始新一輪。
渲染物體之前寫的代碼都是在準備前期工作和處理一些游戲的狀態等,下面將進入正題:我們需要將所有的東西畫出來
// Draw everything var render = function () { if (bgReady) { ctx.drawImage(bgImage, 0, 0); } if (heroReady) { ctx.drawImage(heroImage, hero.x, hero.y); } if (monsterReady) { ctx.drawImage(monsterImage, monster.x, monster.y); } // Score ctx.fillStyle = "rgb(250, 250, 250)"; ctx.font = "24px Helvetica"; ctx.textAlign = "left"; ctx.textBaseline = "top"; ctx.fillText("Goblins caught: " + monstersCaught, 32, 32); };
這里的ctx就是最前面我們創建的變量。然后利用canvas的drawImage()首先當然是把背景圖畫出來。然后如法炮制將英雄和怪物也畫出來。這個過程中的順序是有講究的,因為后畫的物體會覆蓋之前的物體。
這之后我們改變了一下Canvas的繪圖上下文的樣式并調用fillText來繪制文字,也就是記分板那一部分。本游戲沒有其他復雜的動畫效果和打斗場面,繪制部分大功告成
主循環函數我們實現了將畫面畫出來以后,我們緊接著需要實現的就是游戲的循環結構,于是將它放在main函數里:
// The main game loop var main = function () { var now = Date.now(); var delta = now - then; //console.log(delta); update(delta / 1000); render(); then = now; // Request to do this again ASAP requestAnimationFrame(main); };
上面的主函數控制了整個游戲的流程。先是拿到當前的時間用來計算時間差(距離上次主函數被調用時過了多少毫秒)。得到modifier后除以1000(也就是1秒中的毫秒數)再傳入update函數。最后調用render 函數并且將本次的時間保存下來。
設置requestAnimationFrame()在上面的main函數中,我們通過requestAnimationFrame()調用了main函數,所以我們需要聲明:
var w = window; requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
這里這么多的||,不為別的,就是考慮到瀏覽器兼容問題而已。
最后啟動游戲萬事具備,只欠東風。到此,所有的游戲代碼基本就寫完了,我們現在需要做的就是調用相應的函數來啟動游戲:
// Let"s play this game! var then = Date.now(); reset(); main();
到這里代碼就寫完了。先是設置一個初始的時間變量then用于首先運行main函數使用。然后調用 reset 函數來開始新一輪游戲(如果你還記得的話,這個函數的作用是將英雄放到畫面中間同時將怪物放到隨機的地方以方便英雄去捉它)
用瀏覽器打開game.html,開始玩游戲吧!
進一步思考在玩游戲的過程中,你會發現每一次hero捕獲到monster,hero就回到了canvas畫布的正中間。那么現在需要做的就是,將hero在捕捉到monster的時候讓hero就停留在捕獲的位置,不再是回到canvas正中間。
這個現象的出現主要是因為在reset函數中將hero.x和hero.y寫死了,所以一個最簡單的方法就是在reset中傳入參數:
var reset = function (x,y) { hero.x = x; hero.y = x; };
然后在update調用reset的時候傳入捕獲時位置的參數:
var update = function (modifier) { //...other codes ++monstersCaught; reset(heor.x,hero.y); };
最后在開始游戲的時候將hero放在canvas最中間即可:
var then = Date.now(); reset(canvas.width / 2,canvas.height / 2); main();
大功告成!
Hapyy Hacking
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85822.html
摘要:推薦一些好用的游戲引擎開發庫引言如果你是一個游戲開發者,并且正在尋找一個可以與和無縫工作的游戲引擎。是另一個容易使用,適用于移動設備和桌面的游戲引擎。是一個開源的用來創建使用高級技術和服務的游戲引擎。用于建立游戲和繪圖引擎。 推薦一些好用的 HTML5 & JavaScript 游戲引擎開發庫 0. 引言 如果你是一個游戲開發者,并且正在尋找一個可以與 JavaScript 和 HT...
摘要:推薦一些好用的游戲引擎開發庫引言如果你是一個游戲開發者,并且正在尋找一個可以與和無縫工作的游戲引擎。是另一個容易使用,適用于移動設備和桌面的游戲引擎。是一個開源的用來創建使用高級技術和服務的游戲引擎。用于建立游戲和繪圖引擎。 推薦一些好用的 HTML5 & JavaScript 游戲引擎開發庫 0. 引言 如果你是一個游戲開發者,并且正在尋找一個可以與 JavaScript 和 HT...
閱讀 1646·2023-04-26 02:11
閱讀 2990·2023-04-25 16:18
閱讀 3720·2021-09-06 15:00
閱讀 2636·2019-08-30 15:55
閱讀 1942·2019-08-30 13:20
閱讀 2058·2019-08-26 18:36
閱讀 3131·2019-08-26 11:40
閱讀 2549·2019-08-26 10:11