2

起動時に画面に50個のスプライトを追加するこのゲームを作成しようとしています。このスプライトの__init__関数には次のものがあります。

if self.overlapping_sprites:
    for sprite in self.overlapping_sprites:
        self.game.make_obstacles(1, 1400, self.game.speed)
        self.die()

これは、重複するスプライトがあるかどうかをほぼ検出し、それらのスプライトごとに、新しいスプライトを作成し、問題のあるスプライトを削除します。このコードを実装することは不思議でしたが、それでも完璧ではありません。ロード時にまだいくつかの重複するスプライトが確かにあります。ああ、私は与えられた長さに基づいて、これらのスプライトをランダムに作成していることに言及する必要があります。

参考までに、これはmake_obstacles()関数が何であるかです:

def make_obstacles(self, num, length, dx):
    for i in range(num):
        x = random.randrange(700, length)
        y = random.randrange(10, games.screen.height - 10)
        size = random.choice([Obstacle.obstacle_1,Obstacle.obstacle_3])
        new_obstacle = Obstacle(game = self, x = x, y = y, size = size, dx = dx)
        games.screen.add(new_obstacle)

ここで目標を達成するための別の方法はありますか?また、理解を深めるために、なぜこれが概念レベルで起こっているのかを理解したいので、助けていただければ幸いです。

4

1 に答える 1

1

明らかな解決策?

私は pygame の専門家ではありません。しかし、ここで問題が何であるかを理解したと思います。ただし、コードの残りの部分がどのように見えるかわからないため、完全にオフになっている可能性があります。

コードの最初のブロックで障害物を作成していて、それらの障害物のスプライトが他のスプライトと衝突するかどうかをチェックしていません! 最初のコード ブロックで衝突するかどうかを確認するだけです。このコード ブロックは、2 回目に作成された障害物では実行されません。

私が正しいかどうかをテストするには、最初のコード ブロックでself.game.make_obstacles呼び出しを削除してみてください。衝突するスプライトが再作成されるのではなく削除されるだけです。次に、スプ​​ライトの衝突があるかどうかを確認します。

何もないことを確認したので、コードの書き直しに取り掛かります。あなたがこれを構築した方法は、私には少し不自然に思えます-私はGameMakerのためにこのようなコードを書いていました. このコードを作成する明らかに良い方法は、make_obstaclesメソッドを書き直して、障害物を配置する前に衝突をチェックするようにすることです。whileループに次のようなことを言ってもらいます

def make_obstacles(self, num, length, dx):
    for i in range(num):
        while True:
            x = random.randrange(700, length)
            y = random.randrange(10, games.screen.height - 10)
            size = random.choice([Obstacle.obstacle_1,Obstacle.obstacle_3])
            if is_empty(x, y, size):
                break
        new_obstacle = Obstacle(game = self, x = x, y = y, size = size, dx = dx)
        games.screen.add(new_obstacle)

is_emptyは基本的にブール式であり、xyが障害物サイズに対して空の場合(つまり、そこにオブジェクトを配置しても衝突が発生しない場合) は true と評価され、xyが既存の障害物と衝突する場合は false と評価されます。is_emptyを本来の動作をするブール式に置き換えます。

これにより、実行が停止しないループが発生する可能性があることに注意してください。ゲーム画面が障害物でいっぱいの場合、インタプリタは、予想される宇宙の終わりまでwhile True:ループの内容を評価し続けます。これは、画面上に障害物が多すぎないようにするか、あきらめる前に特定の回数だけ試す必要があることを意味します。(後者を選択した場合は、while True:for x in range(10000):またはその他の適切な数値に置き換えます)

これで問題が解決したことを願っています。さらにヘルプが必要な場合は、以下にコメントしてください。

于 2012-12-12T04:23:21.517 に答える