Jumping on the trampoline while the animation is playing

sensodyne

Member
Hello all

I have an object that the player is bouncing on ... It's a bit of a parabolic movement and very forward. Everything works fine, but I would like to have this effect on my object.
Now it is so that as soon as the player touches the object, he jumps immediately and I would like the jump to be possible every 3 seconds and it should look like this.
When the object animation plays, only then the player can bounce, and when the object animation is not there, then it cannot bounce. And the sound should be played when the object animation is on, but this sound should also be heard when the player is close to the object


Please help, thank you

obj_trampoline

create

GML:
image_speed = 0;
pwr = 152;
step

GML:
if place_meeting(x,y,par_entity) {
 with instance_place(x,y,par_entity) {
  hspd = lengthdir_x(1,other.image_angle+45)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+45)*other.pwr;
  audio_play_sound(snd_trampoline, 10, false);
 }
 image_speed = 1;
}

Animation end

GML:
///Reset
image_index = 0;
image_speed = 0;
 

sensodyne

Member
I managed to set a timer to use the trampoline every 5 seconds, the player can bounce off the trampoline every 5 seconds.


but I have two more problems to solve. Maybe some of you know how to solve them:

First


The animation of the trampoline is not displayed and should play in full every 5 seconds


Second


I have gravity set to 1 in the game when the player bounces off the trampoline, I would like the animation to slow down and amount to 0.5 until the player lands and touches the ground

I've already started setting a slower gravity when the player bounces off the trampoline but I don't know how to bring it back to its original value when the player lands on the ground.

please do support. Below is my updated code

Obj_trampoline

create

GML:
start = false;
pwr = 152;
image_speed = 2;


Alarm[0]

GML:
start = false;
Step

GML:
if start == false && place_meeting(x,y,par_entity) {
alarm[0] = room_speed * 5
start = true;
 with instance_place(x,y,par_entity)
 {
  g = 0.5;//gravity

  hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

 
 }
 
 
}
Animation End

GML:
image_index = 0;
image_speed = 0;
 

Slade

Member
The animation of the trampoline is not displayed and should play in full every 5 seconds
There's multiple ways to get this to work but start by getting a value in the Create Event of your trampoline which dictates the various 'states' the trampoline object can be in.
While this might not be of use if you want an animation to play every 5 seconds, you can use this variable for other things to limit or allow what the object can or cannot do if in a certain state.

GML:
state = 0; // 0 = normal, 1 = jumped on;
Now if you want to switch animations every X seconds, you can do this by setting up an Alarm which will change the animations from one to the other.

In your Create Event
GML:
Alarm[0] = 25;
Then in your Alarm[0] event
GML:
If (sprite_index = spr_normal) 
{
sprite_index = spr_bouncing; // switch animations
alarm[0]=25; // reset the alarm 
}
else if (sprite_index = spr_bouncing)
{
sprite_index = spr_normal; // switch animations
alarm[0]=25;  // reset the alarm 
}
but I don't know how to bring it back to its original value when the player lands on the ground.
You can accomplish this by rather than setting the gravity to 1; setting the gravity to a Global value which you update after the player bounces, and reset to its original value when the player touches the ground.

In your Create Event
GML:
Global.GravityVar = 1; // default Gravity
gravity = Global.GravityVar;
Then in your Ground Objects code for checking vertical collision with the player, you can simply add
GML:
Global.GravityVar = 1; // reset gravity to 1.
Hope this helps!
 

sensodyne

Member
There's multiple ways to get this to work but start by getting a value in the Create Event of your trampoline which dictates the various 'states' the trampoline object can be in.
While this might not be of use if you want an animation to play every 5 seconds, you can use this variable for other things to limit or allow what the object can or cannot do if in a certain state.

GML:
state = 0; // 0 = normal, 1 = jumped on;
Now if you want to switch animations every X seconds, you can do this by setting up an Alarm which will change the animations from one to the other.

In your Create Event
GML:
Alarm[0] = 25;
Then in your Alarm[0] event
GML:
If (sprite_index = spr_trampolinel)
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25;  // reset the alarm
}


You can accomplish this by rather than setting the gravity to 1; setting the gravity to a Global value which you update after the player bounces, and reset to its original value when the player touches the ground.

In your Create Event
GML:
global.GravityVar = 1; // default Gravity
Then in your Ground Objects code for checking vertical collision with the player, you can simply add
GML:
global.GravityVar = 1; // reset gravity to 1.
Hope this helps!
Thank you so much Slade.

what about my code? I used an alarm so that you can bounce off the springboard every 5 seconds, I would like to leave this option.
should it be like this?
When it comes to free gravity i just want it to change while bouncing off that one trampoline, not while game and bouncing off other items


create

GML:
start = false;
pwr = 152;
Alarm[0] = 25;
global.GravityVar = 0.5; // default Gravity

Alarm[0]

GML:
If (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25;  // reset the alarm
}

Alarm[1]

GML:
start = false;

step

GML:
if start == false && place_meeting(x,y,par_entity) {
alarm[1] = room_speed * 5
start = true;
with instance_place(x,y,par_entity)
{

gravity = global.GravityVar

  hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;


}
       }

par_entity

create

GML:
global.GravityVar = 1; // reset gravity to 1.
 
Last edited:

sensodyne

Member
Now the trampoline animation plays constantly and is supposed to play every 5 seconds. I use one springboard sprite. What about gravity? how to properly set it up? to be slower when bounce in from this one trampoline and return to the default value when the player touches the ground??

The animation should be played every 5 seconds .. that is, the animation plays in full then stops and again after 5 seconds the entire animation plays and then stops for 5 seconds and so on all the time
 
Last edited:

sensodyne

Member
Can anyone help me? because now the animation of the trampoline is constantly playing in a loop

The animation should be played every 5 seconds .. that is, the animation plays in full then stops and again after 5 seconds the entire animation plays and then stops for 5 seconds and so on all the time

And the second thing when I set the slow gravity while the player bounces, I don't know how to reset it to the default values when the player touches the ground
I described it in more detail in the comments.

obj_trampoline

Create

GML:
start = false;
pwr = 152;

Alarm[0]

GML:
start = false;

Step


GML:
if start == false && place_meeting(x,y,par_entity) {
alarm[0] = room_speed * 5 // time after which the player can bounce off the trampoline
start = true;
with instance_place(x,y,par_entity) // the object with the variables used from it is also inherited by the hero
{

g = 0.5 //I set a slower gravity as the player bounces off the trampoline

  hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;


}
       }

par_entity

Create

GML:
///Setup
g = 1; //gravitation
weight = 1;
multiG = 1;
f = 1;
multiF = 1;
vF = false;
hp = 999999999;
maxHp = 999999999;
vspd = 0;
vspdB = 0;
hspd = 0;
hspdB = 0;
inAir = false;
par_entity

End Step

GML:
///Physics
if bbox_left+sign(hspd) < 0 || bbox_right+sign(hspd) >= room_width {
 hspd = 0;
 x = clamp(x,x-bbox_left,room_width-1-(bbox_right-x));
}

if unstick(4) > 8 {
 instance_destroy();
}

hspd += hspdB;
for(i=0;i<abs(hspd);i++) {
 if solid_place(x+sign(hspd),y) {
  if solid_place(x+sign(hspd),y-1) || inAir == true {
   if solid_place(x+sign(hspd),y-2) || inAir == true {
    hspd = 0;
   } else {
    x += sign(hspd);
    y -= 2;
    hspd -= sign(hspd)/2;
   }
  } else {
   x += sign(hspd);
   y -= 1;
   hspd -= sign(hspd)/3;
  }
 } else {
  x += sign(hspd);
 
  if inAir == false && !solid_place(x,y+1) && solid_place(x,y+2) {
   y += 1;
  } else if inAir == false && !solid_place(x,y+2) && solid_place(x,y+3) {
   if !solid_place(x,y+1) {
    y += 1;
   }
   if !solid_place(x,y+1) {
    y += 1;
   }
  }
 }
}
hspd -= hspdB;
hspdB = 0;

if inWater == false {
 //Friction
 if hspd > 0 {
  hspd = max(0,hspd-f*multiF);
 } else if hspd < 0 {
  hspd = min(0,hspd+f*multiF);
 }
 //Vertical friction
 if vF == true {
  if vspd > 0 {
   vspd = max(0,vspd-f*multiF);
  } else if vspd < 0 {
   vspd = min(0,vspd+f*multiF);
  }
 }
 //Gravity
 vspd += g*multiG;
} else {
 //Underwater friction
 hspd = lerp(hspd,0,.1);
 if abs(hspd) < .2 {
  hspd = 0;
 }
 vspd = lerp(vspd,0,.1);
 if abs(vspd) < .2 {
  vspd = 0;
 }
}
multiF = 1;
multiG = 1;

inAir = true;
vspd += vspdB;
for(i=0;i<abs(vspd);i+=1) {
 if solid_place(x,y+sign(vspd)) {
  if vspd > 0 {
   var slope = getSlopeInclination();
   if slope <= -2 && slope >= -8 {
    x -= 1;
    hspd -= 1;
    i -= 1;
   } else if slope >= 2 && slope <= 8 {
    x += 1;
    hspd += 1;
    i -= 1;
   } else {
    vspd = 0;
    inAir = false;
   }
  } else {
   vspd = 0;
  }
 } else {
  y += sign(vspd);
 }
}
vspd -= vspdB;
vspdB = 0;

Thank you
 

Nidoking

Member
If (sprite_index = spr_trampoline) { sprite_index = spr_trampoline; // switch animations alarm[0]=25; // reset the alarm } else if (sprite_index = spr_trampoline) { sprite_index = spr_trampoline; // switch animations alarm[0]=25; // reset the alarm }
Are you still doing this? It's the only place where I see any change to sprite_index, except you're not changing the sprite_index. The example you were provided used two different sprites. You are using only one sprite. What did you expect to change? Either you need to have a sprite for the non-animated trampoline, or you need to set image_speed to zero to stop the animation. It's like they say... "The more things don't change, the more they stay the same."
 

sensodyne

Member
Yes i use the same sprite.
I've already set image_speed to zero but the trampoline animation is still playing in the loop.
I even did a little test and set up two different sprites, one at rest and one movable and this solution did not help either because the trampoline animation is displayed all the time in the loop.
I wouldn't bother this topic if I knew the cause of the problem and how to solve it

GML:
if (sprite_index = spr_trampoline)
{
image_speed = 0;
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
image_speed = 0;
sprite_index = spr_trampoline; // switch animations
alarm[0]=25;  // reset the alarm
}
 

woods

Member
take another look at the example you were shown by slade..
Code:
       If (sprite_index = spr_normal)
{
sprite_index = spr_bouncing; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_bouncing)
{
sprite_index = spr_normal; // switch animations
alarm[0]=25; // reset the alarm
}
and reinforcing what nidoking said..
It's the only place where I see any change to sprite_index, except you're not changing the sprite_index. The example you were provided used two different sprites. You are using only one sprite

what you have currently is
if the sprite is this, change the sprite to this...
it should read change the sprite to not this

;o)
 

Nidoking

Member
sprite_index = spr_trampoline; // switch animations
sprite_index = spr_trampoline; // switch animations
The comments are not code. Saying "//switch animations" does exactly nothing. It is identically equal to not typing anything. Now, can you explain the difference between spr_trampoline and spr_trampoline?

Wait, I think I got those backward. What's the difference between spr_trampoline and spr_trampoline?

Shoot, maybe I was right the first time? Which way round do they go?

I even did a little test and set up two different sprites
Ooh, could you show me that one? That sounds promising, but you did it wrong.
 

sensodyne

Member
The comments are not code. Saying "//switch animations" does exactly nothing. It is identically equal to not typing anything. Now, can you explain the difference between spr_trampoline and spr_trampoline?

Wait, I think I got those backward. What's the difference between spr_trampoline and spr_trampoline?

Shoot, maybe I was right the first time? Which way round do they go?



Ooh, could you show me that one? That sounds promising, but you did it wrong.

like I said from the beginning, I did exactly like the example now I used two different sprites spr_trampoline_idle without animation in one frame and sprite_trampoline with several frames of animation

despite this solution. the trampoline animation still loops for all the time.

GML:
if (sprite_index = spr_trampoline_idle) //sprite without animation in one frame
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline_idle; // switch animations //sprite without animation in one frame
alarm[0]=25; // reset the alarm
}
 

Vusur

Member
But how does it loop all the time, when spr_trampoline_idle is one frame? If this code is in ALARM[0], then this code will be triggert every 25 frames. So you switch the sprites every 25 frames. It resets its own timer. So once you reached the alarm code, it should be fine. Does is just look like a loop played all the time? 25 frames is not even half a second (assuming room speed 60). I read something about 5 sec was what you wanted? This would be alarm[0]=room_speed*5;
Did you debug it? Set a break point in your alarm and look, if you even reach this code block. Or increase the timer.
Do you set ALARM[0] somewhere else? Or do you switch sprites somewhere else again?

Laste option, maybe a small gif or video with how it looks right now.
 

sensodyne

Member
But how does it loop all the time, when spr_trampoline_idle is one frame? If this code is in ALARM[0], then this code will be triggert every 25 frames. So you switch the sprites every 25 frames. It resets its own timer. So once you reached the alarm code, it should be fine. Does is just look like a loop played all the time? 25 frames is not even half a second (assuming room speed 60). I read something about 5 sec was what you wanted? This would be alarm[0]=room_speed*5;
Did you debug it? Set a break point in your alarm and look, if you even reach this code block. Or increase the timer.
Do you set ALARM[0] somewhere else? Or do you switch sprites somewhere else again?

Laste option, maybe a small gif or video with how it looks right now.

Yes and now it loops despite using sprite idle in one frame.Yes I have room_speed set to 60
The animation should be played every 5 seconds .. that is, the animation plays in full then stops and again after 5 seconds the entire animation plays and then stops for 5 seconds and so on all the time

This is what all my trampoline code looks like


obj_trampoline

create

GML:
start = false;
pwr = 152;
Alarm[1] = room_speed * 5
Alarm[0] = 25;

Step

GML:
if start == false && place_meeting(x,y,par_entity) {
alarm[1] = room_speed * 5
start = true;

 with instance_place(x,y,par_entity)
 {


  hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

  }
   }
Alarm[0]


GML:
if (sprite_index = spr_trampoline_idle) //sprite without animation in one frame
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline_idle; // switch animations //sprite without animation in one frame
alarm[0]=25; // reset the alarm
}

Alarm[1]


GML:
start = false;

here below is a video showing the problem with the trampoline


https://drive.google.com/file/d/1hfSsAsYwTFDtkfA-eOK-Ibohf_k-PtPT/view?usp=sharing
 

chamaeleon

Member
What's wrong with using Animation End event to set an alarm to restart animation (assuming this matches your description "the animation plays in full then stops")
GML:
sprite_index = spr_trampoline_idle;
alarm[whatever_alarm_index] = 5*room_speed;
Alarm whatever_alarm_index
GML:
sprite_index = spr_trampoline;
 

sensodyne

Member
What's wrong with using Animation End event to set an alarm to restart animation (assuming this matches your description "the animation plays in full then stops")
GML:
sprite_index = spr_trampoline_idle;
alarm[whatever_alarm_index] = 5*room_speed;
Alarm whatever_alarm_index
GML:
sprite_index = spr_trampoline;

but this function causes the trampoline animation to not work and is always idle


obj_trampoline

create

GML:
start = false;
pwr = 152;
Alarm[1] = room_speed * 5
//Alarm[0] = 25;


Step

GML:
if start == false && place_meeting(x,y,par_entity) {
alarm[1] = room_speed * 5
start = true;

 with instance_place(x,y,par_entity)
 {


  hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
  vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

  }
   }

Alarm[0]


GML:
sprite_index = spr_trampoline;
Animation end


GML:
sprite_index = spr_trampoline_idle;
alarm[0] = 5*room_speed;

Alarm[1]

GML:
start = false;
 

Vusur

Member
Ok, so while the animation is playing, you are able to bounce. After 5 sec the bouncing stops and the player can't jump? Again 5 sec and the animation starts again, you are again be able to bounce? This is the goal?

Create Event
GML:
player_can_bounce = false; //start with idle
sprite_index = spr_trampoline_idle; //set sprite correspondending to player_can_bounce
pwr = 152;
Alarm[0] = room_speed * 5; //we only need one timer, initial set in create; it "kicks off" the timer
Alarm 0
GML:
if (sprite_index = spr_trampoline_idle) // current state, idle?
{
sprite_index = spr_trampoline; // set bouncing sprite/animation
//image_speed = 1; //not really needed; in case something else stopped the animation
player_can_bounce = true; //the "notification" that the player can bounce
alarm[0]=room_speed * 5; // check alarm0 again after 5 sec
}
else if (sprite_index = spr_trampoline) // current state, bouncing?
{
sprite_index = spr_trampoline_idle; // set idle sprite/animation
//image_speed = 0; //not really needed; definitly stops the animation
player_can_bounce = false; //the "notification" that the player can NOT bounce
alarm[0]=room_speed * 3; // check alarm0 again after 3 sec;
}

//when using image_speed, make sure to enable both places.
Step Event
GML:
if player_can_bounce == true && place_meeting(x,y,par_entity) {

    with instance_place(x,y,par_entity)
     {
          hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
          vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

      }
}

//no need for a timer here. Alarm[0] will restart on its own.
I did two different lengths. The bouncing is 5sec and the idle is 3sec. Just to make it more clear. Also, player_can_bounce ist not really needed. You could delete all the lines and check

Step Event
GML:
if sprite_index == spr_trampoline && place_meeting(x,y,par_entity) {

    with instance_place(x,y,par_entity)
     {
          hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
          vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

      }
}

//no need for a timer here. Alarm[0] will restart on its own.
I used a variable/flag in the first version for making it more clear. The alarm decides, if you can bounce or not.
 

sensodyne

Member
Ok, so while the animation is playing, you are able to bounce. After 5 sec the bouncing stops and the player can't jump? Again 5 sec and the animation starts again, you are again be able to bounce? This is the goal?

Create Event
GML:
player_can_bounce = false; //start with idle
sprite_index = spr_trampoline_idle; //set sprite correspondending to player_can_bounce
pwr = 152;
Alarm[0] = room_speed * 5; //we only need one timer, initial set in create; it "kicks off" the timer
Alarm 0
GML:
if (sprite_index = spr_trampoline_idle) // current state, idle?
{
sprite_index = spr_trampoline; // set bouncing sprite/animation
//image_speed = 1; //not really needed; in case something else stopped the animation
player_can_bounce = true; //the "notification" that the player can bounce
alarm[0]=room_speed * 5; // check alarm0 again after 5 sec
}
else if (sprite_index = spr_trampoline) // current state, bouncing?
{
sprite_index = spr_trampoline_idle; // set idle sprite/animation
//image_speed = 0; //not really needed; definitly stops the animation
player_can_bounce = false; //the "notification" that the player can NOT bounce
alarm[0]=room_speed * 3; // check alarm0 again after 3 sec;
}

//when using image_speed, make sure to enable both places.
Step Event
GML:
if player_can_bounce == true && place_meeting(x,y,par_entity) {

    with instance_place(x,y,par_entity)
     {
          hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
          vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

      }
}

//no need for a timer here. Alarm[0] will restart on its own.
I did two different lengths. The bouncing is 5sec and the idle is 3sec. Just to make it more clear. Also, player_can_bounce ist not really needed. You could delete all the lines and check

Step Event
GML:
if sprite_index == spr_trampoline && place_meeting(x,y,par_entity) {

    with instance_place(x,y,par_entity)
     {
          hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
          vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

      }
}

//no need for a timer here. Alarm[0] will restart on its own.
I used a variable/flag in the first version for making it more clear. The alarm decides, if you can bounce or not.


GML:
Ok, so while the animation is playing, you are able to bounce. After 5 sec the bouncing stops and the player can't jump? Again 5 sec and the animation starts again,
you are again be able to bounce? This is the goal?

Yes that's my goal:)

Thank you very much for the nice description. I tested your two solutions, but there is a problem. The trampoline stopped working and the trampoline sprite is set to idle all the time.


Here is a video showing this problem: the blue sprite trampoline is a sprite in one idle frame and the red one is animated in several frames


https://drive.google.com/file/d/1gLL1-h22oNHLypQ0jWBNX60NcCEzyBzB/view?usp=sharing
 
Last edited:

Vusur

Member
Two questions.
Is Alarm0 in the event list of your trampoline object? Where the create and step event is?
Did you try debugging? Set two breakpoints in your alarm. In each block? Start the debugger (the bug icon) an check if it stops there alternating between the break points?
If you don't reach the break point, you are resetting the timer, somewhere else, the alarm is not in trampoline OR the sprite name aren't correct. If it doesn't alternate but you reach the break point, you are resetting the sprite somewhere else. Good break point place would be at both sprite_index = .... Let it stop, press Continue. Does it stop again? Continue and so on.

I did a demo with the exact same code, except the step event. With, and without setting image_speed in my alarm.
My step event looked like this:

GML:
if(player_can_bounce)
{
    aText = "player_can_bounce: true";   
}
else
{
    aText = "player_can_bounce: false";   
}
I draw the text later. The step event also doesn't set the alarm. I have two different sprites ofc. One is red, 1 sprite/frame long, no animation. The other one is blue, 5 sprite/frames long, animated. No player, no background and so on. It's all about the "spring/trampoline".

The result, if I follow my code provided step by step:
Spring Demo.gif

I didn't time the frames, so it lookes like a jump/cut when it switches. But that is not the point. I alternate between the two sprites. Red is 3 sec, blue is 5 sec. All done with the alarm. Sprite color and different times is just for debugging/visualizing the difference.

Full code of the demo:
Create Event
GML:
player_can_bounce = false;
sprite_index = spr_spring_idle; //my own sprite name
alarm[0] = room_speed * 3;

//debugging later
aText = "";
Step event
GML:
//check if the notification comes through from alarm0
if(player_can_bounce)
{
    aText = "player_can_bounce: true";     
}
else
{
    aText = "player_can_bounce: false";     
}
Alarm0
GML:
if(sprite_index == spr_spring_idle)
{
    sprite_index = spr_spring_ani;
    //image_speed = 1;
    player_can_bounce = true;
    alarm[0] = room_speed * 5;
}
else if (sprite_index == spr_spring_ani)
{
    sprite_index = spr_spring_idle;
    //image_speed = 0;
    player_can_bounce = false;
    alarm[0] = room_speed * 3;
}

//image_speed enabled (removing "//") at both places or not didn't matter in my case
Draw Event
GML:
//debug
draw_self();
draw_text(x+70, y, aText);
 
Last edited:

Nidoking

Member
GML:
if (sprite_index = spr_trampoline_idle) //sprite without animation in one frame
{
sprite_index = spr_trampoline; // switch animations
alarm[0]=25; // reset the alarm
}
else if (sprite_index = spr_trampoline)
{
sprite_index = spr_trampoline_idle; // switch animations //sprite without animation in one frame
alarm[0]=25; // reset the alarm
}
This is your alarm 0 event, right? It's toggling the sprite every 25 frames. Unless your game runs at 5 fps, that's not what you want.

That was probably your problem back then. Just FYI.
 

sensodyne

Member
But how does it loop all the time, when spr_trampoline_idle is one frame? If this code is in ALARM[0], then this code will be triggert every 25 frames. So you switch the sprites every 25 frames. It resets its own timer. So once you reached the alarm code, it should be fine. Does is just look like a loop played all the time? 25 frames is not even half a second (assuming room speed 60). I read something about 5 sec was what you wanted? This would be alarm[0]=room_speed*5;
Did you debug it? Set a break point in your alarm and look, if you even reach this code block. Or increase the timer.
Do you set ALARM[0] somewhere else? Or do you switch sprites somewhere else again?

Laste option, maybe a small gif or video with how it looks right now.

It doesn't loop now.It's just idle all the time.And it doesn't toggle sprite after 5 seconds.
Yes the code is in Alarm 0. It's the same as you described above.
 

chamaeleon

Member
Forgot to add a test in my code (alternatively, if spr_trampoline_idle has a speed of 0, animation end won't trigger when it is the sprite)
Animation End
GML:
if (sprite_index == spr_trampoline) {
    sprite_index = spr_trampoline_idle;
    alarm[0] = 3*game_get_speed(gamespeed_fps);
}
Alarm 0
GML:
sprite_index = spr_trampoline;
Given a spr_trampoline with 10 frames, playing at 2 frames per second, and spr_idle with 2 frames, playing at 2 frames per second, I get the "trampoline" for 5 seconds (the amount of time it takes for the animation of the sprite to play), then the "idle trampoline" for 3 second (the delay I set in the alarm). Once the alarm fires, the process starts over again, 5 seconds/all frames of the animated sprite, followed by 3 seconds of the idle sprite, and so on.

(I'm ignoring anything regarding the player interaction, because it feels like two different problems to be solved one after the other rather than at the same time)
 

Vusur

Member
It doesn't loop now.It's just idle all the time.And it doesn't toggle sprite after 5 seconds.
Yes the code is in Alarm 0. It's the same as you described above.
You have to debug now. There is my code and the result shown in a gif (click on the spoiler). The problem is either within the usage of the code provided or a side effect of something else in your game.
You can't aviod learning the Debugger. This is a crucial tool for us.
 

sensodyne

Member
Two questions.
Is Alarm0 in the event list of your trampoline object? Where the create and step event is?
Did you try debugging? Set two breakpoints in your alarm. In each block? Start the debugger (the bug icon) an check if it stops there alternating between the break points?
If you don't reach the break point, you are resetting the timer, somewhere else, the alarm is not in trampoline OR the sprite name aren't correct. If it doesn't alternate but you reach the break point, you are resetting the sprite somewhere else. Good break point place would be at both sprite_index = .... Let it stop, press Continue. Does it stop again? Continue and so on.

I did a demo with the exact same code, except the step event. With, and without setting image_speed in my alarm.
My step event looked like this:

GML:
if(player_can_bounce)
{
    aText = "player_can_bounce: true";  
}
else
{
    aText = "player_can_bounce: false";  
}
I draw the text later. The step event also doesn't set the alarm. I have two different sprites ofc. One is red, 1 sprite/frame long, no animation. The other one is blue, 5 sprite/frames long, animated. No player, no background and so on. It's all about the "spring/trampoline".

The result, if I follow my code provided step by step:

I didn't time the frames, so it lookes like a jump/cut when it switches. But that is not the point. I alternate between the two sprites. Red is 3 sec, blue is 5 sec. All done with the alarm. Sprite color and different times is just for debugging/visualizing the difference.

Full code of the demo:
Create Event
GML:
player_can_bounce = false;
sprite_index = spr_spring_idle; //my own sprite name
alarm[0] = room_speed * 3;

//debugging later
aText = "";
Step event
GML:
//check if the notification comes through from alarm0
if(player_can_bounce)
{
    aText = "player_can_bounce: true";    
}
else
{
    aText = "player_can_bounce: false";    
}
Alarm0
GML:
if(sprite_index == spr_spring_idle)
{
    sprite_index = spr_spring_ani;
    //image_speed = 1;
    player_can_bounce = true;
    alarm[0] = room_speed * 5;
}
else if (sprite_index == spr_spring_ani)
{
    sprite_index = spr_spring_idle;
    //image_speed = 0;
    player_can_bounce = false;
    alarm[0] = room_speed * 3;
}

//image_speed enabled (removing "//") at both places or not didn't matter in my case
Draw Event
GML:
//debug
draw_self();
draw_text(x+70, y, aText);

Ok you were right something is wrong ... i did according to your example and i still have the variable player_can_bounce: false question what is wrong?

yes, I have alarm0 set in the obj_trampoline object
 

Vusur

Member
Ok you were right something is wrong ... i did according to your example and i still have the variable player_can_bounce: false question what is wrong?

yes, I have alarm0 set in the obj_trampoline object
I don't know. That's why you have to debug it. If you alternate between the break points (as I mentioned) within alarm0 and one sets it to true, the other to false (double check if you are writing the correct statement), then you are setting player_can_bounce somewhere else.
 

sensodyne

Member
Thank you again for your help and especially for Vusur and Chamaeleon It turned out that there was a typo in create. Instead of alarm [0] it was Alarm [0] :)

There is one last thing left, gravity

I want yes, when the player touches the trampoline and bounces, the player's gravity will slow down in the air by half, i.e. 0.5
and when the player lands (on the ground), the gravity should reset to its default value, which is 1

that's what I mean

Yes, I started to change it and added a half-slowed gravity g = 0.5 when reflecting the player, but I don't know how to reset it when the player touches the ground (lands)

I just want to change the gravity for this one obj_trampoline object
The par_entity object is the parent with the variables that the hero and game objects inherit.

Step

GML:
if sprite_index == spr_trampoline && place_meeting(x,y,par_entity) {

    with instance_place(x,y,par_entity)
     {
g = 0.5 slow gravity start
          hspd = lengthdir_x(1,other.image_angle+25)*other.pwr;
          vspd = lengthdir_y(1,other.image_angle+25)*other.pwr;

      }
}

par_entity

Create

GML:
///Setup
g = 1; //gravitation default
weight = 1;
multiG = 1;
f = 1;
multiF = 1;
vF = false;
hp = 999999999;
maxHp = 999999999;
vspd = 0;
vspdB = 0;
hspd = 0;
hspdB = 0;
inAir = false;
End step

GML:
///Physics
if bbox_left+sign(hspd) < 0 || bbox_right+sign(hspd) >= room_width {
 hspd = 0;
 x = clamp(x,x-bbox_left,room_width-1-(bbox_right-x));
}

if unstick(4) > 8 {
 instance_destroy();
}

hspd += hspdB;
for(i=0;i<abs(hspd);i++) {
 if solid_place(x+sign(hspd),y) {
  if solid_place(x+sign(hspd),y-1) || inAir == true {
   if solid_place(x+sign(hspd),y-2) || inAir == true {
    hspd = 0;
   } else {
    x += sign(hspd);
    y -= 2;
    hspd -= sign(hspd)/2;
   }
  } else {
   x += sign(hspd);
   y -= 1;
   hspd -= sign(hspd)/3;
  }
 } else {
  x += sign(hspd);
 
  if inAir == false && !solid_place(x,y+1) && solid_place(x,y+2) {
   y += 1;
  } else if inAir == false && !solid_place(x,y+2) && solid_place(x,y+3) {
   if !solid_place(x,y+1) {
    y += 1;
   }
   if !solid_place(x,y+1) {
    y += 1;
   }
  }
 }
}
hspd -= hspdB;
hspdB = 0;

if inWater == false {
 //Friction
 if hspd > 0 {
  hspd = max(0,hspd-f*multiF);
 } else if hspd < 0 {
  hspd = min(0,hspd+f*multiF);
 }
 //Vertical friction
 if vF == true {
  if vspd > 0 {
   vspd = max(0,vspd-f*multiF);
  } else if vspd < 0 {
   vspd = min(0,vspd+f*multiF);
  }
 }
 //Gravity
 vspd += g*multiG;
} else {
 //Underwater friction
 hspd = lerp(hspd,0,.1);
 if abs(hspd) < .2 {
  hspd = 0;
 }
 vspd = lerp(vspd,0,.1);
 if abs(vspd) < .2 {
  vspd = 0;
 }
}
multiF = 1;
multiG = 1;

inAir = true;
vspd += vspdB;
for(i=0;i<abs(vspd);i+=1) {
 if solid_place(x,y+sign(vspd)) {
  if vspd > 0 {
   var slope = getSlopeInclination();
   if slope <= -2 && slope >= -8 {
    x -= 1;
    hspd -= 1;
    i -= 1;
   } else if slope >= 2 && slope <= 8 {
    x += 1;
    hspd += 1;
    i -= 1;
   } else {
    vspd = 0;
    inAir = false;
   }
  } else {
   vspd = 0;
  }
 } else {
  y += sign(vspd);
 }
}
vspd -= vspdB;
vspdB = 0;
Thank you
 

Nidoking

Member
Well, you're setting inAir to false. Presumably, that means you're on the ground at that point. Might be a good place to set the gravity to what you want it to be when you're on the ground.
 
Top