-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLevel.cpp
More file actions
145 lines (129 loc) · 4.63 KB
/
Level.cpp
File metadata and controls
145 lines (129 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "precomp.h"
#include "Enemy.h"
#include "Ballom.h"
#include "Onil.h"
#include "Dall.h"
#include "Minvo.h"
#include "Ovapi.h"
#include "Kondoria.h"
#include "Parse.h"
#include "Pontan.h"
#include "Level.h"
#include "game.h"
LevelData* Level::currentLevelData = nullptr;
void Level::Init(Game* const game, const LevelData* const data) {
ASSERT(game != nullptr, "Game cannot be null\n");
m_game = game;
m_data = data;
}
void Level::LoadFromData(const LevelData* const data) {
m_data = data;
m_isTimeOver = false;
m_powerupFound = false;
m_doorFound = false;
m_bonusItemFound = false;
m_chainReactionsNum = 0;
m_doorExplosionsNum = 0;
m_timer.reset();
m_gameobjects.Reset(MAX_GAMEOBJECTS);
m_gameobjectsCount = 0;
m_game->m_bonusItemManager.OnLevelChanged();
m_players.Clear();
m_players.ForceAlloc(m_game->m_playerNum);
if (m_game->IsSinglePlayer()) {
Player* player = new Player(m_game, m_game->m_sheet.GetSpriteWithID(PLAYER_IDLE_1), float2(3 * HALF_TILE_WIDTH, 3 * HALF_TILE_HEIGHT));
m_players[0] = player;
player->InitControls(KeyCode::W, KeyCode::S, KeyCode::D, KeyCode::A, KeyCode::X, KeyCode::B);
player->InitCamera(Camera(
int2(0, 0),
int2(SCRWIDTH / 2, CAMERAHEIGHT / 2),
int2(SCRWIDTH, CAMERAHEIGHT)));
AddGameobject(player);
}
else {
Player* player1 = new Player(m_game, m_game->m_sheet.GetSpriteWithID(PLAYER_IDLE_1), float2(3 * HALF_TILE_WIDTH, 3 * HALF_TILE_HEIGHT));
m_players[0] = player1;
player1->InitControls(KeyCode::W, KeyCode::S, KeyCode::D, KeyCode::A, KeyCode::X, KeyCode::B);
player1->InitCamera(Camera(
int2(0, 0),
int2(SCRWIDTH / 4, CAMERAHEIGHT / 2),
int2(CAMERAWIDTH, CAMERAHEIGHT)));
AddGameobject(player1);
Player* player2 = new Player(m_game, m_game->m_sheet.GetSpriteWithID(PLAYER_IDLE_1), float2(7 * HALF_TILE_WIDTH, 3 * HALF_TILE_HEIGHT));
m_players[1] = player2;
player2->InitControls(KeyCode::Up, KeyCode::Down, KeyCode::Right, KeyCode::Left, KeyCode::Slash, KeyCode::Period);
player2->InitCamera(Camera(
int2(0, 0),
int2(3 * SCRWIDTH / 4, CAMERAHEIGHT / 2),
int2(CAMERAWIDTH, CAMERAHEIGHT)));
AddGameobject(player2);
}
m_softBlocksDestroyed = 0;
m_softBlocksLeft = 0;
m_enemiesLeft = 0;
m_enemiesKilled = 0;
m_game->m_map.Clear();
if (m_data->m_isBonus) {
Player::IS_INVINCIBLE = true;
m_timeLeft = MAX_BONUS_TIME;
}
else {
m_game->m_map.GenerateWalls();
Player::IS_INVINCIBLE = false;
m_timeLeft = MAX_TIME;
}
for (int i{ 0 }; i < m_data->m_enemyDiversity; i++) {
const LevelData::EnemyData& enemyData{ m_data->m_enemies[i] };
for (int e{ 0 }; e < enemyData.amount; e++) {
SpawnEnemyRandomPos(enemyData.type);
}
}
}
void Level::AddGameobject(Gameobject* const gameobject) {
ASSERT_VAR(m_gameobjectsCount, m_gameobjectsCount < MAX_GAMEOBJECTS, "Gameobject count surpassed max gameobjects count\n");
m_gameobjects[m_gameobjectsCount] = gameobject;
m_gameobjectsCount++;
}
Enemy* Level::SpawnEnemyRandomPos(EnemyType type) {
return SpawnEnemy(type, m_game->m_map.GetRandomSpawnableTileGrid());
}
Enemy* Level::SpawnEnemy(EnemyType type, int2 gridpos) {
if (!SPAWN_ENEMIES) return nullptr;
float2 position{ Map::GridToWorld(gridpos) };
Sprite* sprite{ m_game->m_sheet.GetSpriteWithID(0) };
Enemy* result{ nullptr };
switch (type) {
case EnemyType::Ballom: result = new Ballom(m_game, sprite, position); break;
case EnemyType::Onil: result = new Onil(m_game, sprite, position); break;
case EnemyType::Dall: result = new Dall(m_game, sprite, position); break;
case EnemyType::Minvo: result = new Minvo(m_game, sprite, position); break;
case EnemyType::Ovapi: result = new Ovapi(m_game, sprite, position); break;
case EnemyType::Kondoria: result = new Kondoria(m_game, sprite, position); break;
case EnemyType::Parse: result = new Parse(m_game, sprite, position); break;
case EnemyType::Pontan: result = new Pontan(m_game, sprite, position); break;
default:
THROW("Enemy of this type cannot be spawned: type is invalid\n");
break;
}
ASSERT(result != nullptr, "Enemy could not be spawned\n");
AddGameobject(result);
OnEnemySpawned();
return result;
}
void Level::SpawnBonusItem(BonusItem item) {
const int2 gridpos{ m_game->m_map.GetRandomEmptyTileGrid() };
m_game->m_map.m_layers[Map::WALLS_LAYER_INDEX].SetTileAtGridPosition(gridpos, item);
}
void Level::OnSoftBlockDestroyed() {
m_softBlocksDestroyed++;
m_softBlocksLeft--;
ASSERT_VAR(m_softBlocksLeft, m_softBlocksLeft >= 0, "Soft blocks number cannot be negative\n");
}
void Level::OnEnemyKilled() {
m_enemiesKilled++;
m_enemiesLeft--;
ASSERT_VAR(m_enemiesLeft, m_enemiesLeft >= 0, "Enemies number cannot be negative\n");
}
void Level::OnEnemySpawned() {
m_enemiesLeft++;
}