【CSON原創】HTML5第一人稱射擊游戲發布
功能說明:
游戲中在躲避敵人攻擊的同時,需要收集三種不同的鑰匙,開啟對應的門,最后到達目的地。
該游戲同樣基于自己開發的HTML5游戲框架cnGameJS。
推薦用chrome瀏覽器查看。
效果預覽:
方向鍵控制移動,空格鍵射擊,shift鍵打開門。
實現分析:
在上一篇文章《HTML5實現3D迷宮》中,通過放射線法模擬出3D場景的效果,而本文則在3D效果的基礎上,添加更多的游戲元素,構建成一個較完整的第一人稱射擊游戲。
關于如何模擬出3D場景效果上文中已經有較詳細的描述,本文則主要介紹如何實現游戲互動部分。
1.游戲元素在地圖上的對象和在屏幕上的對象的對應關系?
首先,每個游戲元素都對應兩個游戲對象,一個游戲對象為左邊地圖上的對象,另一個則為右邊屏幕上的對象。例如,一個敵人的位置,是否射擊狀態等信息都由左邊的地圖對象來表示,而敵人在屏幕上的顯示,則是根據在左邊地圖上對象的信息進行繪制。簡而言之,左邊的地圖對象負責游戲元素位置,狀態的判別,它真正存儲游戲信息。而右邊的屏幕對象則只負責游戲元素的呈現。
newEnemy.relatedObj=new enemy2({src:srcObj.enemy,context:screenContext});
newEnemy.relatedObj.relatedParent=newEnemy;
如上,地圖上的對象和屏幕上的對象保持互相引用的關系,這樣就可以輕易通過地圖對象訪問屏幕對象,反之亦然。
2.如何使敵人在發現玩家后進行射擊?
要實現該功能,我們需要知道玩家相對于敵人的角度,該參數我們可以根據敵人到玩家的距離和它們x,y的差值求出。之后我們就可以在敵人對象的位置向該方向發射出一條射線,如果該射線能在不觸碰墻壁的時候觸碰到玩家,就證明敵人可以看到玩家。這時候敵人就可以向玩家射擊了。
nextX = enemyCenter[0];
nextY = enemyCenter[1];
while (this.map.getPosValue(nextX, nextY) == 0) {
distant += 1;
x = nextX;
y = nextY;
if (cnGame.collision.col_Point_Rect(x, y, playerRect)&&!spriteList[i].relatedObj.isCurrentAnimation("enemyDie")) {//如果地圖上敵人能看到玩家,則向玩家射擊
spriteList[i].isShooting = true;
if (spriteList[i].lastShootTime > spriteList[i].shootDuration) {//檢查是否超過射擊時間間隔,超過則射擊玩家
spriteList[i].shoot(player);
spriteList[i].relatedObj.setCurrentImage(srcObj.enemy1);
spriteList[i].lastShootTime = 0;
}
else {
if (spriteList[i].lastShootTime > 0.1) {
spriteList[i].relatedObj.setCurrentImage(srcObj.enemy);
}
spriteList[i].lastShootTime += duration;
}
break;
}
else {
spriteList[i].isShooting = false;
}
nextX = distant * Math.cos(angle) + enemyCenter[0];
nextY = enemyCenter[1] - distant * Math.sin(angle);
}
}
3.如何檢測是否獲得鑰匙?
檢測鑰匙獲取其實就是簡單地檢測玩家對象和鑰匙對象是否產生碰撞,產生碰撞則獲取到鑰匙。碰撞檢測同樣發生在左邊的地圖對象。
/* 檢測是否獲得鑰匙 */
var checkGetKeys = function() {
var list = cnGame.spriteList;
var playerRect= this.player.getRect();
for (var i = 0, len = list.length; i < len; i++) {
if (list[i] instanceof key) {
if (cnGame.collision.col_Between_Rects(list[i].getRect(),playerRect)) {
this.keysValue.push(list[i].keyValue);
list.remove(list[i]);
i--;
len--;
}
}
}
}
4.如何同時把游戲元素和游戲場景同時繪制在屏幕上并且保持正確的先后關系?
在css里,我們可以使用z-Index使元素保持正確的層級關系,但是我們現在需要在canvas上繪制圖形,因此只能模擬出z-Index效果。
在之前那篇文章中說過,3D場景是由一條條不同長短的像素線的繪制而成,因此在加入了其他游戲元素之后,若要保持正確的層級關系,就需要為每個元素和像素線自定義zIndex屬性,并存放在數組中。每次繪制的時候數組根據zIndex排序,使繪制有一個先后順序,從而保證層級正確。zIndex的值根據玩家到該元素或像素線的距離計算所得:
zIndex= Math.floor(1 / distant * 10000)
之后每次繪制就可以產生近的圖像覆蓋在遠的圖像上的效果:
排序:
colImgsArray.sort(function(obj1, obj2) {
if (obj1.zIndex > obj2.zIndex) {
return 1;
}
else if (obj1.zIndex < obj2.zIndex) {
return -1;
}
else {
return 0;
}
});
繪制:
//畫出每條像素線和游戲元素
for (var i = 0, len = colImgsArray.length; i < len; i++) {
var obj = colImgsArray[i];
if(obj.draw){
obj.draw();
}
else{
context.drawImage(obj.img, obj.oriX, obj.oriY, obj.oriWidth, obj.oriHeight, obj.x, obj.y, obj.width, obj.height);
}
}
5.如何判斷玩家擊中敵人?
玩家擊中敵人的判別其實也是利用碰撞檢測,不過這次是利用元素在屏幕上的對象進行碰撞檢測。我們只需要檢測準星(屏幕中點)與敵人對象所形成的矩形是否產生碰撞,就可以檢測到是否擊中了敵人。
for (var i = list2.length - 1; i >= 0; i--) {
if (list2[i] instanceof enemy2 && list2[i].relatedParent.isShooting) {
var obj = list2[i];
var enemyRect = obj.getRect();//構造敵人在屏幕上形成的矩形對象
if (cnGame.collision.col_Point_Rect(starPos[0], starPos[1], enemyRect)) {
obj.setCurrentAnimation("enemyDie");
break;
}
}
}
擊中敵人之后,需要break跳出循環,停止檢測,防止擊中在該敵人后面的敵人。
最后給出所有源碼下載:點擊下載
歡迎轉載,請標明出處:http://www.rzrgm.cn/Cson/archive/2012/03/05/2380963.html
功能說明:
游戲中在躲避敵人攻擊的同時,需要收集三種不同的鑰匙,開啟對應的門,最后到達目的地。
該游戲同樣基于自己開發的HTML5游戲框架cnGameJS。
推薦用chrome瀏覽器查看。
浙公網安備 33010602011771號