所以我有许多物品,每种物品都具有不同的属性(砖块,玻璃等),每个物体都受到元素效应的不同影响。例如,砖材料受到火或酸的影响不同于水泥材料。当应用另一种燃烧/熔化效果时,燃烧或熔化的砖会受到不同的影响。
在我的游戏中,我有一个FSM,但它非常简单。如果我在砖上放下火元素,它将进入燃烧状态。然而,如果我然后在砖上放下一个水元素,我可能会想要灭火,采取/添加健康和更改纹理(或不取决于当前的组合)。
关键是,我有很多组合,它们之间没有共性,所以我不能创造统一的东西。有时我需要改变纹理,有时我不需要。有时会受到伤害,而其他时候会增加健康有时我需要在函数中什么都不做。在这一点上,我唯一能做的就是创建一个全局映射,例如:
FunctionMap [ObjectMaterial] [CurrentObjectState] [ElementBeingApplied]
(即
FunctionMap [砖] [燃烧] [酸]
FunctionMap [砖] [熔点] [酸]
)
问题在于,由于材料和效果类型可用的组合数量,这显然是一大堆功能。任何人都可以推荐一个采取或模式的路线来看待?
尽管与讨论并不完全相关,但这是在AS3和Away3D中进行的。
以下是我的一些示例:
public class Brick extends AbstractBlock implements IFireable
{
public function Brick()
{
super(this);
this.material = new BitmapMaterial(_spriteManager.GetBlockMaterial(BlockUtilities.GetMaterialMap["brick_new"]));
_type = "Brick";
/*
RulesManager.StateMap["Brick"]["OnFire"]["Water"] = some function;
RulesManager.StateMap["Brick"]["OnFire"]["Fire"] = some function;
RulesManager.StateMap["Brick"]["OnFire"]["Acid"] = some function;
RulesManager.StateMap["Brick"]["OnFire"]["Ice"] = some function;
RulesManager.StateMap["Brick"]["OnWater"]["Water"] = some function;
//and so on...there are nine different materials so I'm not liking this way
*/
}
public override function render():void
{
super.render();
}
}
public class OnFire extends AbstractDamage
{
protected var _timeStart:Number = 0;
private var _damageAccumulated:Number = 0;
public function OnFire(block:AbstractBlock,bombType:String)
{
super(block,bombType);
}
public override function enter():void
{
super.enter();
}
public override function exit():void
{
super.exit();
}
public override function update(time:Number):void
{
super.update(time);
if(_timeStart == 0)
_timeStart = time;
var time_delta:Number = (time - _timeStart)/_waitTime;
var damageToSubtract:Number = (time_delta * _damageDone);
_damageAccumulated += damageToSubtract;
_self.Integrity = _self.Integrity - _damageAccumulated;
}
}
}
因此,火元素可以应用于一堆应用。目前被冻结的那些块现在被击中,现在正在改变为OnFire状态。每个块都有自己的状态机,状态本身就是你可以看到的对象。
block.FSM.changeState(new OnFire(block));
答案 0 :(得分:1)
您是否设置了自定义类?对我来说,这听起来像一个理想的解决方案。 一旦你绘制出每个类的属性和能力,对象管理应该是微不足道的。
即一个Brick类,当它与另一个类[水类]相互作用[碰撞]时,它具有某些状态[燃烧,熔化]并以不同的方式作出反应[函数调用]。
我希望我不会在错误的树上狂奔......如果你能提供更多关于你所寻找的东西,我相信比我聪明的人会跳进去;)
答案 1 :(得分:1)
简短的回答是因为我相信Linquist先生在解释它方面做得很好 - 但听起来像是visitor pattern的工作。简而言之,你的元素(砖块,混凝土等)都允许访客(火,冰,酸等)来“访问”它们并应用它们的效果。
希望这有帮助!
答案 2 :(得分:1)
所以你的问题是你有9 * 5 * 4种效果组合,对吧?为每个人分别提供各种功能,管理起来并不好玩。但是,即使它是大量数据,你也需要它。我会尽可能简化数据,然后解析它。类似的东西:
var materialProperties = {
brick: {
fire: {
normal: {damage: 10, image: 'brick_fire.jpg'},
}
water: {
fire: {damage: 0, image: 'brick_smoking.jpg'}
}
},
//... a lot more of this ...
}
class Material
{
public var damage:int = 0;
public var image:String = '';
private var properties:Object;
private var state:String;
public function Material(properties)
{
this.properties = properties;
}
public function apply(effect:String):void
{
if(properties[effect])
{
if(properties[effect][state])
{
update(properties[effect][state]);
}
else if(properties[effect]['normal'])
{
update(properties[effect]['normal']);
}
}
state = effect;
}
private function update(properties):void
{
damage += properties.damage;
image = properties.image;
}
}
var brick = new Material(materialProperties.brick);
brick.apply('fire');
brick.apply('water');