Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F130096
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
36 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/Game.cpp b/src/Game.cpp
index 254a428..d09477e 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,160 +1,159 @@
//
// Created by Ido Mozes on 18/06/2019.
//
#include <array>
#include "Game.h"
using namespace boost::filesystem;
Game::Game(bool fullscreen, float mapScale) {
gameData.mapScale = mapScale;
gameData.fullscreen = fullscreen;
path p = path("../assets/Bloons");
directory_iterator it{p};
for (auto &p :it) {
gameData.assets[p.path().filename().string().substr(0, p.path().filename().string().length() - 4)] = IMG_Load(
p.path().string().c_str());
}
p = path("../assets/Sprites");
it = directory_iterator{p};
for (auto &p :it) {
gameData.assets[p.path().filename().string().substr(0, p.path().filename().string().length() - 4)] = IMG_Load(
p.path().string().c_str());
}
gameData.assets["map"] = IMG_Load("../assets/map0.jpg");
gameData.assets["upgrade_bar"] = IMG_Load("../assets/upgrade_bar.jpg");
gameData.assets["upgrade_bar2"] = IMG_Load("../assets/upgrade_bar2.jpg");
gameData.assets["menu"] = IMG_Load("../assets/menu.jpg");
renderSystem = new RenderSystem();
renderSystem->init(gameData);
loadMap();
std::initializer_list<std::pair<std::string, Point>> sprites[]{
{{"map", {SIDEBAR_WIDTH, 0}}},
{},
{},
{},
{},
{},
{{"upgrade_bar", {0, 0}}, {"menu", {MAP_WIDTH + SIDEBAR_WIDTH, 0}}},
};
for (int i = 0; i < N_LAYERS; i++) {
for (auto &sprite :sprites[i]) {
auto spriteEntity = new Entity();
spriteEntity->addComponent<Visibility>(gameData.renderer, gameData.assets[sprite.first],
SDL_Rect{int(sprite.second.X), int(sprite.second.Y),
gameData.assets[sprite.first]->w,
gameData.assets[sprite.first]->h});
layers[i].emplace_back(spriteEntity);
}
}
// Towers
auto tower = new Entity();
tower->addComponent<Kind>(SUPER_MONKEY);
tower->addComponent<ShotKind>(DART);
SDL_Surface *surface = gameData.assets["SuperMonkey"];
tower->addComponent<Visibility>(gameData.renderer, surface,
SDL_Rect{SIDEBAR_WIDTH + MAP_WIDTH + 10, 10, int(surface->w / 1.5), 0});
tower->addComponent<Action>(DRAG);
tower->addComponent<Range>(100);
tower->addComponent<AttackSpeed>(30);
tower->addComponent<Pierce>(4);
tower->addComponent<Damage>(21);
tower->addComponent<Distance>(150);
tower->addComponent<Type>(TOWER_T);
layers[MENU_LAYER].emplace_back(tower);
-
tower = new Entity();
tower->addComponent<Kind>(SNIPER_MONKEY);
tower->addComponent<ShotKind>(DART);
surface = gameData.assets["SniperMonkey"];
tower->addComponent<Visibility>(gameData.renderer, surface,
SDL_Rect{SIDEBAR_WIDTH + MAP_WIDTH + 100, 10, int(surface->w / 1.5), 0});
tower->addComponent<Action>(DRAG);
tower->addComponent<Range>(100);
tower->addComponent<AttackSpeed>(6);
tower->addComponent<Pierce>(5);
tower->addComponent<Damage>(1);
tower->addComponent<Distance>(300);
tower->addComponent<Type>(TOWER_T);
layers[MENU_LAYER].emplace_back(tower);
// Sequences
auto s = new Entity();
s->addComponent<Sequence>(1, 1, 0);
s->addComponent<Kind>(BAD);
s->addComponent<Type>(SEQUENCE_T);
layers[SEQUENCES_LAYER].emplace_back(s);
// s = new Entity();
// s->addComponent<Sequence>(100, 20.2, 60 * 5);
// s->addComponent<Kind>(std::string("Blue"));
// s->addComponent<Type>(SEQUENCE_T);
// s->addComponent<Speed>(1.5);
// layers[SEQUENCES_LAYER].emplace_back(s);
// Systems
systems.emplace_back(new BloonsSpawnSystem);
systems.emplace_back(new ShotsSpawnSystem);
systems.emplace_back(new EventSystem);
systems.emplace_back(new DraggingSystem);
systems.emplace_back(new CollisionSystem);
systems.emplace_back(new DamageSystem);
systems.emplace_back(new MovementSystem);
systems.emplace_back(new RemoveEntitiesSystem);
systems.emplace_back(renderSystem);
}
Game::~Game() {
SDL_Quit();
}
void Game::update() {
for (auto &system : systems) {
system->update(layers, gameData);
}
}
void Game::loadMap() {
std::string fileName = "../assets/map" + std::to_string(gameData.map);
std::ifstream obstaclesFile(fileName + "_obstacles.data", std::ios::binary);
int x = 0, y = 0;
for (int i = 0; i < ceilf(MAP_WIDTH * MAP_HEIGHT / 8.0); ++i) {
unsigned char byte;
obstaclesFile.read((char *) &byte, 1);
for (int j = 0; j < 8; ++j) {
char bit = (byte & 2 << j) >> j;
gameData.mapData[x][y] = bit;
x++;
if (x == MAP_WIDTH) {
x = 0;
y++;
}
if (x * y >= MAP_WIDTH * MAP_HEIGHT)
goto readPathFile;
}
}
readPathFile:
gameData.path.clear();
std::ifstream pathFile(fileName + "_path.data", std::ios::binary);
unsigned int length;
TempPoint startingPoint, finishPoint;
pathFile.read((char *) &startingPoint, 4);
pathFile.read((char *) &length, 4);
gameData.path.resize(length);
pathFile.read(&gameData.path[0], length);
pathFile.read((char *) &finishPoint, 4);
gameData.startingPoint = {float(startingPoint.X), float(startingPoint.Y)};
gameData.finishPoint = {float(finishPoint.X), float(finishPoint.Y)};
}
diff --git a/src/main.cpp b/src/main.cpp
index d34bc8e..b45fc7a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,21 +1,21 @@
//#include <iostream>
#include "SDL.h"
#include "Game.h"
int main(int argc, char *argv[]) {
- const int FPS = 120, frameDelay = 1000 / FPS;
+ const int FPS = 200, frameDelay = 1000 / FPS;
Uint32 frameStart;
int frameTime;
- Game game(false, 2);
+ Game game(false, 1.5);
while (game.running()) {
frameStart = SDL_GetTicks();
game.update();
frameTime = SDL_GetTicks() - frameStart;
if (frameDelay > frameTime) {
SDL_Delay(frameDelay - frameTime);
}
}
return 0;
}
\ No newline at end of file
diff --git a/src/systems/BloonsSpawnSystem.cpp b/src/systems/BloonsSpawnSystem.cpp
index d03401d..eff590d 100644
--- a/src/systems/BloonsSpawnSystem.cpp
+++ b/src/systems/BloonsSpawnSystem.cpp
@@ -1,35 +1,35 @@
//
// Created by Ido Mozes on 07/07/2019.
//
#include "BloonsSpawnSystem.h"
void BloonsSpawnSystem::update(Entities *layers, GameData &gameData) {
for (auto &entity: layers[SEQUENCES_LAYER]) {
auto[sequence, kind] = entity->getComponents<Sequence, Kind>().value();
auto [regrowP,camoP,fortifiedP] = entity->getComponentsP<Regrow,Camo,Fortified>();
int amount = sequence.getAmountReady();
for (int j = 0; j < amount; ++j) {
EntityP bloon(new Entity());
bloon->addComponent<Type>(BLOON_T);
bloon->addComponent<Position>(gameData.startingPoint);
bloon->addComponent<PathIndex>(0);
bloon->addComponents(kind);
if (regrowP)
bloon->addComponent<Regrow>();
if (camoP)
bloon->addComponent<Camo>();
if (fortifiedP)
bloon->addComponent<Fortified>();
bloon->addComponent<Lives>(getLives<TOTAL_LIVES>(bloon));
SDL_Surface *surface = gameData.assets[getSurfaceName(bloon)];
bloon->addComponent<Visibility>(gameData.renderer, surface,
SDL_Rect{0, 0, int(surface->w / 3), int(surface->h / 3)});
- bloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
+ bloon->addComponent<Range>(std::min(surface->w / 6, surface->h / 6));
layers[BLOONS_LAYER].emplace_back(bloon);
}
}
}
diff --git a/src/systems/DamageSystem.cpp b/src/systems/DamageSystem.cpp
index 9015ddb..edd7b9a 100644
--- a/src/systems/DamageSystem.cpp
+++ b/src/systems/DamageSystem.cpp
@@ -1,415 +1,419 @@
//
// Created by Ido Mozes on 15/07/2019.
//
#include "DamageSystem.h"
bool didBloonPop(EntityP &bloon, int &lives, int &damage) {
if (bloon->getComponent<Fortified>()) {
if (damage == 1) {
lives -= damage;
if (lives % 2 == 1)
return false;
} else {
lives -= 2;
damage -= 2;
}
} else {
lives -= 1;
damage -= 1;
}
return true;
}
bool didBloonPop(EntityP &bloon, int &lives, int &damage, int minLives) {
if (lives - damage >= minLives) {
lives -= damage;
return false;
}
damage -= lives - minLives + 1;
lives = minLives - 1;
return true;
}
void damageBloon(EntityP &bloon, EntityP &shot, int damage, GameData &gameData, Entities &newBloons) {
if (damage == 0)
return;
auto &lives = bloon->getComponent<Lives>()->value;
if (damage >= lives) {
bloon->addComponent<RemoveEntityEvent>();
return;
}
auto &kind = bloon->getComponent<Kind>()->value;
auto &visibility = *bloon->getComponent<Visibility>();
auto[regrowP, camoP, fortifiedP, glueP, gumP, corrosiveP] = bloon->getComponentsP<Regrow, Camo, Fortified, Glue, Gum, Corrosive>();
SDL_Surface *surface;
switch (kind) {
case RED_BLOON:
lives -= damage;
break;
case BLUE_BLOON:
case GREEN_BLOON:
case YELLOW_BLOON:
case PINK_BLOON: {
lives -= damage;
if (fortifiedP and damage == 1 and lives % 2 == 1)
break;
kind = (fortifiedP ? lives / 2 : lives) - 1;
surface = gameData.assets[getSurfaceName(bloon)];
visibility.setDstRect(SDL_Rect{0, 0, surface->w / 3, 0});
visibility.loadTexture(gameData.renderer, surface);
bloon->getComponent<Range>()->value = std::max(surface->w / 6, surface->h / 6);
break;
}
case PURPLE_BLOON:
case WHITE_BLOON:
case BLACK_BLOON: {
if (!didBloonPop(bloon, lives, damage))
break;
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 2; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(PINK_BLOON);
newBloon->addComponent<Lives>(lives / 2);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i == 0 ? std::fmaxf(0, pathIndex.progress - 10) : std::fminf(gameData.path.size() - 1,
pathIndex.progress + 10);
if (regrowP)
newBloon->addComponent<Regrow>();
if (camoP)
newBloon->addComponent<Camo>();
if (gumP)
newBloon->addComponent<Gum>();
else if (glueP)
newBloon->addComponent<Glue>();
else if (corrosiveP)
newBloon->addComponent<Corrosive>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 2.0) : floorf(damage / 2.0), gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
}
case ZEBRA_BLOON: {
if (!didBloonPop(bloon, lives, damage))
break;
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 2; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(i == 0 ? BLACK_BLOON : WHITE_BLOON);
newBloon->addComponent<Lives>(lives / 2);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i == 0 ? std::fmaxf(0, pathIndex.progress - 10) : std::fminf(gameData.path.size() - 1,
pathIndex.progress + 10);
if (regrowP)
newBloon->addComponent<Regrow>();
if (camoP)
newBloon->addComponent<Camo>();
if (gumP)
newBloon->addComponent<Gum>();
else if (glueP)
newBloon->addComponent<Glue>();
else if (corrosiveP)
newBloon->addComponent<Corrosive>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 2.0) : floorf(damage / 2.0), gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
}
case LEAD_BLOON: {
if (!didBloonPop(bloon, lives, damage))
break;
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 2; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(BLACK_BLOON);
newBloon->addComponent<Lives>(lives / 2);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i == 0 ? std::fmaxf(0, pathIndex.progress - 10) : std::fminf(gameData.path.size() - 1,
pathIndex.progress + 10);
if (regrowP)
newBloon->addComponent<Regrow>();
if (camoP)
newBloon->addComponent<Camo>();
if (gumP)
newBloon->addComponent<Gum>();
else if (glueP)
newBloon->addComponent<Glue>();
else if (corrosiveP)
newBloon->addComponent<Corrosive>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 2.0) : floorf(damage / 2.0), gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
}
case RAINBOW_BLOON: {
if (!didBloonPop(bloon, lives, damage))
break;
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 2; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(ZEBRA_BLOON);
newBloon->addComponent<Lives>(lives / 2);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i == 0 ? std::fmaxf(0, pathIndex.progress - 10) : std::fminf(gameData.path.size() - 1,
pathIndex.progress + 10);
if (regrowP)
newBloon->addComponent<Regrow>();
if (camoP)
newBloon->addComponent<Camo>();
if (gumP)
newBloon->addComponent<Gum>();
else if (glueP)
newBloon->addComponent<Glue>();
else if (corrosiveP)
newBloon->addComponent<Corrosive>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 2.0) : floorf(damage / 2.0), gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
}
case CERAMIC_BLOON: {
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 2; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(RAINBOW_BLOON);
newBloon->addComponent<Lives>(lives / 2);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i == 0 ? std::fmaxf(0, pathIndex.progress - 10) : std::fminf(gameData.path.size() - 1,
pathIndex.progress + 10);
if (regrowP)
newBloon->addComponent<Regrow>();
if (camoP)
newBloon->addComponent<Camo>();
if (gumP)
newBloon->addComponent<Gum>();
else if (glueP)
newBloon->addComponent<Glue>();
else if (corrosiveP)
newBloon->addComponent<Corrosive>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 2.0) : floorf(damage / 2.0), gameData,
newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
case MOAB: {
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 4; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(CERAMIC_BLOON);
newBloon->addComponent<Lives>(lives / 4);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i < 2 ? std::fmaxf(0, pathIndex.progress - 20 + 10 * (i % 2)) : std::fminf(
gameData.path.size() - 1, pathIndex.progress + 20 - 10 * (i % 2));
if (fortifiedP)
newBloon->addComponent<Fortified>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 4.0) : damage - ceilf(damage / 4.0) * 3,
gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
case BFB:{
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 4; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(MOAB);
newBloon->addComponent<Lives>(lives / 4);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i < 2 ? std::fmaxf(0, pathIndex.progress - 20 + 10 * (i % 2)) : std::fminf(
gameData.path.size() - 1, pathIndex.progress + 20 - 10 * (i % 2));
if (fortifiedP)
newBloon->addComponent<Fortified>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 4.0) : damage - ceilf(damage / 4.0) * 3,
gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
case DDT:{
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 4; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(CERAMIC_BLOON);
newBloon->addComponent<Lives>(lives / 4);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i < 2 ? std::fmaxf(0, pathIndex.progress - 20 + 10 * (i % 2)) : std::fminf(
gameData.path.size() - 1, pathIndex.progress + 20 - 10 * (i % 2));
if (fortifiedP)
newBloon->addComponent<Fortified>();
+ newBloon->addComponent<Regrow>();
+ newBloon->addComponent<Camo>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 4.0) : damage - ceilf(damage / 4.0) * 3,
gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
case ZOMG:{
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 4; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
newBloon->addComponent<Kind>(BFB);
newBloon->addComponent<Lives>(lives / 4);
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i < 2 ? std::fmaxf(0, pathIndex.progress - 20 + 10 * (i % 2)) : std::fminf(
gameData.path.size() - 1, pathIndex.progress + 20 - 10 * (i % 2));
if (fortifiedP)
newBloon->addComponent<Fortified>();
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 4.0) : damage - ceilf(damage / 4.0) * 3,
gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
case BAD:{
if (didBloonPop(bloon, lives, damage, getLives<MIN_LIVES>(bloon))) {
auto &pathIndex = *bloon->getComponent<PathIndex>();
for (int i = 0; i < 5; ++i) {
EntityP newBloon(new Entity());
shot->getComponent<PoppedBloons>()->value.emplace(newBloon.get());
newBloon->addComponent<Type>(BLOON_T);
- newBloon->addComponent<Kind>(i<3?ZOMG:DDT);
+ newBloon->addComponent<Kind>(i<2?ZOMG:DDT);
if (fortifiedP)
newBloon->addComponent<Fortified>();
+ if(i>=2)
+ newBloon->addComponent<Camo>();
newBloon->addComponent<Lives>(getLives<TOTAL_LIVES>(newBloon));
newBloon->addComponent<Position>(gameData.startingPoint);
newBloon->addComponent<PathIndex>(0);
newBloon->getComponent<PathIndex>()->progress =
i < 2 ? std::fmaxf(0, pathIndex.progress - 20 + 10 * (i % 2)) : std::fminf(
- gameData.path.size() - 1, pathIndex.progress + 20 - 10 * (i % 2));
+ gameData.path.size() - 1, pathIndex.progress + 30 - 10 * (i % 3));
surface = gameData.assets[getSurfaceName(newBloon)];
newBloon->addComponent<Range>(std::max(surface->w / 6, surface->h / 6));
newBloon->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{0, 0, surface->w / 3, 0});
newBloons.emplace_back(newBloon);
- damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 4.0) : damage - ceilf(damage / 4.0) * 3,
+ damageBloon(newBloon, shot, i == 0 ? ceilf(damage / 5.0) : damage - ceilf(damage / 5.0) * 4,
gameData, newBloons);
}
bloon->addComponent<RemoveEntityEvent>();
break;
} else {
surface = gameData.assets[getSurfaceName(bloon)];
visibility.loadTexture(gameData.renderer, surface);
}
break;
}
}
}
void DamageSystem::update(Entities *layers, GameData &gameData) {
Entities newBloons;
for (auto &bloon: layers[BLOONS_LAYER]) {
if (auto damageEventP = bloon->getComponent<DamageEvent>()) {
auto &damageEvent = *damageEventP;
auto &lives = bloon->getComponent<Lives>()->value;
if (lives < damageEvent.damage)
bloon->addComponent<RemoveEntityEvent>();
else {
damageBloon(bloon, damageEvent.shot, damageEvent.damage, gameData, newBloons);
bloon->removeComponent<DamageEvent>();
}
}
}
layers[BLOONS_LAYER] += newBloons;
}
diff --git a/src/systems/MovementSystem.cpp b/src/systems/MovementSystem.cpp
index 738f03d..6b1942f 100644
--- a/src/systems/MovementSystem.cpp
+++ b/src/systems/MovementSystem.cpp
@@ -1,86 +1,95 @@
//
// Created by Ido Mozes on 02/07/2019.
//
#include "MovementSystem.h"
+enum Directions {
+ RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT, TOP_LEFT, TOP, TOP_RIGHT
+};
+
+std::tuple<int, int> getDelta(int direction) {
+ switch (direction) {
+ case RIGHT:
+ return std::make_tuple(1, 0);
+ case BOTTOM_RIGHT:
+ return std::make_tuple(1, 1);
+ case BOTTOM:
+ return std::make_tuple(0, 1);
+ case BOTTOM_LEFT:
+ return std::make_tuple(-1, 1);
+ case LEFT:
+ return std::make_tuple(-1, 0);
+ case TOP_LEFT:
+ return std::make_tuple(-1, -1);
+ case TOP:
+ return std::make_tuple(0, -1);
+ case TOP_RIGHT:
+ return std::make_tuple(1, -1);
+ default:
+ return std::make_tuple(0, 0);
+ }
+}
void MovementSystem::update(Entities *layers, GameData &gameData) {
for (int i = 0; i < N_LAYERS; ++i) {
for (auto &entity: layers[i]) {
// Move all entities with Visibility and Position
if (auto components = entity->getComponents<Visibility, Position>()) {
auto[visibility, position]=components.value();
float deltaX = 0, deltaY = 0;
if (auto velocityP = entity->getComponent<Velocity>()) {
auto &velocity = *velocityP;
if (auto accelerationP = entity->getComponent<Acceleration>()) {
auto &acceleration = *accelerationP;
velocity.changeVelocity(acceleration.value.X, acceleration.value.Y);
}
deltaX = velocity.value.X;
deltaY = velocity.value.Y;
if (auto distanceP = entity->getComponent<Distance>()) {
auto &distance = distanceP->value;
auto[alpha, R] = cartesianToPolar(deltaX, deltaY);
if (distance == 0) {
entity->addComponent<RemoveEntityEvent>();
} else if (distance >= R) {
distance -= R;
} else {
std::tie(deltaX, deltaY) = polarToCartesian(alpha, distance);
distance = 0;
}
}
} else if (auto pathIndexP = entity->getComponent<PathIndex>()) {
- auto &pathIndex =*pathIndexP;
+ auto &pathIndex = *pathIndexP;
pathIndex.progress += getSpeed(entity);
float deltaIndex = pathIndex.progress - pathIndex.index;
- while (deltaIndex >= (gameData.path[pathIndex.index] % 2 == 0 ? 1 : sqrt(2))) {
- switch (gameData.path[pathIndex.index]) {
- case 0:
- deltaX += 1;
- break;
- case 1:
- deltaX += 1;
- deltaY += 1;
- break;
- case 2:
- deltaY += 1;
- break;
- case 3:
- deltaX += -1;
- deltaY += 1;
- break;
- case 4:
- deltaX += -1;
- break;
- case 5:
- deltaX += -1;
- deltaY += -1;
- break;
- case 6:
- deltaY += -1;
- break;
- case 7:
- deltaX += 1;
- deltaY += -1;
- break;
+ if(entity->getComponent<Kind>()->value>=MOAB) {
+ float angle = 0;
+ Point tempPosition = position.value;
+ for (int j = std::max(0,pathIndex.index-10);
+ j < std::min(pathIndex.index + 10, int(gameData.path.size() - 1)); ++j) {
+ auto[tempDeltaX, tempDeltaY] = getDelta(gameData.path[j]);
+ tempPosition.X += tempDeltaX;
+ tempPosition.Y += tempDeltaY;
}
+ angle = radToDeg(twoPointsAngle( position.value,tempPosition));
+ visibility.angle=angle;
+ }
+ while (deltaIndex >= (gameData.path[pathIndex.index] % 2 == 0 ? 1 : sqrt(2))) {
+ auto[tempDeltaX, tempDeltaY] = getDelta(gameData.path[pathIndex.index]);
+ deltaX += tempDeltaX;
+ deltaY += tempDeltaY;
deltaIndex -= (gameData.path[pathIndex.index] % 2 == 0 ? 1 : sqrt(2));
if (pathIndex.index < gameData.path.size() - 1)
pathIndex.index++;
-
-
}
}
position.changePosition(deltaX, deltaY);
if (position.value.X > MAP_WIDTH or position.value.X < 0 or position.value.Y > MAP_HEIGHT or
position.value.Y < 0) {
entity->addComponent<RemoveEntityEvent>();
}
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jun 15, 11:23 PM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71930
Default Alt Text
(36 KB)
Attached To
Mode
R74 BloonsTD
Attached
Detach File
Event Timeline