機能の説明:
ゲームでは、敵の攻撃を避けながら、3つの異なる鍵を集め、対応するドアを開け、最終的に目的地に到達する必要があります。
このゲームも自社開発のHTML5GameフレームワークcnGameJSに基づいています。
Chromeブラウザでの閲覧を推奨します。
エフェクトプレビュー:
方向キーで動きを制御し、スペースバーで射撃し、Shiftキーでドアを開けます。
実装分析:
前回の記事「3D MazeのHTML5実装」では、3Dシーンの効果を放射法によってシミュレートしましたが、この記事は3Dに基づいていますゲーム要素を追加して、より完全な一人称シューティング ゲームを構築します。
3Dシーンエフェクトをシミュレートする方法については上記で詳しく説明しましたが、この記事では主にゲームのインタラクティブ部分の実装方法を紹介します。
1. マップ上のゲーム要素と画面上のオブジェクトの対応関係は何ですか?
まず、各ゲーム要素は 2 つのゲーム オブジェクトに対応します。1 つは左側のマップ上のオブジェクトで、もう 1 つは右側の画面上のオブジェクトです。例えば、敵の位置、射撃の有無、ステータスなどの情報はすべて左側のマップオブジェクトで表現されており、その情報をもとに画面上の敵の表示が描画されます。左側の地図上のオブジェクト。 つまり、左側のマップ オブジェクトは、ゲーム要素の位置とステータスを決定する役割を果たし、実際にゲーム情報を保存します。右側の画面オブジェクトは、ゲーム要素の表示のみを担当します。 newEnemy.relatedObj= 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--; } } } }
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. プレイヤーが敵に当たったかどうかを判断するには?
プレイヤーが敵に当たるかどうかの判定には実際には当たり判定を使用しますが、今回は画面上の要素のオブジェクトを用いて当たり判定を行っています。
十字線 (画面の中点) によって形成される四角形が敵オブジェクトと衝突するかどうかを検出するだけで、敵が当たったかどうかを検出できます。以上がHTML5 一人称シューティング ゲーム実装のためのコード共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。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;
}
}
}