Legacy GM Help with virtual analog controls

A

Artwark

Guest
Ok so here's the code for the movement for obj_player

But before that I did two scripts here

scr_mouse_x
if os_type == os_windows || os_type == os_linux || os_type == os_macosx
{
return display_get_gui_width() * (argument0/ window_get_width());
}
else
{
return display_get_gui_width() * (argument0/ display_get_width());
}

scr_mouse_y
if os_type == os_windows || os_type == os_linux || os_type == os_macosx
{
return display_get_gui_height() * (argument0/ window_get_height());
}
else
{
return display_get_gui_height() * (argument0/ display_get_height());
}

Now for obj_player

Create Event

gui_x[0] = 64;
gui_y[0] = (display_get_gui_height() - 64);
gui_x[1] = (display_get_gui_width() - 64);
gui_y[1] = (display_get_gui_height() - 64);
stick_x[0] = gui_x[0];
stick_y[0] = gui_y[0];
stick_x[1] = gui_x[1];
stick_y[1] = gui_y[1];
st_pressed[0] = -1;
st_pressed[1] = -1;
st_radius = 40;
vdir = 0;
b_spd = 5;
image_speed = 1/3;
alarm[0] = 100;
alarm[2] = -1;

Step event
speed = max(speed - 0.01,0);

Keyboard UP

motion_add(image_angle, 0.2)
if(speed>5) speed = 5;

Keyboard Left
image_angle = image_angle + 2;

Keyboard Right
image_angle = image_angle - 2;

now for the obj_analog

Create Event

gui_x[0] = 64;
gui_y[0] = (display_get_gui_height() - 86);
gui_x[1] = (display_get_gui_width() - 86);
gui_y[1] = (display_get_gui_height() - 86);
stick_x[0] = gui_x[0];
stick_y[0] = gui_y[0];
stick_x[1] = gui_x[1];
stick_y[1] = gui_y[1];
st_pressed[0] = -1;
st_pressed[1] = -1;
st_radius = 40;
vdir = 0;
b_spd = 5;

Step Event

stick_x[0] = gui_x[0];
stick_y[0] = gui_y[0];
if st_pressed[0] = -1
{
for (i = 0; i < 5; i++; )
{
if device_mouse_check_button(i, mb_left)
{
var tx, ty;
tx = scr_mouse_x(device_mouse_raw_x(i));
ty = scr_mouse_y(device_mouse_raw_y(i));
if point_distance(tx, ty, gui_x[0], gui_y[0]) < st_radius
{
if st_pressed[1] != i
{
st_pressed[0] = i;
break;
} }
}
}
}
if device_mouse_check_button(st_pressed[0], mb_left)
{
var spd, vdist, mx, my;
mx = scr_mouse_x(device_mouse_raw_x(st_pressed[0]));
my = scr_mouse_y(device_mouse_raw_y(st_pressed[0]));
vdist = min(st_radius, point_distance(mx, my, gui_x[0], gui_y[0]));
vdir = point_direction(gui_x[0], gui_y[0], mx, my);
spd = min(b_spd, vdist / 10);
h_spd = lengthdir_x(spd, vdir);
v_spd = lengthdir_y(spd, vdir);
stick_x[0] = gui_x[0] + lengthdir_x(vdist, vdir);
stick_y[0] = gui_y[0] + lengthdir_y(vdist, vdir);
}
else
{
st_pressed[0] = -1;
}

Draw GUI

draw_circle_color(gui_x[0], gui_y[0], st_radius, c_lime, c_lime, true);
draw_circle_color(stick_x[0], stick_y[0], 20, c_lime, c_lime, true);

So I want to know, how to incorporate movement from the obj_player keyboard events to the obj_analog step event?

I'm sorry if this seems like i'm pleading for an answer or something but I honestly feel that for something like this, its too complex and I can't figure out what to do here. I tried doing the tutorial here but that didn't teach me anything here.

EDIT: Not to mention how easy it is to do virtual keys compared to the virtual analog..... :/
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I tried doing the tutorial here but that didn't teach me anything here
Which tutorial? There is one on this in GameMaker itself (from the Tutorials tab on startup), and if it wasn't that then I'd suggest downloading it and having a look.
 
A

Artwark

Guest
Which tutorial? There is one on this in GameMaker itself (from the Tutorials tab on startup), and if it wasn't that then I'd suggest downloading it and having a look.
Its the one that Studio provides.....and I still didn't get the point of the thing......and this code is based on the tutorial if you didn't notice....
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
lol! Okay, just checking... :)

Basically the analog pad code is setting a few variables that you can then use to move the player, namely the h_spd and v_spd variables and the vdir local variable. Now the quick fix would be to simply add this into the gamepad code:

Code:
...
h_spd = lengthdir_x(spd, vdir);
v_spd = lengthdir_y(spd, vdir);
// CODE HERE
with (obj_Player)
    {
    image_angle = vdir;
    motion_add(image_angle, 0.2);
    if speed > 5 speed = 5;
    }
stick_x[0] = gui_x[0] + lengthdir_x(vdist, vdir);
stick_y[0] = gui_y[0] + lengthdir_y(vdist, vdir);
...
You can probably remove the h_spd and v_spd parts too, since you aren't using them...

Note that this is the quick and dirty solution, but you would be advised to unify the whole keyboard/gamepad stuff in one single object (either the player or a controller) and check for movement from ANY source first then actually move. So you'de check for keyboard or mouse and store the results in variables, then you'd use the variables to move at the end.
 
A

Artwark

Guest
lol! Okay, just checking... :)

Basically the analog pad code is setting a few variables that you can then use to move the player, namely the h_spd and v_spd variables and the vdir local variable. Now the quick fix would be to simply add this into the gamepad code:

Code:
...
h_spd = lengthdir_x(spd, vdir);
v_spd = lengthdir_y(spd, vdir);
// CODE HERE
with (obj_Player)
    {
    image_angle = vdir;
    motion_add(image_angle, 0.2);
    if speed > 5 speed = 5;
    }
stick_x[0] = gui_x[0] + lengthdir_x(vdist, vdir);
stick_y[0] = gui_y[0] + lengthdir_y(vdist, vdir);
...
You can probably remove the h_spd and v_spd parts too, since you aren't using them...

Note that this is the quick and dirty solution, but you would be advised to unify the whole keyboard/gamepad stuff in one single object (either the player or a controller) and check for movement from ANY source first then actually move. So you'de check for keyboard or mouse and store the results in variables, then you'd use the variables to move at the end.
Thanks for the help, I'll see what I can do about it.

If possible, please request Yoyo games of a simpler way to make virtual analog controls seeing as how simple the code is for virtual keys.
 
A

Artwark

Guest
Ok so I did as instructed and it works.

But now I want to understand one thing.

To make it so that when I move the analog either left or right, would this logic work or would it make it worse?

else if(st_pressed[1], mb_left)
{

var spd, vdist, mx, my;
mx = scr_mouse_x(device_mouse_raw_x(st_pressed[0]));
my = scr_mouse_y(device_mouse_raw_y(st_pressed[0]));
vdist = min(st_radius, point_distance(mx, my, gui_x[0], gui_y[0]));
vdir = point_direction(gui_x[0], gui_y[0], mx, my);
spd = min(b_spd, vdist / 10);
h_spd = lengthdir_x(spd, vdir);
v_spd = lengthdir_y(spd, vdir);
stick_x[0] = gui_x[0] + lengthdir_x(vdist, vdir);
stick_y[0] = gui_y[0] + lengthdir_y(vdist, vdir);
with (obj_player)
{
image_angle = vdir *(image_angle + 2);
}
stick_x[0] = gui_x[0] + h_spd;
stick_y[0] = gui_y[0] + v_spd;
}
Oh and this is done in one analog object so I did as told.
 
Last edited by a moderator:
A

Artwark

Guest
Ok, I kinda fixed the problem and I somehow got what I wanted. Basically, I just copy pasted whatever the analog tutorial had to offer and I used the player object for this.

I know that this doesn't seem like a very wise move, but I'm sorry....I feel that for something like this, you shouldn't do too much of coding. if it was simple to do this for virtual keys, why is it so hard to do it for a virtual analog? Even Unity can easily do this in minutes!
 
Top