我正在研究游戏的随机波系统。这个想法是每1000个点就可以从大约50种可能性中选择一种运动模式。这会影响所选项目的速度,方向和图像。我设计了一种方法,我觉得它会起作用,但我不确定这是否会耗费太多内存来运行。
public class engine extends MovieClip {
private var countK:Number = 0;
private var newWave:Boolean = true;
public function engine() {
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function update():void {
checkCount();
checkNew();
}
private function checkCount():void {
if (count => 1000) {
newWave=true;
count = 0;
}
}
private function checkNew():void {
if(newWave) {
randomNumber();
newWave=false
}
}
以上是我的快速想法,即每1000点生成一个随机数。可以以您想要的任何方式添加积分(只需将20添加到“分数”,将20添加到“计数”同时)。我可以在checkNew中使用随机数函数,我不会拉另一个函数,它只是为了易读性而存在。
var newEnemy:mEnemy =new mEnemy();
stage.addChild(newEnemy);
EnemyArray.push(newEnemy);
trace(EnemyArray.length);
上面是一些可以将mEnemy实例添加到舞台的代码。现在,我开始放松它,我怎样才能将随机数转换为改变mEnemy行为的可行方法?
在mEnemy类中有50个函数是明智的,就在addChild之前,我做了像newEnemy.WAVEfuncton1(); ?如果是这种情况,我可以通过选择函数来保存代码而无需编写大量的if语句吗?
而不是;if (randomN==1) {
newEnemy.WAVEfunction1();
}
if (randomN==2) {
newEnemy.WAVEfunction2();
}
....
我可以吗;
newEnemy.WAVEfunction[randomN]();
这也是假设在敌人中使用函数是最好的主意。改为在引擎类中使用行为更好吗?
正如你所看到的,我不是程序员。我对这种想法很陌生,我不想制造一个会破坏游戏性能的错误(更不用说养成坏习惯了!)。
如果你花时间阅读这个问题,谢谢!如果你容忍我的无知,那就多谢了你!
答案 0 :(得分:0)
如果wave函数只是创建某个类型的单个敌人,那么制作一个包含每种类型细节的数组可能更有意义:(我猜你的敌人当然是如何工作的)< / p>
private const ENEMY_TYPES:Array = [
{speed:1, direction:90, image:1},
{speed:2, direction:45, image:2}
]
然后根据您提供的详细信息更改mEnemy()以设置自己:
public function mEnemy(details:Object) {
mySpeed = details.speed;
...
这样,你可以写new mEnemy(ENEMY_TYPES[randomN]);
或者,如果您确实需要具有大量单独的wave函数,则可以使用[ ] array access operator按名称(或newEnemy
来访问对象的属性,例如this
引用当前对象):
var exampleProperty:String = "Hello.";
this["exampleProperty"];
因此,您可以通过编写以下命令来运行wave函数:
newEnemy["WAVEfunction" + String(randomN)]();
答案 1 :(得分:0)
一个2岁的问题而且已经非实际问题,但让我在这里尝试自己,因为我刚刚注册了。
据我了解,你在这里提出的建议是为每种敌人编写所有50种行为方法,这当然不好。
首先,您可以添加&#34;行为&#34;实体。所以每个敌人现在都有行为属性。
接下来,您必须创建一个单独的Behavior类或接口,它将有50个子类(Behaviour1 ... Behaviour50),每个子类实现自己的run()方法。请注意,通过这种方式,您可以在不触及任何其他内容的情况下添加或删除行为。基本实现如下所示:
public class Behaviour() {
public function run(e:Enemy):void {
e.y += 10;
}
}
所以你看,它并不像敌人在做什么。它的行为与传递给它的敌人做了一些事情。
接下来,您需要一种机制来从给定的随机数中获取正确的子类。
您需要的是Factory - 一个静态类,它将根据输入参数返回不同类型的行为。像这样:
public class BehaviourFactory {
public static getBehaviour(n:int):Behaviour {
switch(n) {
case 1: return new Behaviour1();
case 2: return new Behaviour2();
// etc.
}
}
}
您可以使用类定义:
,而不是在交换机中有50个选项var c:Class = getDefinitionByName('Behaviour' + your_random_number) as Class;
return new c;
(在进一步的实现中,它可以被缓存,存储在数组等中。)在你拥有一个工厂后,你就可以了:
var b:Behaviour = BehaviourFactory.getBehaviour(your_random_number);
接下来,您可以根据行为的确切变化使用不同的方法。例如,如果敌人天生具有特定的当前行为并且在敌人的生命期内不会发生变化,则可以将行为子类中的一个分配给敌人的行为属性:
public class Enemy {
public var behaviour:Behaviour;
public function Enemy(b:Behaviour) {
this.behaviour = b;
}
}
var e:Enemy = new Enemy(BehaviourFactory.getBehaviour(random_number));
e.behaviour.run(e);
此属性当然也可以动态更改,以便下次运行时敌人的行为会有所不同。
如果所有敌人的行为都是全局的,并且所有敌人的行为都是全局的,那么您不需要在Enemy对象中拥有属性。你只有一个全局的Behavior对象并传递一个Enemy实例:
var e:Enemy = enemy_list[i];
current_behaviour.run(e);
它将根据当前选择的行为处理每个活跃的敌人。
最后,有更有趣的方式来实现行为。假设您有几种行为类型没有共同点。说,敌人可以是爬行,飞行,射击和毒药。因此,让我们假设你试图实现所有可能的组合:Flying,FlyingShooting,FlyingPoisonous,FlyingShootingPoisonous等。尽管它们具有非常常见的基本部分,但您必须为每个组合创建一个Behavior子类。
还有另一种方法,称为装饰者模式。您只需为每种质量编写一种方法。无论何时需要质量组合,您只需创建具有第一质量的对象并将其包装到具有第二质量的对象中,并将其包装到具有第三质量等的对象中。因此,您的基本行为类需要一个添加:
public class Behaviour {
private var parent_bhv: Behaviour;
public function Behaviour(bhv:Behaviour = null) {
if (bhv) this.parent_bhv = bhv;
}
public function run(e:Enemy):void {
e.y += 10; // do what we need to do
if (this.parent_bhv) this.parent_bhv.run(e); // pass to a next bhv.
}
}
让我们创建数字1,3和15的复合行为:
var decorated_behaviour:Behaviour = BehaviourFactory.getDecoratedBehaviour([1, 3, 15]);
让我们添加相应的BehaviourFactory方法:
public class BehaviourFactory {
public static function getDecoratedBehaviour(bhv_list:Array):Behaviour {
var b:Behaviour = null;
for (var i:int = 0; i < bhv_list.length; i++) {
var c:Class = getDefinitionByName('Behaviour' + bhv_list[i]) as Class;
b = new c(b);
}
return b;
}
}
现在您无需编写所有可能的组合即可完成所有设置!