You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GameMaker文本框点击空格即销毁问题求助

GameMaker文本框空格键触发立即销毁问题修复

问题描述

开发文本框时遇到异常:按下空格键后文本框立即被销毁,仅能短暂显示。初步判断问题出在文本框销毁的逻辑上,附上代码求助:

accept_key = keyboard_check_pressed( vk_space );


textbox_x = camera_get_view_x( view_camera[0] );
textbox_y = camera_get_view_y( view_camera[0] ) + 144;

//setup
if setup == false
{

setup = true;
draw_set_font(global.font_main)
draw_set_valign(fa_top);
draw_set_halign(fa_left);

// loop through pages
for(var p = 0; p< page_number ; p++)
{

//find how many characters are on the page and store that number in the "text_length" array
text_length[p] = string_length(text[p]);

//get the x postiotion for the textbox
//no character (center the textbox)
text_x_offset[p] = 44;

}

}


//typing the text
if draw_char < text_length[page]
{
draw_char += text_spd;
draw_char = clamp(draw_char, 0, text_length[page]);
}


//flip through pages
if accept_key
{

//if the typing is done
if draw_char == text_length[page]
{

// next page
if page < page_number-1
{
page++;
draw_char = 0;
}

//link text for options
if option_number > 0 {
create_textbox(option_link_id[option_pos]);
}
instance_destroy();
}
}
//if not done typing
else
{

draw_char = text_length[page];

}



//draw the textbox
var _txtb_x = textbox_x + text_x_offset[page];
var _txtb_y = textbox_y;
txtb_img += txtb_img_spd;
txtb_spr_w = sprite_get_width(txtb_spr);
txtb_spr_h = sprite_get_height(txtb_spr);
//draw back of the textbox
draw_sprite_ext(txtb_spr, txtb_img, _txtb_x, _txtb_y, textbox_width/txtb_spr_w, textbox_height/txtb_spr_h, 0, c_white, 1);


//options
if draw_char == text_length[page] && page == page_number - 1
{

//option selection
option_pos += keyboard_check_pressed(vk_down) - keyboard_check_pressed(vk_up);
option_pos = clamp(option_pos, 0, option_number-1);

//draw the actions
var op_space = 15;
var _op_bord = 4;
for (var op = 0; op < option_number; op++)
{
//the option box
var _o_w = string_width(option[op]) + _op_bord*2;
draw_sprite_ext(txtb_spr, txtb_img, _txtb_x + 16, _txtb_y - op_space*option_number + op_space*op, _o_w/txtb_spr_w, (op_space-1)/txtb_spr_h, 0, c_white, 1);

//the arrow
if option_pos == op
{
draw_sprite(spr_textbox_indecator, 0, _txtb_x, _txtb_y - op_space*option_number + op_space*op);
}

{
//the option text
draw_text(_txtb_x +16 + _op_bord, _txtb_y - op_space*option_number + op_space*op +2, option[op]);
}

{


{
//draw the text
var _drawtext = string_copy(text[page], 1, draw_char);
draw_text_ext(_txtb_x + border, _txtb_y + border, _drawtext, line_sep, line_width);
}

}

}

}

问题根源

  1. 销毁逻辑位置错误:instance_destroy();没有被限制在「最后一页」的判断里——哪怕还有下一页,按下空格后执行完翻页逻辑就会直接销毁文本框,导致文本框刚翻页就消失。
  2. 空格判断的else分支逻辑错误:这个else对应if accept_key,意思是只要没按空格,就强制把当前页的文本直接绘制完成,导致文本还没逐字显示就直接跳完,按下空格就触发销毁。
  3. 文本绘制冗余:文本绘制代码放在了选项的for循环内部,每循环一次就绘制一遍文本,造成性能浪费。

修复方案

调整翻页与销毁逻辑,修正else分支的作用,同时优化文本绘制位置:

accept_key = keyboard_check_pressed(vk_space);

textbox_x = camera_get_view_x( view_camera[0] );
textbox_y = camera_get_view_y( view_camera[0] ) + 144;

//setup
if setup == false
{
    setup = true;
    draw_set_font(global.font_main);
    draw_set_valign(fa_top);
    draw_set_halign(fa_left);

    // loop through pages
    for(var p = 0; p < page_number ; p++)
    {
        //find how many characters are on the page and store that number in the "text_length" array
        text_length[p] = string_length(text[p]);

        //get the x postiotion for the textbox
        //no character (center the textbox)
        text_x_offset[p] = 44;
    }
}

//typing the text
if draw_char < text_length[page]
{
    draw_char += text_spd;
    draw_char = clamp(draw_char, 0, text_length[page]);
}

//flip through pages
if accept_key
{
    //if the typing is done
    if draw_char == text_length[page]
    {
        // next page
        if page < page_number-1
        {
            page++;
            draw_char = 0;
        }
        // 仅在最后一页时执行销毁/跳转逻辑
        else
        {
            //link text for options
            if option_number > 0 {
                create_textbox(option_link_id[option_pos]);
            }
            instance_destroy();
        }
    }
    // 按下空格时,如果文本没打完,直接跳完当前页
    else
    {
        draw_char = text_length[page];
    }
}

//draw the textbox
var _txtb_x = textbox_x + text_x_offset[page];
var _txtb_y = textbox_y;
txtb_img += txtb_img_spd;
txtb_spr_w = sprite_get_width(txtb_spr);
txtb_spr_h = sprite_get_height(txtb_spr);
//draw back of the textbox
draw_sprite_ext(txtb_spr, txtb_img, _txtb_x, _txtb_y, textbox_width/txtb_spr_w, textbox_height/txtb_spr_h, 0, c_white, 1);

//options
if draw_char == text_length[page] && page == page_number - 1
{
    //option selection
    option_pos += keyboard_check_pressed(vk_down) - keyboard_check_pressed(vk_up);
    option_pos = clamp(option_pos, 0, option_number-1);

    //draw the actions
    var op_space = 15;
    var _op_bord = 4;
    for (var op = 0; op < option_number; op++)
    {
        //the option box
        var _o_w = string_width(option[op]) + _op_bord*2;
        draw_sprite_ext(txtb_spr, txtb_img, _txtb_x + 16, _txtb_y - op_space*option_number + op_space*op, _o_w/txtb_spr_w, (op_space-1)/txtb_spr_h, 0, c_white, 1);

        //the arrow
        if option_pos == op
        {
            draw_sprite(spr_textbox_indecator, 0, _txtb_x, _txtb_y - op_space*option_number + op_space*op);
        }

        //the option text
        draw_text(_txtb_x +16 + _op_bord, _txtb_y - op_space*option_number + op_space*op +2, option[op]);
    }
}

//draw the text - 移到循环外,避免重复绘制
var _drawtext = string_copy(text[page], 1, draw_char);
draw_text_ext(_txtb_x + border, _txtb_y + border, _drawtext, line_sep, line_width);

修复说明

  • 把instance_destroy();放到了else分支里,只有当前是最后一页时才会销毁文本框,翻页时不会触发销毁。
  • 调整了空格判断的else分支逻辑,现在只有按下空格且文本没打完时,才会直接跳完当前页文本,而非没按空格就强制跳完。
  • 将文本绘制代码移到了选项循环外部,避免重复绘制,优化性能。

内容的提问来源于stack exchange,提问作者HannahNotBanana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:13:10