网络游戏战斗系统之buff系统具体设计实现

    在网络游戏中的战斗形式多种多样,不同游戏的战斗逻辑也有很大的差异。但是一般都会涉及技能系统和buff系统,两种之间相互关联,技能可以产生buff作用在目标上,影响目标。同时buff也会影响技能的释放效果,两者都可以算得上游戏战斗系统最重要的元素。

    在游戏战斗中有许多各种各样复杂的buff和技能,这些buff和技能是由基础的buff和技能效果机制组合形成的。通过基础的机制效果的组合,形成各种各样的复杂的buff和技能。这些基础的buff效果机制和技能效果机制支持策划通过配置表配置数据,来影响这些buff和技能的实际效果。

    不同类型的游戏的战斗可能多种多样,但是只要把握核心要素,相同buff系统和技能系统可以适应不同类型的游戏。

    下面介绍我对于buff系统的理解,算是抛砖引玉吧。

    buff的来源可能是战斗单元释放的技能,可能是buff效果产生新的buff,可能是战斗一开始因为佩戴某件装备。

    buff产生的效果各种各样例如,增加\降低属性值,一定时间内流失/恢复生命、魔法等,眩晕,沉默,护盾,嘲讽,反伤,攻击时攻击增伤、受击时减伤,死亡时造成对手造成伤,击杀目标时回血等等。同一个战斗单元可以有多个buff。

    为了增加buff系统的可用性和灵活性,我们可以把一个buff拆分成一到多个基础的buff效果,通过实现基础的buff效果,灵活组合形成多种多样的buff。例如给英雄施加一个buff效果是护盾同时在buff移除时恢复英雄10%的血量,这一个buff就有两个基础效果,一个是护盾,另一个是buff移除时回复血量,一个buff可以有一到多个buff效果,而一个英雄有多个buff。

    为了管理战斗单元存在的诸多buff,需要一个buff管理器管理buff的添加、生效、移除等整个生命周期,供外部使用的接口也只能是buffManger,比如添加buff,发送buff列表,检查buff效果状态,在触发点调用来执行buff效果等等。buff基础效果、buff、buff管理器关系如下:

 

    具体实现需要设计一个buff效果的基类,其中成员变量有buff效果编号以及buff效果实现的虚函数。所有buff机制效果需要继承基类,根据具体buff效果实现void perform(unsigned char buffStep)函数,每一个buff效果编号,用于区分所属buff效果,这样便于buff管理包含的buff效果。

struct basePerform
{
	eBuffPerfrom perfromType;//可以定义一个枚举
Buff* owner;				//所属buff
	basePerform(eBuffPerfrom _perfromType, Buff* _owner):perfromType(_perfromType),owner(_owner)
	{}
virtual void perform(unsigned char buffStep)=0;//buff效果具体执行
	virtual ~basePerform(){}
};

    buff管理着一到多个继承自basePerform的子类对象。效果编号决定执行那个buff基础效果。buff中还有记录着释放buff者战斗单元的指针、buffManger的指针、buff叠加层数、buff配置数据,buff生成时间、buff类型、buff移除标志等数据。

class Buff
{
public:
	Buff(FightUnit* _attacker,buffManger* _manger,  const cBuffCfg* _cfg, eBuffType _buffType, DWORD _putTime);
	virtual ~Buff();
//一些函数实现,诸如buff效果的实现,buff初始化,标记移除等等
public:
	FightUnit* attacker;     //产生buff的FightUnit
buffManger* _manger;
	const cBuffCfg* _cfg;	   // buff配置表数据
	unsigned long putTime;    //buff的产生时间
	unsigned short overlay;   //叠加层数
	eBuffType buffType; 		//buff类型
	bool bRemove; 			//移除标记
unsigned char buffStep; 	//buff执行步骤
	std::vector<basePerform*> vecBuffPerform;//buff的所有效果
}

buffManger保存这一组buff,buffManger所属的战斗单元等数据。控制着buff的整个生命周期

class buffManger
{
public:
	buffManger(FightUnit* _owner);
	virtual ~buffManger();
//一些函数实现,比如添加/移除buff函数,timetick函数,buff触发函数,检查buff效果函数等等
privet:
	FightUnit* owner;
	std::vector<Buff*> vecBuffs;
unsigned short buffPerformStatus[eBuffPerfrom_Max];
}

buff效果多种多样,buff效果可能是某种状态,比如眩晕,在战斗单元行动或释放技能时,检查战斗单元的buffManger遍历所有的vecBuffs下所有buff的buff效果是否有眩晕效果,如果有不能行动或者释放技能。也可能是加属性值的,添加或者移除buff时根据buff效果重新计算战斗单元的属性值。或者是触发式,比如流失对于回合制的便可能是每回合造成减血,对于非回合制的可能是每秒造成减血。触发有很多点会导致触发,比如死亡时,攻击时,受击时,暴击时,格挡时等等,这样每次到触发点,要遍历所有buff的所以机制找到符合条件的执行buff效果。

为了减少遍历次数,可以在buffManger中添加buffPerformStatus数组变量,模仿只能指针做一个计数。每一个成员代表这个buffManger的buff效果的计数,如果没有相应的buff效果计数值为零,添加buff时如果有相应的buff效果,计数加一,buff移除相应buff效果也移除,计数减一。这样我们在检查某种buff状态,比如眩晕,就不需要遍历说有的buff了。触发时如果有相应的buff效果再去遍历。

这样这个buff系统模型可以适合大部分战斗,稍微改改不同的战斗都可以使用。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
游戏中,战斗buff是一种常见的技能或状态,它可以在战斗中提供各种加成或减益。虽然游戏中的实现方式因游戏不同而有所不同,但是AOP确实可以用来实现战斗buff功能。 在游戏中,战斗buff通常需要在特定的条件下触发,例如攻击或受到攻击时,或者在特定的时间段内。为了实现这个功能,我们可以使用AOP编写一个切面,它会在满足特定条件时,自动给目标对象增加或移除buff。 例如,我们可以定义一个名为"BuffAspect"的切面,它包含两个方法:一个用于在目标方法执行之前给目标对象增加buff,另一个用于在目标方法执行之后移除buff。例如: ``` @Component @Aspect public class BuffAspect { @Autowired private BuffManager buffManager; @Before("execution(* com.example.demo.Player.attack(..))") public void addBuff() { buffManager.addBuff("attackBuff"); } @After("execution(* com.example.demo.Player.attack(..))") public void removeBuff() { buffManager.removeBuff("attackBuff"); } } ``` 在这个例子中,我们定义了一个名为"BuffAspect"的切面类,并使用@Aspect和@Component注解将它标记为一个切面组件。然后,我们定义了两个方法:一个在目标方法"attack"执行之前调用,另一个在目标方法"attack"执行之后调用。在这两个方法中,我们使用BuffManager类来添加或移除名为"attackBuff"的buff。 在此示例中,我们假设"Player"类有一个名为"attack"的方法,它被用于攻击敌人。当"attack"方法被调用时,"BuffAspect"切面会自动将"attackBuff"添加到"Player"对象中,然后在"attack"方法执行完毕后,自动将"attackBuff"从"Player"对象中移除。 当然,这只是一个简单的例子,实际情况可能更加复杂。在游戏中,buff的种类可能有很多种,每种buff可能需要不同的触发条件和持续时间。因此,实现战斗buff功能需要根据具体情况进行设计实现,AOP只是其中的一种实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值