首页 > 其他分享 >GameMaker Studio开发:高级动作系统_动作事件的高级应用:触发与响应

GameMaker Studio开发:高级动作系统_动作事件的高级应用:触发与响应

时间:2024-12-15 14:59:09浏览次数:7  
标签:触发 逻辑 GameMaker 动作 高级 state 事件 attacking ini

动作事件的高级应用:触发与响应

在上一节中,我们讨论了如何在GameMaker Studio中设置基本的动作事件。这一节,我们将深入探讨如何利用这些事件进行更高级的触发与响应机制,以实现更复杂的游戏逻辑。通过学习本节内容,您将能够:

  • 理解不同类型的事件及其触发条件。

  • 掌握如何在事件中编写复杂的响应逻辑。

  • 学会使用触发器和延迟器来优化事件处理。

  • 了解如何通过自定义事件实现更灵活的事件响应机制。

1. 不同类型的事件及其触发条件

GameMaker Studio提供了多种事件类型,每种事件都有其特定的触发条件。了解这些事件的触发条件是实现高级动作系统的基础。以下是一些常见的事件类型及其触发条件:

1.1 创建事件(Create Event)

创建事件在对象被创建时触发。这是初始化对象属性和设置初始状态的理想时机。


// 创建事件示例

// 在对象被创建时设置初始属性

speed = 4;

direction = 90;

image_index = 0;

image_speed = 0.1;



// 初始化生命值

health = 100;



// 初始化得分

score = 0;



// 初始化其他状态变量

is_attacking = false;

is_jumping = false;

1.2 步事件(Step Event)

步事件在每个游戏帧中触发,用于处理对象的持续性行为。例如,移动、碰撞检测、动画更新等。


// 步事件示例

// 检测玩家是否按下了移动键

if (keyboard_check(vk_left)) {

    x -= speed;

}

if (keyboard_check(vk_right)) {

    x += speed;

}

if (keyboard_check(vk_up)) {

    y -= speed;

}

if (keyboard_check(vk_down)) {

    y += speed;

}



// 检测玩家是否按下了攻击键

if (keyboard_check_pressed(vk_space)) {

    is_attacking = true;

    // 攻击动作的动画切换

    image_index = 1;

}



// 如果正在攻击,执行攻击逻辑

if (is_attacking) {

    // 攻击逻辑代码

    // ...

    is_attacking = false;

    // 攻击动作结束,恢复初始动画

    image_index = 0;

}

1.3 碰撞事件(Collision Event)

碰撞事件在对象与另一个对象发生碰撞时触发。可以通过设置不同的碰撞对象来实现多样的碰撞逻辑。


// 碰撞事件示例

// 在玩家与敌人发生碰撞时触发

if (other.health > 0) {

    // 减少敌人生命值

    other.health -= 10;

    // 播放碰撞音效

    audio_play_sound(snd_hit, 1, false);

}

1.4 销毁事件(Destroy Event)

销毁事件在对象被销毁时触发。可以用于释放资源、保存状态等操作。


// 销毁事件示例

// 在对象被销毁时播放音效

audio_play_sound(snd_destroy, 1, false);



// 保存玩家数据

ini_open("player_data.ini");

ini_write_real("Player", "Score", score);

ini_write_real("Player", "Health", health);

ini_close();

1.5 键盘事件(Keyboard Event)

键盘事件在特定键盘按键被按下、释放或持续按下时触发。可以用于处理玩家的输入。


// 键盘事件示例

// 在玩家按下空格键时触发攻击

if (keyboard_check_pressed(vk_space)) {

    is_attacking = true;

    // 攻击动作的动画切换

    image_index = 1;

}



// 在玩家释放空格键时恢复初始状态

if (keyboard_check_released(vk_space)) {

    is_attacking = false;

    // 恢复初始动画

    image_index = 0;

}

1.6 鼠标事件(Mouse Event)

鼠标事件在鼠标按键被按下、释放或移动时触发。可以用于处理玩家的鼠标输入。


// 鼠标事件示例

// 在玩家点击鼠标左键时触发攻击

if (mouse_check_button_pressed(mb_left)) {

    is_attacking = true;

    // 攻击动作的动画切换

    image_index = 1;

}



// 在玩家释放鼠标左键时恢复初始状态

if (mouse_check_button_released(mb_left)) {

    is_attacking = false;

    // 恢复初始动画

    image_index = 0;

}

1.7 投影事件(Draw Event)

投影事件在对象需要绘制时触发。可以用于处理对象的绘制逻辑,如动画、特效等。


// 投影事件示例

// 绘制玩家

draw_self();



// 绘制生命值条

draw_rectangle(10, 10, 10 + (health / 100) * 100, 20, c_red);



// 绘制得分

draw_text(10, 30, "Score: " + string(score));

1.8 定时器事件(Alarm Event)

定时器事件在对象的定时器达到0时触发。可以用于处理延时逻辑,如冷却时间、定时攻击等。


// 定时器事件示例

// 在定时器0触发时恢复生命值

if (alarm[0] == 0) {

    health += 10;

    // 重新设置定时器,每隔5秒恢复一次生命值

    alarm[0] = 60 * 5; // 60帧/秒,5秒

}

2. 在事件中编写复杂的响应逻辑

在基本的事件处理基础上,我们可以通过编写更复杂的逻辑来实现高级的动作系统。以下是一些常见的复杂逻辑示例:

2.1 状态机

状态机(State Machine)是一种用于管理对象状态的技术。通过状态机,可以更清晰地管理对象的不同状态和行为。


// 状态机示例

var state = "idle"; // 初始状态



// 步事件

if (keyboard_check(vk_left)) {

    state = "moving_left";

    x -= speed;

}

if (keyboard_check(vk_right)) {

    state = "moving_right";

    x += speed;

}

if (keyboard_check(vk_up)) {

    state = "jumping";

    y -= speed;

}

if (keyboard_check(vk_down)) {

    state = "crouching";

    y += speed;

}

if (keyboard_check_pressed(vk_space)) {

    state = "attacking";

    is_attacking = true;

    image_index = 1;

}



// 检查状态并执行相应逻辑

switch (state) {

    case "idle":

        // 闲置状态逻辑

        break;

    case "moving_left":

        // 左移状态逻辑

        break;

    case "moving_right":

        // 右移状态逻辑

        break;

    case "jumping":

        // 跳跃状态逻辑

        break;

    case "crouching":

        // 蹲下状态逻辑

        break;

    case "attacking":

        // 攻击状态逻辑

        if (is_attacking) {

            // 攻击逻辑代码

            // ...

            is_attacking = false;

            // 攻击动作结束,恢复初始动画

            image_index = 0;

            state = "idle";

        }

        break;

}

2.2 多阶段动作

多阶段动作是指一个动作由多个子动作组成,每个子动作在特定条件下触发。例如,一个复杂的攻击动作可以分为起手、挥击和收手三个阶段。


// 多阶段攻击动作示例

var attack_phase = 0; // 攻击阶段



// 步事件

if (is_attacking) {

    switch (attack_phase) {

        case 0:

            // 起手动作

            if (image_index == 0.5) {

                attack_phase = 1;

            }

            break;

        case 1:

            // 挥击动作

            if (image_index == 1.5) {

                // 执行攻击逻辑

                // ...

                attack_phase = 2;

            }

            break;

        case 2:

            // 收手动作

            if (image_index == 2.5) {

                is_attacking = false;

                image_index = 0;

                attack_phase = 0;

            }

            break;

    }

}

2.3 状态转换

状态转换是指在不同状态下,对象的行为可以相互转换。例如,玩家在跳跃过程中可以进行攻击,或者在攻击过程中可以进行移动。


// 状态转换示例

var state = "idle"; // 初始状态



// 步事件

if (keyboard_check(vk_left)) {

    if (state != "jumping") {

        state = "moving_left";

        x -= speed;

    }

}

if (keyboard_check(vk_right)) {

    if (state != "jumping") {

        state = "moving_right";

        x += speed;

    }

}

if (keyboard_check_pressed(vk_space)) {

    if (state == "idle" || state == "moving_left" || state == "moving_right") {

        state = "attacking";

        is_attacking = true;

        image_index = 1;

    }

}

if (keyboard_check_pressed(vk_up)) {

    if (state != "attacking") {

        state = "jumping";

        y -= speed;

    }

}



// 检查状态并执行相应逻辑

switch (state) {

    case "idle":

        // 闲置状态逻辑

        break;

    case "moving_left":

        // 左移状态逻辑

        break;

    case "moving_right":

        // 右移状态逻辑

        break;

    case "jumping":

        // 跳跃状态逻辑

        if (y >= room_height - sprite_height) {

            state = "idle";

        }

        break;

    case "attacking":

        // 攻击状态逻辑

        if (is_attacking) {

            // 攻击逻辑代码

            // ...

            is_attacking = false;

            image_index = 0;

            state = "idle";

        }

        break;

}

3. 使用触发器和延迟器优化事件处理

触发器和延迟器是优化事件处理的重要工具。通过合理使用这些工具,可以减少不必要的计算,提高游戏性能。

3.1 触发器

触发器(Trigger)是一种可以在特定条件满足时触发其他事件的机制。例如,当玩家进入特定区域时触发一个事件。


// 触发器示例

// 在创建事件中设置触发器

var trigger_area = instance_create_layer(x, y + 100, "Instances", obj_trigger_area);



// 在步事件中检测触发器

if (place_meeting(x, y, obj_trigger_area)) {

    // 触发区域检测到玩家

    trigger_area.event_perform(eo_user, 0); // 触发用户事件0

    instance_destroy(trigger_area); // 销毁触发器

}



// 在用户事件0中执行特定逻辑

// 用户事件0

// 播放提示音效

audio_play_sound(snd_trigger, 1, false);

// 显示提示信息

show_message("你进入了触发区域!");

3.2 延迟器

延迟器(Delay)用于在特定时间后执行某个操作。例如,攻击后设置一个冷却时间。


// 延迟器示例

var attack_cooldown = 60; // 攻击冷却时间(60帧)



// 步事件

if (is_attacking) {

    // 攻击逻辑代码

    // ...

    is_attacking = false;

    image_index = 0;

    alarm[0] = attack_cooldown; // 设置定时器,冷却时间结束后恢复攻击能力

}



// 定时器事件

if (alarm[0] == 0) {

    // 冷却时间结束,恢复攻击能力

    is_attacking = false;

}

4. 通过自定义事件实现更灵活的事件响应机制

自定义事件(User-Defined Events)是GameMaker Studio中的一种强大功能,可以用于实现更灵活的事件响应机制。通过自定义事件,可以将复杂的逻辑分解为多个小的事件进行处理。

4.1 创建自定义事件

在GameMaker Studio中,可以通过右键点击对象的事件列表,选择“Add Event” -> “User-Defined”来创建自定义事件。每个自定义事件都有一个索引号(从0开始)。

4.2 触发自定义事件

可以通过event_perform函数来触发自定义事件。例如,当玩家进入某个区域时,触发一个自定义事件来处理特定逻辑。


// 触发自定义事件示例

// 在步事件中检测玩家是否进入特定区域

if (place_meeting(x, y, obj_special_area)) {

    // 触发用户事件0

    event_perform(eo_user, 0);

}

4.3 处理自定义事件

在自定义事件中编写特定的逻辑代码。例如,用户事件0可以用于处理玩家进入特殊区域的逻辑。


// 用户事件0

// 播放提示音效

audio_play_sound(snd_special, 1, false);

// 显示提示信息

show_message("你进入了特殊区域!");

// 增加玩家得分

score += 100;

// 更新得分显示

ini_open("player_data.ini");

ini_write_real("Player", "Score", score);

ini_close();

4.4 自定义事件的高级应用

自定义事件可以用于处理更复杂的逻辑,例如多阶段任务、特定条件下的奖励等。


// 自定义事件的高级应用示例

// 用户事件1

// 检测玩家是否完成了某个任务

if (task_completed) {

    // 播放任务完成音效

    audio_play_sound(snd_task_complete, 1, false);

    // 显示任务完成信息

    show_message("任务完成!");

    // 增加玩家得分

    score += 500;

    // 更新得分显示

    ini_open("player_data.ini");

    ini_write_real("Player", "Score", score);

    ini_close();

    // 触发用户事件2,处理任务奖励

    event_perform(eo_user, 2);

}



// 用户事件2

// 处理任务奖励逻辑

// 增加玩家生命值

health += 50;

// 更新生命值显示

ini_open("player_data.ini");

ini_write_real("Player", "Health", health);

ini_close();

// 显示奖励信息

show_message("你获得了50点生命值奖励!");

5. 综合示例:高级动作系统的实现

以下是一个综合示例,展示如何在GameMaker Studio中实现一个高级的动作系统。该系统包括玩家的移动、攻击、跳跃和触发器逻辑。

5.1 创建事件


// 创建事件

// 初始化玩家属性

speed = 4;

direction = 90;

image_index = 0;

image_speed = 0.1;



health = 100;

score = 0;



is_attacking = false;

is_jumping = false;



// 创建触发器

var trigger_area = instance_create_layer(x, y + 100, "Instances", obj_trigger_area);

5.2 步事件


// 步事件

// 检测玩家输入

if (keyboard_check(vk_left)) {

    state = "moving_left";

    x -= speed;

}

if (keyboard_check(vk_right)) {

    state = "moving_right";

    x += speed;

}

if (keyboard_check_pressed(vk_space)) {

    if (state == "idle" || state == "moving_left" || state == "moving_right") {

        state = "attacking";

        is_attacking = true;

        image_index = 1;

    }

}

if (keyboard_check_pressed(vk_up)) {

    if (state != "attacking" && !is_jumping) {

        state = "jumping";

        is_jumping = true;

        y -= speed * 2;

        alarm[1] = 30; // 设置跳跃定时器,30帧后结束跳跃

    }

}



// 检查状态并执行相应逻辑

switch (state) {

    case "idle":

        // 闲置状态逻辑

        break;

    case "moving_left":

        // 左移状态逻辑

        break;

    case "moving_right":

        // 右移状态逻辑

        break;

    case "jumping":

        // 跳跃状态逻辑

        if (y >= room_height - sprite_height) {

            is_jumping = false;

            state = "idle";

        }

        break;

    case "attacking":

        // 攻击状态逻辑

        if (is_attacking) {

            // 攻击逻辑代码

            // 检测周围敌人

            var enemies = instance_place(x, y, obj_enemy);

            if (enemies != noone) {

                // 减少敌人生命值

                with (enemies) {

                    health -= 10;

                    // 播放碰撞音效

                    audio_play_sound(snd_hit, 1, false);

                }

            }

            is_attacking = false;

            image_index = 0;

            state = "idle";

        }

        break;

}

5.3 碰撞事件


// 碰撞事件

// 在玩家与敌人发生碰撞时触发

if (other.health > 0) {

    // 减少敌人生命值

    other.health -= 10;

    // 播放碰撞音效

    audio_play_sound(snd_hit, 1, false);

}

5.4 定时器事件


// 定时器事件

// 跳跃定时器

if (alarm[1] == 0) {

    is_jumping = false;

    state = "idle";

}



// 攻击冷却定时器

if (alarm[0] == 0) {

    // 冷却时间结束,恢复攻击能力

    is_attacking = false;

    image_index = 0;

    state = "idle";

}

5.5 键盘事件


// 键盘事件

// 在玩家按下空格键时触发攻击

if (keyboard_check_pressed(vk_space)) {

    if (state == "idle" || state == "moving_left" || state == "moving_right") {

        state = "attacking";

        is_attacking = true;

        image_index = 1;

    }

}



// 在玩家释放空格键时恢复初始状态

if (keyboard_check_released(vk_space)) {

    is_attacking = false;

    image_index = 0;

}

5.6 鼠标事件


// 鼠标事件

// 在玩家点击鼠标左键时触发攻击

if (mouse_check_button_pressed(mb_left)) {

    if (state == "idle" || state == "moving_left" || state == "moving_right") {

        state = "attacking";

        is_attacking = true;

        image_index = 1;

    }

}



// 在玩家释放鼠标左键时恢复初始状态

if (mouse_check_button_released(mb_left)) {

    is_attacking = false;

    image_index = 0;

}

5.7 投影事件


// 投影事件

// 绘制玩家

draw_self();



// 绘制生命值条

draw_rectangle(10, 10, 10 + (health / 100) * 100, 20, c_red);



// 绘制得分

draw_text(10, 30, "Score: " + string(score));

5.8 销毁事件


// 销毁事件

// 在对象被销毁时播放音效

audio_play_sound(snd_destroy, 1, false);



// 保存玩家数据

ini_open("player_data.ini");

ini_write_real("Player", "Score", score);

ini_write_real("Player", "Health", health);

ini_close();

5.9 触发器事件


// 触发器事件

// 在步事件中检测触发器

if (place_meeting(x, y, obj_trigger_area)) {

    // 触发区域检测到玩家

    trigger_area.event_perform(eo_user, 0); // 触发用户事件0

    instance_destroy(trigger_area); // 销毁触发器

}



// 在用户事件0中执行特定逻辑

// 用户事件0

// 播放提示音效

audio_play_sound(snd_trigger, 1, false);

// 显示提示信息

show_message("你进入了触发区域!");

// 增加玩家得分

score += 100;

// 更新得分显示

ini_open("player_data.ini");

ini_write_real("Player", "Score", score);

ini_close();

5.10 自定义事件


// 自定义事件的高级应用示例

// 用户事件1

// 检测玩家是否完成了某个任务

if (task_completed) {

    // 播放任务完成音效

    audio_play_sound(snd_task_complete, 1, false);

    // 显示任务完成信息

    show_message("任务完成!");

    // 增加玩家得分

    score += 500;

    // 更新得分显示

    ini_open("player_data.ini");

    ini_write_real("Player", "Score", score);

    ini_close();

    // 触发用户事件2,处理任务奖励

    event_perform(eo_user, 2);

}



// 用户事件2

// 处理任务奖励逻辑

// 增加玩家生命值

health += 50;

// 更新生命值显示

ini_open("player_data.ini");

ini_write_real("Player", "Health", health);

ini_close();

// 显示奖励信息

show_message("你获得了50点生命值奖励!");

6. 总结

通过本节的学习,您应该已经掌握了如何在GameMaker Studio中利用不同类型的事件进行更高级的触发与响应机制。以下是一些关键点的总结:

  • 创建事件:在对象被创建时初始化属性和状态。

  • 步事件:处理对象的持续性行为,如移动、碰撞检测和动画更新。

  • 碰撞事件:处理对象之间的碰撞逻辑。

  • 销毁事件:在对象被销毁时释放资源和保存状态。

  • 键盘事件鼠标事件:处理玩家的输入。

  • 投影事件:处理对象的绘制逻辑。

  • 定时器事件:处理延时逻辑,如冷却时间和定时恢复。

  • 状态机:管理对象的不同状态和行为。

  • 多阶段动作:将一个复杂动作分解为多个子动作。

  • 状态转换:在不同状态之间进行转换。

  • 自定义事件:实现更灵活的事件响应机制,将复杂逻辑分解为多个小事件。

通过这些技术,您可以创建出更加丰富和复杂的动作系统,提升游戏的可玩性和趣味性。希望本节的内容对您有所帮助,如果您有任何疑问或需要进一步的指导,请随时查阅GameMaker Studio的官方文档或社区资源。
在这里插入图片描述

标签:触发,逻辑,GameMaker,动作,高级,state,事件,attacking,ini
From: https://blog.csdn.net/chenlz2007/article/details/144436814

相关文章

  • 人工智能与大数据:迈向专业应用的高级教程
    在掌握了机器学习、深度学习及大数据处理的基础知识后,你可能希望进一步探索更复杂、更贴近真实场景的应用。本教程将带领你学习更加专业的技术与工具,包括高级深度学习技术、强化学习、分布式深度学习,以及大数据生态系统中的实时数据处理与工程化实践。第一部分:深度学习高级......
  • Hive高级查询
    Hive高级查询更多大数据资源持续更新中。。。一、UDTF之explode函数1、explode语法功能对于UDTF表生成函数,很多人难以理解什么叫做输入一行,输出多行。为什么叫做表生成?能够产生表吗?下面我们就来学习Hive当做内置的一个非常著名的UDTF函数,名字叫做explode函数,中文戏称之......
  • Cesium高级开发教程之四:鹰眼地图#OpenLayers
    教程示例网站:https://thomaz529.github.io一、效果图二、代码init2DDiv(){this.mapDiv=document.createElement('div');this.mapDiv.setAttribute('id',this.mapId)constviewerContainer=this.viewer.cesiumWidget.container.pa......
  • 你认为高级前端工程师应该具备哪些技能?
    高级前端工程师是前端开发团队中的关键成员,他们不仅需要有深厚的技术功底,还需要具备良好的架构设计能力、团队协作能力和持续学习的热情。以下是我认为高级前端工程师应该具备的技能:精通前端技术栈:熟练掌握HTML5、CSS3、JavaScript等前端基础技术,能够编写高质量的代码。熟悉......
  • python面向对象高级编程:使用元类
    在Python中,元类(Metaclass)是创建类的“类”。换句话说,元类是用来控制类的行为的。虽然元类在Python中不常用,但在某些高级编程场景中,它们可以提供强大的功能,如自动注册类、验证类定义、修改类属性等。1.导入必要的模块虽然元类不需要导入额外的模块,但你需要了解如何使用内置的......
  • python面向对象高级编程:使用枚举类
    在Python中,枚举类(Enum)是一种特殊的数据类型,它允许我们定义一组命名的常量。使用枚举类可以使代码更加清晰和易于维护,特别是在处理一组相关常量时。Python的enum模块提供了创建枚举类的功能。以下是如何在Python中使用枚举类的一些高级编程技巧:1.导入enum模块首先,我们需要导......
  • Flutter从入门到高级进阶
    Flutter从入门到高级进阶https://www.bilibili.com/video/BV19x4y1R7LEP1环境搭建P2创建Flutter工程&Flutter优势flutter2.5.3appdart代码module混合开发plugin第三包原生和dartpackage第三包dartname下划线Flutter:效率高!!不依赖UI!!高度统一!!渲染引擎—》Dart......
  • Vue.js高级实战开发移动端音乐App
    F:\Vue教程\Vue高级实战-移动端音乐WebApp\第一章课程内容介绍Vue.js高级实战开发移动端音乐App第一章课程内容介绍1-1导学.mp4做什么?开发一个媳美原生的移动端音乐APP哪些功能?歌手页面、歌手详情页、播放器内核搜索页面、歌曲列表页面等技术栈?Vue全家桶按照App的功能......
  • 中高级运维工程师运维面试题(一)之JVM
    这里写目录标题问题1:什么是堆?它在JVM中的作用是什么?问题2:堆中有哪些内容?问题3:什么是Eden区、Survivor区,年轻代和老年代的作用分别是什么?问题4:什么是GC?有哪些常见的垃圾回收器?问题5:栈是什么?与堆有什么区别?问题6:如何优化堆和栈?问题7:简述FullGC的触发条件以及如何优......
  • Vue+ECharts高级实战】智慧城市数据大屏项目开发完全指南 - 前端开发进阶必看教程 【
    效果图:完整代码<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>智慧城市数据监控大屏</title><scriptsrc="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script><s......