2

PythonでKivyを使用して学校のプロジェクト用のPONGゲームを作成しています。これまでのところ、このフォーラムのおかげで、NPCパドル用のAIを作成しました。これはコードです:

    if self.ball.y < self.player2.center_y:
        self.player2.center_y = self.player2.center_y - 4
    if self.ball.y > self.player2.center_y:
        self.player2.center_y = self.player2.center_y + 4

これは、ArtificialIntelligence()と呼ばれるPongGame()クラスのメソッドにあります。

私はこれを使ってそれを呼びます:

Clock.schedule_interval(game.ArtificialIntelligence, 1/300)     

これにより、1/300秒に1回呼び出すことができます。ただ、1/300以上なら何の違いもないようです。つまり、1/9001は1/9001秒ごとに1回は呼び出されません。

それが機能する方法は、ボールの位置に対してy座標を4ピクセル増やすことであり、これは1/300秒ごとに1回行われるため、この速度で「遅れ」ることはありません。これは基本的にプレイヤーにとって「簡単な」モードです。「ハード」モードを実行したい場合は、NPCをより正確にする必要があります。私はこれを行うことによってこれを行うことができます

self.player2.center_y = self.player2.center_y + 20

このようなもの。これは非常に正確です。ただし、「流動的」ではなく、「遅延」しているように見えます。ピクセルの動きを変更して移動量を変更する代わりに、メソッドをより頻繁に呼び出すことで、同じ量の移動を取得できると思います。ただし、これを行う方法はわかりません。前述したように、1/300より上から変更しても違いはないようです。

これが私のパドルの使い方です:

if touch.x < self.width/3:
    self.player1.center_y = touch.y

マウスを動かすと更新されるので、好きなだけ速く動かすことができます。また、更新が必要な頻度で更新されるため、流動的に見えます。AIでこれを行う方法がわかりません。

基本的にNPCパドルをより正確にして、流動性とラグを維持しながら、イージー-ノーマル-ハードなどを実行できるようにする方法を知っている人はいますか?私はそれを行うことができる唯一の方法を見ています:メソッドが呼び出される量を増やします。

しかし、私はもっと良い方法があるに違いない、そして私はそれをする方法を知らない。誰かが私がこれをどのように行うことができるかについて何か考えを持っていますか?ありがとう。

編集:私はこのようにそれを行うことができるように見えます:

Clock.schedule_interval(game.ArtificialIntelligence, 1/300)     
Clock.schedule_interval(game.ArtificialIntelligence, 1/300) 
Clock.schedule_interval(game.ArtificialIntelligence, 1/300) 
Clock.schedule_interval(game.ArtificialIntelligence, 1/300)         
Clock.schedule_interval(game.ArtificialIntelligence, 1/300) 

しかし、それは本当に醜くて本当に非効率的なようです...私はもっとクリーンな方法を好むでしょう。

4

3 に答える 3

1

私のアドバイスは、トリガーを使用してボールがどこにあるかを判断し、パドルをそこに動かしてインターセプトすることです。

アニメーションは毎秒 30 フレームで滑らかになります。

最近のゲーム AI の作成は非常に重要であり、プレイヤーが AI の「不正行為」に気付かないことが重要であり、より大きなパドルやテレポート機能を与えることは、その明らかな兆候です。プレイヤーがアクセスできないメカニズムを使用しないで、人間と同じようにプレイする必要があります。「このゲームは CPU がチートするから最悪だ」というのは、ビデオゲーム フォーラムで非常に一般的な否定的なコメントです。

したがって、コンピューターがミスする必要がある場合は、トリガーの計算がランダムな要因によってオフになっていることを確認してください。これにより、プレーヤーは自分のプレイと人間のプレイを区別できなくなります。

編集:例:ランダム(X)<=ボールの速度の場合、正しくインターセプトし、そうでない場合はランダム(Y)単位でミスします。

于 2012-07-30T13:08:50.320 に答える
1

1 秒あたり 300 フレームの場合、問題は更新速度ではありません。なぜなら、動きを知覚する人間の目の能力を 50 倍以上超えているからです。

ぎくしゃくした動きが発生するのは、パドルがボールの現在の位置にホッピングしている間に、ボールが直線的な軌道をたどっているからです。理想的には、コンピュータ プレーヤーは、ボールがコンピュータ パドルの平面に当たったときにボールがどこにあるかを計算し、その場所まで 30 フレーム/秒以下で非常に滑らかなコースを取ることができます。確かに、予測計算には微量の三角法が必要ですが、良いプレーヤーが予測することでプレーするという意味で、これは「正しい」方法です。

コンピューターのパドルのサイズを大きくするだけで、ゲームがどれだけ難しいかを人間のプレーヤーに視覚的に示すことができれば、はるかに簡単になります。コンピューターのパドルが壁になったとき、プレーヤーは勝ち目がないことに気付くでしょう。パドルが大きいほどぎくしゃくしにくいという副作用がありますが、これが「良い」方法であるかどうかはあなたの判断です。

于 2012-07-30T11:01:11.380 に答える
1

皆さんの助けに感謝します。あなたの助けと彼の助けに基づいて、先生と一緒に解決することができました.

彼はこのアルゴリズムを開発しました (彼は非常に速く作成したため、私には理解できませんでした!)、これは基本的に三角関数を使用して、パドルがどこに移動するかを生成します (注: 他の値があるため、角度は使用しません)。使用することができます)

def AIController(self, *args):      
    ballsFuturePos = self.ball.center_y + ((self.width - self.ball.center_x) / self.ball.velocity_x) * self.ball.velocity_y
    numIterations = ((self.width - self.ball.center_x) / self.ball.velocity_x)
    #print ballsFuturePos
    #print numIterations
    if numIterations > 0:
        self.wantedPos = self.player2.center_y +(ballsFuturePos - self.player2.center_y) / numIterations        
        #print wantedPos
        #self.player2.center_y = wantedPos + (error / wantedPos) * 100


    if self.player2.center_y < self.wantedPos:
        self.player2.center_y = self.player2.center_y + 9
    if self.player2.center_y > self.wantedPos:
        self.player2.center_y = self.player2.center_y - 9

そこで、ボールの y 位置を取得し、(幅 - ボールの x 位置) を追加して、ボールが画面の右端に当たる場所を生成します (これにより、画面の右端が表示されるまでの距離がわかります)。 x ピクセル)、それから x 速度でそれを割り出し、y 速度で全体を掛けると、勾配が得られます (私が思うに)。したがって、勾配が計算されたので、軌道とそのため、ボールが画面に当たる場所を予測できます。

画面の幅からボールの x 位置を引いて、ボールに到達するまでに必要な反復回数を計算します。これは、画面の右端までの距離を計算し、それを速度で割ります。これにより、反復に使用できる数値が得られます。

今度はこれを繰り返し、パドルを動かしたい場所であるwantedPosという変数を作成します。これは、パドルの y 位置を使用して (ボールの位置 - パドルの位置) を追加します。これにより、ボールとパドルの間の距離が反復回数で割られ、パドルの位置が得られます。ボールに対して同じ位置にいること。各呼び出しで numIterations が減少すると、wantedPos も減少します。つまり、ギャップが小さくなります。次に、速度として 9 を使用してパドルをボールに近づけて繰り返します。これにより、難易度を上げたり下げたりできます。

ありがとう。彼の行動を説明しようとして私の論理を台無しにしてしまった場合は、教えてください! 私はそれを理解していると思いますが、確認はいいでしょう:)

于 2012-07-31T04:24:28.540 に答える