fysxasteroids/asteroids/ShipEntity.cc

124 lines
3.8 KiB
C++

#include "Engine.h"
#include "Model.h"
#include "ShipEntity.h"
#include "RocketEntity.h"
#include "Controller.h"
#include "AsteroidsEvents.h"
#include "coll2d.h"
namespace asteroids {
Engine::Variable ShipEntity::VarAcceleration ("ship_acceleration", "10");
Engine::Variable ShipEntity::VarMaxSpeed ("ship_maxspeed", "10");
Engine::Variable ShipEntity::VarRotationSpeed ("ship_rotationspeed", "180");
Engine::Variable ShipEntity::VarMaxAttackRate ("ship_maxattackrate", "10");
void ShipEntity::Update (float delta_sec) {
if (!mPhysicState || !mControllerState)
return;
mState = Idle;
// the local velocity
vector3d local_velocity = mPhysicState->mVelocity;
mPhysicState->LocalizeRotation (local_velocity);
// set the local velocity as the current state of the keys are
if (mControllerState->GetKey (EntityKeyStateForward)) {
local_velocity[0] += delta_sec * ShipEntity::VarAcceleration.GetFloatValue();
mState = Accelerating;
}
// now transform these to global velocities
mPhysicState->GlobalizeRotation (local_velocity);
// now we can update the new global velocity
mPhysicState->SetVelocity(local_velocity);
if (mControllerState->GetKey (EntityKeyStateTurnLeft)) {
mPhysicState->mOrientation[1] += delta_sec * ShipEntity::VarRotationSpeed.GetFloatValue();
}
if (mControllerState->GetKey (EntityKeyStateTurnRight)) {
mPhysicState->mOrientation[1] -= delta_sec * ShipEntity::VarRotationSpeed.GetFloatValue();
}
// Check for the maximum speed
float speed = mPhysicState->mVelocity.length();
if (speed > ShipEntity::VarMaxSpeed.GetFloatValue()) {
mPhysicState->mVelocity *= ShipEntity::VarMaxSpeed.GetFloatValue() / speed;
}
// update the attack timer if neccessary
if (mAttackTimer > 0.)
mAttackTimer -= delta_sec;
}
bool ShipEntity::CollisionEvent (Engine::EntityBase* entity, vector3d point, vector3d normal) {
GameEntityType other_type = (GameEntityType) entity->mType;
if (other_type == GameEntityTypeAsteroid) {
Engine::LogMessage ("You died!");
mPhysicState->mStatic = true;
mState = Dying;
Engine::EventBasePtr explode_event (new Engine::EventBase());
explode_event->mEventType = EventShipExplode;
explode_event->mEventUnsignedInt = mId;
explode_event->mVector3d = mPhysicState->mVelocity - entity->mPhysicState->mVelocity;
QueueEvent (explode_event);
return true;
} else if (other_type == GameEntityTypeRocket) {
Engine::LogMessage ("You just killed yourself!");
mPhysicState->mStatic = true;
mState = Dying;
Engine::EventBasePtr explode_event (new Engine::EventBase());
explode_event->mEventType = EventShipExplode;
explode_event->mEventUnsignedInt = mId;
explode_event->mVector3d = mPhysicState->mVelocity - entity->mPhysicState->mVelocity;
QueueEvent (explode_event);
return true;
}
return false;
}
void ShipEntity::Attack () {
if (!mAlive)
return;
// skip the attack if we still have to wait
if (mAttackTimer > 0.)
return;
mAttackTimer = 1. / ShipEntity::VarMaxAttackRate.GetFloatValue();
Engine::EntityPhysicState* entity_physic = Engine::GetEntityPhysicState (mId);
vector3d attack_dir (1., 0., 0.);
entity_physic->GlobalizeRotation (attack_dir);
RocketEntity *rocket_entity = (RocketEntity*) Engine::CreateEntity (GameEntityTypeRocket);
rocket_entity->mSecToLive = RocketEntity::VarTimeToLive.GetFloatValue();
RocketEntityPhysicState *rocket_physics = (RocketEntityPhysicState*) rocket_entity->mPhysicState;
rocket_physics->mPosition = attack_dir;
rocket_physics->mPosition *= mPhysicState->mRadius;
rocket_physics->mPosition += entity_physic->mPosition;
rocket_physics->mOrientation = entity_physic->mOrientation;
rocket_physics->mVelocity = attack_dir.normalize();
rocket_physics->mVelocity *= RocketEntity::VarSpeed.GetFloatValue();
Engine::PlaySound (Engine::GetResourceFullPath("/data/sounds/laser.wav"));
}
}