3

それが何と呼ばれているのかわかりませんが、インスタンスだと思います。

「モンスター」クラスがあるとしましょう。このクラスには「Health」値が含まれている必要があります。クラス作成時は「5」に設定されています。また、各モンスターの一意の ID 値も含まれている必要があります。

私は次のようなことを考えています:

$monster_1 = new Monster(); //sets monster ID to 1
$monster_2 = new Monster(); //sets monster ID to 2
$monster_3 = new Monster(); //sets monster ID to 3

では、すべてのモンスターの合計 HP を計算したいとしましょう。

$totalHp = $monster_1->getHp() + $monster_2->getHp() + $monster_3->getHp();

それも機能しますが、 という名前の新しいモンスターを追加するとどうなりますか$monster_4。$totalHp の計算に手動で追加する必要があります。

変数の代わりに配列を作成$monsterし、foreach で $totalHp を計算することもできますが、奇妙に見えます...

他の言語でどのように行われているかはわかりません。

これをアーカイブする他の方法はありますか?

Ps。「 http://www.scirra.com/demos/ghosttutorial/」ゲームの背後にあるロジックを取得しようとしています。Monster クラスを作成すると、各 Monster はこのクラスをインスタンスとして使用します。私の解決策は間違いなく機能しますが、これがハックな方法であるかどうかはわかりません。

4

10 に答える 10

3

モンスターのセットを保持するヘルパークラス、おそらくMonsterTeamクラスを作成します。

class Monster {
     ...
}

class MonsterTeam {
    private $_monsters = [];

    public function addMonster(Monster &$monster) {
        array_push($this->_monsters, $monster);
    }

    public function getTotalHp() {
        $hp = 0;

        foreach ($this->_monsters as $monster) {
            $hp += $monster->getHp();
        }

        return $hp;
    }
}


$team = new MonsterTeam();

$monsterA = new Monster();
$team->addMonster($monsterA);

$monsterB = new Monster();
$team->addMonster($monsterB);

echo "Total HP: " . $team->getTotalHp();
于 2012-06-08T19:38:23.743 に答える
2

まず、オブジェクト指向プログラミングのように、オブジェクトまたはインスタンスと呼ばれますか?

第二に、モンスターの配列を作成することを妨げるものは何もありません (奇妙に見えません):

$monsters = array(
    new Monster(),
    new Monster(),
    new Monster(),
    new Monster()
);

foreach($monsters as $monster) {
    $totalHP += $monster->hp;
}

固有 ID については、モンスターに ID を割り当てる必要があります。つまり、モンスター自体に ID を割り当てるのではなくMonsterFactoryモンスターにIDを割り当てる必要があります。モンスター作成時はこんな感じ。

new Monster(4); //ID is 4

誰がそれを追跡しますか?モンスターではなく、他の誰か。

于 2012-06-08T19:34:32.303 に答える
1

$monsters次のような配列を作成できます。

$monsters = array();

次に、モンスターを追加するたびに、次のようにします。

$monsters[] = new Monster();

次に、配列をループして、次のように合計ヒットポイントを取得できます。

$totalHP = 0;
foreach($monsters as $monster) {
    $totalHP += $monster->getHp();
}

そのループの後$totalHP、配列内のすべてのモンスターの合計ヒットポイントが含まれます。

于 2012-06-08T19:36:01.700 に答える
1

コレクション ファクトリを作成できます。新しいモンスターの作成を担当します。通常、2 つのクラスを融合することは私の好みではありませんが、この方法でコンストラクターをプライベートにできるという事実が気に入っています :)

2 つの静的変数 (美化されたグローバルだと思います) を使用します。1 つはモンスター ID 用で、もう 1 つはモンスターのコレクション用SplObjectStorageです。

すべてのモンスターを反復する必要があるメソッドは メソッドを使用するeach()ため、必要なロジックはクラスの外で定義できます。

class Monster
{
  private $id;
  public $health;

  private static $instances;
  private static $nextid = 1;

  // private constructor
  private function __construct($id)
  {
    $this->id = $id;
    $this->health = 5;
  }

  public static function create()
  {
    if (!self::$instances) {
      self::$instances = new SplObjectStorage;
    }
    $o = new self(self::$nextid++);
    self::$instances->attach($o);

    return $o;
  }

  public static function remove($o)
  {
    if (!self::$instances) { return; }
    self::$instances->detach($o);
  }

  // iterate over all objects
  public static function each($cb)
  {
    if (!self::$instances) { return; }
    foreach (self::$instances as $o) {
      $cb($o);
    }
  }
}

ちょっとした使用例

$m1 = Monster::create();
$m2 = Monster::create();

$total_health = 0;
Monster::each(function(Monster $m) use (&$total_health) {
  $total_health += $m->health;
});
echo "Total health: $total_health\n";
于 2012-06-08T19:45:20.393 に答える
1

モンスターのコンテナとして機能するオブジェクトを使用し、それを使用して追跡することができます。

class MonsterContainer
{
    private $monsters = array();

    public function __construct()
    {
       // do stuff   
    }   

    public function addMonster(Monster $monster)
    {
        $this->monsters[] = $monster;   
    }

    public function totalMonstersHP()
    {
        $hp = 0;
        foreach ($this->monsters as $monster)
        {
            $hp += $monster->getHp()
        }
        return $hp;
    }
}

$monster_1 = new Monster(); 
$monster_2 = new Monster(); 
$monster_3 = new Monster(); 

$container = new MonsterContainer();
$container->addMonster(monster_1);
$container->addMonster(monster_2);
$container->addMonster(monster_3);
echo $container->totalMonstersHP();
于 2012-06-08T19:34:30.130 に答える
0

私は 2 番目の alexn です。配列を使用してクラス インスタンスを格納することはまったく問題ありません (はい、正しい用語です)。

を使用foreachして、合計 HP を計算できます。

于 2012-06-08T19:34:56.000 に答える
0

getNewMonster()メソッドとを含む MonstersCollection クラスを作成しますgetTotalHP()

擬似コード:

class MonstersCollection
{
   private $Monsters;

   public function getNewMonster()
   {
       $Monster=new Monster();
       $this->monsters[]=$Monster;
       return $Monster;
    }

   //and you know how to write method to get total HP :)
}
于 2012-06-08T19:34:59.057 に答える
-1

クラスがそのインスタンスを追跡することは非常に一般的です。

class Monster {
    private $monsters = array();
    public function __construct() {
       self::monsters[] = $this;
    }

    public  function __destruct() {
        array_splice(self::monsters, array_search($this, self::monsters), 1 );
    }

    public static function getTotalHp() {
         $total = 0;
         foreach(self::monsters as $monster) {
            $total += $monster->getHp();
         }
         return $total;
    }    
}
于 2012-06-08T19:47:13.690 に答える
-2

コンストラクターで呼び出されるのと同じMonsterクラスで新しいクラスまたは関数を作成でき、クラスが作成されるたびに、増加するグローバル変数を呼び出すことができます。

于 2012-06-08T19:36:46.673 に答える
-2

Monsterのインスタンス化時に、集中化されたオブジェクトのtotalHpプロパティを自動的に更新できるオブザーバーパターンを作成できます。

しかし、より速く/より簡単な方法は、モンスタークラスでは次のようになります。

class Monster {

   ...
   private $hp = 5;
   private static $totalHp = 0;
   ...

   public function getHp() {
       return $this->hp;
   }

   public function __construct(...) {
       ...
       self::totalHp += $this->getHp();
       ...
   }

   public function __destruct(...) {
       ...
       self::totalHp -= $this->getHp();
       ...
   }

   ...

   public static function getTotalHp() {
       return self::totalHp;
   }

   /**
    * Provide negative number to reduce HP or positive to increase HP.
    */
   public function alterHp($hp) {
       $this->hp += $hp;
       self::totalHp += $hp;
   }
}

次に、現在のtotalHp値を取得するには、クライアントコードで次のことを行う必要があります。

$totalHp = Monster::getTotalHp();
于 2012-06-08T19:38:45.030 に答える