Space Fighter
A "shmup" game for Computer Programming C++
Loading...
Searching...
No Matches
Level.cpp
Go to the documentation of this file.
1
2#include "Level.h"
3#include "EnemyShip.h"
4#include "Blaster.h"
5#include "GameplayScreen.h"
6
7std::vector<Explosion *> Level::s_explosions;
8
9// Collision Callback Functions
10
12void PlayerShootsEnemy(GameObject *pObject1, GameObject *pObject2)
13{
14 bool m = pObject1->HasMask(CollisionType::Enemy);
15 EnemyShip *pEnemyShip = (EnemyShip *)((m) ? pObject1 : pObject2);
16 Projectile *pPlayerProjectile = (Projectile *)((!m) ? pObject1 : pObject2);
17 pEnemyShip->Hit(pPlayerProjectile->GetDamage());
18 pPlayerProjectile->Deactivate();
19}
20
23{
24 bool m = pObject1->HasMask(CollisionType::Player);
25 PlayerShip *pPlayerShip = (PlayerShip *)((m) ? pObject1 : pObject2);
26 EnemyShip *pEnemyShip = (EnemyShip *)((!m) ? pObject1 : pObject2);
27 pPlayerShip->Hit(std::numeric_limits<float>::max());
28 pEnemyShip->Hit(std::numeric_limits<float>::max());
29}
30
31
33{
34 m_sectorSize.X = 64;
35 m_sectorSize.Y = 64;
36
37 m_sectorCount.X = (float)((Game::GetScreenWidth() / (int)m_sectorSize.X) + 1);
38 m_sectorCount.Y = (float)((Game::GetScreenHeight() / (int)m_sectorSize.Y) + 1);
39
40 m_totalSectorCount = m_sectorCount.X * m_sectorCount.Y;
41
42 m_pSectors = new std::vector<GameObject *>[m_totalSectorCount];
43 m_pCollisionManager = new CollisionManager();
44
46
47 // Setup player ship
48 m_pPlayerShip = new PlayerShip();
49 Blaster *pBlaster = new Blaster("Main Blaster");
50 pBlaster->SetProjectilePool(&m_projectiles);
51 m_pPlayerShip->AttachItem(pBlaster, Vector2::UNIT_Y * -20);
52
53 for (int i = 0; i < 100; i++)
54 {
55 Projectile *pProjectile = new Projectile();
56 m_projectiles.push_back(pProjectile);
57 AddGameObject(pProjectile);
58 }
59
60 m_pPlayerShip->Activate();
61 AddGameObject(m_pPlayerShip);
62
63 // Setup collision types
65
69
70 pC->AddNonCollisionType(playerShip, playerProjectile);
71 pC->AddCollisionType(playerProjectile, enemyShip, PlayerShootsEnemy);
72 pC->AddCollisionType(playerShip, enemyShip, PlayerCollidesWithEnemy);
73}
74
76{
77 delete[] m_pSectors;
78 delete m_pCollisionManager;
79
80 m_gameObjectIt = m_gameObjects.begin();
81 for (; m_gameObjectIt != m_gameObjects.end(); m_gameObjectIt++)
82 {
83 delete (*m_gameObjectIt);
84 }
85}
86
87
88void Level::LoadContent(ResourceManager& resourceManager)
89{
90 m_pPlayerShip->LoadContent(resourceManager);
91
92 // Setup explosions if they haven't been already
93 Explosion* pExplosion;
94 if (s_explosions.size() == 0) {
95 AudioSample* pExplosionSound = resourceManager.Load<AudioSample>("Audio\\Effects\\Explosion.ogg");
96 Animation* pAnimation = resourceManager.Load<Animation>("Animations\\Explosion.anim");
97 pAnimation->Stop();
98
99 for (int i = 0; i < 10; i++)
100 {
101 pExplosion = new Explosion();
102 pExplosion->SetAnimation((Animation *)pAnimation->Clone());
103 pExplosion->SetSound(pExplosionSound);
104 s_explosions.push_back(pExplosion);
105 }
106 }
107}
108
109
111{
112 if (IsScreenTransitioning()) return;
113
114 m_pPlayerShip->HandleInput(input);
115}
116
117
118void Level::Update(const GameTime& gameTime)
119{
120 for (unsigned int i = 0; i < m_totalSectorCount; i++)
121 {
122 m_pSectors[i].clear();
123 }
124
125 m_gameObjectIt = m_gameObjects.begin();
126 for (; m_gameObjectIt != m_gameObjects.end(); m_gameObjectIt++)
127 {
128 GameObject *pGameObject = (*m_gameObjectIt);
129 pGameObject->Update(gameTime);
130 }
131
132 for (unsigned int i = 0; i < m_totalSectorCount; i++)
133 {
134 if (m_pSectors[i].size() > 1)
135 {
136 CheckCollisions(m_pSectors[i]);
137 }
138 }
139
140 m_explosionIt = s_explosions.begin();
141 for (; m_explosionIt != s_explosions.end(); m_explosionIt++)
142 {
143 (*m_explosionIt)->Update(gameTime);
144 }
145
146 if (!m_pPlayerShip->IsActive())
147 {
149 }
150}
151
152
154{
155 Vector2 position = pGameObject->GetPosition();
156 //Vector2 previousPosition = pGameObject->GetPreviousPosition();
157 Vector2 halfDimensions = pGameObject->GetHalfDimensions();
158
159 int minX = (int)(position.X - halfDimensions.X - 0.5f);
160 int maxX = (int)(position.X + halfDimensions.X + 0.5f);
161 int minY = (int)(position.Y - halfDimensions.Y - 0.5f);
162 int maxY = (int)(position.Y + halfDimensions.Y + 0.5f);
163
165 //minX = Math::Min(minX, (int)(previousPosition.X - halfDimensions.X - 0.5f));
166 //maxX = Math::Max(maxX, (int)(previousPosition.X + halfDimensions.X + 0.5f));
167 //minY = Math::Min(minY, (int)(previousPosition.Y - halfDimensions.Y - 0.5f));
168 //maxY = Math::Max(maxY, (int)(previousPosition.Y + halfDimensions.Y + 0.5f));
169
170 minX = Math::Clamp<int>(0, m_sectorCount.X - 1, minX / (int)m_sectorSize.X);
171 maxX = Math::Clamp<int>(0, m_sectorCount.X - 1, maxX / (int)m_sectorSize.X);
172 minY = Math::Clamp<int>(0, m_sectorCount.Y - 1, minY / (int)m_sectorSize.Y);
173 maxY = Math::Clamp<int>(0, m_sectorCount.Y - 1, maxY / (int)m_sectorSize.Y);
174
175
176 for (int x = minX; x <= maxX; x++)
177 {
178 for (int y = minY; y <= maxY; y++)
179 {
180 int index = y * (int)m_sectorCount.X + x;
181
182 m_pSectors[index].push_back(pGameObject);
183 }
184 }
185}
186
187
188void Level::SpawnExplosion(GameObject *pExplodingObject)
189{
190 Explosion *pExplosion = nullptr;
191
192 for (unsigned int i = 0; i < s_explosions.size(); i++)
193 {
194 if (!s_explosions[i]->IsActive())
195 {
196 pExplosion = s_explosions[i];
197 break;
198 }
199 }
200
201 if (!pExplosion) return;
202
203 const float aproximateTextureRadius = 120;
204 const float objectRadius = pExplodingObject->GetCollisionRadius();
205 const float scaleToObjectSize = (1 / aproximateTextureRadius) * objectRadius * 2;
206 const float dramaticEffect = 2.2f;
207 const float scale = scaleToObjectSize * dramaticEffect;
208 pExplosion->Activate(pExplodingObject->GetPosition(), scale);
209}
210
211
212float Level::GetAlpha() const
213{
214 return GetGameplayScreen()->GetAlpha();
215}
216
217
218void Level::CheckCollisions(std::vector<GameObject *> &gameObjects)
219{
220 const unsigned int objectCount = (unsigned int)gameObjects.size();
221
222 GameObject *pFirst, *pSecond;
223
224 for (unsigned int i = 0; i < objectCount - 1; i++)
225 {
226 pFirst = gameObjects[i];
227 if (pFirst->IsActive())
228 {
229 for (unsigned int j = i + 1; j < objectCount; j++)
230 {
231 if (!pFirst->IsActive()) continue;
232
233 pSecond = gameObjects[j];
234 if (pSecond->IsActive())
235 {
236 m_pCollisionManager->CheckCollision(pFirst, pSecond);
237 }
238 }
239 }
240 }
241}
242
243void Level::Draw(SpriteBatch& spriteBatch)
244{
245 spriteBatch.Begin();
246
247 const float alpha = GetGameplayScreen()->GetAlpha();
248
249 if (m_pBackground) spriteBatch.Draw(m_pBackground, Vector2::ZERO, Color::White * alpha);
250
251 m_gameObjectIt = m_gameObjects.begin();
252 for (; m_gameObjectIt != m_gameObjects.end(); m_gameObjectIt++)
253 {
254 GameObject *pGameObject = (*m_gameObjectIt);
255 pGameObject->Draw(spriteBatch);
256 }
257
258 spriteBatch.End();
259
260 // Explosions use additive blending so they need to be drawn after the main sprite batch
261 spriteBatch.Begin(SpriteSortMode::Deferred, BlendState::Additive);
262
263 m_explosionIt = s_explosions.begin();
264 for (; m_explosionIt != s_explosions.end(); m_explosionIt++)
265 {
266 (*m_explosionIt)->Draw(spriteBatch);
267 }
268
269 spriteBatch.End();
270}
void PlayerShootsEnemy(GameObject *pObject1, GameObject *pObject2)
Definition Level.cpp:12
void PlayerCollidesWithEnemy(GameObject *pObject1, GameObject *pObject2)
Definition Level.cpp:22
Represents a blaster weapon that can be fired by a game object.
Definition Blaster.h:8
Represents a collision manager that can be used to manage collisions between game objects.
virtual void CheckCollision(GameObject *pGameObject1, GameObject *pGameObject2)
Check for collisions between game objects.
virtual void AddNonCollisionType(const CollisionType type1, const CollisionType type2)
Add a non-collision type to the manager.
virtual void AddCollisionType(const CollisionType type1, const CollisionType type2, OnCollision callback)
Add a collision type to the manager.
Represents a type of collision.
static const CollisionType Projectile
static const CollisionType Ship
static const CollisionType Enemy
static const CollisionType Player
Represents an enemy ship.
Definition EnemyShip.h:8
virtual void Hit(const float damage)
Applies damage to the ship.
Definition EnemyShip.cpp:43
Represents an explosion animation in the game.
Definition Explosion.h:9
virtual void SetAnimation(Animation *pAnimation)
Sets the explosion's animation.
Definition Explosion.h:25
virtual void SetSound(AudioSample *pSound)
Set the sound that will be played when the explosion is activated.
Definition Explosion.h:38
virtual void Activate(const Vector2 position, const float scale=1)
Activates the explosion.
Definition Explosion.cpp:19
Represents a game object in the game. This is the base class for all objects that can be updated,...
Definition GameObject.h:15
static void SetCurrentLevel(Level *pLevel)
Set the current level.
Definition GameObject.h:26
virtual void Activate()
Activate the object.
Definition GameObject.h:45
virtual bool HasMask(CollisionType mask) const
Check if the object has a specific collision bit-mask.
Definition GameObject.h:89
virtual bool IsActive() const
Flag to determine if the object is active.
Definition GameObject.h:42
virtual void Deactivate()
Deactivate the object.
Definition GameObject.h:48
virtual Vector2 GetHalfDimensions() const
Get the half dimensions of the object.
virtual void Draw(SpriteBatch &spriteBatch)=0
Render the object.
virtual float GetCollisionRadius() const
Get the collision radius of the object.
Definition GameObject.h:80
virtual void Update(const GameTime &gameTime)
Update the object.
virtual Vector2 & GetPosition()
Get the position of the object.
Definition GameObject.h:52
Represents timing and framing values for texture animations.
Definition Animation.h:21
virtual void Stop()
Stops the animation.
Represents a 2D grid of texels.
Definition AudioSample.h:21
static const Color White
White.
Definition Color.h:201
static int GetScreenHeight()
Gets the screen width in pixels.
Definition Game.h:40
static int GetScreenWidth()
Gets the screen width in pixels.
Definition Game.h:36
Contains timing values for game updates and rendering.
Definition GameTime.h:21
Handles the state of multiple player input devices.
Definition InputState.h:22
static T Clamp(const T min, const T max, const T value)
Restricts a value to be within a specified range.
Definition MathUtil.h:83
Loads and manages the lifespan of objects from external files.
T * Load(const std::string &path, const bool cache=true, const bool appendContentPath=true)
Load and manage a resource.
float GetAlpha() const
Gets the overall screen transition alpha value (or opacity). This is handy for fading screens in and ...
Definition Screen.h:79
virtual void Exit()
Tells the screen to transition out. When the screen has completed its transition, UnloadContent() wil...
Definition Screen.cpp:95
Enables a group of sprites to be drawn using the same settings.
Definition SpriteBatch.h:48
void Begin(const SpriteSortMode sortMode=SpriteSortMode::Deferred, const BlendState blendState=BlendState::Alpha, ALLEGRO_TRANSFORM *pTransformation=NULL)
Begins a sprite batch operation.
void End()
Flushes the sprite batch and restores the device state to how it was before Begin was called.
void Draw(const Texture *pTexture, const Vector2 position, const Region region, const Color color=Color::White, const Vector2 origin=Vector2::ZERO, const Vector2 scale=Vector2::ONE, const float rotation=0, const float drawDepth=0)
Adds a sprite to a batch of sprites to be rendered.
Defines a vector with 2 components (x and y).
Definition Vector2.h:21
float Y
The y-coordinate of the vector.
Definition Vector2.h:187
static const Vector2 UNIT_Y
A unit vector on the y-axis.
Definition Vector2.h:34
static const Vector2 ZERO
A vector with both of its components set to zero.
Definition Vector2.h:31
float X
The x-coordinate of the vector.
Definition Vector2.h:186
virtual ~Level()
Definition Level.cpp:75
virtual void AddGameObject(GameObject *pGameObject)
Add a game object to the level. This object will be updated, rendered, and checked for collisions.
Definition Level.h:46
virtual void SpawnExplosion(GameObject *pExplodingObject)
Spawn an explosion at a specific position.
Definition Level.cpp:188
virtual GameplayScreen * GetGameplayScreen() const
Get a pointer to the gameplay screen.
Definition Level.h:121
Level()
Instantiate a level object.
Definition Level.cpp:32
virtual void Draw(SpriteBatch &spriteBatch)
Render the level, and all of the game objects within it.
Definition Level.cpp:243
virtual void LoadContent(ResourceManager &resourceManager)
Load the content for the level, including game objects and resources.
Definition Level.cpp:88
virtual bool IsScreenTransitioning() const
Check if the screen is transitioning.
Definition Level.h:71
virtual void Update(const GameTime &gameTime)
Update the level.
Definition Level.cpp:118
virtual float GetAlpha() const
Get the alpha value of the screen.
Definition Level.cpp:212
virtual CollisionManager * GetCollisionManager()
Get a pointer to the collision manager.
Definition Level.h:117
virtual void UpdateSectorPosition(GameObject *pGameObject)
Update the position of a game object within the level, based on its collision sector (only objects wi...
Definition Level.cpp:153
virtual void HandleInput(const InputState &input)
Handle input for the level.
Definition Level.cpp:110
Represents the player's ship.
Definition PlayerShip.h:8
virtual void HandleInput(const InputState &input)
Handles input for the player ship.
virtual void LoadContent(ResourceManager &resourceManager)
Loads the content for the player ship.
Definition PlayerShip.cpp:5
Represents a projectile that can be fired by a weapon.
Definition Projectile.h:9
virtual float GetDamage() const
Get the amount of damage the projectile will deal.
Definition Projectile.h:36
virtual void Hit(const float damage)
Applies damage to the ship.
Definition Ship.cpp:26
virtual void AttachItem(IAttachment *item, Vector2 position)
Attaches a weapon to the ship.
Definition Ship.cpp:83
virtual void SetProjectilePool(std::vector< Projectile * > *pProjectiles)
Set the pool of projectiles that the weapon can fire.
Definition Weapon.h:58