My Player Struct
Posted: Thu Apr 30, 2009 7:41 pm
Hello everybody
For the past few hours i have been working on this Player struct, most things are working fine but i have a few problems
1.) I have no idea how to modify the players (fpscamera) jumpheight after loading the camera.
2.) Crouching is not working as it is supposed to be, you get stuck after you crouch or cant get up again.
Now i was wondering if somebody could explain me these two things, and ofcource general tips are welcome aswell
Here is my code:
Thank you
PS. You are free to use this in your own project if you want, even though it would be nice is you mention me somewhere
For the past few hours i have been working on this Player struct, most things are working fine but i have a few problems
1.) I have no idea how to modify the players (fpscamera) jumpheight after loading the camera.
2.) Crouching is not working as it is supposed to be, you get stuck after you crouch or cant get up again.
Now i was wondering if somebody could explain me these two things, and ofcource general tips are welcome aswell
Here is my code:
Code: Select all
// The Irrlicht examples where very usefull :)
struct Player : public IAnimationEndCallBack
{
Player();
Player(const string<char> &pName, WorldData* nWorldData);
ISceneNodeAnimatorCollisionResponse* camCollisionResponse(IrrlichtDevice* device, ICameraSceneNode* camera);
void OnAnimationEnd(IAnimatedMeshSceneNode* node);
bool Load();
void Update();
void Respawn();
void Shoot();
void Setpos(vector3df &pos, vector3df &rotation);
void SetWeaponAnim(char* animation);
void SetRunSpeed(float value);
void SetRotateSpeed(float value);
void SetJumpHeight(float value);
void SetJumpSpeed(float value);
void SetFlyMode(bool value);
void SetGravity(vector3df &value);
void ToggleCrouch(bool value);
void ToggleCollision(bool value);
WorldData* worldData;
SKeyMap keyMap[10];
ICameraSceneNode* camera;
IAnimatedMeshSceneNode* WeaponNode;
string<char> playerName;
vector3df playerPosition, playerRotation, playerTarget, playerGravityForce, playerEllipsoidRadius, playerEllipsoidTranslation, weaponPosition, weaponRotation;
vector3df defaultPlayerPosition, defaultPlayerRotation, defaultPlayerGravityForce, defaultPlayerEllipsoidRadius, defaultPlayerEllipsoidTranslation, defaultWeaponPosition, defaultWeaponRotation;
float playerRunSpeed, playerRotateSpeed, playerJumpSpeed, playerJumpHeight, playerHeight;
float defaultPlayerRunSpeed, defaultPlayerRotateSpeed, defaultPlayerJumpSpeed, defaultPlayerJumpHeight, defaultPlayerHeight;
bool verticalMovement, crouching, collision;
ISceneNodeAnimator* anim;
ISceneNodeAnimatorCameraFPS* animFPS;
ISceneNodeAnimatorCollisionResponse* animColResp;
};
Player::Player(){}
Player::Player(const string<char> &pName, WorldData* nWorldData)
{
verticalMovement = true;
crouching = false;
playerName = pName;
worldData = nWorldData;
playerGravityForce = vector3df(0, -10.0f, 0);
playerPosition = vector3df(50, 50, -60);
playerRotation = vector3df(-70, 30, -60);
playerEllipsoidRadius = vector3df(30, 50, 30);
playerEllipsoidTranslation = vector3df(0, 30, 0);
weaponPosition = vector3df(0, 0, 0);
weaponRotation = vector3df(-90,-90,90);
playerRunSpeed = 0.3f;
playerRotateSpeed = 100.0f;
playerJumpSpeed = 3.0f;
playerJumpHeight = 200.0f;
playerHeight = 50.0f;
defaultPlayerPosition = playerPosition;
defaultPlayerRotation = playerRotation;
defaultPlayerGravityForce = playerGravityForce;
defaultPlayerRunSpeed = playerRunSpeed;
defaultPlayerRotateSpeed = playerRotateSpeed;
defaultPlayerJumpSpeed = playerJumpSpeed;
defaultPlayerJumpHeight = playerJumpHeight;
defaultPlayerHeight = playerHeight;
defaultPlayerEllipsoidRadius = playerEllipsoidRadius;
defaultPlayerEllipsoidTranslation = playerEllipsoidTranslation;
defaultWeaponPosition = weaponPosition;
defaultWeaponRotation = weaponRotation;
}
ISceneNodeAnimatorCollisionResponse* Player::camCollisionResponse(IrrlichtDevice* device, ICameraSceneNode* camera)
{
for (list<ISceneNodeAnimator*>::ConstIterator it = camera->getAnimators().begin(); it != camera->getAnimators().end(); ++it)
{
ISceneNodeAnimatorCollisionResponse* a = (ISceneNodeAnimatorCollisionResponse*) (*it);
if (a->getType() == ESNAT_COLLISION_RESPONSE) return a;
}
return 0;
}
void Player::OnAnimationEnd(IAnimatedMeshSceneNode* node)
{
worldData->Logger->log("Player::OnAnimationEnd()");
SetWeaponAnim(0);
}
bool Player::Load()
{
worldData->Logger->log("Player::Load()");
keyMap[0].Action = EKA_MOVE_FORWARD;
keyMap[0].KeyCode = KEY_UP;
keyMap[1].Action = EKA_MOVE_FORWARD;
keyMap[1].KeyCode = KEY_KEY_W;
keyMap[2].Action = EKA_MOVE_BACKWARD;
keyMap[2].KeyCode = KEY_DOWN;
keyMap[3].Action = EKA_MOVE_BACKWARD;
keyMap[3].KeyCode = KEY_KEY_S;
keyMap[4].Action = EKA_STRAFE_LEFT;
keyMap[4].KeyCode = KEY_LEFT;
keyMap[5].Action = EKA_STRAFE_LEFT;
keyMap[5].KeyCode = KEY_KEY_A;
keyMap[6].Action = EKA_STRAFE_RIGHT;
keyMap[6].KeyCode = KEY_RIGHT;
keyMap[7].Action = EKA_STRAFE_RIGHT;
keyMap[7].KeyCode = KEY_KEY_D;
keyMap[8].Action = EKA_JUMP_UP;
keyMap[8].KeyCode = KEY_SPACE;
keyMap[9].Action = EKA_CROUCH;
keyMap[9].KeyCode = KEY_LSHIFT;
camera = worldData->smgr->addCameraSceneNodeFPS(0, playerRotateSpeed, playerRunSpeed, -1, keyMap, sizeof(keyMap), verticalMovement, playerJumpSpeed);
camera->setName("First Person Camera");
camera->setFarValue(10000.0f);
IAnimatedMeshMD2* weaponMesh = (IAnimatedMeshMD2*)worldData->smgr->getMesh("gun.md2");
if (weaponMesh == 0)
{
worldData->Logger->log("Failed to Load: Gun.md2");
MessageBox(0, "Failed to Load: Gun.md2", "Load Error!", 0);
return false;
}
if (weaponMesh->getMeshType() == EAMT_MD2)
{
char buf[64];
for (s32 i = 0; i != weaponMesh->getAnimationCount(); i++)
{
sprintf_s(buf, sizeof(buf), "Animations for Gun.md2: %s", weaponMesh->getAnimationName(i));
worldData->Logger->log(buf);
}
}
ITexture* gunTexture = worldData->videoDriver->getTexture("gun.jpg");
if (gunTexture == 0)
{
worldData->Logger->log("Failed to Load: Gun.jpg");
MessageBox(0, "Failed to Load: Gun.jpg", "Load Error!", 0);
return false;
}
WeaponNode = worldData->smgr->addAnimatedMeshSceneNode(weaponMesh, camera, -1, weaponPosition, weaponRotation);
WeaponNode->setMaterialTexture(0, gunTexture);
WeaponNode->setLoopMode(false);
WeaponNode->setMaterialFlag(EMF_LIGHTING, false);
WeaponNode->setName("Weapon");
//create a collision auto response animator
anim = worldData->smgr->createCollisionResponseAnimator(worldData->triangleSelector, camera, playerEllipsoidRadius, playerGravityForce, playerEllipsoidTranslation);
camera->addAnimator(anim);
//anim->drop();
list<ISceneNodeAnimator*>::ConstIterator animsFPSList = camera->getAnimators().begin();
animFPS = (ISceneNodeAnimatorCameraFPS*)*animsFPSList;
animColResp = camCollisionResponse(worldData->device, camera);
Respawn();
return true;
}
void Player::Update()
{
playerPosition = camera->getPosition();
playerRotation = camera->getRotation();
playerTarget = camera->getTarget();
if(playerPosition.Y < -10000.0f) Respawn();
}
void Player::Respawn()
{
worldData->Logger->log("Player::Respawn()");
Setpos(defaultPlayerPosition, defaultPlayerRotation);
SetWeaponAnim("idle");
}
void Player::Setpos(vector3df &pos, vector3df &rotation)
{
worldData->Logger->log("Player::SetPos()");
camera->setPosition(pos);
camera->setRotation(rotation);
camera->OnAnimate(0);
}
void Player::SetWeaponAnim(char* name)
{
worldData->Logger->log("Player::SetAnim()");
char animation[64];
if (name)
{
strcpy(animation, name);
if (WeaponNode)
{
WeaponNode->setAnimationEndCallback(this);
WeaponNode->setMD2Animation(animation);
}
}
else
{
animation[0] = 0;
if (WeaponNode) WeaponNode->setAnimationEndCallback(0);
}
}
void Player::Shoot()
{
//worldData->Logger->log("Player::Shoot()");
vector3df start = camera->getPosition();
vector3df end = (camera->getTarget() - start).normalize();
start += end * 8.0f;
end = start + (end * camera->getFarValue());
SParticleImpact imp;
imp.when = 0;
triangle3df triangle;
line3d<float> line(start, end);
// get intersection point with map
const ISceneNode* hitNode;
if (worldData->collMan->getCollisionPoint(line, worldData->triangleSelector, end, triangle, hitNode))
{
// collides with wall
vector3df out = triangle.getNormal();
out.setLength(0.03f);
imp.when = 1;
imp.outVector = out;
imp.pos = end;
}
else // doesnt collide with wall
{
start = camera->getPosition();
end = (camera->getTarget() - start).normalize();
end = start + (end * camera->getFarValue());
}
// create fire ball
ISceneNode* node = worldData->smgr->addBillboardSceneNode(0, dimension2d<float>(25,25), start);
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMaterialTexture(0, worldData->bulletTexture);
node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
float length = (end - start).getLength();
float time = length / 2.0f;
ISceneNodeAnimator* anim = worldData->smgr->createFlyStraightAnimator(start, end, time);
node->addAnimator(anim);
anim->drop();
anim = worldData->smgr->createDeleteAnimator(time);
node->addAnimator(anim);
anim->drop();
if (imp.when) // create impact note
{
imp.when = worldData->device->getTimer()->getTime() + time - 100;
worldData->Impacts.push_back(imp);
}
worldData->irrKlang->play2D(worldData->ballSound);
}
void Player::SetRunSpeed(float value)
{
worldData->Logger->log("Player::SetRunSpeed()");
playerRunSpeed = value;
animFPS->setMoveSpeed(playerRunSpeed);
}
void Player::SetRotateSpeed(float value)
{
worldData->Logger->log("Player::SetRotateSpeed()");
playerRotateSpeed = value;
animFPS->setRotateSpeed(playerRotateSpeed);
}
void Player::SetJumpHeight(float value) // Not Working At All!
{
worldData->Logger->log("Player::SetJumpHeight()");
playerJumpHeight = value;
//
}
void Player::SetJumpSpeed(float value)
{
worldData->Logger->log("Player::SetJumpSpeed()");
playerJumpSpeed = value;
animColResp->jump(playerJumpSpeed);
}
void Player::SetFlyMode(bool value)
{
worldData->Logger->log("Player::SetFlyMode()");
verticalMovement = value;
if(verticalMovement) SetGravity(vector3df(0, 0, 0));
else SetGravity(defaultPlayerGravityForce);
animFPS->setVerticalMovement(verticalMovement);
}
void Player::SetGravity(vector3df &value)
{
worldData->Logger->log("Player::SetGravity()");
playerGravityForce = value;
animColResp->setGravity(playerGravityForce);
}
void Player::ToggleCrouch(bool value) // Not Working Correctly!
{
worldData->Logger->log("Player::ToggleCrouch()");
crouching = value;
if(crouching)
{
animColResp->setEllipsoidRadius(vector3df(30, 20, 30));
animColResp->setEllipsoidTranslation(vector3df(0, 20, 0));
SetRunSpeed(defaultPlayerRunSpeed / 4);
SetJumpHeight(defaultPlayerJumpHeight / 3);
}
else
{
animColResp->setEllipsoidRadius(defaultPlayerEllipsoidRadius);
animColResp->setEllipsoidTranslation(defaultPlayerEllipsoidTranslation);
SetRunSpeed(defaultPlayerRunSpeed);
SetJumpHeight(defaultPlayerJumpHeight);
}
}
void Player::ToggleCollision(bool value)
{
worldData->Logger->log("Player::ToggleCollision()");
collision = value;
if(collision) camera->addAnimator(anim);
else camera->removeAnimator(anim);
}
PS. You are free to use this in your own project if you want, even though it would be nice is you mention me somewhere