用于对两个竞争对象建模的设计模式

eme*_*his 7 events design-patterns software-design game-engine game-loop

我正在试图找出用于管理两个交互对象之间"竞争"的最佳设计模式.例如,如果我想要Fox一个Rabbit通过简单环境追逐类的类.我想让他们"竞争"并找出哪一个获胜.最终它将成为学生可以用来试验继承和其他OO编程技能的教学工具.

这个用例是否有既定的设计模式?

这是我能想到的最好的:一个表示托管其他对象的环境的类.我保持它非常简单,并假设动物只是直线运行而狐狸抓住兔子,如果他足够接近咬兔子.这是一些代码,展示了我所描述的内容.我使用PHP是因为我可以快速编写它,但我不想专注于语言的细节.我的问题是关于设计模式/架构.

class Forrest() {
        public $fox;
        public $rabbit;
        public $width = 100; //meters?
        public $length = 100;

        __construct() {
                $this->fox = new Fox();
                $this->rabbit = new Rabbit();
                $this->theChase();
        }

        public function theChase() {
                 while (!$this->rabbit->isBitten) {
                         $this->rabbit->react($fox);
                         $this->fox->react($rabbit);
                 }
                 log('The fox got the rabbit!');
        }
}

abstract class Animal() {
        public $speed;
        public $hasTeeth = false;
        public $position;
        public $direction;
        public $isBitten = false;
        public function run($distance) {
                // update coordinates based on direction and speed
        }

        public function bite($someone) {
                 if (isCloseEnough( $someone ) && $this->hasTeeth) {
                          $someone->isBitten = true;
                          log(get_class($this) . ' bit the ' . get_class($someone)); //the Fox bit the Rabbit
                 }
        }

        public abstract function react($someone);
}

class Rabbit extends Animal {
         __construct() {
                  $this->speed = 30;
                  $this->position = [0,0];
                  $this->direction = 'north';
                  log(get_class($this) . ' starts at 0,0');
         }

         public react($fox) {
                //avoid the fox
         }
}

class Fox extends Animal {
          __construct() {
                  $this->speed = 20;
                  $this->position = [100,100];
                  $this->direction = 'south';
                  log (get_class($this) . ' starts at 100,100');
          }

          public react($rabbit) {
                  //try to catch the rabbit
          }
}
Run Code Online (Sandbox Code Playgroud)

我用这种方法看到了两个直接的问题:

  1. 该架构导致顺序的交替动作.换句话说,首先兔子做了什么然后狐狸做了什么然后兔子做了什么...这更像是一个纸牌游戏,每个玩家轮流移动.如果两个物体能够同时作出反应会更有趣.

  2. 目前还没有一种限制每次"转弯"活动量的系统.需要对单个"转弯"中可能发生的事情进行某种限制以保持其有趣.否则,狐狸可以简单地run() run() run()...... run()直到它在第一次转弯时抓住兔子. 

可能还有其他问题我还没有注意到.我怀疑上面(1)和(2)的答案都是某种事件系统,允许一只动物采取行动从另一只动物触发行动,反之亦然.我也认为可能需要对每个动作的时间进行一些表示,但我并不完全确定.

小智 2

在游戏循环中,通常会更新两个对象的速度(在您的反应函数中),然后更新对象的位置。从而同时移动。

while(!gameOver) {
 rabbit->react(fox);
 fox->react(rabbit);
 rabbit->updatePosition();
 fox->updatePosition();
}
Run Code Online (Sandbox Code Playgroud)

为了限制每回合/帧的活动,你必须想出一些聪明的办法。例如,您可以执行一组可以执行的操作,并且每个操作都有能量成本。每回合你都会获得一定量的能量来使用。不过,为了让这一点变得有趣,你必须有多个 run() 操作:)。