[入门]GML常用UI之按钮的制作2


摘要


上一章:[入门]GML常用UI之按钮的制作1

本章涉及主要内容:父对象的理解、与子对象的简单控制
本章节实现内容:在前章内容之下,实现按钮的按下与手动控制弹起,同时实现所有归属父对象的子对象的按下状态是互斥的(此功能可以制作选择中框等)
br
br
br


上章解答


题目:现在情况是会自动弹起,但是当鼠标在按钮上的时候自动弹起也会回归到常规状态(正确的应该是移入状态),有没有一个方法在鼠标在按钮上时按钮自动弹起的时候它是处于移入状态

思路:检测鼠标当前所在的按钮实例,让鼠标所放置的实例的状态恢复成移入状态而不是普通状态

如此我们需要在自动恢复状态的地方加入判断鼠标当前所在的按钮,【计时器0】内的代码修改为如下:

var button = instance_position(mouse_x, mouse_y, obj_button_father) //判断并获取鼠标所在实例位置
if button > 0   btn_state = 1;  //如果是当前实例则切换成移入状态
else    btn_state = 0;  //如果不是当前实例则切换成普通状态

以上就能正确识别鼠标所处在具体哪个按钮之上,下面开始正式教程
br
br
br


思路分析


需求是:同一个父对象中,2个子对象按钮,1个自动弹起,另外个需要手动点击才会弹起,同时相同子对象不同实例之间只有1个会被同时按下。

由此我们需要解决以下问题:
1.如何判断是否需要自动弹起
2.手动弹起的按钮的状态判断
3.相同子对象不同实例间按下状态的互斥。
br
br
br


实现过程


  • 前提概要:父对象与子对象之间的关系上一章已经说过,本章会有一些简单的子对象引用和变量修改。
    br
    br

不自动弹起

1.新增字段
  咱们这里既需要保留自动弹起功能,又需要一个可持续选中的按钮的话就需要针对不同的按钮功能类型进行识别,咱们在父对象obj_button_father创建事件中新增一个变量来进行区分:

btn_type = 0;   //按钮类型 0、点击后选中 1、点击会自动弹起

br
br

2.步事件区分判断
  已经创建好的按钮类型,需要在步事件内进行区分判断后才能用进行下一步的功能实现,如此obj_button_father事件中进行一些改写,代码如下:

switch btn_type
{
    case 0://以下是点击后变为选中,再次点击弹起(点击其他实例也会弹起)
        break;
        
    case 1://以下是点击会自动弹起
        if btn_state == 1 && mouse_check_button(mb_left)    //当鼠标移入且被点击时
        {
            btn_state = 2;  //切换到点击状态
            alarm_set(0, 3);    //设置计时器计时为3帧
        }
        break;
}

以上,case 0既是我们即将增加按下的代码
br
br

3.按下的处理
  按下的逻辑和之前几乎相同,唯一不同的就是咱们这里不需要让他自动弹起,那么就不需要在case 0的按下逻辑中添加计时器(上一章:计时器0的作用就是控制按钮的自动弹起),case 0中新增代码如下:

case 0://以下是点击后变为选中,再次点击弹起(点击其他实例也会弹起)
    if btn_state == 1 && mouse_check_button(mb_left)//当鼠标移入且被点击时
    {
    btn_state = 2;//切换到点击状态
    }
    break;

br
br

4.再次点击弹起
  再次点击弹起的前提必须是当前按钮处于被按下的情况下,那么只需要鼠标点击时判断按钮是否被按下即可,同时需要注意的是为了避免多次触发按下和取消按下状态,这里移入和被点击对于每一次点击都只需要触发一次,而不需要多次触发了。所以mouse_check_button需要改成mouse_check_button_pressed(这两个接口的区别上一章已经说明),代码修改如下:

case 0://以下是点击后变为选中,再次点击弹起(点击其他实例也会弹起)
    if btn_state == 1 && mouse_check_button_pressed(mb_left)//当鼠标移入且被点击时
    {
        btn_state = 2;//切换到点击状态
    }
    else if btn_state == 2 && mouse_check_button_pressed(mb_left)//当按钮状态被按下且被点击时
    {
        btn_state = 0;
    }
    break;
  • 说明:以上其实已经实现了相同子对象不同实例之间只有1个会被同时按下,因为在执行按下【按钮1】的时候,如果【按钮2】是处于按下状态的话,也会执行else if里面的逻辑,简意就是,每次点击其实会对所有当前父对象的子对象都单独执行一次独立的代码逻辑。

br
br

5.子对象的引用修改
  按理来说,功能已经基本完成,但是现在遇到一个问题:现在不管刷多少个子对象他都是需要手动点击才会弹起的,那么我们需要obj_button_child在点击后才会弹起且obj_button_child1在点击后3帧会自动弹起就需要做区分了。
  上面我们是通过字段btn_type来进行识别的,那么只需要在子对象中对btn_type来进行修改则可,因为btn_type在父对象中默认是0,那么obj_button_child则不需要有任何修改,剩下就需要在obj_button_child1中进行修改了。
  首先在obj_button_child1中新建【创建】事件,在这里其实可以直接把父对象的创建事件复制下来填进去修改,但是若未来父对象有修改时,这里也会跟着修改会很麻烦,由此我们在这里需要引用父对象【创建】的代码后进行修改btn_type的值,代码如下:

event_inherited();//引用父对象相同事件内的代码
btn_type = 1;//修改按钮类型

如此,就可非常简单的把obj_button_child1的所有刷出来的实例改为自动弹起的。
br
br

6.点击区域的识别
  基本功能已经搞定,可是在测试的时候发现一个问题:点击按钮没什么问题,但是当有按钮按下时,点击空白区域也会把按钮给弹起来。
  这问题产生的原因是由于mouse_check_button_pressedmouse_check_button都是全局响应导致的,那么我们在响应弹起逻辑时除了按钮要处于按下状态外还需要判断鼠标必须在按钮上点击才行,由此在父对象的【步】事件中做出了如下修改:

case 0://以下是点击后变为选中,再次点击弹起(点击其他实例也会弹起)
    var button = instance_position(mouse_x, mouse_y, obj_button_father) //判断并获取鼠标所在实例位置

    if btn_state == 1 && mouse_check_button_pressed(mb_left)//当鼠标移入且被点击时
    {
        btn_state = 2;//切换到点击状态
    }
    else if btn_state == 2 && mouse_check_button_pressed(mb_left)&& button > 0//当按钮状态被按下且被点击时
    {
        btn_state = 0;//切换到普通状态
    }
    break;

br
br

7.弹起后的状态优化
  和上一章一样,咱们在点击弹起之后按钮是恢复为普通状态的,在这里需要用类似的方法来处理为,弹起后为鼠标移入状态,由此父对象的【步】中的最终代码如下:

switch btn_type
{
    case 0://以下是点击后变为选中,再次点击弹起(点击其他实例也会弹起)
        var button = instance_position(mouse_x, mouse_y, obj_button_father) //判断并获取鼠标所在实例位置

        if btn_state == 1 && mouse_check_button_pressed(mb_left)//当鼠标移入且被点击时
        {
            btn_state = 2;//切换到点击状态
        }
        else if btn_state == 2 && mouse_check_button_pressed(mb_left)&& button > 0//当按钮状态被按下且被点击时
        {
            btn_state = 0;//切换到普通状态
            if button.btn_state == 0 button.btn_state = 1;//切换到移入状态
        }
        break;
        
    case 1://以下是点击会自动弹起
        if btn_state == 1 && mouse_check_button(mb_left)    //当鼠标移入且被点击时
        {
            btn_state = 2;  //切换到点击状态
            alarm_set(0, 3);    //设置计时器计时为3帧
        }
        break;
}

br
br
br


额外思考


现在功能已经没什么大问题了,但是出现另外个问题就是当点击obj_button_child1时obj_button_child被按下的按钮也会弹起来,这明显不是我们想要的,那么应该怎么解决它呢?

提示:针对按钮进行分组,并且在点击的时候进行判断

br
br
br

本次教程到此结束,有任何疑问和意见可以留言或者Q群询问

下一章内容:点击按钮后弹出界面

br
br

教程中源文件 本次教程暂不提供源文件等本系列课程结束后统一提供下载
提取密码:

你可能感兴趣的:([入门]GML常用UI之按钮的制作2)