关于php:我应该在游戏中使用多个类吗?

Should I use multiple classes for game?

我正在考虑用PHP编写一个基于文本的RPG类型的程序,它既是一个假日项目,也是一个了解PHP和OOP更多信息的机会。(也许在语言上不是最好的选择,我知道,但我不想在学习OOP的同时从零开始学习另一种语言。)

不管怎样,我刚刚开始设计过程,并考虑"怪物"。每种怪物类型(你知道,兽人,妖精,老鼠等)都有自己的属性,技能和其他。起初,我想我可以只拥有一个怪物类,并在实例化对象时设置属性。但后来我觉得这可能有点低效,所以我正在考虑为每种类型的怪物开一门课。

考虑到每个类中的方法可能相同,这是处理问题的最佳方法吗?有没有更好的方法来做我还不知道的事情?

感谢您的帮助。


您可以创建一个抽象类,比如说Monster,然后为每种不同类型的Monster扩展该类。所以

1
2
3
4
5
6
7
8
9
10
11
<?php
abstract class Monster {
  private $health;
  public function attack() {
    //do stuff
  }
}
class Orc extends Monster {
  private $damage_bonus;
}
?>

编辑兽人会扩展怪物,然后继承属性$health和函数attack()。


你应该做的是让一些真正的组织进入游戏。

我以前从未构建过一个PHP游戏,但我对结构应该是什么有很好的了解。

一个实体/怪物应该由几个定义其特征的类组成。

下面是我头顶的一个小例子:

1
2
3
4
5
6
7
8
9
10
11
12
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
{
}

抽象类的基本布局如下:

1
2
3
4
5
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.
}

一旦你有了自己的基础类型,你就可以做像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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.
    }
}

通过这样做,就不难为实体生成特征。

您还可以设置父析构函数,将用户名数据保存到数据库中以便下次使用,并使用_uu构造更新类数据。希望这能给你一个好主意:)

还有更多:

如果你为特殊动作开课,让我们说你总是可以的。

1
2
3
4
5
6
$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中,它将具有一些参数,例如损坏、完成所需的时间长度、它使用的能量、您可以使用它的次数。

第一节课,在范围内,我总是需要一个计算器来计算心率、血量、能量、库存等等,所以你总是有必要的!

实现示例

实现确保更高的类包含某些函数和变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?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文档的继承性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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';
}

输出将是:

1
2
3
4
$rat = new Rat();
echo $rat->scare(); //output: Bo! (runs away)
echo $rat->size;    //output: small
echo $rat->color;   //output: grey


你应该读一下S.O.L.I.D.以下是面向对象设计的5个基本原则:

单一责任原则o笔关闭原则l iskov替代原则界面隔离原则依赖性反演原理

http://butunbebob.com/articles.unbebb.principlesofood

顺便说一下,如果您只想使用继承来扩展一些属性和方法,那么可以使用组合而不是继承来实现这一点。继承应该用于向类结构添加多态行为。