-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdynscene.cpp
168 lines (152 loc) · 5.31 KB
/
dynscene.cpp
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "dynscene.hpp"
#include "constants.hpp"
#include "player.hpp"
#include "consumable.hpp"
#include "enemy.hpp"
#include "utils.hpp"
#include "textures.hpp"
const int MAX_DYNAMIC_OBJECTS_ON_SCENE = 10;
const int MAX_ENEMY_OBJECTS_ON_SCENE = 4;
const int NEW_DYNAMIC_OBJECT_PROB = 1;
const int NEW_ENEMY_OBJECT_PROB = 10;
GameplayDynamicScene::GameplayDynamicScene() : Scene(SCENE_WIDTH, SCENE_HEIGHT) {}
void GameplayDynamicScene::activate() {
addNewGameObject(GameObjectKind::PLAYER);
}
void GameplayDynamicScene::deactivate() {
// remove all the objects from the list
objects.remove([&] (const GameObject& object) {
return true;
});
}
SceneID GameplayDynamicScene::getID() const {
return SceneID::DYNAMIC_GAME_FIELD;
}
SceneID GameplayDynamicScene::getNextSceneID() const {
return SceneID::DYNAMIC_GAME_FIELD;
// TODO: write your solution here
}
void GameplayDynamicScene::processEvent(const sf::Event& event) {
return;
}
void GameplayDynamicScene::update(sf::Time delta) {
// update the objects' state
objects.foreach([delta] (GameObject& object) {
object.update(delta);
});
// move objects according to their velocity and elapsed time
objects.foreach([this, delta] (GameObject& object) {
move(object, delta);
});
// compute collision information for each pair of objects
objects.foreach([this] (GameObject& object) {
objects.foreach([this, &object] (GameObject& other) {
if (&object != &other) {
detectCollision(object, other);
}
});
});
updateScore();
// update the list of objects
updateObjectsList();
}
void GameplayDynamicScene::updateObjectsList() {
// remove destroyed objects from the list
objects.remove([] (const GameObject& object) {
return (object.getStatus() == GameObjectStatus::DESTROYED)
&& (object.getKind() != GameObjectKind::PLAYER);
});
// count the number of the different kinds of objects present on the scene
int consumableCount = 0;
int enemyCount = 0;
objects.foreach([&] (const GameObject& object) {
switch (object.getKind()) {
case GameObjectKind::CONSUMABLE:
++consumableCount;
break;
case GameObjectKind::ENEMY:
++enemyCount;
break;
default:
break;
}
});
// add new objects of randomly chosen kind if there is enough room for them on the scene
int dynamicObjectsCount = consumableCount + enemyCount;
if (dynamicObjectsCount < MAX_DYNAMIC_OBJECTS_ON_SCENE) {
int r = rand() % 100;
int k = rand() % 100;
if (r < NEW_DYNAMIC_OBJECT_PROB) {
if (k < NEW_ENEMY_OBJECT_PROB && enemyCount < MAX_ENEMY_OBJECTS_ON_SCENE) {
addNewGameObject(GameObjectKind::ENEMY);
} else if (k > NEW_ENEMY_OBJECT_PROB) {
addNewGameObject(GameObjectKind::CONSUMABLE);
}
}
}
}
std::shared_ptr<GameObject> GameplayDynamicScene::addNewGameObject(GameObjectKind kind) {
std::shared_ptr<GameObject> object;
while (!object) {
// create an object with default position
switch (kind) {
case GameObjectKind::PLAYER: {
object = std::make_shared<PlayerObject>();
player = std::dynamic_pointer_cast<PlayerObject>(object);
break;
}
case GameObjectKind::CONSUMABLE: {
object = std::make_shared<ConsumableObject>();
break;
}
case GameObjectKind::ENEMY: {
object = std::make_shared<EnemyObject>();
break;
}
}
// set random position for consumable and enemy objects
if (kind == GameObjectKind::CONSUMABLE ||
kind == GameObjectKind::ENEMY) {
setObjectPosition(*object, generatePoint(getBoundingBox()));
} else {
fitInto(*object);
}
// check that object does not collide with existing objects
bool collide = false;
objects.foreach([&collide, &object](GameObject& other) {
collide |= collisionInfo(*object, other).collide;
});
// reset a colliding object
if (collide) {
object = nullptr;
}
}
objects.insert(object);
return object;
}
void GameplayDynamicScene::draw(sf::RenderWindow &window, TextureManager& textureManager) {
// draw background
drawBackground(window, textureManager.getTexture(GameTextureID::SPACE));
// draw all objects on the scene
objects.foreach([&] (const GameObject& object) {
object.draw(window, textureManager);
});
// draw player's score
drawScore(window, player->getScore());
}
void GameplayDynamicScene::drawScore(sf::RenderWindow &window, unsigned int value) const {
sf::Text text;
sf::Font font = TextureManager::getFont();
text.setFont(font);
text.setString("Score: " + std::to_string(value));
text.setCharacterSize(20);
text.setFillColor(sf::Color::White);
text.setPosition(SCENE_WIDTH - 160, 0); // top right corner
window.draw(text);
}
void GameplayDynamicScene::updateScore() {
// TODO: write your solution here
}
unsigned int GameplayDynamicScene::getScore() const {
return score;
}