【CSON原創】基於HTML5的橫版射擊游戲發布


功能說明:

  基於HTML5的橫版射擊游戲,參考自flash游戲《雙面特工》左右方向鍵控制移動,下方向鍵蹲下,上方向鍵跳躍,空格鍵射擊。體驗前請先關閉輸入法。

  該游戲基於自己開發的HTML5游戲框架cnGameJS

效果預覽:

  

 

實現分析:

  1.關於多層地圖。  

  在上一個HTML5游戲《坦克后援隊》中,所用的地圖只為簡單的單層地圖,意思是地圖中除了石頭就是空地,僅僅只有一層的地圖。但是這種單層地圖具有比較大的局限性,如果需要實現場景類的游戲(例如超級瑪麗和上面的游戲),只有一層的地圖往往是不夠的,因為我們除了游戲主角所站的障礙物外,還有游戲背景等元素(例如后面的牆壁等),因此我們需要為地圖對象分層,從而達到多層展示的目的。

  新增的layer對象:

  每個layer對象維護該層的sprite,負責更新和繪制它們,並且可以獲取指定坐標在該層的矩陣上的值。layer對象源碼如下:

  

View Code
        /**
*層對象
*
*/
var layer = function(id,mapMatrix, options) {

if (!(this instanceof arguments.callee)) {
return new arguments.callee(id,mapMatrix, options);
}
this.init(id,mapMatrix, options);
}
layer.prototype={

/**
*初始化
*
*/
init: function(id,mapMatrix,options) {
/**
*默認對象
*
*/
var defaultObj = {
cellSize: [32, 32], //方格寬,高
x: 0, //layer起始x
y: 0 //layer起始y

};
options = options || {};
options = cg.core.extend(defaultObj, options);
this.id=options.id;
this.mapMatrix = mapMatrix;
this.cellSize = options.cellSize;
this.x = options.x;
this.y = options.y;
this.row = mapMatrix.length; //有多少行
this.width=this.cellSize[0]* mapMatrix[0].length;
this.height=this.cellSize[1]* this.row;
this.spriteList=new cg.SpriteList();//該層上的sprite列表
this.imgsReference=options.imgsReference;//圖片引用字典:{"1":{src:"xxx.png",x:0,y:0},"2":{src:"xxx.png",x:1,y:1}}
this.zIindex=options.zIndex;
},
/**
*添加sprite
*
*/
addSprites:function(sprites){
if (cg.core.isArray(sprites)) {
for (var i = 0, len = sprites.length; i < len; i++) {
arguments.callee.call(this, sprites[i]);
}
}
else{
this.spriteList.add(sprites);
sprites.layer=this;
}

},
/**
*獲取特定對象在layer中處於的方格的值
*
*/
getPosValue: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
var isUndefined = cg.core.isUndefined;
y = Math.floor(y / this.cellSize[1]);
x = Math.floor(x / this.cellSize[0]);
if (!isUndefined(this.mapMatrix[y]) && !isUndefined(this.mapMatrix[y][x])) {
return this.mapMatrix[y][x];
}
return undefined;
},
/**
*獲取特定對象在layer中處於的方格索引
*
*/
getCurrentIndex: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
return [Math.floor(x / this.cellSize[0]), Math.floor(y / this.cellSize[1])];
},
/**
*獲取特定對象是否剛好與格子重合
*
*/
isMatchCell: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
return (x % this.cellSize[0] == 0) && (y % this.cellSize[1] == 0);
},
/**
*設置layer對應位置的值
*
*/
setPosValue: function(x, y, value) {
this.mapMatrix[y][x] = value;
},
/**
*更新層上的sprite列表
*
*/
update:function(duration){
this.spriteList.update(duration);

},
/**
*根據layer的矩陣繪制layer和該layer上的所有sprite
*
*/
draw: function() {
var mapMatrix = this.mapMatrix;
var beginX = this.x;
var beginY = this.y;
var cellSize = this.cellSize;
var currentRow;
var currentCol
var currentObj;
var row = this.row;
var img;
var col;
for (var i = beginY, ylen = beginY + row * cellSize[1]; i < ylen; i += cellSize[1]) { //根據地圖矩陣,繪制每個方格
currentRow = (i - beginY) / cellSize[1];
col=mapMatrix[currentRow].length;
for (var j = beginX, xlen = beginX + col * cellSize[0]; j < xlen; j += cellSize[0]) {
currentCol = (j - beginX) / cellSize[0];
currentObj = this.imgsReference[mapMatrix[currentRow][currentCol]];
if(currentObj){
currentObj.x = currentObj.x || 0;
currentObj.y = currentObj.y || 0;
img = cg.loader.loadedImgs[currentObj.src];
//繪制特定坐標的圖像
cg.context.drawImage(img, currentObj.x, currentObj.y, cellSize[0], cellSize[1], j, i, cellSize[0], cellSize[1]);
}
}
}
//更新該layer上所有sprite
this.spriteList.draw();

}
}

  之后我們可以很方便地創建不同的層,並添加到地圖中:

/*    背景矩陣    */
var bgMatrix = [
[1,1,1],
[1,1,1],
[1,1,1]
];

this.map = new cnGame.Map({width:3000,height:3000});
var newLayer=new cnGame.Layer("bg",bgMatrix, { cellSize: [1000, 1000], width: this.map.width, height: this.map.height });
newLayer.imgsReference={ "1": { src: srcObj.bg }};
this.map.addLayer(newLayer);

 

  2.關於移動場景。 

  在上一次的HTML5《游戲超級瑪麗游戲demo》中,我們通過使游戲玩家的移動轉換為游戲場景的移動來實現玩家固定,場景移動的效果,但是這種實現方法有比較大的問題,因為它干涉了地圖和玩家的xy值的變化,因此會帶來很多不便。更好的實現方法是,保持玩家和地圖的xy值不變,只改變繪制它們時原點的坐標。

  view對象新增的方法:applyInView:

  applyInView方法的作用是在不改變地圖和玩家實際坐標的前提下,在繪制時使view固定,其他游戲元素相對於view移動,實現移動背景的效果。例如,我們需要使玩家相對於view中點固定,該map上的其他所有游戲元素相對於view移動,我們只需要在初始化時:

        this.view=new cnGame.View({map:this.map,x:0,y:0,width:cnGame.width,height:cnGame.height});
this.view.centerElem(this.player,true);

  在繪制時:

        this.view.applyInView(function(){
map.draw();
});

  這樣map內所有元素都會相對於view而移動。

  而applyInView的實現原理也非常簡單,它只是不斷使繪制的原點和view的坐標等長且相反:

            /**
*使坐標相對於view
*
*/
applyInView:function(func){
cg.context.save();
cg.context.translate(-this.x, -this.y);
func();
cg.context.restore();
},

  這樣無論view的坐標如何變化,view在視覺上始終固定在canvas,其他元素的坐標在視覺上始終相對於view。

 

  該游戲所有源碼下載地址:點擊下載

  歡迎轉載,請標明出處:http://www.cnblogs.com/Cson/archive/2012/03/15/2398129.html




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM