Должен ли я использовать несколько классов для игры? - PullRequest
11 голосов
/ 23 августа 2010

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

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

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

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

Ответы [ 5 ]

11 голосов
/ 23 августа 2010

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

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

edit Орк расширит Monster, а затем унаследует атрибут $ health и функцию attack ().

9 голосов
/ 23 августа 2010

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

Я никогда раньше не создавал 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 для обновления данных классов. Надеюсь, это даст вам хорошую идею:)


Есть еще:)

Если вы создаете классы для SpecialMoves, допустим, вы всегда можете сделать

$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 он будет иметь такие параметры, как урон, продолжительность времени, необходимого для завершения, сколько энергии он использует, сколько раз вы можете использовать его.

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


Пример реализации

Реализует, обеспечивает ли высший класс определенные функции и переменные

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"
*/

?>
4 голосов
/ 23 августа 2010

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

3 голосов
/ 23 августа 2010

ООП позволяет расширять классы, повторно используя ваш код. Вот простой пример. Проверьте документы 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
2 голосов
/ 23 августа 2010

Вы должны прочитать о SOLID .
Это 5 основных принципов OOD (объектно-ориентированного проектирования):

S принцип ответственности
O ручка Закрытый принцип
L iskov Принцип замещения
I Интерфейс разделения сегментов
D Принцип обращения зависимости

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...