Project Description



Description
Light em up was a group project of 13 students. The team was divided as programmers, artists and designers. Light em up is about a fish that emits light and is armed with weapons to shoot his enemy.
My Tasks on this project:
– Creating a hit shader, Which made an enemy colored red when hit.
– The AI for the Mechanical BossPiranha.
– The AI for the regular Enemies.
Details
- Type: Game, Group Project
- Tech: C++, Ogre3D
- Duration: ~16 Weeks 1 day a week
- Status: Finished
Code
#ifndef _BOSSPIRANHA_ #define _BOSSPIRANHA_ #include "./Creature.h" class Player; class BossPiranha : public Creature { public: // Constructor BossPiranha(); // Deconstructor ~BossPiranha(); // Initialises the BossPiranha virtual void Initialize(Ogre::Vector3 pos); // Updates the BossPiranha virtual void Update(float dt); // Resets the BossPiranha virtual void Reset(); // Shoots bullets or explodes virtual void Shoot(); private: void StartUp(float dt); void AttackLaser(float dt); void AttackCharge(float dt); void AttackPowerball(float dt); void JawOpens(float dt); void JawClose(float dt); void Shield(float dt); void CockpitOpen(float dt); void CockpitClose(float dt); void Delay(float dt); void NextBehavior(float dt); void ChangeBehavior(float dt); void Hit(float damage, Ogre::Vector3 hitPosition); void Dead(float dt); void Dance(float dt); void BehaviorHit(float dt); void ChangeColor(); void SetAnimation(int state, bool loop); Player* m_Player; int m_Stage; int m_State; int m_Behavior; int m_NextState; float m_Delay; bool m_AnimationPlaying; bool m_AttackDone; bool m_CanReceiveDamage; int m_StateDetail; float m_ShootCountDown; int m_BulletsToShoot; int m_BulletsShot; float m_BulletShootSpeed; float m_BulletShootCountDown; bool m_IsDancing; float m_AnimationChanger; Ogre::String m_MatName; Ogre::AnimationState* m_Anim; }; #endif
#include "../../GamePlayDefines.h" #include "./BossPiranha.h" #include "../../../GameMain/GameMain.h" #include "../CollisionShapePool.h" #include "Player.h" #include "OgreMath.h" #include "OgreSubMesh.h" #include "OgreSubEntity.h" #include "../../../OISInput/InputManager.h" /*--------------------------------------------------------------------------*/ namespace BossState { enum { STARTUP = 0, IDLE, DELAY, ATTACKLASER, ATTACKCHARGE, ATTACKPOWERBALL, JAWOPENS, JAWCLOSE, COCKPITOPEN, COCKPITCLOSE, SHIELD, BEHAVIORHIT, FULLDEAD, DEAD, DANCESTART, DANCE, HIGH, MID, LOW }; }; /*--------------------------------------------------------------------------*/ BossPiranha::BossPiranha() : Creature(ObjectType::BOSSPIRANHA) { //If there is no shape for this projectile if(gGameMain->GetCollisionShapePool()->GetShapeFor(ObjectType::BOSSPIRANHA)==NULL) { //Create shape for this projectile gGameMain->GetCollisionShapePool()->CreateShapeFor(ObjectType::BOSSPIRANHA,gGameMain->GetWorldPhysics()->CreateBoxShape(Ogre::Vector3(10,10,10))); } m_Model.LoadModel("piranhaBoss.mesh", 5); GetNode()->scale(Ogre::Vector3(2.0f)); m_Position = Ogre::Vector3(1,0,0); assert(gGameMain->GetCollisionShapePool()->GetShapeFor(ObjectType::BOSSPIRANHA)); InitializeKinematicObject(gGameMain->GetCollisionShapePool()->GetShapeFor(ObjectType::BOSSPIRANHA) ,m_Position,1,ObjectCollisionTypes::ENEMY,COLL_MASK_FOR_ENEMY); SetActive(false); m_AnimationChanger = 1.0f; } /*--------------------------------------------------------------------------*/ BossPiranha::~BossPiranha() { } /*--------------------------------------------------------------------------*/ void BossPiranha::Initialize(Ogre::Vector3 pos) { m_Position = pos; m_Player = gGameMain->GetPlayer(); if(!m_Active) { SetActive(true); } m_health = BOSSPIRANHA_START_HEALTH; m_damage = BOSSPIRANHA_DAMAGE; m_MatName = m_Model.mEntities[0]->getSubEntity(1)->getMaterialName(); m_NormalMaterial = static_cast(Ogre::MaterialManager::getSingleton().getByName(m_MatName) ); m_HitMaterial = static_cast(Ogre::MaterialManager::getSingleton().getByName("enemy_hit") ); m_Model.mEntities[0]->getSubEntity(20)->setMaterialName("ball_green"); m_collisionDamage = BOSSPIRANHA_COLLISION_DAMAGE; m_ShootCountDown = BOSSPIRANHA_SHOOT_WAIT_TIME * 1000; m_BulletsToShoot = 0; m_BulletsShot = 0; m_BulletShootSpeed = 0; m_BulletShootCountDown = 0; m_healthRegained = 20; m_Delay = -10; m_AnimationPlaying = false; m_AttackDone = false; m_CanReceiveDamage = true; m_damage = BOSSPIRANHA_DAMAGE; m_State = BossState::STARTUP; m_Behavior = BossState::HIGH; m_NextState = BossState::IDLE; m_AnimationChanger = 1.0f; m_Anim = NULL; SetAnimation(BossState::IDLE, true); m_IsDancing = false; m_Stage = 0; m_StateDetail = 0; m_lightRadius = 0.1f; m_lightColor = 0xFF00FF00; } /*--------------------------------------------------------------------------*/ void BossPiranha::Update(float dt) { if(m_IsHit) { m_CurrentHitTime+= dt; if(m_CurrentHitTime > ENEMY_LIGHT_HIT_TIME) { m_IsHit = false; m_Model.mEntities[0]->setMaterial(m_NormalMaterial); ChangeColor(); } } if(m_health > 0) { m_Anim->addTime(dt * 0.0015f); } else { m_Anim->addTime(dt * 0.0010f); } if(m_Delay >= -1.0f){ Delay(dt); return;} if(m_Player->IsDead()) { Dance(dt); } if(m_State == BossState::STARTUP) { StartUp(dt); }else if(m_State == BossState::COCKPITCLOSE) { CockpitClose(dt); }else if(m_State == BossState::COCKPITOPEN) { CockpitOpen(dt); }else if(m_State == BossState::JAWOPENS) { JawOpens(dt); }else if(m_State == BossState::JAWCLOSE) { JawClose(dt); }else if(m_State == BossState::SHIELD) { Shield(dt); }else if(m_State == BossState::ATTACKCHARGE) { AttackCharge(dt); }else if(m_State == BossState::ATTACKLASER) { AttackLaser(dt); }else if(m_State == BossState::ATTACKPOWERBALL) { AttackPowerball(dt);}else if(m_State == BossState::BEHAVIORHIT) { BehaviorHit(dt); }else if(m_State == BossState::DEAD) { Dead(dt); }else if(m_State == BossState::DELAY) { m_State = BossState::IDLE; }else if(m_State == BossState::IDLE) { NextBehavior(dt); }else if(m_CanReceiveDamage) { float differenceY = (m_Position.y - gGameMain->GetCameraPosition().y); m_Position.y += -(differenceY / BOSSPIRANHA_MOVEMENT_Y_DAMPING) * dt; } SetKinematicBodyPosition(m_Position); } /*--------------------------------------------------------------------------*/ void BossPiranha::Shoot() { } /*--------------------------------------------------------------------------*/ void BossPiranha::Reset() { } /*--------------------------------------------------------------------------*/ void BossPiranha::StartUp(float dt) { Ogre::Vector3 targetpos = Ogre::Vector3((gGameMain->GetCameraPosition().x + BOSSPIRANHA_SCREEN_RIGHT_POSITION), gGameMain->GetCameraPosition().y, m_Player->GetPosition().z); if(m_Position.squaredDistance(targetpos) <= 10) { NextBehavior(dt); } float diff = (m_Position.x - (gGameMain->GetCameraPosition().x + BOSSPIRANHA_SCREEN_RIGHT_POSITION)); m_Position.x += -(diff / BOSSPIRANHA_STARTUP_DAMPING) * dt; float differenceY = (m_Position.y - gGameMain->GetCameraPosition().y); m_Position.y += -(differenceY / BOSSPIRANHA_MOVEMENT_Y_DAMPING) * dt; } /*--------------------------------------------------------------------------*/ void BossPiranha::AttackLaser(float dt) { if(m_BulletShootCountDown < 0) { m_BulletShootCountDown = BOSSPIRANHA_LASER_COUNTDOWN; gGameMain->BossPiranhaShoot(m_Position - Ogre::Vector3(10, 10, 10), Ogre::Vector3(-1, 1, 0).normalisedCopy()); // Up Left gGameMain->BossPiranhaShoot(m_Position - Ogre::Vector3(10, 10, 10), Ogre::Vector3(-1, 0, 0)); // left gGameMain->BossPiranhaShoot(m_Position - Ogre::Vector3(10, 10, 10), Ogre::Vector3(-1,-1, 0).normalisedCopy()); // down left m_BulletsShot++; if(m_BulletsShot >= m_BulletsToShoot) { m_BulletsShot = 0; m_BulletsToShoot = 0; m_BulletShootCountDown = 0; NextBehavior(dt); } } else { m_BulletShootCountDown -= dt; } } /*--------------------------------------------------------------------------*/ void BossPiranha::AttackCharge(float dt) { if(!m_AttackDone) { float diff = (m_Position.x - (gGameMain->GetCameraPosition().x - BOSSPIRANHA_SCREEN_LEFT_POSITION) ); m_Position.x += -(diff / BOSSPIRANHA_ATTACK_DAMPING) * dt; if(m_Position.x <= (gGameMain->GetCameraPosition().x - BOSSPIRANHA_SCREEN_LEFT_POSITION) + 15.0f) { if(m_Anim->hasEnded()) { m_AttackDone = true; SetAnimation(BossState::IDLE, true); } } } else { float diff = (m_Position.x - (gGameMain->GetCameraPosition().x + BOSSPIRANHA_SCREEN_RIGHT_POSITION)); m_Position.x += -(diff / BOSSPIRANHA_ATTACK_DAMPING) * dt; if(m_Position.x >= (gGameMain->GetCameraPosition().x + BOSSPIRANHA_SCREEN_RIGHT_POSITION-1.5f)) { m_AttackDone = false; NextBehavior(dt); } } } /*--------------------------------------------------------------------------*/ void BossPiranha::AttackPowerball(float dt) { gGameMain->BossPiranhaPowerballShoot(Ogre::Vector3(m_Position.x - 35, m_Position.y -8, m_Position.z), Ogre::Vector3(-5, 0, 0)); NextBehavior(dt); } /*--------------------------------------------------------------------------*/ void BossPiranha::JawOpens(float dt) { if(!m_AnimationPlaying) { printf("Jaw Opens \n"); m_AnimationPlaying = true; } else { NextBehavior(dt); } } /*--------------------------------------------------------------------------*/ void BossPiranha::JawClose(float dt) { if(!m_AnimationPlaying) { printf("Jaw Close \n"); m_AnimationPlaying = true; } else { NextBehavior(dt); } } /*--------------------------------------------------------------------------*/ void BossPiranha::CockpitOpen(float dt) { if(!m_AnimationPlaying) { printf("Cockpit Open\n"); m_AnimationPlaying = true; } else { NextBehavior(dt); } } /*--------------------------------------------------------------------------*/ void BossPiranha::CockpitClose(float dt) { if(!m_AnimationPlaying) { printf("Cockpit Close\n"); m_AnimationPlaying = true; } else { NextBehavior(dt); } } /*--------------------------------------------------------------------------*/ void BossPiranha::Shield( float dt ) { NextBehavior(dt); } /*--------------------------------------------------------------------------*/ void BossPiranha::Delay(float dt) { m_Delay-= dt; if(m_Delay <= 0) { m_Delay = -10; } } /*--------------------------------------------------------------------------*/ void BossPiranha::Dead( float dt ) { if(!m_Anim->hasEnded()){return;} SetAnimation(BossState::FULLDEAD, true); m_State = BossState::FULLDEAD; gGameMain->UnfixCamera(); } /*--------------------------------------------------------------------------*/ void BossPiranha::NextBehavior(float dt) { m_Anim->setLoop(false); if(!m_Anim->hasEnded()){ m_State = BossState::IDLE; return;} if(m_Delay >= 0){return;} SetAnimation(BossState::IDLE, true); m_Anim->setLoop(true); m_AnimationPlaying = false; float diff = (m_Position.x - (gGameMain->GetCameraPosition().x + BOSSPIRANHA_SCREEN_RIGHT_POSITION)); m_Position.x += -(diff / BOSSPIRANHA_STARTUP_DAMPING) * dt; float differenceY = (m_Position.y - gGameMain->GetCameraPosition().y); m_Position.y += -(differenceY / BOSSPIRANHA_MOVEMENT_Y_DAMPING) * dt; float oneprocent = BOSSPIRANHA_START_HEALTH / 100; float CurrentProcent = m_health / oneprocent; //printf("%f\n", CurrentProcent); if(CurrentProcent > 70.0f) { if(m_Behavior != BossState::HIGH) { m_Behavior = BossState::HIGH; ChangeBehavior(dt); } else { m_Stage++; if(m_Stage == 1){m_State = BossState::ATTACKCHARGE; m_AttackDone = false; SetAnimation(BossState::ATTACKCHARGE, false); m_Delay = 1.3 * 1000;} if(m_Stage == 2){m_State = BossState::DELAY; m_Delay = 2.0 * 1000;} if(m_Stage == 3){m_State = BossState::ATTACKLASER; m_BulletShootCountDown = 0; m_BulletsToShoot = 1; SetAnimation(BossState::ATTACKLASER, false); m_Delay = 0.6 * 1000;} if(m_Stage == 4){m_State = BossState::DELAY; m_Delay = 2.0 * 1000;} if(m_Stage == 5){m_State = BossState::ATTACKPOWERBALL; SetAnimation(BossState::ATTACKPOWERBALL, false); m_Delay = 2.2f * 1000;} if(m_Stage == 6){m_State = BossState::DELAY; m_Delay = 2.0 * 1000;} if(m_Stage == 7){m_State = BossState::SHIELD; SetAnimation(BossState::SHIELD, false);} if(m_Stage == 8){m_Stage = 0; NextBehavior(dt);} } }else if(CurrentProcent <= 70.0f && CurrentProcent > 30.0f) { if(m_Behavior != BossState::MID) { m_Behavior = BossState::MID; ChangeBehavior(dt); } else { m_Stage++; if(m_Stage == 1){m_State = BossState::ATTACKCHARGE; m_AttackDone = false; SetAnimation(BossState::ATTACKCHARGE, false); m_Delay = 1.3 * 1000;} if(m_Stage == 2){m_State = BossState::DELAY; m_Delay = 1.0 * 1000;} if(m_Stage == 3){m_State = BossState::ATTACKLASER; m_BulletShootCountDown = 0; m_BulletsToShoot = 2; SetAnimation(BossState::ATTACKLASER, false); m_Delay = 0.6 * 1000;} if(m_Stage == 4){m_State = BossState::DELAY; m_Delay = 1.0 * 1000;} if(m_Stage == 5){m_State = BossState::ATTACKLASER; m_BulletShootCountDown = 0; m_BulletsToShoot = 2; SetAnimation(BossState::ATTACKLASER, false); m_Delay = 0.6 * 1000;} if(m_Stage == 6){m_State = BossState::DELAY; m_Delay = 1.0 * 1000;} if(m_Stage == 7){m_State = BossState::ATTACKPOWERBALL; SetAnimation(BossState::ATTACKPOWERBALL, false); m_Delay = 2.2f * 1000;} if(m_Stage == 8){m_State = BossState::SHIELD; SetAnimation(BossState::SHIELD, false);} if(m_Stage == 9){m_Stage = 0; NextBehavior(dt);} } }else if (CurrentProcent <= 30.0f) { if(m_Behavior != BossState::LOW) { m_Behavior = BossState::LOW; ChangeBehavior(dt); } else { m_Stage++; if(m_Stage == 1){m_State = BossState::ATTACKCHARGE; m_AttackDone = false; SetAnimation(BossState::ATTACKCHARGE, false); m_Delay = 1.3 * 1000;} if(m_Stage == 2){m_State = BossState::ATTACKLASER; m_BulletShootCountDown = 0; m_BulletsToShoot = 3; SetAnimation(BossState::ATTACKLASER, false); m_Delay = 0.6 * 1000;} if(m_Stage == 3){m_State = BossState::ATTACKLASER; m_BulletShootCountDown = 0; m_BulletsToShoot = 3; SetAnimation(BossState::ATTACKLASER, false); m_Delay = 0.6 * 1000;} if(m_Stage == 4){m_State = BossState::ATTACKPOWERBALL; SetAnimation(BossState::ATTACKPOWERBALL, false); m_Delay = 2.2f * 1000;} if(m_Stage == 5){m_State = BossState::ATTACKPOWERBALL; SetAnimation(BossState::ATTACKPOWERBALL, false); m_Delay = 2.2f * 1000;} if(m_Stage == 6){m_State = BossState::SHIELD; SetAnimation(BossState::SHIELD, false);} if(m_Stage == 7){m_Stage = 0; NextBehavior(dt);} } } } /*--------------------------------------------------------------------------*/ void BossPiranha::ChangeBehavior( float dt ) { SetAnimation(BossState::BEHAVIORHIT, false); m_Stage = 0; m_State = BossState::BEHAVIORHIT; m_Delay = 2.2 * 1000; ChangeColor(); } /*--------------------------------------------------------------------------*/ void BossPiranha::BehaviorHit( float dt ) { SetAnimation(BossState::IDLE, true); m_State = BossState::IDLE; m_Stage = 0; } /*--------------------------------------------------------------------------*/ void BossPiranha::Dance( float dt) { if(!m_IsDancing) { m_IsDancing = true; SetAnimation(BossState::DANCESTART, false); } else { if(m_Anim->hasEnded()) { SetAnimation(BossState::DANCE, true); } } float differenceY = (m_Position.y - gGameMain->GetCameraPosition().y); m_Position.y += -(differenceY / BOSSPIRANHA_MOVEMENT_Y_DAMPING) * dt; float diff = (m_Position.x - (gGameMain->GetCameraPosition().x + 30.0f) ); m_Position.x += -(diff / BOSSPIRANHA_STARTUP_DAMPING) * dt; } /*--------------------------------------------------------------------------*/ void BossPiranha::SetAnimation(int state, bool loop) { if(m_Anim != NULL){ m_Anim->setEnabled(false);} if(state == BossState::IDLE) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_swim"); m_CanReceiveDamage = true; } if(state == BossState::ATTACKCHARGE) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_charge"); m_CanReceiveDamage = false; } if(state == BossState::ATTACKLASER) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_attack_forward"); m_CanReceiveDamage = false;} if(state == BossState::ATTACKPOWERBALL) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_powerAttack"); m_CanReceiveDamage = false; } if(state == BossState::SHIELD) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_shield"); m_CanReceiveDamage = false; } if(state == BossState::BEHAVIORHIT) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_death"); m_CanReceiveDamage = false; } if(state == BossState::DEAD) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_death"); m_CanReceiveDamage = false; } if(state == BossState::FULLDEAD) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_deathLoop"); m_CanReceiveDamage = false; } if(state == BossState::DANCESTART) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_danceStart"); m_CanReceiveDamage = false; } if(state == BossState::DANCE) { m_Anim = m_Model.mEntities[0]->getAnimationState("piranhaBoss_an_danceLoop"); m_CanReceiveDamage = false; } m_Anim->setEnabled(true); m_Anim->setTimePosition(0); m_Anim->setLoop(loop); } /*--------------------------------------------------------------------------*/ void BossPiranha::Hit( float damage, Ogre::Vector3 hitPosition ) { if(m_CanReceiveDamage) { if(hitPosition.distance(m_Position) <= BOSSPIRANHA_HIT_RADIUS) { m_health-=damage; m_HitMaterial->setDiffuse(ENEMY_LIGHT_HIT_COLOR_R,ENEMY_LIGHT_HIT_COLOR_G,ENEMY_LIGHT_HIT_COLOR_B,ENEMY_LIGHT_HIT_COLOR_A); m_Model.mEntities[0]->setMaterial(m_HitMaterial); m_IsHit = true; m_CurrentHitTime = 0; } if(m_health<=0) { m_CanReceiveDamage = false; m_State = BossState::DEAD; m_Delay = 0; SetAnimation(BossState::DEAD, false); m_collisionDamage = 0; } } } /*--------------------------------------------------------------------------*/ void BossPiranha::ChangeColor() { if(m_Behavior == BossState::HIGH) { m_Model.mEntities[0]->getSubEntity(20)->setMaterialName("ball_green"); m_AnimationChanger = 1.0f; m_lightColor = 0xFF00FF00; } else if(m_Behavior == BossState::MID) { m_Model.mEntities[0]->getSubEntity(20)->setMaterialName("ball_orange"); m_AnimationChanger = 1.1f; m_lightColor = 0xFFFF9900; } else if(m_Behavior == BossState::LOW) { m_Model.mEntities[0]->getSubEntity(20)->setMaterialName("ball_red"); m_AnimationChanger = 1.2f; m_lightColor = 0xFFFF0000; } }