案例研究:高级动作系统在不同类型游戏中的应用
在上一节中,我们探讨了如何在GameMaker Studio中构建基础的动作系统。本节将通过具体案例研究,展示高级动作系统在不同类型游戏中的应用。这些案例将涵盖常见的动作游戏类型,如平台游戏、射击游戏、格斗游戏和冒险游戏,帮助你更深入地理解如何根据游戏类型和需求设计和实现高效的高级动作系统。
平台游戏中的高级动作系统
平台游戏(Platformer)是动作游戏的一个经典类型,玩家通常控制一个角色在不同的平台上跳跃、奔跑和攻击。高级动作系统在平台游戏中可以显著提升游戏的可玩性和挑战性。我们将通过一个具体的案例来展示如何实现这些功能。
1. 角色跳跃的高级控制
在平台游戏中,角色的跳跃控制是核心要素之一。传统的跳跃控制可能只是简单的按下跳跃键,角色就会跳起。但高级的跳跃控制可以包括多种状态,如短跳、长跳、二段跳和空中冲刺等。
代码示例:二段跳
// 在对象的 Create 事件中初始化变量
var jump_count = 0;
// 在对象的 Step 事件中处理跳跃逻辑
if (keyboard_check_pressed(vk_space)) {
if (jump_count < 2) {
// 执行跳跃
vspeed = -10;
jump_count += 1;
}
}
// 在对象的 Collision 事件(与地面碰撞)中重置跳跃次数
if (place_meeting(x, y + 1, obj_ground)) {
jump_count = 0;
}
代码解释
-
jump_count
:记录角色当前的跳跃次数,初始值为0。 -
keyboard_check_pressed(vk_space)
:检查跳跃键(空格键)是否被按下。 -
place_meeting(x, y + 1, obj_ground)
:检查角色是否与地面发生碰撞,确保角色在地面上时可以重新跳跃。
2. 空中冲刺
空中冲刺是平台游戏中的一种高级动作,可以让角色在空中进行短暂的快速移动。这种动作可以增加游戏的动态感和可玩性。
代码示例:空中冲刺
// 在对象的 Create 事件中初始化变量
var jump_count = 0;
var is_dashing = false;
var dash_speed = 20;
var dash_time = 0.1;
// 在对象的 Step 事件中处理空中冲刺逻辑
if (keyboard_check_pressed(vk_shift) && jump_count > 0 && !is_dashing) {
// 执行空中冲刺
is_dashing = true;
image_index = 0; // 重置动画帧
image_speed = 1; // 启动动画
if (keyboard_check(vk_right)) {
hspeed = dash_speed;
} else if (keyboard_check(vk_left)) {
hspeed = -dash_speed;
}
alarm[0] = room_speed * dash_time; // 设置冲刺时间
}
// 在对象的 Alarm 事件中结束空中冲刺
if (alarm[0]) {
is_dashing = false;
hspeed = 0;
image_speed = 0; // 停止动画
}
代码解释
-
is_dashing
:布尔变量,表示角色是否正在冲刺。 -
dash_speed
:冲刺的速度。 -
dash_time
:冲刺的持续时间。 -
alarm[0]
:用于控制冲刺时间的报警。 -
image_index
和image_speed
:用于播放角色冲刺动画。
3. 动态地形和反应
平台游戏中,地形的动态变化可以增加游戏的复杂性和趣味性。角色需要对这些动态地形做出反应,如跳跃、滑行或攀爬。
代码示例:动态地形反应
// 在对象的 Step 事件中处理地形反应
if (place_meeting(x, y + 1, obj_ground)) {
// 角色在地面上
if (keyboard_check_pressed(vk_up) && place_meeting(x, y - 1, obj_ladder)) {
// 角色在梯子上
vspeed = -4;
} else {
// 角色在平地上
vspeed = 0;
hspeed = 0;
if (keyboard_check(vk_right)) {
hspeed = 4;
} else if (keyboard_check(vk_left)) {
hspeed = -4;
}
}
} else if (place_meeting(x, y + 1, obj_moving_platform)) {
// 角色站在移动平台上
vspeed = 0;
hspeed = obj_moving_platform.hspeed;
} else {
// 角色在空中
vspeed += gravity;
}
// 在对象的 Collision 事件(与移动平台碰撞)中处理移动平台的碰撞
if (place_meeting(x, y + 1, obj_moving_platform)) {
jump_count = 0;
}
代码解释
-
place_meeting(x, y + 1, obj_ground)
:检查角色是否在地面上。 -
place_meeting(x, y - 1, obj_ladder)
:检查角色是否在梯子上。 -
place_meeting(x, y + 1, obj_moving_platform)
:检查角色是否站在移动平台上。 -
vspeed
和hspeed
:分别表示角色的垂直和水平速度。 -
gravity
:角色的重力加速度。
射击游戏中的高级动作系统
射击游戏(Shooter)通常要求玩家在快速移动的同时进行精准的射击。高级动作系统可以包括角色的移动、射击和射击后坐力等。
1. 角色的平滑移动
在射击游戏中,角色的平滑移动可以让玩家的操作更加流畅和自然。我们可以使用插值法来实现平滑移动。
代码示例:平滑移动
// 在对象的 Create 事件中初始化变量
var target_x = x;
var target_y = y;
var move_speed = 5;
// 在对象的 Step 事件中处理平滑移动逻辑
if (keyboard_check(vk_right)) {
target_x += move_speed;
} else if (keyboard_check(vk_left)) {
target_x -= move_speed;
}
if (keyboard_check(vk_down)) {
target_y += move_speed;
} else if (keyboard_check(vk_up)) {
target_y -= move_speed;
}
// 使用插值法平滑移动
x = lerp(x, target_x, 0.1);
y = lerp(y, target_y, 0.1);
代码解释
-
target_x
和target_y
:记录目标位置。 -
move_speed
:角色的移动速度。 -
lerp(x, target_x, 0.1)
:线性插值函数,用于平滑地移动角色。
2. 射击和后坐力
射击游戏中的射击动作和后坐力可以增加游戏的真实感和挑战性。后坐力可以让角色在射击时产生轻微的反向移动。
代码示例:射击和后坐力
// 在对象的 Create 事件中初始化变量
var fire_rate = 10;
var bullet_speed = 10;
var recoil_strength = 2;
var can_shoot = true;
// 在对象的 Step 事件中处理射击逻辑
if (keyboard_check_pressed(vk_space) && can_shoot) {
// 创建子弹
instance_create_layer(x, y, "Instances", obj_bullet);
obj_bullet.direction = point_direction(x, y, mouse_x, mouse_y);
obj_bullet.speed = bullet_speed;
// 处理后坐力
vspeed -= recoil_strength;
can_shoot = false;
alarm[0] = room_speed / fire_rate; // 设置射击冷却时间
}
// 在对象的 Alarm 事件中重置射击冷却
if (alarm[0]) {
can_shoot = true;
}
代码解释
-
fire_rate
:射击频率,单位为帧。 -
bullet_speed
:子弹的速度。 -
recoil_strength
:后坐力的强度。 -
can_shoot
:布尔变量,表示角色是否可以射击。 -
instance_create_layer(x, y, "Instances", obj_bullet)
:在角色位置创建子弹对象。 -
point_direction(x, y, mouse_x, mouse_y)
:计算鼠标位置与角色位置之间的角度。 -
alarm[0]
:用于控制射击冷却时间的报警。
3. 闪避和翻滚
闪避和翻滚是射击游戏中的高级动作,可以帮助玩家躲避敌人的攻击。这些动作通常伴随着视觉效果,如烟雾或闪光。
代码示例:闪避和翻滚
// 在对象的 Create 事件中初始化变量
var roll_speed = 15;
var roll_time = 0.5;
var is_rolling = false;
// 在对象的 Step 事件中处理闪避逻辑
if (keyboard_check_pressed(vk_c) && !is_rolling) {
is_rolling = true;
image_index = 0; // 重置动画帧
image_speed = 1; // 启动动画
if (keyboard_check(vk_right)) {
hspeed = roll_speed;
} else if (keyboard_check(vk_left)) {
hspeed = -roll_speed;
}
if (keyboard_check(vk_down)) {
vspeed = roll_speed;
} else if (keyboard_check(vk_up)) {
vspeed = -roll_speed;
}
alarm[1] = room_speed * roll_time; // 设置翻滚时间
}
// 在对象的 Alarm 事件中结束翻滚
if (alarm[1]) {
is_rolling = false;
hspeed = 0;
vspeed = 0;
image_speed = 0; // 停止动画
}
代码解释
-
roll_speed
:翻滚的速度。 -
roll_time
:翻滚的持续时间。 -
is_rolling
:布尔变量,表示角色是否正在翻滚。 -
alarm[1]
:用于控制翻滚时间的报警。 -
image_index
和image_speed
:用于播放角色翻滚动画。
格斗游戏中的高级动作系统
格斗游戏(Fighting Game)通常要求玩家在短时间内执行多种复杂的动作,如连招、格挡和闪避。高级动作系统可以显著提升这些动作的流畅性和反应速度。
1. 连招系统
连招系统是格斗游戏中的一项重要功能,可以让玩家通过连续按下多个按键来执行一系列攻击动作。
代码示例:连招系统
// 在对象的 Create 事件中初始化变量
var combo_timer = 0;
var combo_max_time = 10;
var current_combo = 0;
var max_combo = 3;
// 在对象的 Step 事件中处理连招逻辑
if (keyboard_check_pressed(vk_a)) {
if (current_combo == 0) {
// 执行第一招
attack1();
current_combo += 1;
combo_timer = 0;
} else if (current_combo == 1 && combo_timer < combo_max_time) {
// 执行第二招
attack2();
current_combo += 1;
combo_timer = 0;
} else if (current_combo == 2 && combo_timer < combo_max_time) {
// 执行第三招
attack3();
current_combo = 0; // 重置连招
combo_timer = 0;
}
}
// 在对象的 Step 事件中更新连招计时器
if (current_combo > 0) {
combo_timer += 1;
if (combo_timer >= combo_max_time) {
current_combo = 0; // 如果超过时间限制,重置连招
}
}
代码解释
-
combo_timer
:记录连招的时间。 -
combo_max_time
:连招的最大时间。 -
current_combo
:当前连招的阶段。 -
max_combo
:连招的最大阶段。 -
attack1()
,attack2()
,attack3()
:分别表示第一招、第二招和第三招的攻击动作。
2. 格挡和反击
格挡和反击是格斗游戏中的高级动作,可以让玩家在敌人攻击时进行防御,并在适当的时候进行反击。
代码示例:格挡和反击
// 在对象的 Create 事件中初始化变量
var is_blocking = false;
var block_cooldown = 30;
var block_timer = 0;
var can_counter = false;
// 在对象的 Step 事件中处理格挡逻辑
if (keyboard_check_pressed(vk_s)) {
is_blocking = true;
block_timer = 0;
} else {
is_blocking = false;
}
// 在对象的 Collision 事件(与敌人碰撞)中处理反击逻辑
if (place_meeting(x, y, obj_enemy_attack) && is_blocking) {
block_timer += 1;
if (block_timer >= room_speed * 0.5) {
can_counter = true;
block_timer = 0;
}
}
// 在对象的 Step 事件中处理反击逻辑
if (keyboard_check_pressed(vk_d) && can_counter) {
// 执行反击
attack_counter();
can_counter = false;
alarm[0] = block_cooldown; // 设置格挡冷却时间
}
// 在对象的 Alarm 事件中重置格挡冷却
if (alarm[0]) {
can_counter = false;
}
代码解释
-
is_blocking
:布尔变量,表示角色是否在格挡。 -
block_cooldown
:格挡的冷却时间。 -
block_timer
:记录格挡的时间。 -
can_counter
:布尔变量,表示角色是否可以反击。 -
attack_counter()
:执行反击动作的函数。
3. 空中动作和地面动作的转换
在格斗游戏中,角色可以在空中和地面上执行不同的动作。高级动作系统需要处理这些动作的平滑转换。
代码示例:空中和地面动作的转换
// 在对象的 Create 事件中初始化变量
var is_in_air = false;
var ground_action = "idle";
var air_action = "jump";
// 在对象的 Step 事件中处理动作转换逻辑
if (place_meeting(x, y + 1, obj_ground)) {
is_in_air = false;
if (keyboard_check_pressed(vk_a)) {
ground_action = "attack1";
} else if (keyboard_check_pressed(vk_d)) {
ground_action = "dodge";
} else {
ground_action = "idle";
}
// 设置地面动作的动画
image_index = 0;
image_speed = 0.5;
switch (ground_action) {
case "idle":
sprite_index = spr_idle;
break;
case "attack1":
sprite_index = spr_attack1;
break;
case "dodge":
sprite_index = spr_dodge;
break;
}
} else {
is_in_air = true;
if (keyboard_check_pressed(vk_a)) {
air_action = "air_attack1";
} else if (keyboard_check_pressed(vk_d)) {
air_action = "air_dodge";
} else {
air_action = "jump";
}
// 设置空中动作的动画
image_index = 0;
image_speed = 0.5;
switch (air_action) {
case "jump":
sprite_index = spr_jump;
break;
case "air_attack1":
sprite_index = spr_air_attack1;
break;
case "air_dodge":
sprite_index = spr_air_dodge;
break;
}
}
代码解释
-
is_in_air
:布尔变量,表示角色是否在空中。 -
ground_action
:角色在地面上的当前动作。 -
air_action
:角色在空中的当前动作。 -
place_meeting(x, y + 1, obj_ground)
:检查角色是否在地面上。 -
sprite_index
:当前播放的动画精灵。 -
image_index
和image_speed
:用于播放动画。
冒险游戏中的高级动作系统
冒险游戏(Adventure Game)通常包含丰富的剧情和探索元素。高级动作系统可以增加角色的互动性和灵活性,如攀爬、游泳和特殊技能等。
1. 角色攀爬
冒险游戏中的角色攀爬可以让玩家探索更多的环境。我们可以使用碰撞检测和特定的按键来实现攀爬功能。
代码示例:角色攀爬
// 在对象的 Create 事件中初始化变量
var is_climbing = false;
var climb_speed = 4;
// 在对象的 Step 事件中处理攀爬逻辑
if (place_meeting(x, y, obj_wall)) {
if (keyboard_check_pressed(vk_up) && !is_climbing) {
// 开始攀爬
is_climbing = true;
vspeed = -climb_speed;
sprite_index = spr_climb_up;
} else if (keyboard_check_pressed(vk_down) && !is_climbing) {
// 开始下滑
is_climbing = true;
vspeed = climb_speed;
sprite_index = spr_climb_down;
}
} else {
is_climbing = false;
vspeed += gravity;
sprite_index = spr_idle;
}
// 在对象的 Collision 事件(与地面碰撞)中处理攀爬结束
if (place_meeting(x, y + 1, obj_ground)) {
is_climbing = false;
vspeed = 0;
sprite_index = spr_idle;
}
代码解释
-
is_climbing
:布尔变量,表示角色是否在攀爬。 -
climb_speed
:攀爬的速度。 -
place_meeting(x, y, obj_wall)
:检查角色是否在墙上。 -
vspeed
:角色的垂直速度。 -
gravity
:角色的重力加速度。 -
sprite_index
:当前播放的动画精灵。
2. 角色游泳
冒险游戏中的角色游泳可以让玩家在水下环境中探索。游泳动作通常包括不同的动画和速度控制。我们可以使用碰撞检测和特定的按键来实现游泳功能。
代码示例:角色游泳
// 在对象的 Create 事件中初始化变量
var is_swimming = false;
var swim_speed = 4;
var swim_gravity = 0.1;
var water_drag = 0.5;
// 在对象的 Step 事件中处理游泳逻辑
if (place_meeting(x, y, obj_water)) {
is_swimming = true;
vspeed += swim_gravity;
hspeed *= water_drag;
if (keyboard_check_pressed(vk_up)) {
vspeed = -swim_speed;
sprite_index = spr_swim_up;
} else if (keyboard_check_pressed(vk_down)) {
vspeed = swim_speed;
sprite_index = spr_swim_down;
}
if (keyboard_check_pressed(vk_right)) {
hspeed = swim_speed;
sprite_index = spr_swim_right;
} else if (keyboard_check_pressed(vk_left)) {
hspeed = -swim_speed;
sprite_index = spr_swim_left;
}
} else {
is_swimming = false;
vspeed += gravity;
hspeed = 0;
if (keyboard_check(vk_right)) {
hspeed = 4;
} else if (keyboard_check(vk_left)) {
hspeed = -4;
}
sprite_index = spr_idle;
}
// 在对象的 Collision 事件(与地面碰撞)中处理游泳结束
if (place_meeting(x, y + 1, obj_ground)) {
is_swimming = false;
vspeed = 0;
sprite_index = spr_idle;
}
代码解释
-
is_swimming
:布尔变量,表示角色是否在游泳。 -
swim_speed
:游泳的速度。 -
swim_gravity
:水中的重力加速度,通常比地面的重力更小。 -
water_drag
:水中的阻力,用于减缓角色的水平速度。 -
place_meeting(x, y, obj_water)
:检查角色是否在水中。 -
vspeed
和hspeed
:分别表示角色的垂直和水平速度。 -
gravity
:角色在空中的重力加速度。 -
sprite_index
:当前播放的动画精灵。
3. 特殊技能
冒险游戏中的角色通常拥有多种特殊技能,如魔法、箭矢、瞬移等。这些技能可以增加游戏的多样性和策略性。
代码示例:特殊技能
// 在对象的 Create 事件中初始化变量
var can_cast_magic = true;
var magic_cooldown = 60;
var magic_timer = 0;
var can_teleport = true;
var teleport_cooldown = 120;
var teleport_timer = 0;
// 在对象的 Step 事件中处理魔法技能逻辑
if (keyboard_check_pressed(vk_q) && can_cast_magic) {
// 执行魔法技能
cast_magic();
can_cast_magic = false;
magic_timer = 0;
alarm[0] = magic_cooldown; // 设置魔法冷却时间
}
// 在对象的 Step 事件中处理瞬移技能逻辑
if (keyboard_check_pressed(vk_e) && can_teleport) {
// 执行瞬移技能
teleport();
can_teleport = false;
teleport_timer = 0;
alarm[1] = teleport_cooldown; // 设置瞬移冷却时间
}
// 在对象的 Step 事件中更新技能冷却计时器
if (magic_timer < magic_cooldown) {
magic_timer += 1;
}
if (teleport_timer < teleport_cooldown) {
teleport_timer += 1;
}
// 在对象的 Alarm 事件中重置技能冷却
if (alarm[0]) {
can_cast_magic = true;
}
if (alarm[1]) {
can_teleport = true;
}
// 魔法技能函数
function cast_magic() {
// 创建魔法效果
instance_create_layer(x, y, "Effects", obj_magic_effect);
// 播放魔法动画
sprite_index = spr_cast_magic;
image_index = 0;
image_speed = 1;
}
// 瞬移技能函数
function teleport() {
// 瞬移至目标位置
x = mouse_x;
y = mouse_y;
// 播放瞬移动画
sprite_index = spr_teleport;
image_index = 0;
image_speed = 1;
}
代码解释
-
can_cast_magic
和can_teleport
:布尔变量,分别表示角色是否可以使用魔法和瞬移技能。 -
magic_cooldown
和teleport_cooldown
:分别表示魔法和瞬移技能的冷却时间,单位为帧。 -
magic_timer
和teleport_timer
:分别记录魔法和瞬移技能的冷却时间。 -
alarm[0]
和alarm[1]
:用于控制技能冷却时间的报警。 -
instance_create_layer(x, y, "Effects", obj_magic_effect)
:在角色位置创建魔法效果对象。 -
x = mouse_x; y = mouse_y;
:将角色瞬移至鼠标位置。 -
sprite_index
:当前播放的动画精灵。 -
image_index
和image_speed
:用于播放动画。
总结
通过上述案例研究,我们可以看到高级动作系统在不同类型游戏中的应用。这些系统不仅提升了游戏的可玩性和挑战性,还增加了游戏的真实感和动态感。在平台游戏中,我们实现了二段跳、空中冲刺和动态地形反应;在射击游戏中,我们实现了平滑移动、射击后坐力和闪避翻滚;在格斗游戏中,我们实现了连招系统、格挡和反击以及空中和地面动作的转换;在冒险游戏中,我们实现了角色攀爬、游泳和特殊技能。
每一种游戏类型都有其独特的动作需求,设计和实现高效的高级动作系统需要对游戏机制有深入的理解。希望这些案例能够帮助你在自己的项目中实现更加丰富和有趣的角色动作。