Должен ли я использовать несколько классов для игры?

Рассматриваю возможность создания текстовой RPG-программы на PHP как праздничного проекта и возможности узнать больше о PHP и ООП. (Возможно, не лучший выбор языка, я знаю, но я не хотел изучать другой язык с нуля одновременно с ООП.)

В любом случае, я только начинаю процесс проектирования и думаю о «монстры». Каждый тип монстров (вы знаете, орк, гоблин, крыса и т. Д.) Будет иметь свою собственную статистику, навыки и что нет. Сначала я подумал, что мог бы просто иметь один класс монстров и устанавливать свойства при создании экземпляра объекта. Но потом я подумал, что это может быть немного неэффективно, поэтому я подумываю о том, чтобы создать класс для каждого типа монстра .

Это лучший способ решения проблемы, учитывая, что методы в каждом классе, вероятно, будут одинаковыми? Есть ли лучший способ сделать то, о чем я еще не знаю?

Любая помощь приветствуется.

11
задан Saladin Akara 23 August 2010 в 13:59
поделиться

5 ответов

Вы можете создать абстрактный класс, скажем, Monster, а затем расширить этот класс для каждого из различных типов монстров. Итак

<?php
abstract class Monster {
  private $health;
  public function attack() {
    //do stuff
  }
}
class Orc extends Monster {
  private $damage_bonus;
}
?>

редактировать Orc расширил бы Monster, а затем унаследовал бы атрибут $ health и функцию attack ().

11
ответ дан 3 December 2019 в 03:03
поделиться

Что вам следует сделать, так это привнести в игру настоящую организацию.

Я никогда раньше не создавал PHP-игр, но у меня есть довольно хорошее представление о том, какой должна быть структура.

Сущность / монстр должен быть построен из нескольких классов, определяющих его характеристики

Вот небольшой пример из моей головы:

abstract class NonHuman implements Strengh,Weapons,Vehicles
{
     var $strength;
}
abstract class Vermin implements Strengh,Chemicals
{
    var $strength = 20;
    var $poisonous = true;
}
abstract class Humanoid implements Strengh,Weapons,Vehicles,Arms,Legs
{
}

Основная схема для абстрактных классов выглядит так:

abstract class <BeingType> implements < Characteristics , Weapons , Etc>
{
    // Depending on < Characteristics , Weapons , Etc> you should
    // Build the methods here so that theres less work in the long run.
}

Затем, когда у вас есть базовые типы существ, вы можете делать такие вещи, как

class Rat extends Vermin
{
    public function __construct($name,$strength = 50)
    {
         $this->strength = $strength;
    }

    //Any new methods here would be specific to this Being / Rat.
}

$Robert = new Rat('Robert',80);
$Andrew = new Rat('Andrew',22);

if($Robert->strength > 50)
{
    $Robert->Kick($Andrew,'left',20); //20 mph lol
    if($Andrew->IsAlive())
    {
        if($Robert->TakeWeapon($Andrew,20)) //Uses 20% force
        {
             $Robert->FireWeaponAt($Andrew,-1); //Use all bullets on andrew!
        }
    }
    if(!$Andrew->IsAlive())
    {
        $Robert->UpdateScoreFromPLayer($Andrew,100); //Max of 100 points if andrew has them.
    }
}

Сделав это, будет несложно генерировать характеристики для сущностей.

Вы также можете настроить родительские деструкторы, чтобы сохранить данные об именах пользователей в базе данных для следующего раза, и использовать __construct для обновления данных классов. Надеюсь, это даст вам хорошую идею :)


Есть еще кое-что :)

Если вы сделаете классы для специальных движений, скажем, вы всегда можете сделать

$Robert->AddSpecialMove('Roundhouse',new SpecialMove_Roundhouse(12));
$Robert->UserSpecialMove('Roundhouse',2);/ x2
if($Robert->_SpecialMoves->Roundhouse->Left() < 12)
{
    $Robert->UserSpecialMove('Roundhouse',-1);/ Use all kicks.
}

В рамках SpecialMove_Roundhouse у него будут такие параметры, как урон, время, необходимое для завершения, сколько энергии он использует, сколько раз вы можете его использовать.

и самый первый класс, который находится в области видимости, должен всегда содержать калькулятор для таких вещей, как пульс, уровень крови, энергия, инвентарь и т.д., так что у вас всегда будет самое необходимое!


Пример Implements

Implements убедитесь, что более высокий класс содержит определенные функции и переменные

interface Weapons
{
    public function Fire($target,$bullets);
}

class Colt45 implements Weapons
{
   var $damage = 2;
   var $max_bullets = 80;
   var $clip = 80;

   //THIS CLASS MUST HAVE FIRE
   public function fire($target,$bullets)
   {
      $ammo = $bullets > $clip ? $clip : $ammo;
      for($shot=0;$shot<=$ammo;$shot++)
      {
          $target->ReduceHealth($damage);
          if(!$target->IsAlive())
          {
              break;
          }
          $clip--; //Reduce ammo in clip.
      }
   }
}

Пример взят с php.net | http://www.php.net/manual/en/language.oop5.interfaces.php#96368

<?php

interface Auxiliary_Platform
{
    public function Weapon();
    public function Health();
    public function Shields();
}

class T805 implements Auxiliary_Platform
{
    public function Weapon()
    {
        var_dump(__CLASS__);
    }
    public function Health()
    {
        var_dump(__CLASS__ . "::" . __FUNCTION__);
    }
    public function Shields()
    {
        var_dump(__CLASS__ . "->" . __FUNCTION__);
    }
}

class T806 extends T805 implements Auxiliary_Platform
{
    public function Weapon()
    {
        var_dump(__CLASS__);
    }
    public function Shields()
    {
        var_dump(__CLASS__ . "->" . __FUNCTION__);
    }
}

$T805 = new T805();
$T805->Weapon();
$T805->Health();
$T805->Shields();

echo "<hr />";

$T806 = new T806();
$T806->Weapon();
$T806->Health();
$T806->Shields();

/* Output:
    string(4) "T805"
    string(12) "T805::Health"
    string(13) "T805->Shields"
    <hr />string(4) "T806"
    string(12) "T805::Health"
    string(13) "T806->Shields"
*/

?>
9
ответ дан 3 December 2019 в 03:03
поделиться

Классы определяют поведение, поэтому, если разные типы монстров в вашей игре ведут себя по-разному, моделируйте их как разные объекты. Если все монстры в основном имеют одно и то же поведение (например, у всех есть общий набор свойств, все могут атаковать, защищаться и двигаться), то вы можете сэкономить много работы, если моделируете их как один класс монстров. Вы всегда можете расширить класс монстров до специализированных классов для монстров, которые могут, например, разговаривать.

4
ответ дан 3 December 2019 в 03:03
поделиться

Прочтите о S.O.L.I.D .
Вот 5 основных принципов OOD (объектно-ориентированного дизайна):

S единый принцип ответственности
O pen Closed Principle
L iskov Принцип замещения
I nterface Segregation Principle
D ependency Inversion Principle

http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

Кстати, если вы хотите использовать наследование только для расширения некоторых свойств и методов , вы можете сделать это, используя Composition вместо Inheritance . Для добавления полиморфного поведения в структуру вашего класса следует использовать наследование.

2
ответ дан 3 December 2019 в 03:03
поделиться

ООП позволяет вам расширять классы, повторно используя ваш код. Вот простой пример. Ознакомьтесь с документацией PHP для Наследование .

class Monster
{
  public $size = 'average';
  public $color = 'grey';

  public function scare()
  {
    return "Bo!";
  }
}

class Rat extends Monster
{
  public $size = 'small';

  public function scare()
  {
    return parent::scare() . " (runs away)";
  }
}

class Mouse extends Rat 
{
  public $color = 'white';
}

Результат будет следующим:

$rat = new Rat();
echo $rat->scare(); //output: Bo! (runs away)
echo $rat->size;    //output: small
echo $rat->color;   //output: grey
3
ответ дан 3 December 2019 в 03:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: