122 lines
3.5 KiB
C++
122 lines
3.5 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) {
|
|
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;
|
|
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;
|
|
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 = 1.75;
|
|
|
|
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 *= ShipEntity::VarMaxSpeed.GetFloatValue() + 0.5;
|
|
|
|
Engine::PlaySound ("./data/sounds/laser.wav");
|
|
}
|
|
|
|
}
|