• 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 Squash N' Stretch With Kirby

M

MegaGamer99

Guest
Greetings, Game Makers!

While I'm implementing animations for my game, I happen to run towards a few issues:

  • I don't know a way to add a horizontal squish sprite whenever I run into a wall and turn back to normal (I tried doing it but the squished sprite stayed that way whenever I still touched the wall).
  • The squished sprite for my vertical collision (AKA the crouch sprite) works, but landing on the floor had the sprite changing back to normal quicker than the sprite change on collision with the ceiling.
  • And finally, whenever Kirby has Fall mode on and landing on the floor, his fall2 sprite changes after colliding the floor the first time, I want the fall2 sprite to change after the Fall bounce (performed when colliding with the floor in Fall mode).
I don't know how to resolve these, so I was wondering how you guys would figure out about this. If you can, thanks. By the way, here's my player's code for explanation and reference:

Code:
Create Event:

execute code:

//-----Intitialize Variables-----//
movespeed = 2; //Moving speed (2 pixels per frame)
runspeed = 4;//Running Speed (4 pixels per frame)
jumpspeed = -7; //Jumping speed (negative because it goes up)
grav = 0.6; //Gravity strength (usually a small value)
//These variables are actually used to move the player
hsp = 0; //Horizontal speed
vsp = 0; //Vertical speed
ground = 1; //Whether the player is on the ground
Duck = false;
Fall = false;
step = 0;


Step Event:

execute code:

//-----Keyboard Input-----//
Key_Left = keyboard_check(vk_left);
Key_Right = keyboard_check(vk_right);
Key_Jump = keyboard_check_pressed(ord('Z'));
//This one's for variable jump height:
Key_Fall = keyboard_check_released(ord('Z'));
Key_Down = keyboard_check(vk_down);
Key_Attack = keyboard_check(ord('X'));

//Horizontal Motion
if (Key_Left) and (Duck = false)
{
    hsp = -movespeed; //Walk left
    image_xscale = -1; //Face left
}
if (Key_Right) and (Duck = false)
{
    hsp = movespeed; //Walk right
    image_xscale = 1; //Face right
}

//Movement Key Release
if (!Key_Left) and (!Key_Right) hsp = 0;

//Vertical Motion
//Is the player in the air?
if (place_meeting(x,y+1,obj_blockpar)) ground = 1;
else ground = 0;

if (Key_Jump and ground and !Key_Down)
{
   vsp = jumpspeed;
}
//Variable Jumping
if (Key_Fall and !ground and vsp < -3  and !Key_Down) vsp = -2;
//Fall with gravity
if (!ground) vsp += grav;
//Limit Vspeed
if (vsp > 6) vsp = 6;

//Horizontal Collision
if (place_meeting(x+hsp,y,obj_blockpar))
{
    while(!place_meeting(x+sign(hsp),y,obj_blockpar))
    {
        x += sign(hsp);
    }
    hsp = 0;
}
x += hsp;

//Vertical Collision
if (place_meeting(x,y+vsp,obj_blockpar))
{
    while(!place_meeting(x,y+sign(vsp),obj_blockpar))
    {
        y += sign(vsp);
    }
    vsp = 0;
}
y += vsp;

//Ducking
if (Key_Down) and (Duck = false) and (ground = 1)
Duck = true;
if (Duck = true) and (ground = 1) and (hsp != 0)
{
    if (hsp > 0) hsp -= movespeed;
    if (hsp < 0) hsp += movespeed;
}
if (!Key_Down) and (Duck = true)
Duck = false;

//Falling
if (ground = 0 and vsp > 0 and Fall = false)
{
    step += 1;
    }else{
    step = 0;
}

if (step = 17 and Fall = false)
{
    if (step < 17) step = 17;
    Fall = true;
}

if (ground = 1)
{
    if (Fall = true)
    vsp = -4;
    Fall = false;
}

//Sprite Change
if (ground = 1) and (hsp = 0)
sprite_index = spr_kirby_idle;

if (ground = 0)
sprite_index = spr_kirby_jump;
if (ground = 0) and (vsp > 0)
sprite_index = spr_kirby_fall;

if (ground = 1) and (hsp != 0)
sprite_index = spr_kirby_walk; image_speed = 0.30;

if (Duck = true) and (Key_Down)
sprite_index = spr_kirby_duck;

if (Fall = true)
sprite_index = spr_kirby_fall2;

if (place_meeting(x,y+1,obj_blockpar)) and (ground = 0)
sprite_index = spr_kirby_duck;

if (place_meeting(x,y-1,obj_blockpar)) and (ground = 0)
sprite_index = spr_kirby_squishv;

//Mask Change
if (Duck = true) or (sprite_index = spr_kirby_duck)
{
    mask_index = spr_kirby_mask2;
    }else{
    mask_index = spr_kirby_mask1;
}

if (sprite_index = spr_kirby_squish)
{
    mask_index = spr_kirby_mask3;
    }else{
    mask_index = spr_kirby_mask1;
}
 
T

TDSrock

Guest
The first can be resolved through a Boolean.
Here is an example, it is slightly different to ensure you work this out on your own(I prefer people doing their own coding)
What I want: whenever I hit a button for the first time ever I want it to work. If I push a reset button I want ALL buttons to reset. I will assume my reset button has a script called: reset(), which does the resetting for me. I will also assume I already have a pressed boolean that trackes when a left mouseclick occors on the button. I also assume I have a perform_Button_Action() script as what the button actually does is not relevant.
Code:
//In our buttons
//creation code
FirstPress = false;

//step event
if(pressed && !FirstPress)
{
    FirstPress = true;
    perform_Button_Action();
}
Code:
//reset button
//step event
if(pressed)
{
   reset();
}
This concept can be brought over to the character hitting the wall for the first time.
If it's the first time hitting the wall, run the animation, as long as we are still on the wall no need to rerun the code we have already done it.
As soon as we are released from the wall change say that it can happen again.

The second issue is most likely because the if is no longer true (if( touching the ceiling))
So there again we can handle it via a Boolean.
if we touched the ceiling
ceiling animation becomes true, let it play for it's entirety and then set ceiling animation back to false.
 
Last edited by a moderator:
M

MegaGamer99

Guest
Do you think you could simplify that a little bit, that looks a little be complex...:confused:

Besides, for the first one, I'm looking for when colliding with the side of the wall, it changes the sprite a Kirby into a squished sprite, then after a second, he reverts back to his normal sprite.
 
T

TDSrock

Guest
What exactly is looking complex to you? As it might just be that you are not familiar with some other concepts, such as the logical operator &&, which just simply means "and".
 
M

MegaGamer99

Guest
You're right, I have never seen the reset code before.
 
M

MegaGamer99

Guest
The reason why I called it complex is because I don't see how I'm gonna implement my squished sprite code to the boolean code
 
T

TDSrock

Guest
You're right, I have never seen the reset code before.
Reset is just a function I decided to assume would exists. I did forget to mention that reset would as loop through the all the buttons I had and set FirstPress back to false.

It would be script within gamemaker that I could invoke that would probably do quite allot, as it would have to first find each button in my scenario, build them into an array and the loop through that array setting each buttons FirstPress to false, so that they could be pressed again.

My bad for not including that in my initial post!


Well what I am doing is an example of the concept you would be applying. The concept is to track a Boolean, set it to false and then set it true when the condition it is looking for happens, keep it there until the condition has ended.
 
M

MegaGamer99

Guest
Problem: Unknown function or script: perform button action and reset
 
T

TDSrock

Guest
Problem: Unknown function or script: perform button action and reset
Because you have not defined them. You didn't make a script within your gamemaker which would then hold the information for the scripts. Maybe referencing scripts was a mistake on my behalf.

All you will need is to manage a single Boolean value properly and add it into the conditional of your if statement when playing animations.
 
M

MegaGamer99

Guest
Code:
if (place_meeting(x+1,y,obj_blockpar) or (place_meeting(x-1,y,obj_blockpar)))
sprite_index = spr_kirby_squish;
Ok, so I pasted my code to change my sprite when colliding horizontally. Now, I want Kirby to change back to his normal sprite after a second and allow him to use other sprites while he's at the wall. However, this is my only piece of code, so he changes into his Squish sprite but doesn't change back while he's next to the wall.
 
T

TDSrock

Guest
Yeap. I got that from before. Now we need to make the conditonal of the if statement a little more complicated.

Before we toutch it though you'll need to head to the create event and say something like
Code:
SquishModePossible = true;
Then add the new Boolean to the conditional of the above code(your code).
In the if statement we set the new =Boolean to false, to avoid the code from repeating.
After a second time has passed you set back the sprite_index to the one you want.
if kirby ever stoppes touching the wall set the new Boolean back to true so squishmode is possible again next time he hits a wall.
 
Last edited by a moderator:
M

MegaGamer99

Guest
Ok I added the possible = true code in the create event, now what?
 
M

MegaGamer99

Guest
Yeap. I got that from before. Now we need to make the conditonal of the if statement a little more complicated.

Before we toutch it though you'll need to head to the create event and say something like
Code:
SquishModePossible = true;

Then add the new Boolean to the conditional of the above code.
In the if statement we set the new =Boolean to false, to avoid the code from repeating.
After a second time has passed you set back the sprite_index to the one you want.
if kirby ever stoppes touching the wall set the new Boolean back to true so squishmode is possible again next time he hits a wall.
Not to be difficult, but do I just type in Squishmodepossible = false on my sprite change code and add another sprite change code after that?
 
M

MegaGamer99

Guest
Sorry if i sounded a little unintelligible back there, I'm just still new to GML.
 
T

TDSrock

Guest
That depends on how you plan to interpret the new Boolean.

A cool thing with Booleans is that if statements and Booleans are friends. No need to check if the Boolean is true, as that would return true.
if you want check if a Boolean is false you can just say the inverse of the Boolean which would be this: !greg (where greg is the Boolean)

The things that are important to get down is how you change the Boolean. So When you change it and to what you change it in those conditions.

Thats perfectly fine dude no worries. We all started somewhere! I'm just trying to find a good way to teach you this so that you actually understand what you are doing instead of just randomly plopping in code and shrugging at it if it works.
Understanding your code is vital when it comes to debugging so you'll have to learn it sooner or later.

For me it's gotten rather late(nearing four AM) So I am heading of and won't be back to help for several hours. Just play around with what I gave you and show what you ended up doing/trying what you expected it to do and what it does. Once I wake up I'll help you add these features to completion if you haven't gotten there already.
 
M

MegaGamer99

Guest
if (place_meeting(x+1,y,obj_blockpar) or (place_meeting(x-1,y,obj_blockpar)))
{
sprite_index = spr_kirby_squish;
SquishModePossible = false;
}

if (!SquishModePossible) sprite_index = spr_kirby_idle;
SquishModePossible = true;

Is this correct?
 
T

TDSrock

Guest
if (place_meeting(x+1,y,obj_blockpar) or (place_meeting(x-1,y,obj_blockpar)))
{
sprite_index = spr_kirby_squish;
SquishModePossible = false;
}

if (!SquishModePossible) sprite_index = spr_kirby_idle;
SquishModePossible = true;

Is this correct?
instead of asking, test it ;)
Hint you are setting squishModePossible back to true too often now and there is no logic operator between the two condiontsals !SquishModePossible) and sprite_index = spr_kirby_idle;
For that to be a valid if statement it should look like this:
Code:
if ((!SquishModePossible) && sprite_index = spr_kirby_idle){ //assumong you want this to be AND
//do stuff
}
 
M

MegaGamer99

Guest
Well, I tested it and he just changes into an idle sprite instead of a squish sprite, and can't use any other sprites while next to the wall. Wow, this is a long post for one little issue. You know what, I just want a short and simple code so it'll be more easier for us.
 
Last edited by a moderator:
T

TDSrock

Guest
Whoops I misread.
The code you put up ALMOST works.
Two small things.

Just think of what happens right now.
first if kirby hits a wall he will turn squish mode off
Then if squishmode is off we set the sprite to idle
then we set squishmode to true again.
This happens each frame. All the time.
 
M

MegaGamer99

Guest
if (place_meeting(x+1,y,obj_blockpar) or (place_meeting(x-1,y,obj_blockpar)))
{
sprite_index = spr_kirby_squish;
SquishModePossible = false;
}

if (!SquishModePossible)
{
sprite_index = spr_kirby_idle;
}

if ((!SquishModePossible) && sprite_index = spr_kirby_idle)
{
SquishModePossible = true;
}

Here's the code that we've worked on as a refresher. I tested the game, and whenever he goes to the wall, his sprite skips the squish sprite and goes straight to idle sprite and won't allow other sprites to display but the idle sprite while next to the wall.
 
T

TDSrock

Guest
So this time the main issue is when to change the sprite_index back to the idle sprite.

instead of checking the !squishModePossible check for wheiter or not the sprite_index is on it's last frame by asking if(sprite_index == spr_kirby_squish && image_index == 5)
Where 5 would be the number of the last image in the sprite.
 
T

TDSrock

Guest
Oh. So it's working as you want it to work?
if not, you can do what I said. And to extent the time just add more frames to the sprite_index untill you are content and change the number till you think the delay is good
 
M

MegaGamer99

Guest
Ok, so far, so good. However, we need to do something about the SquishMode variable, because he got squish and idle sprite, but while next to the wall, he is flashing back and forth over the two sprites.
 
Last edited by a moderator:
Top