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

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

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

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

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

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

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

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

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

Я никогда раньше не строил 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" */ ?> 

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

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

 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 

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

Принцип ответственности
O pen Закрытый принцип
Принцип замещения L iskov
Принцип Сегрегации
Принцип обращения инверсии D

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

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