• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM gamemaker creates objects and surfaces before its supposed to

S

Shadowblitz16

Guest
can someone tell me why my objects and surfaces are getting created and rendered before I can offset their positions?

it should create them on screen and then move them to their correct positions before being rendered
however they are not and are rendered in the wrong place for 1 to 2 frames

you can only really tell when debugging since the screen renders afterwards when I'm playing normally

here is my code
Code:
///Menu create

menu_changed = 1;
menu_state = 0;
menu_index = 0;

if (surface_get_width(application_surface) != view_wview[0] || surface_get_height(application_surface) != view_hview[0])
{
    surface_resize(application_surface, view_wview[0], view_hview[0])
}
Code:
///Menu step

if (keyboard_check_pressed(vk_up)) { menu_index = clamp(menu_index + 1, 0, instance_number(Slider)-1); }
if (keyboard_check_pressed(vk_down)) { menu_index = clamp(menu_index - 1, 0, instance_number(Slider)-1); }

switch (menu_state)
{
    case 0: scr_menu_main() break;
    case 1: scr_menu_single() break;

    default: show_error("Menu.menu_state is out of bounds", true);
}

var _menu = menu_state;
var _index = menu_index;

with (Slider)
{
    for (var _i=0; _i<instance_count; _i++)
    {
        if (element_index != _i) { break; }
  
        if (element_index == _index) { element_selected = 1; }
        else { element_selected = 0; }
 
        if (element_menu != _menu) { x = max(x - 1, element_hidden_x); }
        else { x = min(x + 1, xstart); }
    }

}
menu_changed = 0;
Code:
///scr_menu_main

if (menu_changed == 1)
{
    var _rect = rectangle(5, 3, 88, 22, 1);
    var _inst = menus_create_slider(spr_title, 0, -1, 0, "SPACE #BUSTERS", fnt_large, _rect, 0);
        _inst.element_text_y = -2;
  
    var _rect = rectangle(5, 3, 55, 6, 1);
    var _inst = menus_create_slider(spr_button, 0, 0, 64, "SINGLE", fnt_small, _rect, 32);
        _inst.element_text_y = 0;
}
else
{
    if (keyboard_check_pressed(vk_enter))
    switch (menu_index)
    {
        case 0 : menu_state = 1; menu_changed = 1; break;
    }
}
Code:
///Slider create

element_controller = noone;
element_menu = 0;
element_index = 0;
element_selected = 0;

element_width = sprite_get_width(sprite_index);
element_hidden_x = xstart - element_width

element_surf = surface_create(0, 0);
element_rect = rectangle(0, 0, 0, 0, 1)
element_font = fnt_small;
element_text = "";
element_flicker = 0;
element_text_x = 0;
element_text_y = 0;
Code:
///Slider step

//Update hidden x when resized
if (sprite_get_width(sprite_index) != element_width)
{
    element_width = sprite_get_width(sprite_index);
    element_hidden_x = xstart - element_width
    x = element_hidden_x;
}

if (surface_get_width(element_surf) != element_rect[2] - element_rect[0] || surface_get_height(element_surf) != element_rect[3] - element_rect[1])
{
    surface_resize(element_surf, element_rect[2] - element_rect[0], element_rect[3] - element_rect[1])
}

element_flicker ++;
element_flicker = element_flicker mod 8;

if (!element_selected)
if (x = element_hidden_x)
{
    instance_destroy();
}
Code:
///Slider draw

draw_self();

//Update surface and make sure it exists
if (!surface_exists(element_surf))
{
    element_surf = surface_create(0, 0)
    surface_resize(element_surf, element_rect[2] - element_rect[0], element_rect[3] - element_rect[1])
}

surface_set_target(element_surf);

draw_set_halign(fa_left)
draw_set_valign(fa_top)
draw_set_font(element_font)

draw_set_alpha(0.5);
draw_set_colour($FFFF00);
draw_rectangle(0, 0, element_rect[2], element_rect[3], false);

if (element_flicker mod 2 == 0)
{
    draw_set_alpha(1);
    draw_set_colour($FFFFFF);
    draw_text(element_text_x, element_text_y, element_text);

    draw_set_alpha(1);
    draw_set_colour($FFFF00);
    draw_text(element_text_x + 1, element_text_y, element_text);
}

if (element_selected)
if (element_flicker mod 8 == 0)
{
    draw_set_alpha(1);
    draw_set_colour($FFFFFF);
    draw_rectangle(0, 0, element_rect[2], element_rect[3], false);
}

draw_set_alpha(1);
surface_reset_target();
draw_surface(element_surf, x + element_rect[0], y + element_rect[1]);

Edit: my code has changed a lot from when I posted this 2 hours ago
however I think GMS1.4 is bugged since there is no difference between the "CO-OP" slider and the "SINGLE" slider except for the y position, delay, and text
which neither of them should effect this

it only renders that specific instance and its surface.
with the surface being rendered in the wrong place.

also note that the surface should be a size of 0,0 since I init it as that value
and only set it the in the step event if the element_rect has changed size

they should either all be rendered or none of them
here is my project
I minimized it so that it would be easier to download
 
Last edited by a moderator:

obscene

Member
Maybe make a video if you can showing the problem unless someone else manages to figure it out. Otherwise I'm just guessing at what you mean. You say objects are being created early but this code doesn't create any objects at all.
 
S

Shadowblitz16

Guest
@obscene the instances get created in a script that I didn't post sorry
its best to just download the project as that code is outdated anyways

but if you open the project and go into the debugger and press continue until it hit the break point in the Menu step event you'll see that it only renders the 2nd instance of obj_button and its surface is not the right size

I can post a picture of what it looks like give me a sec

Edit: here it is
http://imgur.com/a/DdSqe
 
S

Shadowblitz16

Guest
bump I cannot even find a way to create this type of menu without horrible bugs that shouldn't be there.

this is the hardest thing I have done in gml when it seems to make sense in my head
 
I

icuurd12b42

Guest
I cant figure it out...

1) you should delay the room with a boot room for a second. you cant create surfaces on create in the first room the graphics card is not ready yet. I got a blank screen, when I added the boot room I got the flash of a menu...
2) you cant create surfaces of size 0,0, I got surface create failed error in the console
3) your code keep creating the items every (menu) step...
 
S

Shadowblitz16

Guest
well then idk I have recoded this menu many times and I can't seem to get it working.
I have absolutely no experience with coding menus, and I feel like I am doing this blindly.

I have a idea of what I want to do, I just don't know how to actually implement it.

@icuurd12b42
I am some pics let me show you my menu idea.
http://imgur.com/a/SW8Rk

I have tried using arrays, lists and maps but I don't know how to actually handle them with initialization, updating, input, and the different menu types.
I can even seem to make them slide in and out one by one.
 
I

icuurd12b42

Guest
the fact the project you posted does not work at all on my machine is an indication you are not doing stuff proper...
 
S

Shadowblitz16

Guest
idk I would just follow a video tutorial but they either fall under these categories...
- uses separate objects for each element.
- uses mouse instead of direct input like console menus do.
- are very basic and have no creativity at all.

I would like to learn how to program menus but I would like it to be a somewhat decent menu.
I also have very low resolution for my game so I have to fit a lot of content in a small space and upscaling my game isn't a option since I don't have sprites for it.
 
I

icuurd12b42

Guest
I dont really see the need for such a complex surface based setup as you have for a menu when a sprite with text over it would do

I can see you have a list there and yes the text need clipping. menus dont need to be efficient so you could just create the surface the size of the clipping region right there in the draw and destroy it right there in the draw

array_create

draw:
Code:
var mnu = array_create("Menu1","Menu2","Menu3","Menu4","Menu5","Menu6");
draw_det_font(MyFont);
var h = string_get_height("W");
var mnu_ln = array_length_1d(mnu);
var yy = 0; //yy = -scrollpos*h
var xx = 0;
var framex = 200;
var framey = 200;
var surf = surface_create(200,300);
if(surface_exists(surf))
{
    surface_set_target(surf);
    draw_clear_alpha(c_black,0);
    for(var i = 0; i<mnu_ln; i++)
    {
        draw_text_colour(xx, yy, mnu[i], c_white, c_white, c_white, c_white, 1);
        yy+=h;
    }
    surface_reset_target();
    draw_surface(surf,framex,framey);
    surface_free(surf);
}
mnu = undefined; //force the garbage collector on the mnu
 
Last edited by a moderator:
Top