Должен ли я использовать несколько классов для игры?
Я рассматриваю возможность создания текстовой RPG-программы на PHP как проект праздника, а также возможность узнать больше о PHP и ООП. (Может быть, это не лучший выбор на языке, я знаю, но я не хотел, чтобы учиться другому языку с нуля в то же время, что и ООП.)
В любом случае, я только начинаю процесс проектирования и думаю о "монстрах". Каждый тип монстра (я знаю, орк, гоблин, крыса и т.д.) Будет иметь свои собственные характеристики, навыки, а что нет. Сначала я, хотя я мог просто иметь один класс монстров и устанавливать свойства при создании объекта. Но потом я подумал, что это может быть немного неэффективно, поэтому я подумываю о том, чтобы иметь класс для каждого типа монстра.
Это лучший способ подойти к проблеме, учитывая, что методы в каждом классе, вероятно, будут одинаковыми? Есть ли лучший способ делать то, о чем я еще не знаю?
Любая помощь приветствуется.
Ответы
Ответ 1
Вы можете создать абстрактный класс, скажем, Monster, а затем расширить этот класс для каждого из разных типов монстров. Так
<?php
abstract class Monster {
private $health;
public function attack() {
//do stuff
}
}
class Orc extends Monster {
private $damage_bonus;
}
?>
изменить
Орк расширяет Monster, а затем наследует атрибут $health и функцию attack().
Ответ 2
Что вам нужно сделать, так это получить какую-то реальную организацию в игре.
Я никогда раньше не строил PHP-игру, но у меня довольно хорошая идея, как должна выглядеть структура.
A Entity/Monster должен быть создан из нескольких классов, определяющих его характеристики.
Вот небольшой пример верхней части головы:
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"
*/
?>
Ответ 3
Классы относятся к поведению, поэтому, если разные типы монстров в вашей игре ведут себя по-другому, то моделируйте их как разные объекты. Если все монстры в основном используют одно и то же поведение (например, все имеющие общий набор свойств, все могут атаковать или защищать и перемещать), тогда вы можете сэкономить много работы, если вы моделируете их как один класс монстров. Вы всегда можете расширить класс монстров в специализированные классы для монстров, которые могут, например, разговаривать.
Ответ 4
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
Ответ 5
Вы должны прочитать о S.O.L.I.D.
Это 5 основных принципов OOD (объектно-ориентированный дизайн):
S ingle Принцип ответственности
O ручка Закрытый принцип
L iskov Замена Принцип
I Принцип сегрегации nterface
D Принцип обращения вспять
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Кстати, если вы хотите использовать наследование только для расширения некоторых свойств и методов, вы можете сделать это, используя Состав вместо наследования. Наследование должно использоваться, чтобы добавить к вашему классу структуру полиморфного поведения.