javascript異步編程系列【十】—Jscex+Easeljs制作坦克大戰
2011-09-15 08:01 【當耐特】 閱讀(5570) 評論(13) 收藏 舉報一.簡介
為了利用當今和未來的硬件,您可以對代碼進行并行化,以將工作分攤在多個處理器上。 往往,并行化需要線程和鎖的低級操作,但是Jscex不用,因為javascript這種解釋型語言,僅僅需要一個線程來解釋它,已其他線程無關,且不沖突!
二.回顧
上面介紹了一下Easeljs以及其優勢,并且利用Easeljs+Jscex實現了坦克的右移以及開炮,但是還存在許多問題,比如移動不能開炮,開炮不能移動。
這篇主要利用Jscex并行編程模型搭起游戲的基本框架,并且解決坦克的轉彎和開火。
三.架構設計
昨天我仔細想了想,不管是任何東西,拆得越細就越好控制。如果使用Easeljs的tick(也就相當于Jscex的while(true)),任何東西都往里面丟,函數冗長,不能靈活控制。Jscex有個很明顯的優勢,它可以輕松掛起一個while(true),用于監聽,然后根據監聽的結果做出相應的操作。所以,我把坦克大戰拆成以下七個異步任務,游戲的所有元素都在下面七個異步任務當中:
a.坦克的移動
b.子彈的生產
c.子彈的飛行
d.碰撞檢測,比如擊中墻壁,擊中敵方坦克
e.寶物的生成,比如增加火力的寶物,增加生命的寶物
f.統計任務,比如消滅敵軍坦克獲取積分
g. GameOver監聽,比如老巢被滅,比如自己犧牲并且剩余生命條數為0
這七個任務同時執行,看似相互獨立,其實是相互影響,比如
碰撞檢測到擊中敵方坦克,就會觸發統計任務,
擊中掉寶坦克,觸發寶物的生成
被敵方坦克消滅老巢,觸發GameOver
四.轉彎和開火
開始打算用rotation屬性來旋轉圖片,實現轉彎,并且帶有轉彎動畫,這也算超越了以前的坦克大戰。然后rotation旋轉圖片不會以圖片的中心旋轉,而會以圖片左上角為基準點旋轉,這叫我情何以堪!旋轉效果如下:
好吧,我還是用四張圖片吧,反正素材就提供了4張圖片。
我們把轉彎與開火拆成三個異步任務:
a.坦克的移動
b.子彈的生產
c.子彈的飛行
坦克的移動:
var moveAsync = eval(Jscex.compile("async", function () { var i = 0; while (true) { if (goRight == true) { bmpR.visible = true; bmpL.visible = false; bmpD.visible = false; bmpU.visible = false; bmpL.x += 1; bmpR.x += 1; bmpD.x += 1; bmpU.x += 1; } if (goLeft == true) { bmpR.visible = false; bmpL.visible = true; bmpD.visible = false; bmpU.visible = false; bmpR.x -= 1; bmpL.x -= 1; bmpD.x -= 1; bmpU.x -= 1; } if (goUp == true) { bmpR.visible = false; bmpL.visible = false; bmpD.visible = false; bmpU.visible = true; bmpR.y -= 1; bmpL.y -= 1; bmpD.y -= 1; bmpU.y -= 1; } if (goDown == true) { bmpR.visible = false; bmpL.visible = false; bmpD.visible = true; bmpU.visible = false; bmpR.y += 1; bmpL.y += 1; bmpD.y += 1; bmpU.y += 1; } stage.update(); $await(Jscex.Async.sleep(10)); } }))
生成子彈:
var bulletStream = new Array(); var createBulletAsync = eval(Jscex.compile("async", function () { var i = 0; while (true) { if (shootHeld == true) { bulletStream[i] = new Bitmap("image/tankmissile.gif"); if (bmpD.visible == true) { bulletStream[i].direction = "down"; bulletStream[i].x = bmpR.x + 21; bulletStream[i].y = bmpR.y + 60; } if (bmpL.visible == true) { bulletStream[i].direction = "left"; bulletStream[i].x = bmpR.x ; bulletStream[i].y = bmpR.y + 21; } if (bmpR.visible == true) { bulletStream[i].direction = "right"; bulletStream[i].x = bmpR.x + 60; bulletStream[i].y = bmpR.y + 21; } if (bmpU.visible == true) { bulletStream[i].direction = "up"; bulletStream[i].x = bmpR.x + 21; bulletStream[i].y = bmpR.y ; } stage.addChild(bulletStream[i]); i++; } stage.update(); $await(Jscex.Async.sleep(200)); } }))
我們要在生成子彈的時候,告訴子彈的方向,也許以后會擴展一個子彈的速度。
子彈的飛行:
var fireAsync = eval(Jscex.compile("async", function () { while (true) { for (bullet in bulletStream) { if (bulletStream[bullet].direction == "up") { bulletStream[bullet].y -= 10; } if (bulletStream[bullet].direction == "down") { bulletStream[bullet].y += 10; } if (bulletStream[bullet].direction == "right") { bulletStream[bullet].x += 10; } if (bulletStream[bullet].direction == "left") { bulletStream[bullet].x -= 10; } } stage.update(); $await(Jscex.Async.sleep(50)); } }))
元素初始化,并行任務開始:
function init() { canvas = document.getElementById("testCanvas"); stage = new Stage(canvas); bmpR = new Bitmap("image/p1tankR.gif"); bmpL = new Bitmap("image/p1tankL.gif"); bmpD = new Bitmap("image/p1tankD.gif"); bmpU = new Bitmap("image/p1tankU.gif"); bmpL.visible = false; bmpD.visible = false; bmpU.visible = false; stage.addChild(bmpR); stage.addChild(bmpL); stage.addChild(bmpD); stage.addChild(bmpU); Ticker.addListener(stage); createBulletAsync().start(); fireAsync().start(); moveAsync().start(); }
五.在線演示
未完待續,下篇加入敵方坦克,ohoh··········
最新的Jscex 庫,請上https://github.com/JeffreyZhao/jscex或者http://www.sndacode.com/projects/jscex/wiki下載吧····
六.同步
本文已同步更新至:

浙公網安備 33010602011771號