Forum

Double jumping...sigh

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Double jumping...sigh

Postby Mexicouger » Tue Jun 29, 2010 12:05 pm

I really didn't want to come here and Ask, But I spent an hour trying to figure this out. I wanna add double jumping(jumping again in mid-air). I used the approach of using a .float jumplives to remember how many times you can jump, And if you have 0 jump lives, You can't jump. Here's my code:

Code: Select all
void() PlayerJump =
{   
   if (self.flags & FL_WATERJUMP)
      return;
   
   if (self.waterlevel >= 2)
   {
      if (self.watertype == CONTENT_WATER)
         self.velocity_z = 100;
      else if (self.watertype == CONTENT_SLIME)
         self.velocity_z = 300;
      else
         self.velocity_z = 350;

// play swiming sound
      if (self.swim_flag < time)
      {
         self.swim_flag = time + 1;
         if (random() < 0.5)
            sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
         else
            sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
      }

      return;
   }

   //Note that I took out the jumpreleased code and Other code.
   if (self.mballtoggle == 1)//No jump for Morphball
   self.velocity_z = self.velocity_z + 0;
   else
   {
   sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
   self.velocity_z = self.velocity_z + 400;
   }
};



I took out the Jumpreleased code and the other flags as well. I didn't know if they were affecting my goal or not. Testing out stuff is the way to learn :lol:

The second part of my code is to check if the button is being pressed in preplayerthink:

Code: Select all
/*
================
PlayerPreThink

Called every frame before physics are run
================
*/
void() PlayerPreThink =
{
   
if (BotPreFrame()) // FrikBot
   return;
   if (self.flags & FL_ONGROUND)//If your on the ground,Refill //your jumplives
   self.jumplives = 2;
   CheckRope();

   if (intermission_running)
   {
      IntermissionThink ();   // otherwise a button could be missed between
      return;               // the think tics
   }

   if (self.view_ofs == '0 0 0')
      return;      // intermission or finale
      
   if ( self.aflag )
      CCamChasePlayer ();

   makevectors (self.v_angle);      // is this still used

   CheckRules ();
   WaterMove ();

   if (self.waterlevel == 2)
      CheckWaterJump ();

   if (self.deadflag >= DEAD_DEAD)
   {
      PlayerDeathThink ();
      return;
   }
   
   if (self.deadflag == DEAD_DYING)
      return;   // dying, so do nothing

   if (self.button2)
   {
      if (self.jumplives == 0)//If you have no lives, do nothing
      {}
      else//Otherwise, Take 1 life away and jump
      {
      self.jumplives -= 1;
      PlayerJump ();
      }
   }
// teleporters can force a non-moving pause time   
   if (time < self.pausetime)
      self.velocity = '0 0 0';

   if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
   {
      self.weapon = W_BestWeapon ();
      W_SetCurrentAmmo ();
   }
};
   


Am I taking the right approach or heading in the right Direction on this? And the result from this code is: I jump really high. Not 100% up to the sky-box, But in kurok, that climbable wall, I can jump it barely(just 1 jump).
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby goldenboy » Tue Jun 29, 2010 1:18 pm

normal z velocity when jumping (jumpflag) is 270, if I'm not mistaken, so setting that to 350 would certainly make you jump pretty high. :)
User avatar
goldenboy
 
Posts: 924
Joined: Fri Sep 05, 2008 11:04 pm
Location: Kiel

Postby Spike » Tue Jun 29, 2010 2:42 pm

350 was the value for underwater.
See he adds 400 to velocity when out of water.

adds, not sets.

so vel_z = 800.

Which is really kinda fast.


Also I see an ent.fld -= foo; and I'm not sure if his qcc works properly. Silly fteqcc bugs... But mneh.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Downsider » Tue Jun 29, 2010 3:29 pm

Two things.

if (self.button2) is true if the button is down, regardless if it's a press or if it's been held down for several seconds. You have to check for it being released first, otherwise if you hold it for two frames you'll get a very high jump, which is probably what you're seeing.

Second, you shouldn't add the z-velocity of 400, you should just set it to 400. Otherwise you'll, again, get very, very high jumps if you double tap it very fast.
User avatar
Downsider
 
Posts: 621
Joined: Tue Sep 16, 2008 1:35 am

Postby Mexicouger » Tue Jun 29, 2010 7:28 pm

I have already had it set to Jump higher before. But I want Double jump. And I think Why I can jump high Is because I am basically double jumping, But there's no pause. I think I will keep at it. Double jumping is a nice thing Is metroid, So I can't pass it up. I will add The jumpreleased flag again and keep at it.
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby Sajt » Tue Jun 29, 2010 7:39 pm

Here's a start (this is based on the default progs, not your code, so you should undo your changes before trying this).

Code: Select all
float DOUBLEJUMP_EXTRAJUMPS = 1; // how many times you can jump in the air (0 = quake, 1 = double jump, 2 = triple jump, ...)
float DOUBLEJUMP_TIMER = 0.2; // you can't doublejump faster than this

.float doublejump_time;
.float doublejump_lives;

// put these lines in PutClientInServer:
//
//   self.doublejump_time = 0;
//   self.doublejump_lives = 0;

// modified PlayerJump:
void() PlayerJump =
{
   local vector start, end;
   
   if (self.flags & FL_WATERJUMP)
      return;
   
   if (self.waterlevel >= 2)
   {
      if (self.watertype == CONTENT_WATER)
         self.velocity_z = 100;
      else if (self.watertype == CONTENT_SLIME)
         self.velocity_z = 80;
      else
         self.velocity_z = 50;

// play swiming sound
      if (self.swim_flag < time)
      {
         self.swim_flag = time + 1;
         if (random() < 0.5)
            sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
         else
            sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
      }

      return;
   }

   if ( !(self.flags & FL_JUMPRELEASED) )
      return;      // don't pogo stick

   if (self.flags & FL_ONGROUND)
   {
      self.doublejump_lives = DOUBLEJUMP_EXTRAJUMPS;

      self.flags = self.flags - FL_ONGROUND;   // don't stairwalk
   }
   else if (self.doublejump_lives > 0 && time >= self.doublejump_time && self.velocity_z > -100)
   {
      self.doublejump_lives = self.doublejump_lives - 1;
   }
   else
   {
   // can't jump
      return;
   }

   self.doublejump_time = time + DOUBLEJUMP_TIMER;

   self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
   
   self.button2 = 0;
// player jumping sound
   sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
   self.velocity_z = 350;
};

// no changes to PlayerPreThink


With this, there is a timeout between double jumps, so you can't double jump two frames in a row. Also, you can't doublejump if your upward velocity is less than -100 u/s, so you can't "cancel" a big fall with a doublejump.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Mexicouger » Tue Jun 29, 2010 10:49 pm

Wow thanks! :P

But I wanna learn from this code, So what does this Mean? I have never used/seen an if statement like this:

Code: Select all
else if (self.doublejump_lives > 0 && time >= self.doublejump_time && self.velocity_z > -100)
   {
      self.doublejump_lives = self.doublejump_lives - 1;
   }


What is self.velocity_z > -100?
Does that mean if you are falling and Your fall velocity is 100?

What does the &&'s do? Is it the same thing as putting this:

|

Could I just put this?

Code: Select all
(self.doublejump_lives > 0 | time >= self.doublejump_time |self.velocity_z > -100)


I want to try to see what it means:

If you have more than 0 doublejump_lives, and If (I kinda don't understand this one) time is greater than or equal to your double jump time, and If your velocity is -100, Then you lose a doublejump_live? I really don't get the Time part.... I may even be completely wrong on all of this. Please clarify
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby Ghost_Fang » Wed Jun 30, 2010 12:11 am

self.velocity_z > -100 means your velocity up(z) (or down if negative) by 100 (units?). the && is for if you want more than on thing to happen for an action in this case "self.doublejump_lives - 1" has to abide by the jump time, jump lives, AND the velocity to do anything.

and by this " | " you mean this " || ". || means OR. for example

if coop || deathmatch
return;

if its coop mode OR deathmatch mode dont do anything.

P.S. Inb4 Arkage :P
Last edited by Ghost_Fang on Wed Jun 30, 2010 12:15 am, edited 2 times in total.
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby Arkage » Wed Jun 30, 2010 12:12 am

The && means and, so if this is true and this is true then run this code.

That if statment is the same as
Code: Select all
if (self.doublejump_lives > 0)
{
if (time >= self.doublejump_time)
{
if (self.velocity_z > -100)
{
// Do stuff
}
}
}


What is self.velocity_z > -100?
Does that mean if you are falling and Your fall velocity is 100?


Thats checks if you velocity in the z axsis is greater than -100.
User avatar
Arkage
 
Posts: 66
Joined: Thu Nov 19, 2009 4:17 pm

Postby Mexicouger » Wed Jun 30, 2010 1:55 am

I added the Code And I can't jump at all Now

And Also,

Code: Select all
// put these lines in PutClientInServer:
//
//   self.doublejump_time = 0;
//   self.doublejump_lives = 0;


Why are they Commented? Should I undo that?
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby Ghost_Fang » Wed Jun 30, 2010 3:28 am

the same thing i told you in the chat. those dont go where you put sajt's code. you need to make it so the player starts with self.doublejump_time and self.doublejump_lives. For him to start with them inside PutClientInServer. But i think you must start the player off with 2 jump lives based on what i see with Sajt's code. It says if the player doesnt have any jump lives he wont jump. thats why he isnt jumping.
Last edited by Ghost_Fang on Wed Jun 30, 2010 3:32 am, edited 1 time in total.
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby Downsider » Wed Jun 30, 2010 3:30 am

I like how you ignored my post which would've most definitely solved your problem.
User avatar
Downsider
 
Posts: 621
Joined: Tue Sep 16, 2008 1:35 am

Postby Mexicouger » Wed Jun 30, 2010 3:34 am

Your post Doesn't even make sense to me.

At least Sajt Posted a code and I learned a thing or 2 from it (even though it didn't work). I guess I will just stick To higher jumping. Double Jumping isn't Very high On my priority list.

And Ghostfang, I made the Player spawn with 2 jumplives and 0 jumptime(I don't even think It makes a difference).

Is there an open source Mod that has double Jump that I can look at?
EDIT: Ok Downsider, I understand what you're saying now.
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm

Postby Sajt » Wed Jun 30, 2010 4:56 am

Okay if you don't use it, but my code does work, I tested it.

Explanation will follow each code sample.

Code: Select all
if (self.flags & FL_ONGROUND)
{
   self.doublejump_lives = DOUBLEJUMP_EXTRAJUMPS;

   self.flags = self.flags - FL_ONGROUND // don't stairwalk
}


If you are on the ground, don't return (because "return;" is in the else block). Thus if you are on the ground at this point, you can jump, no matter what doublejump_lives is set to. doublejump_lives is how many air-jumps you can do. As you can see, when you touch the ground your doublejump_lives is reset to the initial value (1 for double-jump, 2 for triple-jump, etc. as I said).

Code: Select all
else if (self.doublejump_lives > 0 && time >= self.doublejump_time && self.velocity_z > -100)
{
   self.doublejump_lives = self.doublejump_lives - 1;
}


If you have some "lives" left, and if time is greater than doublejump_time (that is, doublejump_time is in the past - more about this later), and your vertical-velocity is greater than -100 (meaning, you are either moving upwards, or moving downwards just a bit, so you are allowed to doublejump before or just after you reach the apex of your previous jump.) doublejump_lives is decremented, obviously, this is how we limit how many times you're allowed to jump before touching the ground again.

Code: Select all
else
{
// can't jump
   return;
}


This is reached if neither of the previous if/else-if things were executed. That is, if we're not on the ground (aka we're airborne), and we weren't allowed to double-jump, return from this function. Since the actual jumping is done below this point in the function, returning here means we won't jump.

Code: Select all
self.doublejump_time = time + DOUBLEJUMP_TIMER;


Here we set the "timeout" value which controls how fast we're allowed to double-jump. We're setting it to a fixed point in the future: "time" plus a constant value. "time" by the way is a global variable which holds how much time has passed since the beginning of the game, measured in seconds (so it might be 0.1 now, then 0.15 next frame, then 0.2 next frame, for example). Anyway, we're not going to allow the player to jump until "time" catches up to "self.doublejump_time". (This was done earlier, in the else-if condition, where we tested whether "time >= self.doublejump_time".)

After this point in the code, things are basically the same as the original code. However, I changed the last line to SET the velocity_z instead of ADD to it, otherwise rapid double-jumps will really launch you into the air.

As for these lines:

Code: Select all
// put these lines in PutClientInServer:
//
//   self.doublejump_time = 0;
//   self.doublejump_lives = 0;


I meant you should actually uncomment them and put them in the body of the PutClientInServer function, where you'll see a ton of other stuff is also being initialized to zero. This function is called when you spawn, so if you don't clear things to zero, some values might carry over from your previous "life" if you died in multiplayer then respawned, which would be bad.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Mexicouger » Thu Jul 01, 2010 12:42 am

Wow thanks Sajt ^.^

It was a Problem In playerprethink I guess. I found the problem when I went to put the riginal jump code back in. Then I wen tot test and I still Couldn't jump.

So I replaced playerprethink with the original code, And then I could jump. I inserted this code, And Now I can jump ^.^

What i plan to do is turn these all into abilities to unlock in campaign. That is my next big thing: Telling the game to record the abilities you have..

But I commented credit for the code. Thank you alot Sajt
User avatar
Mexicouger
 
Posts: 514
Joined: Sat May 01, 2010 10:12 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest