パックマンとスネークを実装した後、次の非常に古典的なゲームであるポンを実装しています。
実装は本当に簡単ですが、私には1つだけ小さな問題が残っています。パドルの1つ(パドルと呼ばれるかどうかはわかりません)がコンピューターによって制御されている場合、正しい位置に配置するのに問題があります。
ボールには、現在の位置、速度(今のところ一定)、方向角があります。それで、コンピューター制御のパドルの側面に当たる位置を計算することができました。そして、私はパドルをそこに配置することができました。しかし、実際のゲームでは、コンピューターのパドルがボールを見逃す可能性があります。この確率をどのように実装できますか?
コンピューターのパドルがボールに当たる確率を0.5とすると、問題は解決しますが、それほど単純ではないと思います。
元のゲームから、確率は現在のパドルの位置とボールが境界に当たる位置との間の距離に依存すると思います。
誰かがこれがどのように正確に計算されるかについて何かヒントがありますか?
高校のCSクラス用に(疑似)3Dピンポンゲームを作りました。私たちがやったことは、コンピューターが常にパドルをボールに向かって動かすようにしたことですが、最高速度では、ボールが遠すぎるとボールを見逃す可能性がありますが、それでもスマートです。これは役に立ちますか?
とても楽しい本「RacingtheBeam」からの引用(Googleブックス: http://books.google.co.uk/books?id=DqePfdz_x6gC&lpg=PP1&dq=racing%20the%20beam&pg=PA40#v=onepage&q&f = false )元の手法は次のとおりです。
パドルの正確な位置決めに固有の人為的エラーをシミュレートするために、AIパドルは8フレームごとに調整をスキップします。結果として生じる動作は目に見えて目立たないものですが、コンピュータープレーヤーの狙いを十分にドリフトさせて、ボールを時々逃すことができます。実装することも技術的に簡単であり、単一のマスクとバイナリAND演算のみが必要であり、対応する6502命令が存在します。プログラマーは、別の単一のオペコードを使用して結果がゼロかどうかをテストし、必要に応じて分岐して、パドルを移動する命令をスキップできます。
ゲームを完全に機能させるには、この動作を少し変更する必要があります。 AIプレーヤーが8フレームごとにボールの追跡を停止した場合、数秒以内に同期がとれてしまう可能性があります。これを防ぐために、AIは、プレイフィールドの上部と下部の近くにある2番目のボール追跡スキームに従います。パドルも位置合わせされているときにボールがこれらの壁の1つに衝突すると、パドルは再調整され、ボールが最後に壁に当たってから蓄積されたドリフトから回復します。その結果、コンピューターのパドルとボールの確率的なミスアライメントと再アライメントが発生します。
パドルを常に現在の位置から特定のポイントに移動させる必要があると思います。特定のポイントは、ボールがパドルと垂直に整列すると予想される場所です。次に、パドルがこの正確なポイントに移動してボールを偏向させる可能性が50%、おそらくXピクセルだけオーバーシュートする可能性が25%、アンダーシュートする可能性が25%になる可能性があります。それを行うさらに良い方法は、ベルカーブ上のその位置に移動して、毎回異なる量だけミスするようにすることです。
これを行うための「公式」の方法が何であるかはわかりませんが、私はいつも(擬似コード)を使用してきました
if (ball is above Paddle) {
move Paddle up
}
if (ball is below Paddle) {
move Paddle down
}
それから私はパドルに少し変化する速度を与えましたが、それは十分に遅く、常にボールに追いつくことができませんでした。粗雑なものですが、機能します。
このスレッドには、あなたが見たいと思うかもしれないいくつかの興味深いアイデアもあります: http://www.gamedev.net/community/forums/topic.asp?topic_id=439576
他の回答では、さまざまな状況で移動する正しい方向を決定する方法について説明しています。コンピュータプレーヤーがこの方向に動き始めることによって「反応」する前にラグタイムを追加することもできます。これは人間のプレーヤーの典型的な反応を反映しています。
先日、楽しみのためにポンクローンを書いたのです。
あなたはそれを再生することができます ここ そしてソースコードを見る ここ 。
AIはボールの現在の速度を取得し、壁から離れたx距離を乗算します。次に、上限速度で計算された位置に向かって移動します。垂直方向のバウンスは考慮されていませんが、それは一種の意図されたものです(AIを打ち負かすため)。
関連するスニペットは次のとおりです。
/* Update enemy based on simple AI */
enemy.update = function (delta) {
var impactDistance, impactTime, targetY, speed;
speed = .25; // a little slower than the human player
if (ball.vx < 0) {
// Ball is moving away, AI takes a nap ..
return;
}
// Figure out linear trajectory ..
impactDistance = width - ball.width - ball.x;
impactTime = impactDistance / (ball.vx * .25 * 1000);
targetY = ball.y + (ball.vy * .25 * 1000) * impactTime;
if (Math.abs(targetY - (this.y + this.height/2)) < 10) {
// AI doesn't need to move
return;
}
if (targetY < this.y + (this.height / 2)) {
// Move up if ball is going above Paddle
speed = -speed;
}
this.y += speed * delta;
this.keepInBounds();
};
数回繰り返した後、パドル(つまり、視点に応じてあなたまたはAI)が画面の上部または下部に近すぎる場合、必要な距離をカバーすることは不可能です。パドルは、ボールのy値を簡単に追跡できます。あなたが遠すぎるならあなたは逃すでしょう。
または、ヒットするたびにAIを中央にリセットするか、ボールが離れている間(つまり、相手に向かって)、中央に向かって移動することができます。
またはもっと簡単に:
-ボールが遠ざかっている間に中心に向かって移動します-ボールが近づいているときにボールのy座標を模倣します。
ここから、y座標の模倣メカニズムをボールよりも遅くするか(より一貫性があり、おそらく元の実装がどのようなものであったか。難易度は単純な速度係数に抽象化されるため)、各動きにランダムエラーを追加するか、さもないと。