Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b53919..1372c3c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.14)
project(SDL_Game)
set(CMAKE_CXX_STANDARD 17)
include_directories(include)
find_package(Boost REQUIRED COMPONENTS filesystem)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(lib)
link_libraries(mingw32 SDL2main SDL2 SDL2_image SDL2_gfx)
-add_executable(SDL_Game src/main.cpp src/Game.cpp src/Game.h src/Entity.h src/Component.h src/System.h src/systems/RenderSystem.cpp src/systems/RenderSystem.h src/components/Visibility.cpp src/components/Visibility.h src/components/Velocity.cpp src/components/Velocity.h src/systems/MovementSystem.cpp src/systems/MovementSystem.h src/components/Position.h src/components/PathIndex.h src/GameData.h src/components/Speed.h src/components/Sequence.cpp src/components/Sequence.h src/components/Kind.h src/systems/SpawnSystem.cpp src/systems/SpawnSystem.h src/GameData.cpp src/components/Action.h src/systems/EventSystem.cpp src/systems/EventSystem.h src/components/Draggable.h src/systems/DraggingSystem.cpp src/systems/DraggingSystem.h src/Settings.h src/components/Type.h src/systems/RemoveEntitiesSystem.cpp src/systems/RemoveEntitiesSystem.h src/eventComponents/RemoveEntityEvent.h src/eventComponents/MoveEntityEvent.h src/systems/HandleMoveEntitiySystem.cpp src/systems/HandleMoveEntitiySystem.h src/components/Range.h)
+add_executable(SDL_Game src/main.cpp src/Game.cpp src/Game.h src/Entity.h src/Component.h src/System.h src/systems/RenderSystem.cpp src/systems/RenderSystem.h src/components/Visibility.cpp src/components/Visibility.h src/components/Velocity.cpp src/components/Velocity.h src/systems/MovementSystem.cpp src/systems/MovementSystem.h src/components/Position.h src/components/PathIndex.h src/GameData.h src/components/Speed.h src/components/Sequence.cpp src/components/Sequence.h src/components/Kind.h src/systems/SpawnSystem.cpp src/systems/SpawnSystem.h src/GameData.cpp src/components/Action.h src/systems/EventSystem.cpp src/systems/EventSystem.h src/components/Draggable.h src/systems/DraggingSystem.cpp src/systems/DraggingSystem.h src/Settings.h src/components/Type.h src/systems/RemoveEntitiesSystem.cpp src/systems/RemoveEntitiesSystem.h src/eventComponents/RemoveEntityEvent.h src/eventComponents/MoveEntityEvent.h src/systems/HandleMoveEntitiySystem.cpp src/systems/HandleMoveEntitiySystem.h src/components/Range.h src/components/RangeShadow.h)
target_link_libraries(SDL_Game ${Boost_LIBRARIES})
\ No newline at end of file
diff --git a/src/Component.h b/src/Component.h
index 8ab6c76..1bd14a4 100644
--- a/src/Component.h
+++ b/src/Component.h
@@ -1,29 +1,29 @@
//
// Created by Ido Mozes on 20/06/2019.
//
#ifndef SDL2_GAME_COMPONENT_H
#define SDL2_GAME_COMPONENT_H
struct Point {
short X;
short Y;
};
class Entity;
enum ComponentType {
- VISIBILITY, POSITION, VELOCITY, SPEED, ACCELERATION, PATH_INDEX, HEALTH, KIND, TYPE,RANGE, DAMAGE, PIERCE, SPREAD, SEQUENCE, ACTION, DRAGGABLE,
+ VISIBILITY, POSITION, VELOCITY, SPEED, ACCELERATION, PATH_INDEX, HEALTH, KIND, TYPE,RANGE, DAMAGE, PIERCE, SPREAD, SEQUENCE, ACTION, DRAGGABLE,RANGE_SHADOW,
MOVE_ENTITY_EVENT, REMOVE_ENTITY_EVENT,
LENGTH
};
class Component {
public:
Component() = default;
virtual ~Component() = default;
};
#endif //SDL2_GAME_COMPONENT_H
diff --git a/src/Game.cpp b/src/Game.cpp
index 195b2de..1287469 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,124 +1,124 @@
//
// 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());
}
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");
gameData.assets["Super_Monkey"] = IMG_Load("../assets/Super_Monkey.png");
gameData.assets["Sniper_Monkey"] = IMG_Load("../assets/Sniper_Monkey.png");
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{sprite.second.X, sprite.second.Y,
gameData.assets[sprite.first]->w,
gameData.assets[sprite.first]->h});
layers[i].emplace_back(spriteEntity);
}
}
auto button = new Entity();
button->addComponent<Kind>("Super_Monkey");
button->addComponent<Visibility>(gameData.renderer, gameData.assets["Super_Monkey"],
SDL_Rect{SIDEBAR_WIDTH + MAP_WIDTH + 10, 10,
int(gameData.assets["Super_Monkey"]->w / 1.5), 0});
button->addComponent<Action>(DRAG);
button->addComponent<Range>(200);
layers[MENU_LAYER].emplace_back(button);
button = new Entity();
button->addComponent<Kind>("Sniper_Monkey");
button->addComponent<Visibility>(gameData.renderer, gameData.assets["Sniper_Monkey"],
SDL_Rect{SIDEBAR_WIDTH + MAP_WIDTH + 100, 10,
int(gameData.assets["Sniper_Monkey"]->w / 1.5), 0});
button->addComponent<Action>(DRAG);
button->addComponent<Range>(50);
layers[MENU_LAYER].emplace_back(button);
- auto s = new Entity();
- s->addComponent<Sequence>(100, 10, 0);
- s->addComponent<Kind>(std::string("Ceramic"));
- s->addComponent<Speed>(3.5);
- layers[GAME_LAYER].emplace_back(s);
- s = new Entity();
- s->addComponent<Sequence>(100, 10, 60 * 5);
- s->addComponent<Kind>(std::string("Blue"));
- s->addComponent<Speed>(1.5);
- layers[GAME_LAYER].emplace_back(s);
+// auto s = new Entity();
+// s->addComponent<Sequence>(100, 10, 0);
+// s->addComponent<Kind>(std::string("Ceramic"));
+// s->addComponent<Speed>(3.5);
+// layers[GAME_LAYER].emplace_back(s);
+// s = new Entity();
+// s->addComponent<Sequence>(100, 10, 60 * 5);
+// s->addComponent<Kind>(std::string("Blue"));
+// s->addComponent<Speed>(1.5);
+// layers[GAME_LAYER].emplace_back(s);
systems.emplace_back(new EventSystem);
systems.emplace_back(new SpawnSystem);
systems.emplace_back(new DraggingSystem);
systems.emplace_back(new MovementSystem);
systems.emplace_back(new HandleMoveEntitiySystem);
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;
pathFile.read((char *) &gameData.startingPoint, 4);
pathFile.read((char *) &length, 4);
gameData.path.resize(length);
pathFile.read(&gameData.path[0], length);
pathFile.read((char *) &gameData.finishPoint, 4);
}
diff --git a/src/GameData.h b/src/GameData.h
index 3013f1a..3a544d9 100644
--- a/src/GameData.h
+++ b/src/GameData.h
@@ -1,39 +1,40 @@
//
// Created by Ido Mozes on 03/07/2019.
//
#ifndef SDL_GAME_GAMEDATA_H
#define SDL_GAME_GAMEDATA_H
#include <vector>
#include <memory>
#include <unordered_map>
#include "Component.h"
#include "Settings.h"
#include "SDL.h"
constexpr char FREE = 0;
constexpr char OBSTACLE = 1;
constexpr char TOWER = 2;
constexpr char BLOON = 3;
class GameData {
public:
bool isRunning = true;
bool isDragging = false;
int level = 0;
int map = 0;
float mapScale = 1.5;
bool fullscreen;
std::vector<char> path;
char mapData[MAP_WIDTH][MAP_HEIGHT];
Point startingPoint;
Point finishPoint;
std::unordered_map<std::string, SDL_Surface *> assets;
SDL_Window *window = nullptr;
SDL_Renderer *renderer = nullptr;
std::shared_ptr<Entity> selected;
+ bool selectedHasRangeShadow = false;
~GameData();
};
#endif //SDL_GAME_GAMEDATA_H
diff --git a/src/Settings.h b/src/Settings.h
index dca535e..4fecf71 100644
--- a/src/Settings.h
+++ b/src/Settings.h
@@ -1,15 +1,15 @@
//
// Created by Ido Mozes on 09/07/2019.
//
#ifndef SDL_GAME_SETTINGS_H
#define SDL_GAME_SETTINGS_H
-enum Layers{
- BACKGROUND_LAYER,GAME_LAYER,MENU_LAYER,
+enum Layers {
+ BACKGROUND_LAYER, SHADOW_LAYER, GAME_LAYER, MENU_LAYER,
N_LAYERS
};
constexpr int SIDEBAR_WIDTH = 150;
constexpr int MENU_WIDTH = 250;
constexpr int MAP_WIDTH = 686;
constexpr int MAP_HEIGHT = 511;
#endif //SDL_GAME_SETTINGS_H
diff --git a/src/System.h b/src/System.h
index b86504d..4098306 100644
--- a/src/System.h
+++ b/src/System.h
@@ -1,39 +1,40 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#ifndef SDL2_GAME_SYSTEM_H
#define SDL2_GAME_SYSTEM_H
#include <initializer_list>
#include <vector>
#include <cmath>
#include "Entity.h"
#include "GameData.h"
#include "components/Sequence.h"
#include "components/Speed.h"
#include "components/Kind.h"
#include "components/Position.h"
#include "components/Visibility.h"
#include "components/PathIndex.h"
#include "components/Velocity.h"
#include "components/Draggable.h"
#include "components/Action.h"
#include "components/Range.h"
+#include "components/RangeShadow.h"
#include "eventComponents/MoveEntityEvent.h"
#include "eventComponents/RemoveEntityEvent.h"
typedef std::vector<std::shared_ptr<Entity>> Entities;
inline void
operator+=(Entities &originalVector, Entities &newVector) {
originalVector.insert(originalVector.end(), std::make_move_iterator(newVector.begin()),
std::make_move_iterator(newVector.end()));
}
class System {
public:
virtual void update(Entities *entities, GameData &gameData) = 0;
};
#endif //SDL2_GAME_SYSTEM_H
diff --git a/src/components/Action.h b/src/components/Action.h
index 38cc02a..dc31713 100644
--- a/src/components/Action.h
+++ b/src/components/Action.h
@@ -1,28 +1,28 @@
//
// Created by Ido Mozes on 08/07/2019.
//
#ifndef SDL_GAME_ACTION_H
#define SDL_GAME_ACTION_H
#include "../Component.h"
enum ActionType {
- DRAG, CLICK, DROP, CHOOSE
+ DRAG, CLICK, DROP, SELECT
};
class Action : public Component {
public:
bool disabled;
ActionType actionType;
static constexpr ComponentType type = ComponentType::ACTION;
explicit Action(ActionType actionType, bool disabled = false) :actionType(actionType),
disabled(disabled) {}
~Action() override = default;
};
#endif //SDL_GAME_ACTION_H
diff --git a/src/components/RangeShadow.h b/src/components/RangeShadow.h
new file mode 100644
index 0000000..1dc0d14
--- /dev/null
+++ b/src/components/RangeShadow.h
@@ -0,0 +1,22 @@
+//
+// Created by Ido Mozes on 10/07/2019.
+//
+
+#ifndef SDL_GAME_RANGESHADOW_H
+#define SDL_GAME_RANGESHADOW_H
+
+#include "../Component.h"
+#include <memory>
+
+class RangeShadow : public Component {
+
+public:
+ std::shared_ptr<Entity> entity;
+ static constexpr ComponentType type = ComponentType::RANGE_SHADOW;
+
+ RangeShadow(std::shared_ptr<Entity> &entity) : entity(entity) {};
+
+ ~RangeShadow() override = default;
+};
+
+#endif //SDL_GAME_RANGESHADOW_H
diff --git a/src/systems/EventSystem.cpp b/src/systems/EventSystem.cpp
index 31d020f..7854e84 100644
--- a/src/systems/EventSystem.cpp
+++ b/src/systems/EventSystem.cpp
@@ -1,116 +1,125 @@
//
// Created by Ido Mozes on 08/07/2019.
//
#include "EventSystem.h"
void EventSystem::update(Entities *layers, GameData &gameData) {
SDL_PumpEvents();
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT: {
gameData.isRunning = false;
break;
}
case SDL_MOUSEBUTTONDOWN: {
if (!gameData.isDragging)
gameData.selected.reset();
int mouseX, mouseY, originalMouseX;
SDL_GetMouseState(&mouseX, &mouseY);
mouseX = originalMouseX = int(mouseX / gameData.mapScale);
mouseY = int(mouseY / gameData.mapScale);
bool entityClicked = false;
Entities newEntities[N_LAYERS];
for (int i = N_LAYERS - 1; i >= 0; --i) {
for (auto &entity: layers[i]) {
if (auto components = entity->getComponents<Action, Visibility>()) {
auto[action, visibility] = components.value();
if (action.disabled or (action.actionType != DROP and gameData.isDragging))
continue;
int entityX, entityY, w, h;
SDL_Rect *dstRect = visibility.getDstRect();
entityX = dstRect->x;
entityY = dstRect->y;
w = dstRect->w;
h = dstRect->h;
if (auto positionP = entity->getComponent<Position>()) {
auto &position = *positionP;
entityX = int(position.getX() - w / 2.0);
entityY = int(position.getY() - h / 2.0);
mouseX = originalMouseX - SIDEBAR_WIDTH;
} else
mouseX = originalMouseX;
if (entityX <= mouseX and mouseX <= entityX + w and entityY <= mouseY and
mouseY <= entityY + h) {
switch (action.actionType) {
case DRAG: {
auto &kind = *entity->getComponent<Kind>();
auto &range = *entity->getComponent<Range>();
auto draggable = new Entity();
SDL_Surface *surface = gameData.assets[kind.kind];
draggable->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{
originalMouseX - int(surface->w / 4.0), mouseY - int(surface->h / 4.0),
int(surface->w / 1.5), int(surface->h / 1.5)});
draggable->addComponent<Draggable>();
draggable->addComponent<Action>(DROP);
draggable->addComponent<Kind>(kind);
draggable->addComponent<Range>(range);
std::shared_ptr<Entity> ptr(draggable);
gameData.selected = ptr;
newEntities[MENU_LAYER].emplace_back(ptr);
gameData.isDragging = true;
+ gameData.selectedHasRangeShadow = false;
goto entityClicked;
}
case CLICK: {
goto entityClicked;
}
case DROP: {
auto &draggable = *entity->getComponent<Draggable>();
if (draggable.isPlaceable) {
entity->removeComponent<Draggable>();
- entity->getComponent<Action>()->actionType = CLICK;
+ entity->getComponent<Action>()->actionType = SELECT;
gameData.isDragging = false;
for (int x = std::max(mouseX - SIDEBAR_WIDTH - 20, 0);
x < std::min(mouseX - SIDEBAR_WIDTH + 21, MAP_WIDTH); ++x) {
for (int y = std::max(mouseY - 20, 0);
y < std::min(mouseY + 21, MAP_HEIGHT); ++y) {
if (gameData.mapData[x][y] == FREE)
gameData.mapData[x][y] = TOWER;
}
}
- if (i == MENU_LAYER)
+ if (i == MENU_LAYER){
+ gameData.selectedHasRangeShadow=true;
+ auto rangeShadow = new Entity();
+ rangeShadow->addComponent<RangeShadow>(entity);
+ newEntities[SHADOW_LAYER].emplace_back(rangeShadow);
entity->addComponent<MoveEntityEvent>(GAME_LAYER);
+ }
+
}
goto entityClicked;
}
- case CHOOSE: {
+ case SELECT: {
+ gameData.selected = entity;
+ gameData.selectedHasRangeShadow=true;
goto entityClicked;
}
}
}
}
}
}
entityClicked:
for (int i = 0; i < N_LAYERS; ++i) {
if (!newEntities[i].empty())
layers[i] += newEntities[i];
}
break;
}
default:
break;
}
}
}
diff --git a/src/systems/RenderSystem.cpp b/src/systems/RenderSystem.cpp
index 876055a..163899b 100644
--- a/src/systems/RenderSystem.cpp
+++ b/src/systems/RenderSystem.cpp
@@ -1,61 +1,71 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#include "RenderSystem.h"
#include "../components/Visibility.h"
#include "../components/Position.h"
void RenderSystem::init(GameData &gameData) {
if (gameData.window != nullptr)
SDL_DestroyWindow(gameData.window);
if (gameData.renderer != nullptr)
SDL_DestroyRenderer(gameData.renderer);
- gameData.window = SDL_CreateWindow("BloonsTD", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, // NOLINT(hicpp-signed-bitwise)
+ gameData.window = SDL_CreateWindow("BloonsTD", SDL_WINDOWPOS_CENTERED,
+ SDL_WINDOWPOS_CENTERED, // NOLINT(hicpp-signed-bitwise)
int((MAP_WIDTH + SIDEBAR_WIDTH + MENU_WIDTH) * gameData.mapScale),
- int(MAP_HEIGHT * gameData.mapScale), gameData.fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
+ int(MAP_HEIGHT * gameData.mapScale),
+ gameData.fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
gameData.renderer = SDL_CreateRenderer(gameData.window, -1, 0);
SDL_SetRenderDrawColor(gameData.renderer, 255, 255, 255, 255);
}
void RenderSystem::update(Entities *layers, GameData &gameData) {
SDL_RenderClear(gameData.renderer);
for (int i = 0; i < N_LAYERS; ++i) {
for (auto &entity: layers[i]) {
- if (auto visibilityP = entity->getComponent<Visibility>()) {
+ auto rangeShadowP = entity->getComponent<RangeShadow>();
+ auto &currentEntity = (rangeShadowP and rangeShadowP->entity == gameData.selected) ? rangeShadowP->entity
+ : entity;
+
+ if (auto visibilityP = currentEntity->getComponent<Visibility>()) {
auto &visibility = *visibilityP;
- auto positionP = entity->getComponent<Position>();
- SDL_Rect * dstRect = visibility.getDstRect();
+ auto positionP = currentEntity->getComponent<Position>();
+ SDL_Rect *dstRect = visibility.getDstRect();
SDL_Rect r = {int(dstRect->x * gameData.mapScale), int(dstRect->y * gameData.mapScale),
int(dstRect->w * gameData.mapScale), int(dstRect->h * gameData.mapScale)};
if (positionP) {
auto &position = *positionP;
- r.x = int((position.getX() + SIDEBAR_WIDTH) * gameData.mapScale -r.w / 2.0);
- r.y = int(position.getY() * gameData.mapScale -r.h / 2.0);
+ r.x = int((position.getX() + SIDEBAR_WIDTH) * gameData.mapScale - r.w / 2.0);
+ r.y = int(position.getY() * gameData.mapScale - r.h / 2.0);
}
- SDL_RenderCopy(gameData.renderer, visibility.getTexture(), nullptr, &r);
- if (gameData.selected == entity) {
- int entityX, entityY;
+
+ if (gameData.selected == currentEntity and
+ ((gameData.selectedHasRangeShadow and currentEntity != entity) or
+ (!gameData.selectedHasRangeShadow and currentEntity == entity))) {
+ int currentEntityX, currentEntityY;
if (positionP) {
- entityX = r.x;
- entityY = r.y;
+ currentEntityX = r.x;
+ currentEntityY = r.y;
} else {
- entityX = r.x + int((dstRect->w / 2.0) * gameData.mapScale);
- entityY = r.y + int((dstRect->h / 2.0) * gameData.mapScale);
+ currentEntityX = r.x + int((dstRect->w / 2.0) * gameData.mapScale);
+ currentEntityY = r.y + int((dstRect->h / 2.0) * gameData.mapScale);
}
- auto draggableP = entity->getComponent<Draggable>();
+ auto draggableP = currentEntity->getComponent<Draggable>();
bool isRed = draggableP ? !draggableP->isPlaceable : false;
- float range = entity->getComponent<Range>()->range;
- filledCircleRGBA(gameData.renderer, entityX, entityY, range, isRed ? 255 : 0, 0, 0, 100);
- aacircleRGBA(gameData.renderer, entityX, entityY, range, isRed ? 255 : 0, 0, 0, 150);
+ float range = currentEntity->getComponent<Range>()->range;
+ filledCircleRGBA(gameData.renderer, currentEntityX, currentEntityY, range, isRed ? 255 : 0, 0, 0,
+ 100);
+ aacircleRGBA(gameData.renderer, currentEntityX, currentEntityY, range, isRed ? 255 : 0, 0, 0, 150);
}
+ if (entity == currentEntity)
+ SDL_RenderCopy(gameData.renderer, visibility.getTexture(), nullptr, &r);
}
}
}
-
SDL_RenderPresent(gameData.renderer);
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:11 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
72397
Default Alt Text
(24 KB)

Event Timeline