Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
46 KB
Referenced Files
None
Subscribers
None
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 728d9e7..6de4187 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)
-add_executable(SDL_Game src/main.cpp src/Game.cpp src/Game.h src/Entity.cpp src/Entity.h src/Component.cpp src/Component.h src/System.cpp 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.cpp src/components/Position.h src/components/PathIndex.cpp 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)
+link_libraries(mingw32 SDL2main SDL2 SDL2_image SDL2_gfx)
+add_executable(SDL_Game src/main.cpp src/Game.cpp src/Game.h src/Entity.cpp src/Entity.h src/Component.cpp src/Component.h src/System.cpp 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.cpp src/components/Position.h src/components/PathIndex.cpp 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.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)
target_link_libraries(SDL_Game ${Boost_LIBRARIES})
\ No newline at end of file
diff --git a/scripts/convert_maps.py b/scripts/convert_maps.py
index 1a14afc..4ddd8c7 100644
--- a/scripts/convert_maps.py
+++ b/scripts/convert_maps.py
@@ -1,84 +1,83 @@
from PIL import Image
from sys import argv
from struct import pack
arrows = ['→', '↘', '↓', '↙', '←', '↖', '↑', '↗']
# obstacles
image = Image.open(argv[1] + "_obstacles.bmp")
width, height = image.size
obstacles = b''
byte = 0
-i = 7
-for i, pixel in enumerate(image.getdata()):
- byte += 2 ** (i % 8) * (pixel == (0, 0, 0))
- if i % 8 == 7:
- obstacles += bytes([byte])
- byte = 0
+i = 0
+for y in range(height):
+ for x in range(width):
+ pixel = image.getpixel((x, y))
+ byte |= (2 ** (i % 8)) * (pixel == (0, 0, 0))
+ print(i,pixel,byte)
+ _=input()
+ if i % 8 == 7:
+ obstacles += bytes([byte])
+ byte = 0
+ i += 1
if i % 8 != 7:
obstacles += bytes([byte])
with open(argv[1] + "_obstacles.data", 'wb') as file:
- file.write(pack('<H', width))
- file.write(pack('<H', height))
file.write(obstacles)
# path
image = Image.open(argv[1] + "_path.bmp")
width, height = image.size
instructions = b''
i = 0
for i, pixel in enumerate(image.getdata()):
if pixel == (255, 0, 0):
break
start_loc_x = x = i % width
start_loc_y = y = i // width
-# print(x, y)
prev_x = prev_y = next_x = next_y = 0
pixels = image.load()
pixel = pixels[x, y]
length = 0
prev_locations = [(x, y)]
directions = ((1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1))
while pixel != (255, 255, 0):
length += 1
possible_locations = [(pixels[x + delta_x, y + delta_y], x + delta_x, y + delta_y, mask) for
mask, (delta_x, delta_y) in
enumerate(directions) if (0 <= x + delta_x < width) and (0 <= y + delta_y < height) and not (
x + delta_x == prev_x and y + delta_y == prev_y) and pixels[x + delta_x, y + delta_y] != (
255, 255, 255)]
if len(possible_locations) == 1:
pixel, next_x, next_y, mask = possible_locations[0]
else:
special_locations = sorted([loc for loc in possible_locations if loc[0][2] == 255])
if len(special_locations) > 0:
pixel, next_x, next_y, mask = special_locations[0]
ttl = pixel[1] - 1
pixels[next_x, next_y] = (pixel[0] if ttl else 0, ttl, 255 if ttl else 0)
else:
new_locations = [loc for loc in possible_locations if (loc[1], loc[2]) not in prev_locations]
if len(new_locations) > 0:
pixel, next_x, next_y, mask = new_locations[0]
else:
old_locations = sorted((prev_locations.index((loc[1], loc[2])), loc) for loc in possible_locations if
(loc[1], loc[2]) in prev_locations)[::-1]
pixel, next_x, next_y, mask = old_locations[0][1]
if (next_x, next_y) in prev_locations:
prev_locations.remove((next_x, next_y))
prev_locations.append((next_x, next_y))
- # print(next_x, next_y)
- # print(arrows[mask])
- # _ = input()
instructions += bytes([mask])
prev_x = x
prev_y = y
x = next_x
y = next_y
with open(argv[1] + "_path.data", 'wb') as file:
file.write(pack('<H', start_loc_x))
file.write(pack('<H', start_loc_y))
file.write(pack('<I', length))
file.write(instructions)
file.write(pack('<H', x))
file.write(pack('<H', y))
diff --git a/src/Component.h b/src/Component.h
index deb40a7..c7dd6e9 100644
--- a/src/Component.h
+++ b/src/Component.h
@@ -1,31 +1,30 @@
//
// 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, DAMAGE, PIERCE, SPREAD,SEQUENCE,
+ VISIBILITY, POSITION, VELOCITY,SPEED, ACCELERATION, PATH_INDEX, HEALTH, KIND, TYPE, DAMAGE, PIERCE, SPREAD,SEQUENCE,ACTION,DRAGGABLE,
LENGTH
};
class Component {
Entity *entity;
public:
explicit Component(Entity *entity) : entity(entity) {};
- ~Component() = default;
Entity *getEntity() { return entity; }
};
#endif //SDL2_GAME_COMPONENT_H
diff --git a/src/Entity.cpp b/src/Entity.cpp
index 5358b18..2fc8206 100644
--- a/src/Entity.cpp
+++ b/src/Entity.cpp
@@ -1,10 +1,6 @@
//
// Created by Ido Mozes on 20/06/2019.
//
#include "Entity.h"
-Entity::Entity():componentsMask() ,components(){
- id = getNewId();
-}
-
diff --git a/src/Entity.h b/src/Entity.h
index 961818c..f0afe01 100644
--- a/src/Entity.h
+++ b/src/Entity.h
@@ -1,47 +1,66 @@
//
// Created by Ido Mozes on 20/06/2019.
//
#ifndef SDL2_GAME_ENTITY_H
#define SDL2_GAME_ENTITY_H
#include <bitset>
#include <vector>
+#include <cmath>
#include <memory>
+#include <optional>
#include "Component.h"
-constexpr int maxComponents = 64;
-typedef std::size_t EntityId;
-
+constexpr uint64_t createMask(std::initializer_list<int> types) noexcept {
+ uint64_t mask = 0;
+ for (int bit : types) {
+ mask |= (uint64_t) pow(2, bit);
+ }
+ return mask;
+}
class Entity {
- static EntityId getNewId() {
- static EntityId id_counter = 0;
- return id_counter++;
- }
- EntityId id;
std::bitset<ComponentType::LENGTH> componentsMask;
- std::array<Component *, ComponentType::LENGTH> components;
+ std::unique_ptr<Component> components[ComponentType::LENGTH];
public:
- Entity();
- ~Entity() = default;
+// bool hasComponents(uint64_t mask) { return (componentsMask.to_ullong() & mask) == mask; }
- EntityId getId() { return id; }
+// template<class T>
+// T &getComponent() { return *(T *) (components[T::getComponentType()].get()); }
- bool hasComponents(uint64_t mask) { return (componentsMask.to_ullong() & mask) == mask; }
+ template<class ... T>
+ std::optional<std::tuple<T &...>> getComponents() {
+ uint64_t mask = createMask({T::getComponentType()...});
+ if ((componentsMask.to_ullong() & mask) == mask) {
+ return std::tuple<T &...>((*(T *) components[T::getComponentType()].get())...);
+ }
+ return std::nullopt;
+ }
template<class T>
- T &getComponent() { return *(T *) (components[T::getComponentType()]); }
+ T * getComponent() {
+ if (auto &c =components[T::getComponentType()])
+ return (T*)c.get();
+ return nullptr;
+ }
template<typename T, typename ... Targs>
- Component &addComponent(Targs &&... args){
+ Component &addComponent(Targs &&... args) {
T *c = new T(this, std::forward<Targs>(args)...);
- components[T::getComponentType()] = c;
+ components[T::getComponentType()] = std::move(std::unique_ptr<Component>(c));
componentsMask[T::getComponentType()] = true;
return *c;
}
+
+ template<typename T>
+ void removeComponent() {
+ components[T::getComponentType()].release();
+ componentsMask[T::getComponentType()] = false;
+ }
+
};
#endif //SDL2_GAME_ENTITY_H
diff --git a/src/Game.cpp b/src/Game.cpp
index 27848eb..2575aec 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,89 +1,120 @@
//
// 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");
- renderSystem.init(gameData);
+ 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();
- auto mapEntity = new Entity();
- mapEntity->addComponent<Visibility>(gameData.renderer, gameData.assets["map"],
- SDL_Rect{150, 0, gameData.assets["map"]->w, gameData.assets["map"]->h});
- layers[0].emplace_back(mapEntity);
- auto upgrade_bar = new Entity();
- upgrade_bar->addComponent<Visibility>(gameData.renderer, gameData.assets["upgrade_bar"],
- SDL_Rect{0, 0, gameData.assets["upgrade_bar"]->w, gameData.assets["upgrade_bar"]->h});
- layers[1].emplace_back(upgrade_bar);
- auto menu = new Entity();
- menu->addComponent<Visibility>(gameData.renderer, gameData.assets["menu"],
- SDL_Rect{685+150, 0, gameData.assets["menu"]->w, gameData.assets["menu"]->h});
- layers[1].emplace_back(menu);
+ 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, gameData.assets["Super_Monkey"]->w,
+ gameData.assets["Super_Monkey"]->h});
+ button->addComponent<Action>(DRAG);
+ layers[3].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, gameData.assets["Sniper_Monkey"]->w,
+ gameData.assets["Sniper_Monkey"]->h});
+ button->addComponent<Action>(DRAG);
+ layers[3].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[0].emplace_back(s);
+ layers[1].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[0].emplace_back(s);
+ layers[1].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(&renderSystem);
+ systems.emplace_back(renderSystem);
}
Game::~Game() {
SDL_Quit();
}
-void Game::handleEvents() {
- SDL_Event event;
- SDL_PollEvent(&event);
- switch (event.type) {
- case SDL_QUIT:
- gameData.isRunning = false;
- break;
- default:
- break;
- }
-}
void Game::update() {
for (auto &system : systems) {
system->update(layers, gameData);
}
}
void Game::loadMap() {
- gameData.path.clear();
std::string fileName = "../assets/map" + std::to_string(gameData.map);
- std::ifstream file(fileName + "_path.data", std::ios::binary);
+ 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 & int(pow(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;
- file.read((char *) &gameData.startingPoint, 4);
- file.read((char *) &length, 4);
+ pathFile.read((char *) &gameData.startingPoint, 4);
+ pathFile.read((char *) &length, 4);
gameData.path.resize(length);
- file.read(&gameData.path[0], length);
- file.read((char *) &gameData.finishPoint, 4);
+ pathFile.read(&gameData.path[0], length);
+ pathFile.read((char *) &gameData.finishPoint, 4);
}
diff --git a/src/Game.h b/src/Game.h
index 31c70cd..bcd7f48 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -1,49 +1,46 @@
//
// Created by Ido Mozes on 18/06/2019.
//
#ifndef SDL2_GAME_GAME_H
#define SDL2_GAME_GAME_H
#include <iostream>
+#include <cmath>
#include <fstream>
#include <memory>
#include <vector>
#include "SDL.h"
#include "SDL_image.h"
#include <comdef.h>
#include "Entity.h"
#include "System.h"
#include "systems/RenderSystem.h"
#include "systems/MovementSystem.h"
+#include "systems/EventSystem.h"
#include "systems/SpawnSystem.h"
-#include "components/Visibility.h"
-#include "components/PathIndex.h"
-#include "components/Speed.h"
+#include "systems/DraggingSystem.h"
#include "GameData.h"
#include "boost/filesystem.hpp"
#include <iostream>
class Game {
std::vector<std::unique_ptr<System>> systems;
std::vector<std::shared_ptr<Entity>> layers[N_LAYERS];
- RenderSystem renderSystem;
+ RenderSystem * renderSystem;
GameData gameData;
public:
explicit Game(bool fullscreen, float mapScale=1.5);
~Game();
- void handleEvents();
-
void update();
-
bool running() { return gameData.isRunning; }
void loadMap();
};
#endif //SDL2_GAME_GAME_H
diff --git a/src/GameData.cpp b/src/GameData.cpp
index da0953b..dff7a83 100644
--- a/src/GameData.cpp
+++ b/src/GameData.cpp
@@ -1,9 +1,12 @@
//
// Created by Ido Mozes on 07/07/2019.
//
#include "GameData.h"
GameData::~GameData() {
+ for(auto & item:assets){
+ SDL_FreeSurface(item.second);
+ }
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
}
diff --git a/src/GameData.h b/src/GameData.h
index d7e699a..075d864 100644
--- a/src/GameData.h
+++ b/src/GameData.h
@@ -1,31 +1,33 @@
//
// Created by Ido Mozes on 03/07/2019.
//
#ifndef SDL_GAME_GAMEDATA_H
#define SDL_GAME_GAMEDATA_H
-constexpr int N_LAYERS = 2;
+
#include <vector>
#include <unordered_map>
#include "Component.h"
+#include "Settings.h"
#include "SDL.h"
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;
+ char mapData[MAP_WIDTH][MAP_HEIGHT];
Point startingPoint;
Point finishPoint;
- std::unordered_map<std::string,SDL_Surface *> assets;
+ std::unordered_map<std::string, SDL_Surface *> assets;
SDL_Window *window = nullptr;
SDL_Renderer *renderer = nullptr;
~GameData();
};
#endif //SDL_GAME_GAMEDATA_H
diff --git a/src/Settings.h b/src/Settings.h
new file mode 100644
index 0000000..99f2478
--- /dev/null
+++ b/src/Settings.h
@@ -0,0 +1,12 @@
+//
+// Created by Ido Mozes on 09/07/2019.
+//
+
+#ifndef SDL_GAME_SETTINGS_H
+#define SDL_GAME_SETTINGS_H
+constexpr int SIDEBAR_WIDTH = 150;
+constexpr int MENU_WIDTH = 250;
+constexpr int MAP_WIDTH = 686;
+constexpr int MAP_HEIGHT = 511;
+constexpr int N_LAYERS = 4;
+#endif //SDL_GAME_SETTINGS_H
diff --git a/src/System.h b/src/System.h
index 332f21b..a565f76 100644
--- a/src/System.h
+++ b/src/System.h
@@ -1,24 +1,27 @@
//
// 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"
+
-constexpr uint64_t createMask( std::initializer_list<int> types) noexcept {
- uint64_t mask = 0;
- for (int bit : types) {
- mask |= (uint64_t) pow(2, bit);
- }
- return mask;
-}
class System{
public:
virtual void update(std::vector<std::shared_ptr<Entity>> *entities, GameData & gameData)=0;
};
#endif //SDL2_GAME_SYSTEM_H
diff --git a/src/components/Action.cpp b/src/components/Action.cpp
new file mode 100644
index 0000000..9286f63
--- /dev/null
+++ b/src/components/Action.cpp
@@ -0,0 +1,5 @@
+//
+// Created by Ido Mozes on 08/07/2019.
+//
+
+#include "Action.h"
diff --git a/src/components/Action.h b/src/components/Action.h
new file mode 100644
index 0000000..ee83bf4
--- /dev/null
+++ b/src/components/Action.h
@@ -0,0 +1,26 @@
+//
+// 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
+};
+
+class Action : public Component {
+
+public:
+ bool disabled;
+ ActionType type;
+
+ static ComponentType getComponentType() { return ComponentType::ACTION; }
+
+ Action(Entity *entity, ActionType type, bool disabled = false) : Component(entity), type(type),
+ disabled(disabled) {}
+};
+
+#endif //SDL_GAME_ACTION_H
diff --git a/src/components/ComponentHeader.h b/src/components/ComponentHeader.h
new file mode 100644
index 0000000..e8232db
--- /dev/null
+++ b/src/components/ComponentHeader.h
@@ -0,0 +1,7 @@
+#include "../Component.h"
+
+class __: public Component{
+public:
+ static ComponentType getComponentType() { return ComponentType::__; }
+ __(Entity *entity):Component(entity){}
+};
\ No newline at end of file
diff --git a/src/components/Draggable.h b/src/components/Draggable.h
new file mode 100644
index 0000000..6bffb89
--- /dev/null
+++ b/src/components/Draggable.h
@@ -0,0 +1,15 @@
+//
+// Created by Ido Mozes on 09/07/2019.
+//
+
+#ifndef SDL_GAME_DRAGGABLE_H
+#define SDL_GAME_DRAGGABLE_H
+#include "../Component.h"
+
+class Draggable: public Component{
+public:
+ bool isPlaceable = false;
+ static ComponentType getComponentType() { return ComponentType::DRAGGABLE; }
+ Draggable(Entity *entity):Component(entity){}
+};
+#endif //SDL_GAME_DRAGGABLE_H
diff --git a/src/components/Kind.h b/src/components/Kind.h
index f6000e0..e5452d4 100644
--- a/src/components/Kind.h
+++ b/src/components/Kind.h
@@ -1,21 +1,22 @@
//
// Created by Ido Mozes on 07/07/2019.
//
#ifndef SDL_GAME_KIND_H
#define SDL_GAME_KIND_H
#include "../Component.h"
#include <string>
class Kind : public Component {
public:
std::string kind;
static ComponentType getComponentType() { return ComponentType::KIND; }
Kind(Entity *entity, std::string kind) : Component(entity), kind(std::move(kind)) {}
+ Kind(Entity *entity, Kind& kind) : Component(entity), kind(kind.kind) {}
};
#endif //SDL_GAME_KIND_H
diff --git a/src/components/Type.h b/src/components/Type.h
new file mode 100644
index 0000000..4882227
--- /dev/null
+++ b/src/components/Type.h
@@ -0,0 +1,16 @@
+//
+// Created by Ido Mozes on 09/07/2019.
+//
+
+#ifndef SDL_GAME_TYPE_H
+#define SDL_GAME_TYPE_H
+#include "../Component.h"
+enum Types{
+ OBSTACLE, TOWER, BLOON, RADIOS
+};
+class Type: public Component{
+public:
+ static ComponentType getComponentType() { return ComponentType::TYPE; }
+ Type(Entity *entity):Component(entity){}
+};
+#endif //SDL_GAME_TYPE_H
diff --git a/src/components/Visibility.cpp b/src/components/Visibility.cpp
index dfe13c2..e801e94 100644
--- a/src/components/Visibility.cpp
+++ b/src/components/Visibility.cpp
@@ -1,40 +1,39 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#include "Visibility.h"
-Visibility::Visibility(Entity *entity, SDL_Renderer *renderer, SDL_Surface *newSurface, std::optional<SDL_Rect> dstR)
- : Component(entity), dstRect(dstR) {
+Visibility::Visibility(Entity *entity, SDL_Renderer *renderer, SDL_Surface *newSurface, std::optional<SDL_Rect> dstR,
+ std::optional<float> radios) : Component(entity), dstRect(dstR), radios(radios) {
loadTexture(renderer, newSurface);
}
Visibility::~Visibility() {
SDL_DestroyTexture(texture);
- SDL_FreeSurface(surface);
}
void Visibility::loadTexture(SDL_Renderer *renderer, SDL_Surface *newSurface) {
surface = newSurface;
reloadTexture(renderer);
if (dstRect) {
if (dstRect->w == 0)
dstRect->w = int((float(surface->w) / surface->h) * dstRect->h);
else if (dstRect->h == 0)
dstRect->h = int((float(surface->h) / surface->w) * dstRect->w);
}
}
void Visibility::reloadTexture(SDL_Renderer *renderer) {
texture = SDL_CreateTextureFromSurface(renderer, surface);
}
void Visibility::setPosition(int x, int y) {
if (dstRect) {
dstRect->x = x;
dstRect->y = y;
}
}
diff --git a/src/components/Visibility.h b/src/components/Visibility.h
index 89fc46a..3401552 100644
--- a/src/components/Visibility.h
+++ b/src/components/Visibility.h
@@ -1,42 +1,48 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#ifndef SDL2_GAME_VISIBILITY_H
#define SDL2_GAME_VISIBILITY_H
#include <fstream>
#include <optional>
#include "SDL.h"
#include "SDL_image.h"
#include "../Component.h"
-
+constexpr float NO_RADIOS = -1;
SDL_Texture *loadTexture(SDL_Renderer *renderer, const char *path);
class Visibility : public Component {
- SDL_Surface *surface;
- SDL_Texture *texture;
+ SDL_Surface *surface = nullptr;
+ SDL_Texture *texture = nullptr;
std::optional<SDL_Rect> dstRect;
-
+ std::optional<float> radios;
public:
- static ComponentType getComponentType() { return ComponentType::VISIBILITY; }
+ static constexpr inline ComponentType getComponentType() { return ComponentType::VISIBILITY; }
+
+ Visibility(Entity *entity, SDL_Renderer *renderer, SDL_Surface *newSurface,
+ std::optional<SDL_Rect> dstR = std::nullopt, std::optional<float> radios = std::nullopt);
- Visibility(Entity *entity, SDL_Renderer *renderer, SDL_Surface * newSurface,std::optional<SDL_Rect> dstR = std::nullopt);
~Visibility();
SDL_Texture *getTexture() { return texture; }
SDL_Rect *getDstRect() { return dstRect ? &dstRect.value() : nullptr; }
+ float getRadios() { return radios ? radios.value() : NO_RADIOS; }
+
+ void setRadios(std::optional<float> newRadios) { radios = newRadios; }
+
void setPosition(int x, int y);
- void loadTexture(SDL_Renderer *renderer, SDL_Surface * newSurface);
+ void loadTexture(SDL_Renderer *renderer, SDL_Surface *newSurface);
void reloadTexture(SDL_Renderer *renderer);
};
#endif //SDL2_GAME_VISIBILITY_H
diff --git a/src/main.cpp b/src/main.cpp
index 6faa8be..e754cb5 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 = 60, frameDelay = 1000 / FPS;
Uint32 frameStart;
int frameTime;
Game game(false, 1.5);
while (game.running()) {
frameStart = SDL_GetTicks();
- game.handleEvents();
+
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/DraggingSystem.cpp b/src/systems/DraggingSystem.cpp
new file mode 100644
index 0000000..badac80
--- /dev/null
+++ b/src/systems/DraggingSystem.cpp
@@ -0,0 +1,40 @@
+//
+// Created by Ido Mozes on 09/07/2019.
+//
+
+#include "DraggingSystem.h"
+
+
+
+void DraggingSystem::update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) {
+
+ int mouseX, mouseY;
+ SDL_GetMouseState(&mouseX, &mouseY);
+ mouseX = int(mouseX / gameData.mapScale);
+ mouseY = int(mouseY / gameData.mapScale);
+ for (int i = 0; i < N_LAYERS; ++i) {
+ for (auto &entity: layers[i]) {
+ if (auto components = entity->getComponents<Draggable, Visibility>()) {
+ auto[draggable, visibility] = components.value();
+ visibility.setPosition(mouseX - int(visibility.getDstRect()->w / 2.0),
+ mouseY - int(visibility.getDstRect()->h / 2.0));
+ bool freePosition = true;
+ if (mouseX > SIDEBAR_WIDTH + MAP_WIDTH or mouseX < SIDEBAR_WIDTH)
+ freePosition = false;
+
+ else
+ for (int x = mouseX - SIDEBAR_WIDTH - 4; x < mouseX - SIDEBAR_WIDTH + 5; ++x) {
+ for (int y = mouseY - 4; y < mouseY + 5; ++y) {
+ if (gameData.mapData[x][y]) {
+ freePosition = false;
+ goto setIsPlaceable;
+ }
+ }
+ }
+ setIsPlaceable:
+ draggable.isPlaceable = freePosition;
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/systems/DraggingSystem.h b/src/systems/DraggingSystem.h
new file mode 100644
index 0000000..e4c9d78
--- /dev/null
+++ b/src/systems/DraggingSystem.h
@@ -0,0 +1,13 @@
+//
+// Created by Ido Mozes on 09/07/2019.
+//
+
+#ifndef SDL_GAME_DRAGGINGSYSTEM_H
+#define SDL_GAME_DRAGGINGSYSTEM_H
+#include <iostream>
+#include "../System.h"
+class DraggingSystem : public System {
+public:
+ void update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) override;
+};
+#endif //SDL_GAME_DRAGGINGSYSTEM_H
diff --git a/src/systems/EventSystem.cpp b/src/systems/EventSystem.cpp
new file mode 100644
index 0000000..f61506b
--- /dev/null
+++ b/src/systems/EventSystem.cpp
@@ -0,0 +1,90 @@
+//
+// Created by Ido Mozes on 08/07/2019.
+//
+
+#include "EventSystem.h"
+
+
+void EventSystem::update(std::vector<std::shared_ptr<Entity>> *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: {
+ std::vector<std::shared_ptr<Entity>> newEntities;
+ std::vector<std::shared_ptr<Entity>> entitiesToRemove;
+ int mouseX, mouseY, originalMouseX;
+ SDL_GetMouseState(&mouseX, &mouseY);
+ mouseX = originalMouseX = int(mouseX / gameData.mapScale);
+ mouseY = int(mouseY / gameData.mapScale);
+ 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.type == DRAG and gameData.isDragging))
+ continue;
+ int entityX, entityY, w, h;
+ entityX = visibility.getDstRect()->x;
+ entityY = visibility.getDstRect()->y;
+ w = visibility.getDstRect()->w;
+ h = visibility.getDstRect()->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.type) {
+ case DRAG: {
+ auto &kind = *entity->getComponent<Kind>();
+ auto draggable = new Entity();
+ SDL_Surface *surface = gameData.assets[kind.kind];
+ draggable->addComponent<Visibility>(gameData.renderer, surface, SDL_Rect{
+ originalMouseX - int(surface->w / 2.0), mouseY - int(surface->h / 2.0),
+ surface->w, surface->h}, 100);
+ draggable->addComponent<Draggable>();
+ draggable->addComponent<Action>(DROP);
+ draggable->addComponent<Kind>(kind);
+ newEntities.emplace_back(draggable);
+ gameData.isDragging = true;
+ goto entityClicked;
+ }
+
+ case CLICK: {
+ goto entityClicked;
+ }
+ case DROP: {
+ auto &draggable = *entity->getComponent<Draggable>();
+ if (draggable.isPlaceable) {
+ entity->removeComponent<Draggable>();
+ gameData.isDragging = false;
+ }
+ break;
+ }
+ }
+
+ }
+ }
+ }
+ }
+ entityClicked:
+ layers[3].insert(layers[3].end(), std::make_move_iterator(newEntities.begin()),
+ std::make_move_iterator(newEntities.end()));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+}
diff --git a/src/systems/EventSystem.h b/src/systems/EventSystem.h
new file mode 100644
index 0000000..a57cb3b
--- /dev/null
+++ b/src/systems/EventSystem.h
@@ -0,0 +1,19 @@
+//
+// Created by Ido Mozes on 08/07/2019.
+//
+
+#ifndef SDL_GAME_EVENTSYSTEM_H
+#define SDL_GAME_EVENTSYSTEM_H
+
+#include <iostream>
+#include "../System.h"
+#include "../systems/RenderSystem.h"
+
+
+
+class EventSystem : public System {
+public:
+ void update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) override;
+};
+
+#endif //SDL_GAME_EVENTSYSTEM_H
diff --git a/src/systems/MovementSystem.cpp b/src/systems/MovementSystem.cpp
index d822eb3..d5a60cc 100644
--- a/src/systems/MovementSystem.cpp
+++ b/src/systems/MovementSystem.cpp
@@ -1,70 +1,68 @@
//
// Created by Ido Mozes on 02/07/2019.
//
#include "MovementSystem.h"
void MovementSystem::update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) {
for (int i = 0; i < N_LAYERS; ++i) {
for (auto &entity: layers[i]) {
// Move all entities with Visibility and Position
- if (entity->hasComponents(createMask({ComponentType::VISIBILITY, ComponentType::POSITION}))) {
- auto &visibility = entity->getComponent<Visibility>();
- auto &position = entity->getComponent<Position>();
+ if (auto components = entity->getComponents<Visibility, Position>()) {
+ auto[visibility, position]=components.value();
float deltaX = 0, deltaY = 0;
- if (entity->hasComponents(createMask({ComponentType::VELOCITY}))) {
- auto &velocity = entity->getComponent<Velocity>();
- if (entity->hasComponents(createMask({ACCELERATION}))) {
- auto &acceleration = entity->getComponent<Acceleration>();
+ if (auto velocityP = entity->getComponent<Velocity>()) {
+ auto &velocity = *velocityP;
+ if (auto accelerationP = entity->getComponent<Acceleration>()) {
+ auto &acceleration = *accelerationP;
velocity.changeVelocity(acceleration.getX(), acceleration.getY());
}
deltaX = velocity.getX();
deltaY = velocity.getY();
- } else if (entity->hasComponents(createMask({ComponentType::PATH_INDEX, ComponentType::SPEED}))) {
- auto &pathIndex = entity->getComponent<PathIndex>();
- auto &speed = entity->getComponent<Speed>();
+ } else if (auto components2 = entity->getComponents<PathIndex, Speed>()) {
+ auto[pathIndex, speed] =components2.value();
pathIndex.progress += speed.speed;
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;
}
deltaIndex -= (gameData.path[pathIndex.index] % 2 == 0 ? 1 : sqrt(2));
if (pathIndex.index < gameData.path.size() - 1)
pathIndex.index++;
}
}
position.changePosition(deltaX, deltaY);
}
}
}
}
diff --git a/src/systems/MovementSystem.h b/src/systems/MovementSystem.h
index bb2ede3..089e90a 100644
--- a/src/systems/MovementSystem.h
+++ b/src/systems/MovementSystem.h
@@ -1,23 +1,18 @@
//
// Created by Ido Mozes on 02/07/2019.
//
#ifndef SDL_GAME_MOVEMENTSYSTEM_H
#define SDL_GAME_MOVEMENTSYSTEM_H
#include <iostream>
-#include "../components/Visibility.h"
-#include "../components/Velocity.h"
-#include "../components/Position.h"
-#include "../components/PathIndex.h"
-#include "../components/Speed.h"
#include "../GameData.h"
#include "../System.h"
class MovementSystem : public System{
public:
MovementSystem()= default;
~MovementSystem()= default;
void update(std::vector<std::shared_ptr<Entity>> *layers, GameData & gameData) override;
};
#endif //SDL_GAME_MOVEMENTSYSTEM_H
diff --git a/src/systems/RenderSystem.cpp b/src/systems/RenderSystem.cpp
index 9665c52..a0318d1 100644
--- a/src/systems/RenderSystem.cpp
+++ b/src/systems/RenderSystem.cpp
@@ -1,52 +1,64 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#include "RenderSystem.h"
#include "../components/Visibility.h"
#include "../components/Position.h"
-uint64_t RenderSystem::mask = createMask({ComponentType::VISIBILITY});
-
-
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,
- (685 + 400) * gameData.mapScale,
- 511 * gameData.mapScale, gameData.fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
+ (MAP_WIDTH + SIDEBAR_WIDTH + MENU_WIDTH) * gameData.mapScale,
+ 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(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) {
+
SDL_RenderClear(gameData.renderer);
for (int i = 0; i < N_LAYERS; ++i) {
for (auto &entity: layers[i]) {
- if (entity->hasComponents(mask)) {
- auto &visibility = entity->getComponent<Visibility>();
+ if (auto visibilityP = entity->getComponent<Visibility>()) {
+ auto &visibility = *visibilityP;
+ auto positionP = entity->getComponent<Position>();
SDL_Rect r = {int(visibility.getDstRect()->x * gameData.mapScale),
int(visibility.getDstRect()->y * gameData.mapScale),
int(visibility.getDstRect()->w * gameData.mapScale),
int(visibility.getDstRect()->h * gameData.mapScale)};
- if (entity->hasComponents(createMask({ComponentType::POSITION}))) {
- if (entity->hasComponents(createMask({ComponentType::POSITION}))) {
- auto &position = entity->getComponent<Position>();
- r.x = int(position.getX() * gameData.mapScale);
- r.y = int(position.getY() * gameData.mapScale);
- }
- r.x -= int(r.w / 2.0);
- r.y -= int(r.h / 2.0);
- r.x += int(150 * 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);
}
SDL_RenderCopy(gameData.renderer, visibility.getTexture(), nullptr, &r);
+ if (visibility.getRadios() != NO_RADIOS) {
+ int entityX, entityY;
+ if (positionP) {
+ entityX = r.x;
+ entityY = r.y;
+ } else {
+ entityX = r.x + int((visibility.getDstRect()->w / 2.0) * gameData.mapScale);
+ entityY = r.y + int((visibility.getDstRect()->h / 2.0) * gameData.mapScale);
+ }
+ auto draggableP = entity->getComponent<Draggable>();
+ bool isRed = draggableP ? !draggableP->isPlaceable : false;
+ filledCircleRGBA(gameData.renderer, entityX, entityY, visibility.getRadios(), isRed ? 255 : 0, 0, 0,
+ 100);
+ aacircleRGBA(gameData.renderer, entityX, entityY, visibility.getRadios(), isRed ? 255 : 0, 0, 0,
+ 150);
+
+ }
}
}
}
+
SDL_RenderPresent(gameData.renderer);
}
diff --git a/src/systems/RenderSystem.h b/src/systems/RenderSystem.h
index c3d9ff2..f1fd4a3 100644
--- a/src/systems/RenderSystem.h
+++ b/src/systems/RenderSystem.h
@@ -1,25 +1,26 @@
//
// Created by Ido Mozes on 23/06/2019.
//
#ifndef SDL2_GAME_RENDERSYSTEM_H
#define SDL2_GAME_RENDERSYSTEM_H
#include <iostream>
-#include "../components/Visibility.h"
#include "../System.h"
#include "../GameData.h"
+#include "SDL2_gfxPrimitives.h"
+
+
class RenderSystem : public System {
- static uint64_t mask;
public:
RenderSystem() { SDL_Init(SDL_INIT_EVERYTHING); }
void init(GameData &gameData);
void update(std::vector<std::shared_ptr<Entity>> *layers , GameData & gameData) override;
};
#endif //SDL2_GAME_RENDERSYSTEM_H
diff --git a/src/systems/SpawnSystem.cpp b/src/systems/SpawnSystem.cpp
index 67a351d..31639c2 100644
--- a/src/systems/SpawnSystem.cpp
+++ b/src/systems/SpawnSystem.cpp
@@ -1,32 +1,32 @@
//
// Created by Ido Mozes on 07/07/2019.
//
#include "SpawnSystem.h"
-uint64_t SpawnSystem::mask = createMask({ComponentType::SEQUENCE, ComponentType::KIND});
void SpawnSystem::update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) {
for (int i = 0; i < N_LAYERS; ++i) {
std::vector<std::shared_ptr<Entity>> newEntities;
for (auto &entity: layers[i]) {
- if (entity->hasComponents(mask)) {
- int amount = entity->getComponent<Sequence>().getAmountReady();
- for (int i = 0; i < amount; ++i) {
+ if (auto components = entity->getComponents<Sequence, Kind, Speed>()) {
+ auto[sequence, kind, speed] = components.value();
+ int amount =sequence.getAmountReady();
+ for (int j = 0; j < amount; ++j) {
auto *newEntity = new Entity();
- newEntity->addComponent<Kind>(entity->getComponent<Kind>().kind);
+ newEntity->addComponent<Kind>(kind);
newEntity->addComponent<Position>(gameData.startingPoint.X, gameData.startingPoint.Y);
newEntity->addComponent<PathIndex>(0);
- newEntity->addComponent<Speed>(entity->getComponent<Speed>().speed);
- SDL_Surface *surface = gameData.assets[entity->getComponent<Kind>().kind];
+ newEntity->addComponent<Speed>(speed.speed);
+ SDL_Surface *surface = gameData.assets[kind.kind];
newEntity->addComponent<Visibility>(gameData.renderer, surface,
SDL_Rect{gameData.startingPoint.X, gameData.startingPoint.Y,
surface->w / 3, surface->h / 3});
newEntities.emplace_back(newEntity);
}
}
}
layers[i].insert(layers[i].end(), std::make_move_iterator(newEntities.begin()),
std::make_move_iterator(newEntities.end()));
}
}
diff --git a/src/systems/SpawnSystem.h b/src/systems/SpawnSystem.h
index ce93985..fdc00b5 100644
--- a/src/systems/SpawnSystem.h
+++ b/src/systems/SpawnSystem.h
@@ -1,24 +1,17 @@
//
// Created by Ido Mozes on 07/07/2019.
//
#ifndef SDL_GAME_SPAWNSYSTEM_H
#define SDL_GAME_SPAWNSYSTEM_H
#include <vector>
#include <iterator>
#include "../System.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"
class SpawnSystem : public System {
- static uint64_t mask;
public:
void update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) override;
};
#endif //SDL_GAME_SPAWNSYSTEM_H
diff --git a/src/systems/SystemHeader.h b/src/systems/SystemHeader.h
new file mode 100644
index 0000000..b85af64
--- /dev/null
+++ b/src/systems/SystemHeader.h
@@ -0,0 +1,5 @@
+#include "../System.h"
+class __ : public System {
+public:
+ void update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) override;
+};
\ No newline at end of file
diff --git a/src/systems/SystemSource.cpp b/src/systems/SystemSource.cpp
new file mode 100644
index 0000000..025038c
--- /dev/null
+++ b/src/systems/SystemSource.cpp
@@ -0,0 +1,9 @@
+void __::update(std::vector<std::shared_ptr<Entity>> *layers, GameData &gameData) {
+ for (int i = 0; i < N_LAYERS; ++i) {
+ for (auto &entity: layers[i]) {
+
+ }
+ }
+}
+
+

File Metadata

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

Event Timeline