4

私は現在、自分のゲーム デザインで設計上の問題に直面しています。ひどいものではありませんが、十分に気になるので、他の人の意見を聞きたいです :-)

私は現在 pygame を試しています。小さなスペース シューターを開発しましたが、いくつかのボーナスを処理したいと考えています。

現在、私は現在実装されているすべてのボーナスを派生させる抽象クラス ボーナスを持っています: プレイヤーにいくらかのヘルスを戻す「ヘルス ボーナス」、プレイヤーのヘルスを 1 に落とす「デス ボーナス」です。

私のゲームループでは、これが私がしていることです(大まかに):

def testCollisionBonusBolt():
    #bolts are sprites fired by the player that allow him to get the bonuses
    collisions = pygame.sprite.groupcollide(bonusesGroup, boltsGroup, True, True)
    for col in collisions:
        player.bonuses.append(col)

そして、プレイヤーにボーナスを使うように言った直後

class Player:
...
def useBonuses(self):
    for bonus in self.bonuses:
        bonus.use(self)

これまでのところはすべて問題ありませんが、プレイヤーが撃ったときに爆発して周囲の敵を殺す「爆弾ボーナス」を追加したいと思います。

この「ボーナス」は、私の抽象クラス Bonus の「use(target)」メソッドを他のものと同じように実装していますが、そのようなボーナスをプレーヤーのボーナスのリストに追加するのはちょっと悪い気がします。

ボーナスの背後にある概念は、これが「何かに何かをするもの」であるということです。以前は私のプレーヤークラスのターゲットでしたが、今ではそれほど明確ではありません...もちろん、どのボーナスがどこにあるかを検出した後に player.useBonuses() を呼び出す代わりにたとえば、ボーナスのタイプを(isinstanceを使用して)テストできましたが、ダックタイピングについて読んだすべての議論の後、なぜそれがpythonicな方法なのか、ボーナスの問題をどのように管理できるのか疑問に思っていますか?

ここまで読んでくれてありがとう、皆さんが私を助けてくれることを願っています!

よろしく

4

4 に答える 4

1

col特定のものを入れたくない場合は、抽象クラスにデフォルトの実装でメソッドをplayer.bonuses作成します。toplayerBonus

def toplayer(self, player):
    player.bonuses.append(self)

クラスでそれをオーバーライドしますbomb bonus。(あなたが言及したように、継承する必要はありませんが、機能を簡単に再利用できるのであれば、継承しても問題はありません。)

したがって、たとえば、プレーヤーはbomb通常None、属性を持ち、bomb bonusクラスは次のようにすることができます。

def toplayer(self, player):
    player.bomb = self

そして、発生したすべてのボーナスに対処するときが来たら、それは次のことから始めることができます

if player.bomb is not None:
    player.bomb.explode(player.position)

など。

于 2009-07-06T05:24:22.520 に答える
1

私はPythonで書いていませんが、ここに私の推奨事項があります:プレイヤーが入手できる各タイプの武器(ボーナスによる武器も含む)をロードし、ボーナスにより入手した武器の弾薬を0に設定します。 「爆弾ボーナス」(または何でも)を上げて、プレーヤーの爆弾武器に弾薬を1つ追加します。それはうまくいくはずです。

于 2009-07-06T05:25:37.353 に答える
0

あなたは正しい方向に進んでいると思います。「爆弾ボーナス」は、プレイヤーの周りの敵に影響を与えるため、プレイヤーオブジェクトに関連していると思います。次のような「爆弾ボーナス」のuse()メソッドを実装する必要があります。

class BombBonus(Bonus):
    def use(self, player):
        assert isinstance(player, Player)
        # TODO: find all enemies that are close to the player - assuming you
        # have all enemy objects in a list call 'enemies'
        global enemies
        for enemy in enemies:
          if distance(player.position, enemy.position) < 400:
            # if the distance between player and an enemy is less than 400
            # (change this value to your liking), destroy that enemy.
            enemy.explode()

の独自の実装を作成する必要がありますdistance()

詳細な計画なしでゲームを開発するということは、既存のオブジェクトにほぼ適合する新しいアイデアを思いつくことが多いことを意味します。新しいアイデアをサポートするために既存のクラスを新しい機能で拡張するか、新しいアイデアを作成するかを選択する必要があります。新しいアイデアがあまりにも違うと思うので、クラスのセット。ここには正しいことも悪いこともありません。あなたのアイデアがあなたにとって意味のある方法で整理されていることを確認してください。

于 2009-07-06T05:37:29.793 に答える
0

数年前に書いた小惑星のクローンにボーナス システムがありました。それは現在、 Bitbucketに存在します (死んだプロジェクトが存在できる限り) 。あなたが目指しているほど柔軟ではないと思います。しかし、小さな「ボーナス」エンティティがスポーンして動き回り、小惑星と衝突すると、ボーナスが取り除かれ、プレイヤーは逃してしまいます。プレイヤーがそれに衝突すると、ボーナスポイントが付与されます。

于 2009-12-04T10:51:18.480 に答える