BGE: Adding a maxJumps to the character controller to adjust how many jumps a character can perform before having to touch the ground. By default this is set to 1, which means a character can only jump once before having to touch the ground again. Setting this to 2 allows for double jumping.
This commit is contained in:
@@ -3749,6 +3749,12 @@ Types
|
|||||||
|
|
||||||
:type: float
|
:type: float
|
||||||
|
|
||||||
|
.. attribute:: maxJumps
|
||||||
|
|
||||||
|
The maximum number of jumps a character can perform before having to touch the ground. By default this is set to 1. 2 allows for a double jump, etc.
|
||||||
|
|
||||||
|
:type: int
|
||||||
|
|
||||||
.. method:: jump()
|
.. method:: jump()
|
||||||
|
|
||||||
The character jumps based on it's jump speed.
|
The character jumps based on it's jump speed.
|
||||||
|
@@ -45,6 +45,7 @@ PyTypeObject KX_CharacterWrapper::Type = {
|
|||||||
PyAttributeDef KX_CharacterWrapper::Attributes[] = {
|
PyAttributeDef KX_CharacterWrapper::Attributes[] = {
|
||||||
KX_PYATTRIBUTE_RO_FUNCTION("onGround", KX_CharacterWrapper, pyattr_get_onground),
|
KX_PYATTRIBUTE_RO_FUNCTION("onGround", KX_CharacterWrapper, pyattr_get_onground),
|
||||||
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_CharacterWrapper, pyattr_get_gravity, pyattr_set_gravity),
|
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_CharacterWrapper, pyattr_get_gravity, pyattr_set_gravity),
|
||||||
|
KX_PYATTRIBUTE_RW_FUNCTION("maxJumps", KX_CharacterWrapper, pyattr_get_max_jumps, pyattr_set_max_jumps),
|
||||||
{ NULL } //Sentinel
|
{ NULL } //Sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,6 +78,27 @@ int KX_CharacterWrapper::pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_D
|
|||||||
return PY_SET_ATTR_SUCCESS;
|
return PY_SET_ATTR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *KX_CharacterWrapper::pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||||
|
{
|
||||||
|
KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
|
||||||
|
|
||||||
|
return PyLong_FromLong(self->m_character->GetMaxJumps());
|
||||||
|
}
|
||||||
|
|
||||||
|
int KX_CharacterWrapper::pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||||
|
{
|
||||||
|
KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
|
||||||
|
long param = PyLong_AsLong(value);
|
||||||
|
|
||||||
|
if (param == -1)
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_ValueError, "KX_CharacterWrapper.maxJumps: expected an integer");
|
||||||
|
return PY_SET_ATTR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->m_character->SetMaxJumps((int)param);
|
||||||
|
return PY_SET_ATTR_SUCCESS;
|
||||||
|
}
|
||||||
PyMethodDef KX_CharacterWrapper::Methods[] = {
|
PyMethodDef KX_CharacterWrapper::Methods[] = {
|
||||||
KX_PYMETHODTABLE_NOARGS(KX_CharacterWrapper, jump),
|
KX_PYMETHODTABLE_NOARGS(KX_CharacterWrapper, jump),
|
||||||
{NULL,NULL} //Sentinel
|
{NULL,NULL} //Sentinel
|
||||||
|
@@ -26,6 +26,8 @@ public:
|
|||||||
|
|
||||||
static PyObject* pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
static PyObject* pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||||
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||||
|
static PyObject* pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||||
|
static int pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||||
#endif // WITH_PYTHON
|
#endif // WITH_PYTHON
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -68,6 +68,48 @@ float gAngularSleepingTreshold;
|
|||||||
|
|
||||||
btVector3 startVel(0,0,0);//-10000);
|
btVector3 startVel(0,0,0);//-10000);
|
||||||
|
|
||||||
|
BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
|
||||||
|
: btKinematicCharacterController(ghost,shape,stepHeight,2),
|
||||||
|
m_motionState(motionState),
|
||||||
|
m_jumps(0),
|
||||||
|
m_maxJumps(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlenderBulletCharacterController::updateAction(btCollisionWorld *collisionWorld, btScalar dt)
|
||||||
|
{
|
||||||
|
btKinematicCharacterController::updateAction(collisionWorld,dt);
|
||||||
|
m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlenderBulletCharacterController::getMaxJumps() const
|
||||||
|
{
|
||||||
|
return m_maxJumps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlenderBulletCharacterController::setMaxJumps(int maxJumps)
|
||||||
|
{
|
||||||
|
m_maxJumps = maxJumps;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlenderBulletCharacterController::canJump() const
|
||||||
|
{
|
||||||
|
return onGround() || m_jumps < m_maxJumps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlenderBulletCharacterController::jump()
|
||||||
|
{
|
||||||
|
if (onGround())
|
||||||
|
m_jumps = 0;
|
||||||
|
|
||||||
|
if (!canJump())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_verticalVelocity = m_jumpSpeed;
|
||||||
|
m_wasJumping = true;
|
||||||
|
m_jumps++;
|
||||||
|
}
|
||||||
|
|
||||||
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
|
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
|
||||||
:m_cci(ci)
|
:m_cci(ci)
|
||||||
{
|
{
|
||||||
@@ -154,25 +196,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlenderBulletCharacterController : public btKinematicCharacterController
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
btMotionState* m_motionState;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
|
|
||||||
: btKinematicCharacterController(ghost,shape,stepHeight,2),
|
|
||||||
m_motionState(motionState)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt)
|
|
||||||
{
|
|
||||||
btKinematicCharacterController::updateAction(collisionWorld,dt);
|
|
||||||
m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
btRigidBody* CcdPhysicsController::GetRigidBody()
|
btRigidBody* CcdPhysicsController::GetRigidBody()
|
||||||
{
|
{
|
||||||
return btRigidBody::upcast(m_object);
|
return btRigidBody::upcast(m_object);
|
||||||
|
@@ -391,10 +391,31 @@ struct CcdConstructionInfo
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
class btCollisionObject;
|
class btCollisionObject;
|
||||||
class btSoftBody;
|
class btSoftBody;
|
||||||
|
class btPairCachingGhostObject;
|
||||||
|
|
||||||
|
class BlenderBulletCharacterController : public btKinematicCharacterController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
btMotionState* m_motionState;
|
||||||
|
int m_jumps;
|
||||||
|
int m_maxJumps;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight);
|
||||||
|
|
||||||
|
virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt);
|
||||||
|
|
||||||
|
int getMaxJumps() const;
|
||||||
|
|
||||||
|
void setMaxJumps(int maxJumps);
|
||||||
|
|
||||||
|
virtual bool canJump() const;
|
||||||
|
|
||||||
|
virtual void jump();
|
||||||
|
};
|
||||||
|
|
||||||
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
|
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
|
||||||
class CcdPhysicsController : public PHY_IPhysicsController
|
class CcdPhysicsController : public PHY_IPhysicsController
|
||||||
|
@@ -270,10 +270,10 @@ public:
|
|||||||
class CharacterWrapper : public PHY_ICharacter
|
class CharacterWrapper : public PHY_ICharacter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
btKinematicCharacterController* m_controller;
|
BlenderBulletCharacterController* m_controller;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CharacterWrapper(btKinematicCharacterController* cont)
|
CharacterWrapper(BlenderBulletCharacterController* cont)
|
||||||
: m_controller(cont)
|
: m_controller(cont)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -295,6 +295,16 @@ public:
|
|||||||
{
|
{
|
||||||
m_controller->setGravity(gravity);
|
m_controller->setGravity(gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int GetMaxJumps()
|
||||||
|
{
|
||||||
|
return m_controller->getMaxJumps();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void SetMaxJumps(int maxJumps)
|
||||||
|
{
|
||||||
|
m_controller->setMaxJumps(maxJumps);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CcdOverlapFilterCallBack : public btOverlapFilterCallback
|
class CcdOverlapFilterCallBack : public btOverlapFilterCallback
|
||||||
@@ -2320,7 +2330,7 @@ PHY_ICharacter* CcdPhysicsEnvironment::getCharacterController(KX_GameObject *ob)
|
|||||||
{
|
{
|
||||||
CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData();
|
CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData();
|
||||||
if (controller->GetCharacterController())
|
if (controller->GetCharacterController())
|
||||||
return new CharacterWrapper(controller->GetCharacterController());
|
return new CharacterWrapper((BlenderBulletCharacterController*)controller->GetCharacterController());
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,9 @@ public:
|
|||||||
virtual float GetGravity()= 0;
|
virtual float GetGravity()= 0;
|
||||||
virtual void SetGravity(float gravity)= 0;
|
virtual void SetGravity(float gravity)= 0;
|
||||||
|
|
||||||
|
virtual int GetMaxJumps()= 0;
|
||||||
|
virtual void SetMaxJumps(int maxJumps)= 0;
|
||||||
|
|
||||||
#ifdef WITH_CXX_GUARDEDALLOC
|
#ifdef WITH_CXX_GUARDEDALLOC
|
||||||
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter")
|
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter")
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user