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); } } } }
问题根源
- 销毁逻辑位置错误:
instance_destroy();没有被限制在「最后一页」的判断里——哪怕还有下一页,按下空格后执行完翻页逻辑就会直接销毁文本框,导致文本框刚翻页就消失。 - 空格判断的else分支逻辑错误:这个
else对应if accept_key,意思是只要没按空格,就强制把当前页的文本直接绘制完成,导致文本还没逐字显示就直接跳完,按下空格就触发销毁。 - 文本绘制冗余:文本绘制代码放在了选项的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
相关产品推荐
相关产品推荐

