ホームページ >ウェブフロントエンド >H5 チュートリアル >HTML5ベースの横型シューティングゲームを詳しく解説
機能説明:
フラッシュゲーム「Double」を参考にしたHTML5ベースの横スクロールシューティングゲーム-エージェント」。 左右の矢印キーで移動を制御し、下矢印キーでジャンプし、スペースキーで射撃します。
このゲームは、自社開発の HTML5 ゲーム フレームワーク cnGameJS に基づいています。 :
実装分析:
1.多層マップについて
以前のHTML5ゲーム「Tank Support Team」では、使用されたマップは単純な単層マップのみでした。つまり、石しかありません。ただし、この単一レイヤーのマップには比較的大きな制限があります (スーパー マリオや上記のゲームなど)。多くの場合、1 つのレイヤーだけでは十分ではありません。ゲームの主人公が立っている障害物に加えて、ゲームの背景 (後ろの壁など) などの要素もあるため、レイヤーを重ねる必要があります。マルチレイヤー表示の目的を達成するためのマップ オブジェクト
新規追加レイヤー オブジェクト: 各レイヤー オブジェクトはレイヤーのスプライトを維持し、それらの更新と描画を担当し、オブジェクト上の指定された座標の値を取得できます。レイヤーオブジェクトのソースコードは以下の通りです:/** *层对象 **/ 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「ゲームスーパーマリオゲームデモ」では、ゲームプレイヤーの動きをゲームシーンに変換して、プレイヤーの固定とシーンの移動の効果を実現しましたが、この実装方法には大きな問題があります。マップとプレイヤーの xy 値が変更されるため、非常に不便になります より良い実装方法は、プレイヤーとマップの xy 値を変更せず、座標のみを変更することです。
ビューオブジェクトの新しいメソッド: applyInView:
applyInView メソッド
の機能は、マップとプレイヤーの実際の座標を変更することではありません。たとえば、背景を移動する効果を得るには、プレイヤーをビューの中点に対して固定し、マップ上の他のすべてのゲーム要素を相対的に移動させる必要があります。ビューに追加するには、初期化するだけです: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(); });このようにして、マップ内のすべての要素がビューに対して相対的に移動します applyInView の実装原理も非常に単純で、単に継続的に実行するだけです。描画原点とビューを変更します。座標は等しく反対です:
/** *使坐标相对于view **/ applyInView:function(func){ cg.context.save(); cg.context.translate(-this.x, -this.y); func(); cg.context.restore(); },このようにして、ビューの座標がどのように変化しても、ビューは常に
canvas
上に視覚的に固定され、他の要素の座標は常に固定されます。ビューに対して視覚的に相対的に。以上がHTML5ベースの横型シューティングゲームを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。