GameMaker Studio 2—制作横版射击游戏教程-HeartBeast 短期小结5

这期视频讲了如何使用 用户自定义事件实现状态机。

由于实现功能使用了大量的 if-else 语句,整个 step 事件显得特别乱,而other事件里的 user event 事件可以解决这个问题。

/// @description Move towards the player
event_user(state_);

step 事件里调用 user event 事件,然后把相关的代码写入 user event 事件里即可。

// states
MOVEMENT_ = 0;
ATTACK_ = 1;
HIT_ = 2;

state_ = MOVEMENT_;

create 事件里添加如上代码,用于切换状态,下面逐一讲解 MOVEMENT_ , ATTACK_HIT_三个状态。

/// @description Movement State

// Move force
var dir = point_direction(x, y, o_player.x, o_player.y);
hspeed_ = lengthdir_x(speed_, dir);
vspeed_ = lengthdir_y(speed_, dir);
move();

// Push force
move_push_();
if !place_meeting(x, y, o_enemy) {
	hspeed_push_ = lerp(hspeed_push_, 0, .1);
	vspeed_push_ = lerp(vspeed_push_, 0, .1);
}


// Death
if health_ < 0 {
	instance_destroy();
}

if distance_to_object(o_player) < 48 {
	state_ = ATTACK_;
}

MOVEMENT_ 事件就是我们之前写过的移动代码,不做过多讲解。当与玩家的距离小于48时,切换为 ATTACK_ 状态。

/// @description Attack State
if distance_to_object(o_player) >= 48 {
	state_ = MOVEMENT_;
}

ATTACK_ 状态还没有完善(具体内容在下一节),当距离大于等于48时,切换为 MOVEMENT_ 状态,以便再次移动。

/// @description Take damage

// Push force
move_push_();
hspeed_push_ = lerp(hspeed_push_, 0, .1);
vspeed_push_ = lerp(vspeed_push_, 0, .1);


if point_distance(0, 0, hspeed_push_, vspeed_push_) < 1 {
	state_ = MOVEMENT_;
}

HIT_ 事件使得敌人在被击中时产生击退效果,这个事件要在与子弹的碰撞事件中调用。

state_ = HIT_;
var dir = other.direction;
hspeed_push_ = lengthdir_x(8, dir);
vspeed_push_ = lengthdir_y(8, dir);

dir 的值直接调用子弹的即可,然后做类似之前敌人互相碰撞的处理。

值得一提的是 HIT_ 事件里,切换为 MOVEMENT_ 状态的判断条件很奇葩,效果是当 hspeed_push_vspeed_push_ 小于1,触发语句。

经过这样的处理后,我们可以直接在对象的窗口里定义和脚本差不多的东西,显得结构较为紧凑,而不是之前那样分散。

猜你喜欢

转载自www.cnblogs.com/2ufun/p/12419211.html