Adding Double Jumping (feedback welcome)
by Jesse Chounard · in Torque X Platformer Kit · 07/18/2007 (7:42 am) · 15 replies
This is a very simple change, so I doubt it's worth being turned into a resource or adding to TDN, but for anybody else who is new to playing around with the PlatformerKit, I thought it might be useful. I'm having quite a bit of fun tinkering around, and if anybody finds this useful I'll post other little things I find.
All of the changes are in ActorComponent.cs, which is a PlatformerFramework file. I'm not sure if this would cause any negative side effects (I haven't seen any yet), but you could easily move them up to a derived class, such as the DragonActorComponent class in the Demo kit, if there are problems.
Double jumping is a feature you've probably seen in many platformers, and it's pretty simple to add to either the starter or demo kits. For anybody who isn't familiar, this is a feature where you get to jump once from the ground, and then a second jump while you are in the air.
Here are the changes:
All of the changes are in ActorComponent.cs, which is a PlatformerFramework file. I'm not sure if this would cause any negative side effects (I haven't seen any yet), but you could easily move them up to a derived class, such as the DragonActorComponent class in the Demo kit, if there are problems.
Double jumping is a feature you've probably seen in many platformers, and it's pretty simple to add to either the starter or demo kits. For anybody who isn't familiar, this is a feature where you get to jump once from the ground, and then a second jump while you are in the air.
Here are the changes:
Public properties, operators, constants and enums section add:
[TorqueXmlSchemaType(DefaultValue = "1")]
public bool AllowDoubleJump
{
get { return _allowDoubleJump; }
set { _allowDoubleJump = value; }
}
Private, protected, internal fields section add:
protected bool _allowDoubleJump = true;
protected bool _doubleJumpActivated = false;
OnGroundState.UpdatePhysics method add the following as a new first line:
actor._doubleJumpActivated = false;
OnLadderState.UpdatePhysics method add the following as a new first line:
actor._doubleJumpActivated = false;
InAirState.UpdatePhysics after the "if(moveLeft) else if (moveRight) else { }":
// note: this bit is a copy of the jump code from OnGroundState.UpdatePhysics
if (actor._allowDoubleJump && !actor._doubleJumpActivated && actor._Jumping)
{
actor._doubleJumpActivated = true;
// jump up
actor._actor.Physics.VelocityY = actor._groundVelocity.Y - actor._jumpForce;
// set the appropriate animation state for jumping
if (Math.Abs(actor._moveSpeed.X) < 0.01f)
FSM.Instance.SetState(actor._animationManager, "jump");
else
FSM.Instance.SetState(actor._animationManager, "runJump");
// override the 'on ground' state manually
// (this allows the animation manager, among other things
// to react to jumping properly)
actor._onGround = false;
// set actor's jump flag to false
// (we used the jump 'event' - let's turn it off so it's not used again)
// (without this, it's possible to launch yourself up crazy distances
// by jumping off the ground through a ladder.. or 'something')
// (we also want to cancel the jump-down flag in case a lazy
// controller sent both events)
actor._jump = false;
actor._jumpDown = false;
}About the author
#2
Here's the whole file: (DoubleJumpActorComponent.cs)
07/18/2007 (11:35 am)
As a learning exercise, I've gone ahead and made this work from a derived class instead of changing ActorComponent. (I've actually derived from PlayerActorComponent, so I could use the existing control stuff.)Here's the whole file: (DoubleJumpActorComponent.cs)
using System;
using GarageGames.Torque.Core;
using GarageGames.Torque.PlatformerFramework;
namespace PlatformerStarter
{
[TorqueXmlSchemaType]
class DoubleJumpActorComponent : PlayerActorComponent
{
[TorqueXmlSchemaType(DefaultValue = "1")]
public bool AllowDoubleJump
{
get { return _allowDoubleJump; }
set { _allowDoubleJump = value; }
}
public override void CopyTo(TorqueComponent obj)
{
base.CopyTo(obj);
DoubleJumpActorComponent obj2 = obj as DoubleJumpActorComponent;
obj2._allowDoubleJump = _allowDoubleJump;
obj2._doubleJumpActivated = _doubleJumpActivated;
}
protected override void _registerPhysicsStates()
{
base._registerPhysicsStates();
FSM.Instance.RegisterState<DoubleJumpOnGroundState>(this, "onGround");
FSM.Instance.RegisterState<DoubleJumpOnLadderState>(this, "onLadder");
FSM.Instance.RegisterState<DoubleJumpInAirState>(this, "inAir");
}
protected class DoubleJumpOnGroundState : OnGroundState
{
public override void Enter(IFSMObject obj)
{
base.Enter(obj);
DoubleJumpActorComponent actor = obj as DoubleJumpActorComponent;
if (actor == null)
return;
actor._doubleJumpActivated = false;
}
}
protected class DoubleJumpOnLadderState : OnLadderState
{
public override void Enter(IFSMObject obj)
{
base.Enter(obj);
DoubleJumpActorComponent actor = obj as DoubleJumpActorComponent;
if (actor == null)
return;
actor._doubleJumpActivated = false;
}
}
protected class DoubleJumpInAirState : InAirState
{
public override void UpdatePhysics(ActorComponent actor, float elapsed)
{
base.UpdatePhysics(actor, elapsed);
DoubleJumpActorComponent doubleJumpActor = actor as DoubleJumpActorComponent;
if (doubleJumpActor == null)
return;
if (doubleJumpActor._allowDoubleJump &&
!doubleJumpActor._doubleJumpActivated &&
doubleJumpActor._Jumping)
{
doubleJumpActor._doubleJumpActivated = true;
doubleJumpActor._actor.Physics.VelocityY = doubleJumpActor._groundVelocity.Y -
doubleJumpActor._jumpForce;
if (Math.Abs(doubleJumpActor._moveSpeed.X) < 0.01f)
FSM.Instance.SetState(doubleJumpActor._animationManager, "jump");
else
FSM.Instance.SetState(doubleJumpActor._animationManager, "runJump");
doubleJumpActor._onGround = false;
doubleJumpActor._jump = false;
doubleJumpActor._jumpDown = false;
}
}
}
protected bool _allowDoubleJump = true;
protected bool _doubleJumpActivated = false;
}
}
#3
Another thing that a lot of games do that might be a nice little tweak is that they only allow double-jumping at the peak of a jump. You could easily do that by checking if the absolute value of the actor's Y velocity is less than some threshold value.
07/18/2007 (12:53 pm)
Very nice work! I might've put the "_doubleJumpActivated = false;" lines in the Enter methods on the states, but other than that this is perfect.Another thing that a lot of games do that might be a nice little tweak is that they only allow double-jumping at the peak of a jump. You could easily do that by checking if the absolute value of the actor's Y velocity is less than some threshold value.
#4
Edit: I just tried it and that worked great. I'll update the code in my previous post to reflect that, because it's a much better solution. Thanks again.
07/18/2007 (2:08 pm)
I started to put it into the Enter method, but I noticed that the parameter isn't an ActorComponent. But now that you've mentioned it and I've looked in the demo code, it appears that the IFSMObject passed in is being cast to an ActorComponent. I'll give that a try. Thanks!Edit: I just tried it and that worked great. I'll update the code in my previous post to reflect that, because it's a much better solution. Thanks again.
#5
Other than that. It's great !
Keep up the good work. People like me really appreciate your work.
Finally got it to work.
07/22/2007 (6:35 am)
Nice component. But I can't seem to add it as a completely separate part. Like KillTrigerComponent. I would like it to be separate from any other like PlayerComponent. Can it be done ? (I'm a complete newbie at this). And there is a small bugs: I can't seem to jump high on the mushroom. I'm guessing because the double jump tries to overpower the mushroom code. And my wings don't work :(Other than that. It's great !
Keep up the good work. People like me really appreciate your work.
Finally got it to work.
#6
Edit: I think part my question was answered by Jesse in the example above but I'm not sure could some one clarify please?
10/06/2007 (4:32 am)
I wanna know the same thing I'm working on a game that the characters have various types of jumps such as double jump, a power jump similar to Alucard with the gravity boots in Castlevania, a jump then float like the dragon in the platformer demo, and a jump then flight type move. I'm wondering if it's possible to make them each a separate component like the player component so they can be used elsewhere with ease. I'm also taking suggestions for a fifth style of jumping that can be used in a platformer if anyone has any suggestions.Edit: I think part my question was answered by Jesse in the example above but I'm not sure could some one clarify please?
#7
cheers
10/06/2007 (9:01 am)
Thanks for sharing this i think every one using tx will b making great games with help from people like u cheers
#8
http://pastebin.com/f2a0eee7e
10/16/2007 (3:03 am)
Ok, i got it working but i just chucked it in along with the dragonactor component so that you dont have to loose the bouncing or gliding (Unless thats what you want) Anyway .. here is the full DragonActorComponent.cs:http://pastebin.com/f2a0eee7e
#9
Got some ideas?
11/04/2007 (8:30 am)
Does anyone know how I can add this code directly into the PlayerActorComponent file? I tried copy pasting the class part of the code in that file but it didn't work. Got some ideas?
#10
And I mean difficulty for you crazy awesome programmer Guru's, I'm still only programming in the console window so that would be way beyond my level of skill-- unless it was a text adventure that just thold you the character double jumped...watch out Zork!
08/04/2008 (11:23 am)
What about adding in a wall jump? would that be much different--I mean in level of difficulty, not in the actual code, I know that would be different. I would love to be able to add that into my game.And I mean difficulty for you crazy awesome programmer Guru's, I'm still only programming in the console window so that would be way beyond my level of skill-- unless it was a text adventure that just thold you the character double jumped...watch out Zork!
#11
10/07/2008 (7:45 am)
Thanks alot for sharing this - I'd also love to get wall jumping working in my game!
#13
05/25/2010 (3:00 pm)
Yeah, I just copied and pasted this code, and it worked, perfectly. I pasted it directly into PlayerDragonActorComponent in the demo, then changed all instances of DoubleJumpActorComponent to PlayerDragonActorComponent. It works because its another derived class. It might even work with all the derived classes, this is quite a find.
#14
03/26/2011 (11:02 am)
Is there any way I can use this in Torque 3D?
#15
03/26/2011 (11:14 am)
Nope, this is written in c# for the platform starter kit (Which is using TorqueX), Sorry.
Torque Owner Zilla