#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; // If we die, we have to decrease the fade timer if (!mAlive) { mFadeTimer -= delta_sec; if (mFadeTimer <= 0.) { Model *model = (Model*) Engine::EngineGetModel(); model->SetGameState (GameStatePlayerDied); } 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; mAlive = false; mFadeTimer = 3.; 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; mAlive = false; mFadeTimer = 1.; mState = Dying; 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; } }