Move 'cursor' on a stage...

luxo-JR

Member
I am a beginner (for 1 month, French user) and I am coming to you for help. I'm trying to move an object with the 'Up', 'Down', 'Left' and 'Right' keys. The object only moves one 'step' and disappears. I attach you the code , 'Stage' event of the object. Thanks for your help. Finally, I am working on a project that looks like 'Sokoban'.


GML:
global.Nb_col = 15;
global.Nb_lig = 15;
global.Larg_spr = 50;
global.Haut_spr = 50;
global.Cur_col = 1;
global.Cur_lig = 1;
var X_spr = 1;
var Y_spr = 1;

draw_set_colour(c_white);
draw_text(10, 100, "Col: " + string(global.Cur_col));

if (keyboard_check(vk_right))
{
    if (global.Cur_col <= global.Nb_col)
    {
         global.Cur_col += 1;   
    }
    else
    {
        global.Cur_col = 1;
    }
    X_spr = (global.Cur_col - 1) * global.Larg_spr;
    x = X_spr;
}

if (keyboard_check(vk_left))
{
    if (global.Cur_col >= 0)
    {
         global.Cur_col -= 1;   
    }
    else
    {
        global.Cur_col = global.Nb_col;
    }
    X_spr = (global.Cur_col - 1) * global.Larg_spr;
    x = X_spr;
}


if (keyboard_check(vk_up))
{
    if (global.Cur_lig >= 0)
    {
         global.Cur_lig -= 1;   
    }
    else
    {
        global.Cur_lig = global.Nb_lig;
    }
    Y_spr = (global.Cur_lig - 1) * global.Haut_spr;
    y = Y_spr;
}

if (keyboard_check(vk_down))
{
    if (global.Cur_lig <= global.Nb_lig)
    {
         global.Cur_lig += 1;   
    }
    else
    {
        global.Cur_lig = 1;
    }
    Y_spr = (global.Cur_lig - 1) * global.Haut_spr;
    y = Y_spr;
}
 

Nidoking

Member
draw_set_colour(c_white); draw_text(10, 100, "Col: " + string(global.Cur_col));
Is this the Step event or the Draw event? There's no "Stage" event. If it's the Step event, then this draw does nothing. If it's the Draw event, then you shouldn't be doing any of the other stuff you're doing here in that event.

Also, it appears that you're resetting the position of this instance (determined by global variables) to 1,1 every step. Or is this the Create event? If so, then none of what you've written there is ever going to respond to keyboard commands, because the Create event only ever happens once per instance. So: Please define, using the correct name, which event this is, and move each part to the appropriate event. I would also recommend not using global variables for most of those values. If you're using sprite widths, there are functions that will get the width of the sprite, for example. If you're tracking the position of an instance, that instance should use its own variables. I would recommend using some tutorials - I don't know of any in French specifically, but you have a lot to learn.
 

luxo-JR

Member
Thank you for your reply. If I understood your answer correctly, you must put each key detection (vk_right, vk_left, vk_up, vk_down) in a specific event specific to each of these keys ('key pressed' event), therefore 4 events. How to initiate (in another object or via a 'draw' event) the displacement tracking variables (Cur_lig, Cur_col, Nb_lig and Nb_col), they must be put into global variables. The goal of the game is to move a 50x50 object in a 750x750 area and this by leaps of 50 pixels; I also want to move this same object with the mouse (x = floor (mouse_x) * global.Larg_spr; y = floor (mouse_y) * global.Haut_spr;). It is true that I am a novice and I only want to learn. I am taker of all documentations and tutorials. Best regards.
 

Nidoking

Member
If I understood your answer correctly, you must put each key detection (vk_right, vk_left, vk_up, vk_down) in a specific event specific to each of these keys ('key pressed' event), therefore 4 events.
Incorrect. The key detections can all be in a single event, but WHICH event it is matters. In the code you posted, you are doing three things:
Initializing variables. That needs to be done in a Create event.
Drawing text. That needs to be done in a Draw event.
Detecting keypresses and moving. That needs to be done in an event that runs regularly, such as a Step event. You can use Key events for this, but you don't have to.
It is impossible to create a game if you try to put all of these things into the same event. It will not work. I think you have discovered this.

How to initiate (in another object or via a 'draw' event) the displacement tracking variables (Cur_lig, Cur_col, Nb_lig and Nb_col), they must be put into global variables.
Incorrect. I think you don't understand variable scopes. Read this Manual page and all of the pages linked from it thoroughly.
 

luxo-JR

Member
Thank you for your response and advice. I initialized my variables in a 'Create' event; I put the display of my variables in a 'Draw' event (it's just to see the contents of the variables) and I put the processing of the keyboard keys in a 'Step' event. Everything is going correctly except that the object to which the events are linked is not displayed in the room; yet I have positioned it well in it. Did I forget something. Best regards. Jean-Francois. I hope my english is correct, I am using google translator ...
 

WilloX

Member
I advise not to bother with the draw events for the time being (as there are more important things to tend to as a beginner).

If i understand correctly what you want to do i would try:
GML:
/// create event - executes only once when the instance is created
// use it to set the variables you want to use

global.variable1 = 42
global.variable2 = 12
variable1 = "hello"
variable2 = 4
variable3 = 5
variable_speed = 4
//^^only examples of course

/// step event - executes every step while the game is running
// use it to move the player for example
// a very easy way for linear movement is this:

var horizontal_movement = keyboard_check(vk_right) - keyboard_check(vk_left);
var vertical_movement = keyboard_check(vk_down) - keyboard_check(vk_up);
//these to variables are only temporarily stored

x += variable_speed * horizontal_movement
y += variable_speed * vertical_movement
// it is important to ADD (+=) to the x and y
// not to SET (=) them
Your english is fine^^
 

Nidoking

Member
Everything is going correctly except that the object to which the events are linked is not displayed in the room; yet I have positioned it well in it.
If you do not define a Draw event, then there is a default Draw event that does only this: draw_self();. If you define a Draw event, then the default is removed, and you will need to call draw_self(); in the defined event, if you want the default behavior of drawing the set sprite.
 

luxo-JR

Member
Hello and thank you for your answer and your advice. I enclose the code I'm working on, my goal is to drive the 'curses' object both with the mouse (it works) and also with the keyboard (using the arrow keys). I'm a bit confused, I implemented some of the code you provided me. My goal is to create (my first game) a 'Sokoban' style game; for now I'm focusing on the level editor; then I tackle the game itself.
Best regards.
Jean-François
PS : I knew Game Maker in the early 2000s, version developed by Mark Overmars, I used it a little and I gave up. At the time it was already a magnificent program. Game Maker Studio is a cut above.
GML:
x = (mouse_x div Larg_spr) * Larg_spr;
y = (mouse_y div Haut_spr) * Haut_spr;

Cur_col = mouse_x div Larg_spr;
Cur_lig = mouse_y div Haut_spr;

horizontal_movement = keyboard_check(vk_right) - keyboard_check(vk_left);
vertical_movement = keyboard_check(vk_down) - keyboard_check(vk_up);
vx = (Larg_spr * horizontal_movement);
vy = (Haut_spr * vertical_movement);
x += vx;
y += vy;

if (keyboard_check(vk_right))
{
    if (Cur_col < Nb_col)
    {
         Cur_col += 1;
    }
    else
    {
        Cur_col = 1;
    }
    X_spr = (Cur_col - 1) * Larg_spr;
    x = X_spr;
}

if (keyboard_check(vk_left))
{
    if (Cur_col > 0)
    {
         Cur_col -= 1;   
    }
    else
    {
        Cur_col = Nb_col;
    }
    X_spr = (Cur_col - 1) * Larg_spr;
    x = X_spr;
}


if (keyboard_check(vk_up))
{
    if (Cur_lig >= 0)
    {
         Cur_lig -= 1;   
    }
    else
    {
        Cur_lig = Nb_lig;
    }
    Y_spr = (Cur_lig - 1) * Haut_spr;
    y = Y_spr;
}

if (keyboard_check(vk_down))
{
    if (Cur_lig <= Nb_lig)
    {
         Cur_lig += 1;   
    }
    else
    {
        Cur_lig = 1;
    }
    Y_spr = (Cur_lig - 1) * Haut_spr;
    y = Y_spr;
}
 

luxo-JR

Member
Hello. I'm coming back to you for a question about the 'instance_create_layer' function. I wanted my level editor to use the keyboard and mouse, but I'll just keep the mouse (it works, half-win). I added a piece of code that creates an instance of a test object, so that when the left mouse button is pressed, it creates an intance of a specific object on the desired layer. Unfortunately, the created instance continues to follow the mouse cursor instead of remaining displayed in its place. I want to apologize to you because I often solicit you. I am attaching the code to you. Best regards. Jean-François
GML:
x = (mouse_x div Larg_spr) * Larg_spr;
y = (mouse_y div Haut_spr) * Haut_spr;

if mouse_check_button_pressed(mb_left)
   {
   instance_create_layer(x, y, "Instances_1", obj_dalle);
   //draw_sprite(spr_dalle, 0, x, y);
   //instance_create_depth(x, y, -10000, obj_dalle);
   }
 

Nidoking

Member
I assume that there's code in the obj_dalle that causes it to follow the mouse. If you don't want the obj_dalle to follow the mouse, don't tell it to do that.
 
Top