• 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!

GameMaker Quite new to coding and I need a bit of help with my RPG game any help would be greatly appreciated

B

bhoyle753

Guest
What I'm trying to make happen is, whenever the right_key is pressed show the sprite spr_player_right but however still show the sprite spr_player_right whenever moving diagonally up or downward. Same for moving left, up, and down.

The challenge with this is that when moving upward and suddenly you press the right_key or left_key to move diagonally whilst moving up I want the sprite to still show as spr_player_up and not for it to change to spr_player_left or spr_player_right.

(I want the same to happen with both the left and down movements of course)

I'm thinking that I need to somehow tell gamemaker to specifically check which button was pressed first. For example, If the right_key was pressed first and then the down_key or up_key was pressed after set the sprite to stay as spr_player_right. But if the down_key was pressed first and then the right_key was pressed after keep the sprite to be spr_player_down.

You can see which type of movement I am trying to achieve by watching some Zelda: a link to the past gameplay and watch how link can move diagonally whilst staying facing right and whilst facing down etc

Here is most of my code If you need it:

Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));


// Get the axis
var xaxis = (right_key - left_key);
var yaxis = (down_key - up_key);

// Check for gamepad input
if (gamepad_is_connected(0)) {
    gamepad_set_axis_deadzone(0, .35);
    xaxis = gamepad_axis_value(0, gp_axislh);
    yaxis = gamepad_axis_value(0, gp_axislv);
}


// Get direction
var dir = point_direction(0, 0, xaxis, yaxis);

// Get the length
if (xaxis == 0 and yaxis == 0) {
   len = 0;
} else {
   len = spd;
}

// Get the hspd and vspd
hspd = round(lengthdir_x(len, dir));
vspd = round(lengthdir_y(len, dir));

// Move
phy_position_x += hspd;
phy_position_y += vspd;


if down_key = true {
    sprite_index = spr_player_down
}

if up_key = true {
    sprite_index = spr_player_up
}

if right_key = true {                             
    sprite_index = spr_player_right         
}

if left_key = true {
    sprite_index = spr_player_left
}

// Correct direction sprites

if right_key = true and down_key = true {
    script_execute(scr_move_state_right)
} else if right_key = true and up_key = true {
    script_execute(scr_move_state_right())
}

if left_key = true and down_key = true {
    script_execute(scr_move_state_left)
} else if left_key = true and up_key = true {
    script_execute(scr_move_state_left())
}

if down_key = true and right_key = true {
    script_execute(scr_move_state_down)
} else if down_key = true and left_key = true {
    script_execute(scr_move_state_down())
}

if up_key = true  and right_key = true {
    script_execute(scr_move_state_up)
} else if up_key = true and left_key = true {
    script_execute(scr_move_state_up())
}

// Changing sprite to correct idle sprite

if sprite_index = spr_player_right and (hspd = 0) {
    sprite_index = spr_player_right_idle
}

if sprite_index = spr_player_left and (hspd = 0) {
    sprite_index = spr_player_left_idle
}

if sprite_index = spr_player_down and (vspd = 0) {
    sprite_index = spr_player_down_idle
}

if sprite_index = spr_player_up and (vspd = 0) {
    sprite_index = spr_player_up_idle
}

/// scr_move_state_up

sprite_index = spr_player_up


/// scr_move_state_down

sprite_index = spr_player_down


/// scr_move_state_right

sprite_index = spr_player_right


/// scr_move_state_left

sprite_index = spr_player_left


Here are my obj_player properties:

Step Event:

event_inherited();
script_execute(state);


Create Event:

event_inherited();
spd = 1;   
state = scr_move_state;
hspd = 0;
vspd = 0;
len = 0;
xaxis= 0;
yaxis = 0;
dir = 0;

Draw Event:

draw_sprite(spr_player_shadow, image_index, x, y);
draw_self();

I also have created a parent object so I can have the same collisions code for both the enemies and the player itself (mainly to keep things organized better) Here are the properties for it:

Create Event:
phy_fixed_rotation = true;

Step Event:
/// Control depth
depth = -y


 

CloseRange

Member
You had a detailed description of what you want and provided code. I like that!
I'm thinking that I need to somehow tell gamemaker to specifically check which button was pressed first. For example, If the right_key was pressed first and then the down_key or up_key was pressed after set the sprite to stay as spr_player_right. But if the down_key was pressed first and then the right_key was pressed after keep the sprite to be spr_player_down.
yes that is a good way to do it and how most people would do it.

What i propose might be more simple, just code in 4 checks:
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

if(right_key && !left_key && !up_key && !down_key) sprite_index = spr_player_right;
if(!right_key && left_key && !up_key && !down_key) sprite_index = spr_player_left;
if(!right_key && !left_key && up_key && !down_key) sprite_index = spr_player_up;
if(!right_key && !left_key && !up_key && down_key) sprite_index = spr_player_down;
 
B

bhoyle753

Guest
You had a detailed description of what you want and provided code. I like that!

yes that is a good way to do it and how most people would do it.

What i propose might be more simple, just code in 4 checks:
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

if(right_key && !left_key && !up_key && !down_key) sprite_index = spr_player_right;
if(!right_key && left_key && !up_key && !down_key) sprite_index = spr_player_left;
if(!right_key && !left_key && up_key && !down_key) sprite_index = spr_player_up;
if(!right_key && !left_key && !up_key && down_key) sprite_index = spr_player_down;
Thanks a lot for replying! I will definitely try this and see how it goes! Thanks again :)
 
B

bhoyle753

Guest
You had a detailed description of what you want and provided code. I like that!

yes that is a good way to do it and how most people would do it.

What i propose might be more simple, just code in 4 checks:
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

if(right_key && !left_key && !up_key && !down_key) sprite_index = spr_player_right;
if(!right_key && left_key && !up_key && !down_key) sprite_index = spr_player_left;
if(!right_key && !left_key && up_key && !down_key) sprite_index = spr_player_up;
if(!right_key && !left_key && !up_key && down_key) sprite_index = spr_player_down;
omg, you are a legend, finally! it's working! Since I'm new to the coding scene I was trying to get it to work all day and sending a post over to this forum was the best decision I've made. Not criticizing this code you sent me at all but I'm noticing a few issues here where I hold multiple keys down it shows my idle position any solution to this? Sorry for asking so many questions.
 

CloseRange

Member
it's fine i threw some code together and hoped it would work i didn't even really look at your code so no suprise there are problems:

Code:
if sprite_index = spr_player_right and (hspd = 0) {
    sprite_index = spr_player_right_idle
}

if sprite_index = spr_player_left and (hspd = 0) {
    sprite_index = spr_player_left_idle
}

if sprite_index = spr_player_down and (vspd = 0) {
    sprite_index = spr_player_down_idle
}

if sprite_index = spr_player_up and (vspd = 0) {
    sprite_index = spr_player_up_idle
}
you have that code and it 'overriding' the stuff I have.
try this instead:

Code:
if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle;
            break;
    }
}
you're new to coding so here is how a switch statement works (short version)
switch(VAR)
it will check the value of 'VAR'
case CONDITION:
if VAR equals CONDITION run the code below.
break;
this is the end of that bit of code, so now it will check if sprite_index is the one below.

This is the same as 4 if statements, but because we are always checking the value of sprite_index compared to something else, a switch statement will work better.
 
B

bhoyle753

Guest
it's fine i threw some code together and hoped it would work i didn't even really look at your code so no suprise there are problems:

Code:
if sprite_index = spr_player_right and (hspd = 0) {
    sprite_index = spr_player_right_idle
}

if sprite_index = spr_player_left and (hspd = 0) {
    sprite_index = spr_player_left_idle
}

if sprite_index = spr_player_down and (vspd = 0) {
    sprite_index = spr_player_down_idle
}

if sprite_index = spr_player_up and (vspd = 0) {
    sprite_index = spr_player_up_idle
}
you have that code and it 'overriding' the stuff I have.
try this instead:

Code:
if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle;
            break;
    }
}
you're new to coding so here is how a switch statement works (short version)
switch(VAR)
it will check the value of 'VAR'
case CONDITION:
if VAR equals CONDITION run the code below.
break;
this is the end of that bit of code, so now it will check if sprite_index is the one below.

This is the same as 4 if statements, but because we are always checking the value of sprite_index compared to something else, a switch statement will work better.
Thanks for that explanation i have that copied and pasted onto a sticky note on my desktop so i can refer to it in the future, still getting idle animatoins displaying whenever i hold right_key left_key and down_key at the same time, not a big issue really you've helped me a lot and i appreciate that here is my current code now:
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

// Get the axis
var xaxis = (right_key - left_key);
var yaxis = (down_key - up_key);

// Check for gamepad input
if (gamepad_is_connected(0)) {
    gamepad_set_axis_deadzone(0, .35);
    xaxis = gamepad_axis_value(0, gp_axislh);
    yaxis = gamepad_axis_value(0, gp_axislv);
}


// Get direction
var dir = point_direction(0, 0, xaxis, yaxis);

// Get the length
if (xaxis == 0 and yaxis == 0) {
   len = 0;
} else {
   len = spd;
}

// Get the hspd and vspd
hspd = round(lengthdir_x(len, dir));
vspd = round(lengthdir_y(len, dir));

// Move
phy_position_x += hspd;
phy_position_y += vspd;

if(right_key && !left_key && !up_key && !down_key) sprite_index = spr_player_right;
if(!right_key && left_key && !up_key && !down_key) sprite_index = spr_player_left;
if(!right_key && !left_key && up_key && !down_key) sprite_index = spr_player_up;
if(!right_key && !left_key && !up_key && down_key) sprite_index = spr_player_down;


if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle;
 
B

bhoyle753

Guest
oh sorry btw this only happens whenever i press the three buttons at the exact same time, not one after the other.
 
B

bhoyle753

Guest
The only thing that happens when i press the three buttons one after the other is for example if i press the right_key then the down_key i run diagonally but if i press the left_key too my player kinda shuffles downwards
 

CloseRange

Member
ohhhh ok that acutally makes sense.
try this then:

Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

var dx = right_key - left_key;
var dy = down_key - up_key;
if(dx == 1 && dy == 0)  sprite_index = spr_player_right;
if(dx == -1 && dy == 0)  sprite_index = spr_player_left;
if(dy == -1 && dx == 0)  sprite_index = spr_player_up;
if(dy == 1 && dx == 0)  sprite_index = spr_player_down;
booleans (true and false) are the same as 1 and 0 (true =1 and false =0)
so the var dx and var dy equates to:
if you arn't holding left or right, dx = 0 - 0 (or just 0)
if you are holdiing both then dx = 1 - 1 (still 0)
if you are holding just left then dx = 0 - 1 (so dx is -1)
if you hold just right then dx = 1 - 0 (so it's 1)

also the 'var' keyword means the variable is temporary and will be removed from memory after the code ends (so it isn't wasting space when you don't need it)
 
B

bhoyle753

Guest
LATEST UPDATE ON THE SITUATION: Changed things a little so the controller would work too using your code, the whole situation with the keys being pressed at the same time now only occurs when two keys either down_key and right_key or up_key and right_key or left_key and up_key or left_key and down_key happen to cause an idle sprite to show. If you don't wanna help me furthermore I respect that since you have already kindly helped me out a ton today thanks again!


Here is my latest current code:
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

// Get the axis
var xaxis = (right_key - left_key);
var yaxis = (down_key - up_key);

// Check for gamepad input
if (gamepad_is_connected(0)) {
    gamepad_set_axis_deadzone(0, .175);
    xaxis = gamepad_axis_value(0, gp_axislh);
    yaxis = gamepad_axis_value(0, gp_axislv);
}


// Get direction
var dir = point_direction(0, 0, xaxis, yaxis);

// Get the length
if (xaxis == 0 and yaxis == 0) {
   len = 0;
} else {
   len = spd;
}

// Get the hspd and vspd
hspd = round(lengthdir_x(len, dir));
vspd = round(lengthdir_y(len, dir));

// Move
phy_position_x += hspd;
phy_position_y += vspd;

if((hspd = 1) && !(hspd = -1) && !(vspd = -1) && !(vspd = 1)) sprite_index = spr_player_right;
if(!(hspd = 1) && (hspd = -1) && !(vspd = -1) && !(vspd = 1)) sprite_index = spr_player_left;
if(!(hspd = 1) && !(hspd = -1) && (vspd = -1) && !(vspd = 1)) sprite_index = spr_player_up;
if(!(hspd = 1) && !(hspd = -1) && !(vspd = -1) && (vspd = 1)) sprite_index = spr_player_down;


if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle;
            break;
    }
}
 
B

bhoyle753

Guest
ohhhh ok that acutally makes sense.
try this then:

Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

var dx = right_key - left_key;
var dy = down_key - up_key;
if(dx == 1 && dy == 0)  sprite_index = spr_player_right;
if(dx == -1 && dy == 0)  sprite_index = spr_player_left;
if(dy == -1 && dx == 0)  sprite_index = spr_player_up;
if(dy == 1 && dx == 0)  sprite_index = spr_player_down;
booleans (true and false) are the same as 1 and 0 (true =1 and false =0)
so the var dx and var dy equates to:
if you arn't holding left or right, dx = 0 - 0 (or just 0)
if you are holdiing both then dx = 1 - 1 (still 0)
if you are holding just left then dx = 0 - 1 (so dx is -1)
if you hold just right then dx = 1 - 0 (so it's 1)

also the 'var' keyword means the variable is temporary and will be removed from memory after the code ends (so it isn't wasting space when you don't need it)
will this work for my controller too since it relies on the use of hspd and vspd?
 
B

bhoyle753

Guest
ohhhh ok that acutally makes sense.
try this then:

Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));

var dx = right_key - left_key;
var dy = down_key - up_key;
if(dx == 1 && dy == 0)  sprite_index = spr_player_right;
if(dx == -1 && dy == 0)  sprite_index = spr_player_left;
if(dy == -1 && dx == 0)  sprite_index = spr_player_up;
if(dy == 1 && dx == 0)  sprite_index = spr_player_down;
booleans (true and false) are the same as 1 and 0 (true =1 and false =0)
so the var dx and var dy equates to:
if you arn't holding left or right, dx = 0 - 0 (or just 0)
if you are holdiing both then dx = 1 - 1 (still 0)
if you are holding just left then dx = 0 - 1 (so dx is -1)
if you hold just right then dx = 1 - 0 (so it's 1)

also the 'var' keyword means the variable is temporary and will be removed from memory after the code ends (so it isn't wasting space when you don't need it)
hmmm this unfortunately doesn't work
 

CloseRange

Member
Oh then instead maybe this:
Code:
var dx = sign(hspd);
var dy = sign(vspd);
if(dx == 1 && dy == 0)  sprite_index = spr_player_right;
if(dx == -1 && dy == 0)  sprite_index = spr_player_left;
if(dy == -1 && dx == 0)  sprite_index = spr_player_up;
if(dy == 1 && dx == 0)  sprite_index = spr_player_down;
same thing but using the speeds instead of the actual inputs. I'm not sure if there is any huge things that will change doing it this way I'm just used to always using the inputs as reference.
 
B

bhoyle753

Guest
Oh then instead maybe this:
Code:
var dx = sign(hspd);
var dy = sign(vspd);
if(dx == 1 && dy == 0)  sprite_index = spr_player_right;
if(dx == -1 && dy == 0)  sprite_index = spr_player_left;
if(dy == -1 && dx == 0)  sprite_index = spr_player_up;
if(dy == 1 && dx == 0)  sprite_index = spr_player_down;
same thing but using the speeds instead of the actual inputs. I'm not sure if there is any huge things that will change doing it this way I'm just used to always using the inputs as reference.
another question does it matter where i place these pieces of code? obviously inside my script but location inside the script.
 
B

bhoyle753

Guest
Here is a screen recording of what happens when I press the buttons at the exact same time
 
B

blandanablandana

Guest
you can make a condition on your keypresses that can be seperate from the speed if you are having trouble with idle animations.
That way if you have a "direction" variable, you can set it to "left" when you press left, and "right" when you press right, etc, and it should change even if you have multiple keys being held down depending on the last one you pressed I believe.

Using that variable you might be more able to accurately adjust your sprites sort of doing that same thing that CloseRange has been trying to explain. This might help.

define "spriteDirection = 0;" or something in your create event and then change it to something else in your key press code. Then below that you should be able to have more control over your if statements. I'm not sure if this helps but I found this is what I had to do if I want my character to "keep" a direction or sprite after it stops moving or something.
 

CloseRange

Member
Code:
if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle;
            break;
    }
}
comment this out.
test if you ever go to idle poisition.
If the player ever goes back to idle position (not counting the very start) then you are setting the sprite index somewhere else as well.
If it stay on the walking animation always, then the problem would be with this code. Just don't want to go on a wild goose chase if the problem is somewhere else.
 
B

bhoyle753

Guest
I have a piece of code which states draw_self(); in the draw event of my obj_player and I believe it is drawing spr_player_down_idle
 
B

bhoyle753

Guest
hmm taking out the draw_self(); means my sprite doesn't show at all
 

CloseRange

Member
draw_self wouldn't be the problem.
It's the same as doing:
Code:
draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, 0, image_blend, image_alpha);
so if you change the sprite_index then draw_self will reflect that.
 
B

bhoyle753

Guest
Yeah It's no bother I shall just leave it the way it is now thanks for spending time out of your day helping me fix the main issue I had, all the best, goodbye!
 
B

bhoyle753

Guest
you can make a condition on your keypresses that can be seperate from the speed if you are having trouble with idle animations.
That way if you have a "direction" variable, you can set it to "left" when you press left, and "right" when you press right, etc, and it should change even if you have multiple keys being held down depending on the last one you pressed I believe.

Using that variable you might be more able to accurately adjust your sprites sort of doing that same thing that CloseRange has been trying to explain. This might help.

define "spriteDirection = 0;" or something in your create event and then change it to something else in your key press code. Then below that you should be able to have more control over your if statements. I'm not sure if this helps but I found this is what I had to do if I want my character to "keep" a direction or sprite after it stops moving or something.
Ok, how could i implement this?
 
B

blandanablandana

Guest
Ok, how could i implement this?
I ended up doing a farm rpg tutorial that is listed on this website. I'll look up exactly what I did but I'm pretty sure it should do exactly what you need. It gives you all four directions but keeps your sprite fixed in the "main" direction you are going.

If you find it before I can post it it is from "friendly cosmonaut" it is video two and three in their farming rpg tutorial series.

you can start watching it by clicking on the link here if you havent, it starts out with no sprites but then adds them in the next video. I'll will do my best to see if I can get you something that works in the next 24 hours or so if nobody else's responses quite help you enough.
 
Last edited by a moderator:
B

blandanablandana

Guest
ok great. I got a basic system working where it makes you move when you press WASD and also using the left analog without having to check if controller zero is connected. You just have to add a "characterWalkSpeed=3;" (or speed of your choice) variable to your create event since I added it in to let you adjust the speed. I'll try to get the sprites working like you need as soon as i can. You can create a backup version of your character and try pasting this code into the step event instead and see if you like the way it performs.

*** a little known fact I think. hspeed and vspeed are built in variables and give you far more accurate results if you use them for movement. Sorry if you are not used to the green letters if you type it in. I had a lot of pixel glitches with sprites until I started using specifically hspeed and vspeed.

Code:
right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));



// define deadzone of gamepad_axis_value(controller_ID, axis) to be 0.2
// abs means absolute value (always positive if analog stick is tilted)
if (abs(gamepad_axis_value(0,gp_axislh)) > 0.2
 or abs(gamepad_axis_value(0,gp_axislv)) > 0.2)

{
    left_key = abs(min(gamepad_axis_value(0,gp_axislh),0));
    right_key = max(gamepad_axis_value(0,gp_axislh),0);
    up_key = -max(gamepad_axis_value(0,gp_axislv),0);
    down_key= -abs(min(gamepad_axis_value(0,gp_axislv),0));
 
 
}

hspeed = (right_key-left_key) * characterWalkSpeed;
vspeed = (down_key-up_key) * characterWalkSpeed;
 
Last edited by a moderator:
B

bhoyle753

Guest
I ended up doing a farm rpg tutorial that is listed on this website. I'll look up exactly what I did but I'm pretty sure it should do exactly what you need. It gives you all four directions but keeps your sprite fixed in the "main" direction you are going.

If you find it before I can post it it is from "friendly cosmonaut" it is video two and three in their farming rpg tutorial series.

you can start watching it by clicking on the link here if you havent, it starts out with no sprites but then adds them in the next video. I'll will do my best to see if I can get you something that works in the next 24 hours or so if nobody else's responses quite help you enough.
ah thanks for this i will try it later on at the moment i am trying to add a dash state which only lasts for as long as you have the dash button held down here is my code so you can see what i can do :
Code:
/// scr_move_state

right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));
dash_key = keyboard_check(vk_lshift) or gamepad_button_check(0, gp_face1);
dash_key_released = keyboard_check_released(vk_lshift) or gamepad_button_check_released(0, gp_face1);

// Get the axis
var xaxis = (right_key - left_key);
var yaxis = (down_key - up_key);

// Check for gamepad input
if (gamepad_is_connected(0)) {
    gamepad_set_axis_deadzone(0, .175);
    xaxis = gamepad_axis_value(0, gp_axislh);
    yaxis = gamepad_axis_value(0, gp_axislv);
}

// Get direction
dir = point_direction(0, 0, xaxis, yaxis);

// Get the length
if (xaxis == 0 and yaxis == 0) {
   len = 0;
} else {
   len = spd;
}

// Get the hspd and vspd
hspd = round(lengthdir_x(len, dir));
vspd = round(lengthdir_y(len, dir));

// Move
phy_position_x += hspd;
phy_position_y += vspd;

if((hspd > 0) && !(hspd < 0) && !(vspd < 0) && !(vspd > 0)) sprite_index = spr_player_right;
if(!(hspd > 0) && (hspd < 0) && !(vspd < 0) && !(vspd > 0)) sprite_index = spr_player_left;
if(!(hspd > 0) && !(hspd < 0) && (vspd < 0) && !(vspd > 0)) sprite_index = spr_player_up;
if(!(hspd > 0) && !(hspd < 0) && !(vspd < 0) && (vspd > 0)) sprite_index = spr_player_down;


if(hspd == 0 && vspd == 0) {
    switch(sprite_index) {
        case spr_player_right:
            sprite_index = spr_player_right_idle image_index = 1;
            break;
        case spr_player_down:
            sprite_index = spr_player_down_idle image_index = 1;
            break;
        case spr_player_up:
            sprite_index = spr_player_up_idle image_index = 1;
            break;
        case spr_player_left:
            sprite_index = spr_player_left_idle image_index = 1;
            break;
    }
}
 
B

blandanablandana

Guest
I think I should have a version of your code that works the way you need or really close soon.
I'll post again here in an hour or two.
 
B

blandanablandana

Guest
ok sure thanks.
ok here you go, it's not perfect but it's close try pasting this into your step event and also create a variable in your create event for "characterWalkSpeed=3;" or whatever value you want.

This seems like it does exactly what you want but unfortunately actually it has a tough time playing animations with multiple key presses. You may have to make your animations in a sprite sheet and sort of do what that farm video I posted explains. It's a little more in depth but my code is pretty close.

It does not take the "idle" animation into account but I'm pretty proud that I could make this work in such a short amount of time.

let me know if this helps you at all.
Ill try to post a final version but it will have a lot more explanation if I can get it work right. It will be a condensed version of that farm tutorial.

Code:
/// @description Insert description here
// You can write your code in this editor
right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));



// define deadzone of gamepad_axis_value(controller_ID, horizontal axis) to be 0.2
// abs means absolute value (always positive if analog stick is tilted)
if (abs(gamepad_axis_value(0,gp_axislh)) > 0.2
 or abs(gamepad_axis_value(0,gp_axislv)) > 0.2)

{
    left_key = abs(min(gamepad_axis_value(0,gp_axislh),0));
    right_key = max(gamepad_axis_value(0,gp_axislh),0);
    up_key = -max(gamepad_axis_value(0,gp_axislv),0);
    down_key= -abs(min(gamepad_axis_value(0,gp_axislv),0));
 
 
}

hspeed = (right_key-left_key) * characterWalkSpeed;
vspeed = (down_key-up_key) * characterWalkSpeed;


//sprite indexes
if left_key {obj_player.sprite_index = spr_player_left}
if right_key {obj_player.sprite_index = spr_player_right}
if down_key {obj_player.sprite_index = spr_player_down}
if up_key {obj_player.sprite_index = spr_player_up}
 
Last edited by a moderator:
B

bhoyle753

Guest
ok here you go, it's not perfect but it's close try pasting this into your step event and also create a variable in your create event for "characterWalkSpeed=3;" or whatever value you want.

This seems like it does exactly what you want but unfortunately actually it has a tough time playing animations with multiple key presses. You may have to make your animations in a sprite sheet and sort of do what that farm video I posted explains. It's a little more in depth but my code is pretty close.

It does not take the "idle" animation into account but I'm pretty proud that I could make this work in such a short amount of time.

let me know if this helps you at all.
Ill try to post a final version but it will have a lot more explanation if I can get it work right. It will be a condensed version of that farm tutorial.

Code:
/// @description Insert description here
// You can write your code in this editor
right_key = keyboard_check(vk_right) or (keyboard_check(ord("D")));
left_key = keyboard_check(vk_left) or (keyboard_check(ord("A")));
up_key = keyboard_check(vk_up) or (keyboard_check(ord("W")));
down_key = keyboard_check(vk_down) or (keyboard_check(ord("S")));



// define deadzone of gamepad_axis_value(controller_ID, horizontal axis) to be 0.2
// abs means absolute value (always positive if analog stick is tilted)
if (abs(gamepad_axis_value(0,gp_axislh)) > 0.2
 or abs(gamepad_axis_value(0,gp_axislv)) > 0.2)

{
    left_key = abs(min(gamepad_axis_value(0,gp_axislh),0));
    right_key = max(gamepad_axis_value(0,gp_axislh),0);
    up_key = -max(gamepad_axis_value(0,gp_axislv),0);
    down_key= -abs(min(gamepad_axis_value(0,gp_axislv),0));
 
 
}

hspeed = (right_key-left_key) * characterWalkSpeed;
vspeed = (down_key-up_key) * characterWalkSpeed;


//sprite indexes
if left_key {obj_player.sprite_index = spr_player_left}
if right_key {obj_player.sprite_index = spr_player_right}
if down_key {obj_player.sprite_index = spr_player_down}
if up_key {obj_player.sprite_index = spr_player_up}
woah did you sit there and type all this code for me?
 
B

blandanablandana

Guest
haha no offence but why?
i sort of need a refresher on rpg movement and controller axis input and I've also been working on a platformer so it's a nice break if I can help someone who needs it. (im working on the final version now but it involves making a sprite sheet. I will send you a link to the photoshop grid file that you can use when I am finished so you can just replace the sprites or get the basic idea.


what are your sprite dimensions by the way? 32x32? 64x64? 128x128?
this might be pretty tough if your animations dont keep a consistant size. I'm actually not an expert but I'm fairly certain my next example will get you on the right track.
 
Last edited by a moderator:
B

bhoyle753

Guest
i sort of need a refresher on rpg movement and controller axis input and I've also been working on a platformer so it's a nice break if I can help someone who needs it.
oh ok i see, well i tried it, but it doesn't move my player at all i put the thing you told me to into the create event, i believe the reason is because before i created my own variables for vertical speed and horizontal speed simply because i knew the in game vspeed and hspeed variables dont work with physics objects.
 
B

bhoyle753

Guest
i sort of need a refresher on rpg movement and controller axis input and I've also been working on a platformer so it's a nice break if I can help someone who needs it. (im working on the final version now but it involves making a sprite sheet. I will send you a link to the photoshop grid file that you can use when I am finished so you can just replace the sprites or get the basic idea.


what are your sprite dimensions by the way? 32x32? 64x64? 128x128?
this might be pretty tough if your animations dont keep a consistant size. I'm actually not an expert but I'm fairly certain my last example will get you on the right track.
oh dear haha your going to laugh but my sprite is super small and weird at 14x21
 
B

blandanablandana

Guest
oh dear haha your going to laugh but my sprite is super small and weird at 14x21
ok. I'm going to make a grid of 32x32 pixels but you will have to see what you can do to center each one of your sprites in the boxes when it is all finished I will explain it when I am finished. I'm not sure if it will help you completely but it should help you a bit.
 
B

blandanablandana

Guest
oh I apologize. If you are trying to use physics objects I actually have no idea how to do that. I will post my final version of what I was trying to do but it probably wont be exactly what you want in that case. You can use the code though if you think it helps of course.

You can probably modify it once I am done to work with your standards or variables once the sprites are working (that's the problem right?)
 
B

bhoyle753

Guest
ok. I'm going to make a grid of 32x32 pixels but you will have to see what you can do to center each one of your sprites in the boxes when it is all finished I will explain it when I am finished. I'm not sure if it will help you completely but it should help you a bit.
Ok no problem, is there anything i can do for you? It's just i feel bad for you getting nothing out of this experience
 
B

blandanablandana

Guest
Ok no problem, is there anything i can do for you? It's just i feel bad for you getting nothing out of this experience
It's ok. I think if I get the sprites working with your controller inputs you can change the variable to add physics_x real positions and replace the vspeed/hspeed parts.
 
B

bhoyle753

Guest
oh I apologize. If you are trying to use physics objects I actually have no idea how to do that. I will post my final version of what I was trying to do but it probably wont be exactly what you want in that case. You can use the code though if you think it helps of course.
Why don't you use physics objects? How do you go about making collisions work?
 
B

blandanablandana

Guest
Why don't you use physics objects? How do you go about making collisions work?
make an object you want to make the player collide with.
-then- for every other object you want to have a basic collision with, create the object, choose the sprite, and then parent it (select the object and click the parent button in the viewport popup) to something called
"obj_wallBasic" (your original object) as seen in this example. This will allow you to paste obj_wallBasic and also anything that is parented to it and they will all receive collisions from this code if you paste it into your character's step event.

my collision code always looks like this
if you make an object and place it in your scene and name it "obj_wallBasic" and paste this code into you character step event you should collide pixel perfectly.
Code:
// horizontal collision
if (place_meeting(x+hspeed, y, obj_wallBasic))
{
    while (!place_meeting(x+sign(hspeed), y, obj_wallBasic))
    {
        x = x + sign(hspeed);
    }
    hspeed = 0;
 
}


// vertical collision
if (place_meeting(x, y+vspeed, obj_wallBasic))
{
    while (!place_meeting(x, y+sign(vspeed), obj_wallBasic))
    {
        y = y + sign(vspeed);
    }
    vspeed = 0;

 
}
 
Last edited by a moderator:
B

bhoyle753

Guest
ah ok i see, is that all physics objects are used for or does density etc depend on the physics too?
 
B

blandanablandana

Guest
ah ok i see, is that all physics objects are used for or does density etc depend on the physics too?
I actually have no idea about any physics related stuff, but maybe you are right. I wish I could give you an answer, you probably know more than me about the physics part of the engine. The code seems to be working, it has movement and perfect collisions now. The next one I post will be the final version with the sprite grid explanation.
 
B

bhoyle753

Guest
I actually have no idea about any physics related stuff, but maybe you are right. I wish I could give you an answer, you probably know more than me about the physics part of the engine. The code seems to be working, it has movement and perfect collisions now. The next one I post will be the final version with the sprite grid explanation.
Thanks a bunch
i will be looking forward to it!
 
B

blandanablandana

Guest
Thanks a bunch
i will be looking forward to it!
I think it's going to take a few more hours but I will have the last post ready in 24 hours for you.

Thank you for your pateience. This is actually a valuable thread I'm saving all the code I'm making for sure.
 
B

bhoyle753

Guest
Thats perfectly fine, no rush, and yep save all the code you make definitely, even if i only use small sections from your code im sure you can help someone else with it further down the line. By the way, if you're interested, my game im making is going to be zombie apocalypse based RPG with various puzzle elements somehow infused into the gameplay. I thought this was a brilliant idea and a very challenging one too.
 
B

blandanablandana

Guest
Thats perfectly fine, no rush, and yep save all the code you make definitely, even if i only use small sections from your code im sure you can help someone else with it further down the line. By the way, if you're interested, my game im making is going to be zombie apocalypse based RPG with various puzzle elements somehow infused into the gameplay. I thought this was a brilliant idea and a very challenging one too.
that's cool I'm going to try and incorporate puzzle sort of themes into my platformer as well. it's very mentally stimulating when you figure out puzzles.
 
B

bhoyle753

Guest
that's cool I'm going to try and incorporate puzzle sort of themes into my platformer as well. it's very mentally stimulating when you figure out puzzles.
yeh it adds a new and interesting dimension to the game if you can pull it off properly. if you dont mind me asking \what is your platformer based on and is it going to be published? or is that confidential information?
 
Top