国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

用HTML5開(kāi)發(fā)一個(gè)小游戲

CompileYouth / 1743人閱讀

摘要:它是基于開(kāi)始且隨時(shí)間變化的一個(gè)因子。最后調(diào)用函數(shù)并且將本次的時(shí)間保存下來(lái)。這個(gè)現(xiàn)象的出現(xiàn)主要是因?yàn)樵诤瘮?shù)中將和寫死了,所以一個(gè)最簡(jiǎn)單的方法就是在中傳入?yún)?shù)然后在調(diào)用的時(shí)候傳入捕獲時(shí)位置的參數(shù)最后在開(kāi)始游戲的時(shí)候?qū)⒎旁谧钪虚g即可大功告成

先上效果圖

開(kāi)始之前的準(zhǔn)備

game.html

js/ 里面創(chuàng)建game.js

images/ 里面放三張圖片,一張背景圖片(background.png),一張英雄圖片(hero.png),一張怪物的圖片(monster.png)

game.html里面寫上以下幾行簡(jiǎn)單的HTML代碼:


Simple Canvas Game

我們?cè)?b>game.html引入了game.js文件,沒(méi)錯(cuò),剩下的所有工作都是在操作game.js,為其添加游戲的js代碼。

創(chuàng)建畫布

在game.js 里面,我們首先需要為游戲的舞臺(tái)創(chuàng)建一張畫布(canvas):

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);

這里通過(guò)js來(lái)創(chuàng)建了一個(gè)元素并設(shè)置canvas的寬和高,最后將其添加到標(biāo)簽后。var ctx = canvas.getContext("2d");中的ctx變量是我們后面會(huì)用到的,具體的canvas用法查看這里的鏈接:

https://developer.mozilla.org/en/canvas_tutorial

準(zhǔn)備圖片

游戲需要加載我們之前存放在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";

以上三張圖片都是通過(guò)創(chuàng)建簡(jiǎn)單的圖片對(duì)象來(lái)實(shí)現(xiàn)加載的,類似bgReady的三個(gè)變量用來(lái)標(biāo)識(shí)圖片是否已經(jīng)加載完成,如果如果在圖片加載未完成情況下進(jìn)行繪制是會(huì)報(bào)錯(cuò)的。如果你不太確定new Image()到底是個(gè)什么東西,你可以在bgImage.src = "images/background.png";之后使用console.log(bgImage);來(lái)查看,你看到的將是類似:



游戲?qū)ο?/b>

我們需要定義一些對(duì)象,以便我們?cè)诤竺鏁?huì)用到:

var hero = {
    speed: 256 // movement in pixels per second
};
var monster = {};
var monstersCaught = 0;

既然是英雄抓獲怪物,我們得要有一個(gè)英雄怪物的對(duì)象。而英雄有一個(gè)speed屬性用來(lái)控制他每秒移動(dòng)多少像素。怪物游戲過(guò)程中不會(huì)移動(dòng),所以暫時(shí)不用設(shè)置屬性。monstersCaught則用來(lái)存儲(chǔ)怪物被捉住的次數(shù),初始值當(dāng)然為0了。

處理用戶的輸入

游戲是給人玩的,那么我們?cè)趺粗烙脩舻降自谶@個(gè)過(guò)程中干了什么?按了鍵盤?點(diǎn)了鼠標(biāo)?這些都是用戶在玩游戲的時(shí)候的輸入,所以我們一旦捕獲到這些輸入,我們就可以根據(jù)游戲的邏輯對(duì)用戶的輸入進(jìn)行處理了:

// Handle keyboard controls
var keysDown = {};

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

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

這里我們只是監(jiān)聽(tīng)兩個(gè)用戶的輸入:

keydown

keyup

然后我們將用戶的輸入先保存起來(lái),并沒(méi)有立即響應(yīng)。為此,我們用keysDown這個(gè)對(duì)象來(lái)保存用戶按下的鍵值(keyCode),如果按下的鍵值在這個(gè)對(duì)象里,那么我們就做相應(yīng)處理。

  

在前端開(kāi)發(fā)中,一般是用戶觸發(fā)了點(diǎn)擊事件然后才去執(zhí)行動(dòng)畫或發(fā)起異步請(qǐng)求之類的

開(kāi)始一輪游戲

游戲在結(jié)束的時(shí)候,我們需要開(kāi)始新的一輪游戲,所以在game.js添加reset函數(shù)

// 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()函數(shù)用于開(kāi)始新一輪和游戲,在這個(gè)方法里我們將英雄放回畫布中心同時(shí)將怪物放到一個(gè)隨機(jī)的地方。

更新對(duì)象

在游戲的過(guò)程中,不管是用戶在玩(有正確輸入的狀態(tài))還是游戲結(jié)束,我們都是需要及時(shí)更新游戲的對(duì)象:

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函數(shù)負(fù)責(zé)更新游戲的各個(gè)對(duì)象,會(huì)被規(guī)律地重復(fù)調(diào)用。首先它負(fù)責(zé)檢查用戶當(dāng)前按住的是中方向鍵,然后將英雄往相應(yīng)方向移動(dòng)。

有點(diǎn)費(fèi)腦力的或許是這個(gè)傳入的modifier 變量。你可以后面將要實(shí)現(xiàn)的main 方法里看到它的來(lái)源,但這里還是有必要詳細(xì)解釋一下。它是基于1開(kāi)始且隨時(shí)間變化的一個(gè)因子。例如1秒過(guò)去了,它的值就是1,英雄的速度將會(huì)乘以1,也就是每秒移動(dòng)256像素;如果半秒鐘則它的值為0.5,英雄的速度就乘以0.5也就是說(shuō)這半秒內(nèi)英雄以正常速度一半的速度移動(dòng)。理論上說(shuō)因?yàn)檫@個(gè)update函數(shù)被調(diào)用的非常快且頻繁,所以modifier的值會(huì)很小,但有了這一因子后,不管我們的代碼跑得快慢,都能夠保證英雄的移動(dòng)速度是恒定的。

這里需要說(shuō)明一下下面的判斷怪物和英雄是什么根據(jù):

 if (
        hero.x <= (monster.x + 31)
        && monster.x <= (hero.x + 31)
        && hero.y <= (monster.y + 32)
        && monster.y <= (hero.y + 32)
    )

上面的31,32是由heromonster圖片的大小決定的,我們的hero圖片是32x32,monster圖片是30x32,所以根據(jù)坐標(biāo)的位于圖片中心的法制,就可以得到上面的判斷條件。

現(xiàn)在英雄的移動(dòng)已經(jīng)是基于用戶的輸入(按下鍵)了,接下來(lái)該檢查移動(dòng)過(guò)程中所觸發(fā)的事件了,也就是英雄與怪物相遇。這就是本游戲的勝利點(diǎn),monstersCaught +1然后重新開(kāi)始新一輪。

渲染物體

之前寫的代碼都是在準(zhǔn)備前期工作和處理一些游戲的狀態(tài)等,下面將進(jìn)入正題:我們需要將所有的東西畫出來(lái)

// 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就是最前面我們創(chuàng)建的變量。然后利用canvasdrawImage()首先當(dāng)然是把背景圖畫出來(lái)。然后如法炮制將英雄和怪物也畫出來(lái)。這個(gè)過(guò)程中的順序是有講究的,因?yàn)楹螽嫷奈矬w會(huì)覆蓋之前的物體。

這之后我們改變了一下Canvas的繪圖上下文的樣式并調(diào)用fillText來(lái)繪制文字,也就是記分板那一部分。本游戲沒(méi)有其他復(fù)雜的動(dòng)畫效果和打斗場(chǎng)面,繪制部分大功告成

主循環(huán)函數(shù)

我們實(shí)現(xiàn)了將畫面畫出來(lái)以后,我們緊接著需要實(shí)現(xiàn)的就是游戲的循環(huán)結(jié)構(gòu),于是將它放在main函數(shù)里:

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

上面的主函數(shù)控制了整個(gè)游戲的流程。先是拿到當(dāng)前的時(shí)間用來(lái)計(jì)算時(shí)間差(距離上次主函數(shù)被調(diào)用時(shí)過(guò)了多少毫秒)。得到modifier后除以1000(也就是1秒中的毫秒數(shù))再傳入update函數(shù)。最后調(diào)用render 函數(shù)并且將本次的時(shí)間保存下來(lái)。

設(shè)置requestAnimationFrame()

在上面的main函數(shù)中,我們通過(guò)requestAnimationFrame()調(diào)用了main函數(shù),所以我們需要聲明:

var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;


這里這么多的||,不為別的,就是考慮到瀏覽器兼容問(wèn)題而已。

最后啟動(dòng)游戲

萬(wàn)事具備,只欠東風(fēng)。到此,所有的游戲代碼基本就寫完了,我們現(xiàn)在需要做的就是調(diào)用相應(yīng)的函數(shù)來(lái)啟動(dòng)游戲:


// Let"s play this game! var then = Date.now(); reset(); main();

到這里代碼就寫完了。先是設(shè)置一個(gè)初始的時(shí)間變量then用于首先運(yùn)行main函數(shù)使用。然后調(diào)用 reset 函數(shù)來(lái)開(kāi)始新一輪游戲(如果你還記得的話,這個(gè)函數(shù)的作用是將英雄放到畫面中間同時(shí)將怪物放到隨機(jī)的地方以方便英雄去捉它)

用瀏覽器打開(kāi)game.html,開(kāi)始玩游戲吧!

進(jìn)一步思考

在玩游戲的過(guò)程中,你會(huì)發(fā)現(xiàn)每一次hero捕獲到monsterhero就回到了canvas畫布的正中間。那么現(xiàn)在需要做的就是,將hero在捕捉到monster的時(shí)候讓hero就停留在捕獲的位置,不再是回到canvas正中間。

這個(gè)現(xiàn)象的出現(xiàn)主要是因?yàn)樵?b>reset函數(shù)中將hero.xhero.y寫死了,所以一個(gè)最簡(jiǎn)單的方法就是在reset中傳入?yún)?shù):

var reset = function (x,y) {
    hero.x = x;
    hero.y = x;
};

然后在update調(diào)用reset的時(shí)候傳入捕獲時(shí)位置的參數(shù):

var update = function (modifier) {

        //...other codes

        ++monstersCaught;
        reset(heor.x,hero.y);

};


最后在開(kāi)始游戲的時(shí)候?qū)?b>hero放在canvas最中間即可:


var then = Date.now(); reset(canvas.width / 2,canvas.height / 2); main();

大功告成!

Hapyy Hacking

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85822.html

相關(guān)文章

  • 推薦一些好HTML5 & JavaScript 游戲引擎開(kāi)發(fā)庫(kù)

    摘要:推薦一些好用的游戲引擎開(kāi)發(fā)庫(kù)引言如果你是一個(gè)游戲開(kāi)發(fā)者,并且正在尋找一個(gè)可以與和無(wú)縫工作的游戲引擎。是另一個(gè)容易使用,適用于移動(dòng)設(shè)備和桌面的游戲引擎。是一個(gè)開(kāi)源的用來(lái)創(chuàng)建使用高級(jí)技術(shù)和服務(wù)的游戲引擎。用于建立游戲和繪圖引擎。 推薦一些好用的 HTML5 & JavaScript 游戲引擎開(kāi)發(fā)庫(kù) 0. 引言 如果你是一個(gè)游戲開(kāi)發(fā)者,并且正在尋找一個(gè)可以與 JavaScript 和 HT...

    happen 評(píng)論0 收藏0
  • 推薦一些好HTML5 & JavaScript 游戲引擎開(kāi)發(fā)庫(kù)

    摘要:推薦一些好用的游戲引擎開(kāi)發(fā)庫(kù)引言如果你是一個(gè)游戲開(kāi)發(fā)者,并且正在尋找一個(gè)可以與和無(wú)縫工作的游戲引擎。是另一個(gè)容易使用,適用于移動(dòng)設(shè)備和桌面的游戲引擎。是一個(gè)開(kāi)源的用來(lái)創(chuàng)建使用高級(jí)技術(shù)和服務(wù)的游戲引擎。用于建立游戲和繪圖引擎。 推薦一些好用的 HTML5 & JavaScript 游戲引擎開(kāi)發(fā)庫(kù) 0. 引言 如果你是一個(gè)游戲開(kāi)發(fā)者,并且正在尋找一個(gè)可以與 JavaScript 和 HT...

    Zack 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

CompileYouth

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<