0
0
mirror of https://github.com/Nimac0/SDL_Minigame synced 2026-01-12 15:53:42 +00:00

Compare commits

..

No commits in common. "eff959d11e06fbcdf98368eb93a9361de6cf23e6" and "7a3c845c40ee362f89bd79ba6f2ea2d04b1d8dd8" have entirely different histories.

43 changed files with 136 additions and 405 deletions

View File

@ -1,7 +1,7 @@
{ {
"fullscreen": false, "fullscreen": false,
"title": "VGG (Very Good Game)", "title": "VGG (Very Good Game)",
"screen_height": 640, "screen_height": 600,
"screen_width": 800, "screen_width": 800,
"icon": "./engine/internalAssets/iconImage.bmp" "icon": "./engine/internalAssets/iconImage.bmp"
} }

View File

@ -548,7 +548,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation. # included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_STATIC = YES EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO, # locally in source files will be included in the documentation. If set to NO,
@ -573,7 +573,7 @@ EXTRACT_LOCAL_METHODS = NO
# are hidden. # are hidden.
# The default value is: NO. # The default value is: NO.
EXTRACT_ANON_NSPACES = YES EXTRACT_ANON_NSPACES = NO
# If this flag is set to YES, the name of an unnamed parameter in a declaration # If this flag is set to YES, the name of an unnamed parameter in a declaration
# will be determined by the corresponding definition. By default unnamed # will be determined by the corresponding definition. By default unnamed
@ -588,7 +588,7 @@ RESOLVE_UNNAMED_PARAMS = YES
# section is generated. This option has no effect if EXTRACT_ALL is enabled. # section is generated. This option has no effect if EXTRACT_ALL is enabled.
# The default value is: NO. # The default value is: NO.
HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set # undocumented classes that are normally visible in the class hierarchy. If set
@ -597,7 +597,7 @@ HIDE_UNDOC_MEMBERS = YES
# if EXTRACT_ALL is enabled. # if EXTRACT_ALL is enabled.
# The default value is: NO. # The default value is: NO.
HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# declarations. If set to NO, these declarations will be included in the # declarations. If set to NO, these declarations will be included in the
@ -949,7 +949,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = ./include ./src ./docs/md-pages INPUT = ./include ./src
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -991,8 +991,7 @@ INPUT_FILE_ENCODING =
FILE_PATTERNS = *.cpp \ FILE_PATTERNS = *.cpp \
*.h \ *.h \
*.hpp \ *.hpp
*.md
# The RECURSIVE tag can be used to specify whether or not subdirectories should # The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well. # be searched for input files as well.
@ -1060,7 +1059,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the # that contain images that are to be included in the documentation (see the
# \image command). # \image command).
IMAGE_PATH = ./docs/img IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should # The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program # invoke to filter for each input file. Doxygen will invoke the filter program
@ -1121,7 +1120,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub # (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output. # and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = ./docs/md-pages/main.md USE_MDFILE_AS_MAINPAGE =
# The Fortran standard specifies that for fixed formatted Fortran code all # The Fortran standard specifies that for fixed formatted Fortran code all
# characters from position 72 are to be considered as comment. A common # characters from position 72 are to be considered as comment. A common
@ -2380,7 +2379,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,12 +0,0 @@
# Configuring the game
By either adding your own configuration .json file and overwriting its path in setConfigFilePath() found in Chickengame.cpp or editing configs/mainConfig.json you can configure some aspects of the game. These are:
- **fullscreen**: bool to determine if you want your game to be displayed in fullscreen or not. Maintains the screen size set in screen_width and screen_height and stretches it out
- **screen_width**: int, in pixels
- **screen_height**: int, in pixels
- **title**: string, the title of the game/the name displayed on the top left of the window
- **icon**: string, path to the bitmap (.btm) you want to use as the app icon of your game

View File

@ -1,62 +0,0 @@
# Entities and Components
## Entities
In the scope of this library entities essentially function like empty containers that you can add components or properties to. So an entity can be whatever you want it to be, give it a texture, make it pickupable, give it collision or all of the above and more.
Relevant functions for the creation and editing of Entities and Components:
### Manager
- [addEntity()](@ref Manager#addEntity())
- [getAll()](@ref Manager#getAll())
### Entity
- [addComponent()](@ref Entity#addComponent())
- [getComponent()](@ref Entity#getComponent())
- [destroy()](@ref Entity#destroy())
**If you are ever lost when looking for related functionality via search or side bar remember it is all neatly organized on this page for better readability and a better overview**
## Components
The following components are currently available for you to use in your entities (the associated managers/handlers are also linked):
---
### [Transform Component](@ref TransformComponent)
The Transform Component manages the position and movement of an Entity. Multiple overloaded constructors exist depending on whether or not the entity is stationary
> [!important]
> If an Entity is supposed to be able to move the data entry "speed" has to be added and set to a positive int!
---
### [Sprite Component](@ref SpriteComponent)
Textures and Animations can be added via this component.
> [!important]
> A [Transform Component](@ref TransformComponent) is first needed before adding a Texture as the coordinates from the transform component are needed to tell the game where to render the texture
---
### [Data Component](@ref DataComponent)
Custom Data such as Stats can be added to an Entity and accessed using this Component.
---
### [Collider Component](@ref ColliderComponent)
see also [Collision Handler](@ref CollisionHandler)
Adds collision functionality to an Entity. It is used to stop entities with a [PLAYER group label](@ref Entity#GroupLabel) from running through tiles that were given the "collision" tag in the Tiled editor (see [Tiled](@ref md_docs_2md-pages_2tilemaps) section) or the [COLLIDERS group label](@ref Entity#GroupLabel) in the code.
Also enables "picking up" other entities via [Pickup Component](@ref PickupComponent).
---
### [Interaction Component](@ref InteractionComponent)
see also [InteractionEventdataStruct](@ref InteractionEventdataStruct)
Adding this component to an entity tells it to react to triggered Interactions for example by button press. For this a custom lambda or function pointer is passed to determine what exactly should happen once an entities ineraction was triggered.
> [!note]
> You want certain buttons to do something? You're in the wrong place, see [Input Management](@ref md_docs_2md-pages_2inputhandling)
> This component is only used to assign a functionality to an entity to be triggered when it is interacted with, to actually map a button to do something such as trigger an interaction refer to [Input Management](@ref md_docs_2md-pages_2inputhandling) and [Eventhandling](@ref md_docs_2md-pages_2eventhandling)
---
### [Pickup Component](@ref PickupComponent)
see also [Pickup Manager](@ref PickupManager)
Entities with pickup components will disappear once another collision having entity with the [Group Label](@ref Entity#GroupLabel) "Player" intersects with it and executes the custom functionality given to it via constructor.
---
### [Stat Effects Component](@ref StatEffectsComponent)
Temporary stateffects can be added using this component. Using the time and function passed it will execute whatever is in the function after the given time. It is used to e.g. reset stats after raising them in order to allow for temporary stat raises

View File

@ -1,4 +0,0 @@
# Interactions
In order to make an entity react to interactions it needs to include an implementation of InteractionListener such as the InteractionComponent. Using [its constructor](@ref InteractionComponent#InteractionComponent) you can add a lambda/function pointer containing what you want to happen once an interaction with this entity happens.

View File

@ -1,5 +0,0 @@
# Input Management
Using the function [registerAction()](@ref InputManager#registerAction) Keys (both key press and key release) can be mapped to do certain actions such as moving an entity. Example code can be found within the template under `Controls.h` and `Controls.cpp`.
**Tip: If you want to apply any Inputs to a specific entity e.g. movement, simply pass the entity as a parameter in the initControls() function**

View File

@ -1,22 +0,0 @@
# Welcome to the VEGO library documentation
Here you will (hopefully) find any information necessary to use the different classes and components of this engine to develop your own simple 2D games.
Alternatively you could also just look at the code in the templates include and src folders and look at the example implementations there. The best place to start is `GameImplementation.h` and `GameImplementation.cpp`. All .cpp files have an associated .h file, please always start in the .h file with the same name as the .cpp file, otherwise you might get confused at some of the inline explanations provided in the files.
> [!note]
> When navigating this documentation click on hyperlinks if you ever feel like information is missing (there is usually more information available in the detailed view only visible if you click it or scroll far enough)
The base functionality can be split into a few major sections:
### Setup and Config
1. [Quickstart guide for setting up the library](@ref md_docs_2md-pages_2quickstart)
2. [Configuring game settings](@ref md_docs_2md-pages_2config)
3. [Building a map using Tiled and tmx and loading it](@ref md_docs_2md-pages_2tilemaps)
### Implementation of Features
4. [Entities and Components](@ref md_docs_2md-pages_2entitiesAndComponents)
5. [Input Management](@ref md_docs_2md-pages_2inputhandling)
6. [Eventhandling](@ref md_docs_2md-pages_2eventhandling)
You can also of course just browse the classes on your own this just act as a more structured separation and docuementation of relevant features
DISCLAIMER: EVERYTHING IN THE GIVEN TEMPLATE CODE IS OPTIONAL EVERYTHING FOUND IN THERE IS JUST A GUIDE AND CAN BE CHANGED AND/OR DELETED WITHOUT A PROBLEM

View File

@ -1,20 +0,0 @@
# Quickstart guide for setting up the library
This guide's purpose is to get developers from 0 to being able to create their game in the quickest and most uncomplicated way possible. Therefore it will only go over the bare minimum to get everything up and running for implementation guides check out the other sections on the welcome page.
## Installations and tools
Go to the github repository and download the setup file for your OS (windows and linux supported). This file needs to be executed in the folder you want to start your project in which will start the initial setup. While you can also manually download all of the necessary tools, this setup file acts as a central automated executable to streamline and expedite the non-game development aspect of this process which is why it is highly recommended.
The tools downloaded are:
- mingw(win)/gcc(linux)
- CMake
- Tiled (Installer)
- Git
It will also automatically download the library and templates to start a project with.
The only manual step required of the user is to finalize the installation of Tiled in order to use it for the creation of maps. For this simply double click the downloaded setup file and go through the installation wizard. After it is installed the .msi file can be deleted.
After this is completed there should be a folder named vego, with everything necessary in it.
The optional templates will be under `vego/my_game/include` and `vego/my_game/src`. Even if you choose not to use them still place your .h files in include and your .cpp files in src. Once setup, open the project folder in the IDE of your choosing, building and compiling should work using the associated compilation script as it is “IDE Agnostic”. For actual development it is recommended to look into the preexisting files in the template. Within them inline short explanations and code snippets can be found that act as a guide for your own implementation of features.

View File

@ -1,56 +0,0 @@
# Building a map using Tiled and tmx and loading it
In order to create a map for your game the library has .tmx format support. In order to get .tmx files you use the associated tile editor "Tiled" which gets automatically downloaded when executing the VEGO libraries setup file (the installer is provided the installation itself must be finalized by the user). This section will walk you step by step through the creation of your first map/background using Tiled.
see also: [the official Tiled documentation](https://doc.mapeditor.org/en/stable/manual/introduction/#getting-started)
### Getting started
After opening Tiled, select "New Map", a custom size measured in tiles and as tile size select 32x32 as this is
the size the library currently supports. Also choose the size of your canvas, it is recommended you choose the same size as the one you defined in the [games config](@ref md_docs_2md-pages_2config) (default is 25w x 20h, measured in tiles, to get the pixel size just multiply by 32 as that is the tilesize the library uses)
![](@ref Tiled1.jpg){html: width=50%}
![](@ref Tiled2.jpg){html: width=50%}
### Create a New Tileset
1. In the editor, go to the lower-right corner and select "New Tileset".
2. Give your tileset a name.
3. Make sure to select "Embed in map".
4. Choose your tilesheet as the source.
5. Leave the rest of the settings on default
![](@ref Tiled3.jpg){html: width=50%}
![](@ref Tiled4.jpg){html: width=50%}
### Draw Your Environment
Once imported, you can select tiles from the tileset and use them to build your environment.
### Understand Layers in Tiled
Tiled allows you to use multiple layers for organizing your map.
You need to give your Layers seperate z-Indices to decide their rendering order, the lower the number the earlier it gets rendered.
In order to do this:
1. Select a layer.
1. Right-click "Custom Properties" and go to "Add Property".
1. Add a new int property named "zIndex" and give it a number starting with 0 to decide when to render it (the lower the number the more the layer is in the background i.e. tiles on layer 0 will be covered by tiles on layer 1 if they occupy the same space).
![](@ref Tiled5.jpg){html: width=50%}
**Important: Tiles that should have collision must be placed on a separate layer as custom properties are per layer not per tile.**
### Set Up Collision
To add collision to a layer:
1. Select the layer you want to have collision.
1. Right-click and go to "Custom Properties".
1. Add a new boolean property named "collision" and tick the checkbox.
![](@ref Tiled5.jpg){html: width=50%}
Any tile placed on this layer will now automatically have collision—meaning moving entities cannot pass through them.
### Saving your work
After completeing your map, save it in the asset folder of the library (or any place really the asset folder just exists as a recommendation to easily find all of your maps and textures)
![](@ref Tiled6.jpg){html: width=50%}
### Loading your work into the game
The map gets loaded into the game in `GameImplementation.cpp`, simply add the path of the map .tmx file to the [Map](@ref Map) constructor

View File

@ -1,9 +1,5 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
//! \brief Animation struct to hold animation data
//! \param index The row in the sprite sheet (every 32 pixels on the y-axis is a new row)
//! \param frames The number of frames in the animation
//! \param speed The speed of the animation in milliseconds
struct Animation struct Animation
{ {
uint8_t index; uint8_t index;

View File

@ -7,31 +7,23 @@
class TransformComponent; class TransformComponent;
//! \brief Adds a collision box to an entity when added via entity.addComponent()
class ColliderComponent : public Component class ColliderComponent : public Component
{ {
public: public:
SDL_Rect& getCollider() { return collider; } //!< \returns the collider of the entity SDL_Rect collider;
const char* getTag() const { return tag; } //!< \returns the tag of the entity const char* tag;
bool hasCollision() const { return collision; } //!< \returns the collision state of the entity TransformComponent* transform;
bool hasCollision; //added for removing collision of destroyed projectiles
float hitboxScale; //adds a seperate variable for the scale of the hitbox (not the sprite) so each sprite can have a different hitbox size if needed
bool isProjectile = false;
//! \brief Constructor for ColliderComponent
//! \param tag The tag of the collider, can be any char*
ColliderComponent(const char* tag); ColliderComponent(const char* tag);
//! \brief Constructor for ColliderComponent
//! \param tag The tag of the collider, can be any char*
//! \param hitboxScale The scale of the collider, used to scale the collider size (this is independent of the sprite size), default is 1.0f and takes up the 32x32 pixels
ColliderComponent(const char* tag, float hitboxScale); ColliderComponent(const char* tag, float hitboxScale);
void init() override; void init() override;
void update(uint_fast16_t diffTime) override; void update(uint_fast16_t diffTime) override;
//! \brief Removes the collision of an entity
void removeCollision(); void removeCollision();
private:
SDL_Rect collider; void handleCollision(Vector2D& characterPos, SDL_Rect& characterCollider, SDL_Rect& componentCollider);
const char* tag;
TransformComponent* transform;
bool collision; //added for removing collision of destroyed projectiles
float hitboxScale; //adds a seperate variable for the scale of the hitbox (not the sprite) so each sprite can have a different hitbox size if needed
}; };

View File

@ -27,7 +27,6 @@ constexpr uint8_t DIRECTION_C = 4;
using IntersectionBitSet = std::bitset<DIRECTION_C>; using IntersectionBitSet = std::bitset<DIRECTION_C>;
// [IntersectionBitSet] // [IntersectionBitSet]
//! \brief Class responsible for collision detection and handling
class CollisionHandler class CollisionHandler
{ {
private: private:
@ -39,11 +38,7 @@ public:
manager(mManager) { }; manager(mManager) { };
~CollisionHandler(); ~CollisionHandler();
//! \brief Checks for intersections relative to entityA static IntersectionBitSet getIntersection( // intersections relative to entityA
//! \param entityA The first entity to check against
//! \param entityB The second entity to check against
//! \param posModA Modifier to apply to entityA's position before checking collisions
static IntersectionBitSet getIntersection(
Entity* entityA, Entity* entityA,
Entity* entityB, Entity* entityB,
Vector2D posModA = Vector2D(0,0), Vector2D posModA = Vector2D(0,0),

View File

@ -6,16 +6,14 @@
#include <optional> #include <optional>
#include "Component.h" #include "Component.h"
//! \brief DataComponent class to centrally store data about an entity such as stats
class DataComponent : public Component class DataComponent : public Component
{ {
public: public:
//! \brief The data component only has a default constructor
DataComponent() {}; DataComponent() {};
~DataComponent() {}; ~DataComponent() {};
/** /**
* @brief Set a key-value pair of any type in the data map * @brief Set a key-value pair of any type in the data map
* @details e.g. \code{.cpp}setEntry("speed", 180);\endcode in this case the key is "speed" and the value is set to an integer of 180 * @details e.g. setEntry("speed", 180); in this case the key is "speed" and the value is set to an integer of 180
* @param key The name to store the value under * @param key The name to store the value under
* @param value The value to store of type T * @param value The value to store of type T
*/ */
@ -24,8 +22,7 @@ public:
/** /**
* @brief Get a value of type T from the data map * @brief Get a value of type T from the data map
* @details e.g. \code{.cpp}getEntry<int>("speed").value();\endcode in this case the key is "speed" and the value is returned as an integer * @details e.g. getEntry<int>("speed"); in this case the key is "speed" and the value is returned as an integer
* @details the value() or value_or() is NEEDED to handle the optional return type
* @param key The name to retrieve the value from * @param key The name to retrieve the value from
* @return An optional of type T containing the value if it exists and matches in typeid, otherwise std::nullopt * @return An optional of type T containing the value if it exists and matches in typeid, otherwise std::nullopt
*/ */

View File

@ -34,15 +34,23 @@ using ComponentArray = std::array<Component*, MAX_COMPONENTS>;
class Entity class Entity
{ {
public: public:
//! \brief Some premade Entity groups used to avoid checking all entities for everything all of the time
/*!
* \brief Used for rendering order (last is highest) or retrieving entities of group
* \todo Label used in singular entity shouldn't use plural
* \todo HEARTS are rendered above POWERUPS, missleading order
* \todo PROJECTILE are rendered above POWERUPS, missleading order
* \todo Generalize HEARTS as UI or similar
*/
enum class GroupLabel enum class GroupLabel
{ {
MAPTILES, //!< Entity using TileComponent, internal use only MAPTILES, //!< Entity using TileComponent
PLAYERS, //!< Primary entity in player control, used to be able to interact with pickupables PLAYERS, //!< Primary entity in player controll
ENEMIES, //!< \deprecated All players now grouped as Entity::PLAYERS
COLLIDERS, //!< Fixed collider entity, e.g. a wall COLLIDERS, //!< Fixed collider entity, e.g. a wall
PROJECTILE, //!< Not used PROJECTILE, //!< \todo Document
HEARTS, //!< Not used HEARTS, //!< \todo Document
POWERUPS //!< Not used POWERUPS //!< \todo Document
}; };
/*! /*!
@ -62,12 +70,13 @@ public:
this->getComponent<ColliderComponent>().removeCollision(); this->getComponent<ColliderComponent>().removeCollision();
} }
} }
#ifndef DOXYGEN_SHOULD_SKIP_THIS
bool hasGroup(Group mGroup); //!< \sa GroupLabel bool hasGroup(Group mGroup); //!< \sa GroupLabel
void addGroup(Group mGroup); //!< \sa GroupLabel void addGroup(Group mGroup); //!< \sa GroupLabel
void delGroup(Group mGroup); //!< \sa GroupLabel void delGroup(Group mGroup); //!< \sa GroupLabel
//! \returns bitset with true on position GroupLabel if the entity belongs to group
//! \sa GroupLabel
std::bitset<MAX_GROUPS> getGroupBitSet(); std::bitset<MAX_GROUPS> getGroupBitSet();
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
//! \sa Manager //! \sa Manager
Manager& getManager() { return manager; }; Manager& getManager() { return manager; };
@ -77,8 +86,7 @@ public:
return componentBitSet[getComponentTypeID<T>()]; return componentBitSet[getComponentTypeID<T>()];
} }
//! \brief Adds specified type as component and calls its CONSTRUCTOR //! \brief Adds specified type as component and calls Component::init()
//! \details e.g. addComponent<Type of component>(parameters of constructor)
//! \param mArgs Constructor arguments of component //! \param mArgs Constructor arguments of component
template <typename T, typename...TArgs> T& addComponent(TArgs&&...mArgs) template <typename T, typename...TArgs> T& addComponent(TArgs&&...mArgs)
{ {
@ -94,17 +102,12 @@ public:
return *c; return *c;
}; };
//! \brief Access a specific component of an entity
//! \tparam T Type of component to access
//! \return Reference to component of type T
template <typename T> T& getComponent() const //!< \todo: rewrite to use optionals template <typename T> T& getComponent() const //!< \todo: rewrite to use optionals
{ {
auto ptr(componentArray[getComponentTypeID<T>()]); auto ptr(componentArray[getComponentTypeID<T>()]);
return *static_cast<T*>(ptr); return *static_cast<T*>(ptr);
} }
//! \brief Access a specific component of an entity as a pointer
//! \tparam T Type of component to access
//! \return Pointer to component of type T
template <typename T> std::shared_ptr<T> getComponentAsPointer() const template <typename T> std::shared_ptr<T> getComponentAsPointer() const
{ {
return std::static_pointer_cast<T>(components.at(getComponentTypeID<T>())); return std::static_pointer_cast<T>(components.at(getComponentTypeID<T>()));

View File

@ -1,9 +1,5 @@
#pragma once #pragma once
#include <cstdint>
#include <optional>
#include <string>
class GameInternal; class GameInternal;
// TODO: add managers here // TODO: add managers here

View File

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <iostream>
#include <map>
#include <functional> #include <functional>
#include <string>
#include <stdexcept> #include <stdexcept>
#include "Game.h" #include "Game.h"

View File

@ -1,13 +0,0 @@
#pragma once
#include "GameFactory.h"
namespace vego {
template<typename GameType>
struct GameRegistrar {
GameRegistrar() {
static_assert(std::is_base_of<Game, GameType>::value, "Your class must inherit from Game");
GameFactory::instance().registerClass([]() { return new GameType(); });
}
};
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "GameFactory.h"
namespace vego {
template<typename T>
class GameRegistryHelper {
public:
[[deprecated("GameRegistryHelper() does not take a className anymore")]]
GameRegistryHelper(const std::string& className) {
static_assert(std::is_base_of<Game, T>::value, "Your class must inherit from Game");
GameFactory::instance().registerClass(
[]() -> Game* { return new T; }
);
};
GameRegistryHelper() {
static_assert(std::is_base_of<Game, T>::value, "Your class must inherit from Game");
GameFactory::instance().registerClass(
[]() -> Game* { return new T; }
);
};
};
}

View File

@ -9,11 +9,13 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
//! \brief InputManager class to handle input events and actions
//! \details This class manages input events, allowing for the registration of actions and their corresponding key bindings.
class InputManager { class InputManager {
public: public:
//! \brief A list of every key that can be bound to an action enum class EventType {
KeyDown,
KeyUp
};
enum class Key enum class Key
{ {
UP, UP,
@ -97,10 +99,6 @@ public:
GRAVE GRAVE
}; };
//! \brief InputAction struct to represent an action and its bindings
//! \param name The name of the action
//! \param bindings The keys that are bound to this action
//! \param callback The function to call when the action is triggered
struct InputAction { struct InputAction {
std::string name; std::string name;
std::vector<Key> bindings; std::vector<Key> bindings;
@ -112,18 +110,9 @@ public:
void init(); // see if necessary void init(); // see if necessary
void processEvents(); void processEvents();
//! \brief Register an action with a name, key bindings, and a callback function void registerAction(const std::string& actionName, const std::vector<Key>& keys, std::function<void(bool)> callback, const std::string& context);
//! \param actionName The name of the action
//! \param keys The keys that are bound to this action
//! \param callback The function to call when the action is triggered
//! \param context The context in which the action is valid can be used to switch between e.g. gameplay and menu so the same keys can be used for different actions
void registerAction(const std::string& actionName, const std::vector<Key>& keys, std::function<void(bool)> callback, const std::string& context = "Default");
//! \brief set the active context, is "Default" by default
//! \param context The name of the context to set as active
void setActiveContext(const std::string& context); void setActiveContext(const std::string& context);
//! \brief Get the active context
std::string getActiveContext() const; std::string getActiveContext() const;
//void rebindAction(const std::string& actionName, const std::vector<Key>& newBindings, const std::string& context); //void rebindAction(const std::string& actionName, const std::vector<Key>& newBindings, const std::string& context);

View File

@ -5,8 +5,6 @@
#include <functional> #include <functional>
//! \brief InteractionComponent class to handle interaction events
//! \details This class manages interaction events, allowing for the registration of a callback function to be called when an interaction event is triggered.
class InteractionComponent : public Component, public InteractionListener class InteractionComponent : public Component, public InteractionListener
{ {
public: public:
@ -16,7 +14,6 @@ public:
*/ */
InteractionComponent(std::function<void(void*,void*)> callback); InteractionComponent(std::function<void(void*,void*)> callback);
void init() override;
/** /**
* @brief Internal function to be called when an interaction event is triggered. * @brief Internal function to be called when an interaction event is triggered.
*/ */

View File

@ -29,18 +29,13 @@ public:
//! \sa Entity::destroy() //! \sa Entity::destroy()
void refresh(); void refresh();
#ifndef DOXYGEN_SHOULD_SKIP_THIS
void addToGroup(Entity* mEntity, Group mGroup); //!< \todo `friend` to Entity void addToGroup(Entity* mEntity, Group mGroup); //!< \todo `friend` to Entity
std::vector<Entity*>& getGroup(Group mGroup); //!< \returns std::vector containing all entities in group Entity::GroupLabel std::vector<Entity*>& getGroup(Group mGroup); //!< \returns std::vector containing all entities in group Entity::GroupLabel
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
//! \brief Returns all entities currently loaded in the game
std::vector<Entity*> getAll(); //!< \returns std::vector containing all entities std::vector<Entity*> getAll(); //!< \returns std::vector containing all entities
//! \brief Add a new entity to the game
Entity& addEntity(); //!< Creates and returns a new, empty entity Entity& addEntity(); //!< Creates and returns a new, empty entity
/// \deprecated Use \ref VEGO_Game() instead
GameInternal* getGame() { return this->game; }; GameInternal* getGame() { return this->game; };
private: private:

View File

@ -11,7 +11,6 @@
#include <tmxlite/Types.hpp> #include <tmxlite/Types.hpp>
class GameInternal; class GameInternal;
//! \brief Class responsible for the creation and management of the map or background
class Map class Map
{ {
public: public:
@ -22,7 +21,6 @@ public:
* \sa Map::generateTiles() * \sa Map::generateTiles()
*/ */
Map(const char* path); Map(const char* path);
//! \brief Used to generate the tiles of a previously loaded map
void generateTiles(); //!< Generates the map based on the loaded definition void generateTiles(); //!< Generates the map based on the loaded definition
private: private:
// struct required for initialisation // struct required for initialisation
@ -47,7 +45,7 @@ private:
std::vector<std::function<void()>> tileConstructors; std::vector<std::function<void()>> tileConstructors;
void loadTileLayer(const tmx::TileLayer& layer); void loadTileLayer(const tmx::TileLayer& layer);
static void addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool collision); static void addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision);
template<typename T> template<typename T>
static std::optional<T> getLayerProperty(const std::vector<tmx::Property>& properties, std::string propertyName) { return std::nullopt; }; static std::optional<T> getLayerProperty(const std::vector<tmx::Property>& properties, std::string propertyName) { return std::nullopt; };

View File

@ -3,8 +3,6 @@
#include <functional> #include <functional>
#include "Component.h" #include "Component.h"
//! \brief PickupComponent class to handle pickup events
//! \details This class manages pickup events, allowing for the registration of a callback function to be called when an entity with this component collides with another entity that has the "players" group label.
class PickupComponent : public Component class PickupComponent : public Component
{ {
public: public:

View File

@ -11,8 +11,6 @@
class Vector2D; class Vector2D;
class Manager; class Manager;
//! \brief PickupManager class to handle the creation and management of pickups in the game
class PickupManager class PickupManager
{ {
public: public:
@ -20,12 +18,7 @@ public:
PickupManager(Manager* manager); PickupManager(Manager* manager);
~PickupManager(); ~PickupManager();
//! \brief Creates a pickupable item and adds it to the manager void createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture);
//! \param pos The position of the pickupable item
//! \param pickupFunc The function to be called when the pickupable item is picked up
//! \param texture The texture of the pickupable item
//! \details This function creates a pickupable item entity and adds it to the manager. The pickupable item is created with a transform component, a sprite component, a collider component and a pickup component. The pickup function is called when the powerup is picked up by an entity.
void createPickupable(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture);
Vector2D calculateSpawnPosition(); Vector2D calculateSpawnPosition();

View File

@ -13,7 +13,6 @@
class TransformComponent; class TransformComponent;
//! \brief SpriteComponent class to handle sprite rendering and animation of entities
class SpriteComponent : public Component, public RenderObject class SpriteComponent : public Component, public RenderObject
{ {
public: public:
@ -44,47 +43,17 @@ public:
//debug //debug
Textures getTexture() { return this->textureEnum; } Textures getTexture() { return this->textureEnum; }
//! \param texture The texture to be used for the sprite, must be a Texture enum
//! \param xOffset The x offset of the sprite relative to the transform component position, used for rendering position
//! \param yOffset The y offset of the sprite relative to the transform component position, used for rendering position
//! \param zIndex The z-index of the sprite, used for rendering order, in order to show up on the map, the zIndex must be higher than the layer you want it to show up on
SpriteComponent(Textures texture, int zIndex, int xOffset = 0, int yOffset = 0);
//! \param path The path to the texture to be used for the entity (for performance reasons, prefer enums instead)
//! \param xOffset The x offset of the sprite relative to the transform component position, used for rendering position
//! \param yOffset The y offset of the sprite relative to the transform component position, used for rendering position
//! \param zIndex The z-index of the sprite, used for rendering order, in order to show up on the map, the zIndex must be higher than the layer you want it to show up on
SpriteComponent(const char* path, int zIndex, int xOffset = 0, int yOffset = 0);
/** SpriteComponent(Textures texture, int zIndex);
* \brief Constructor used for **animated** sprites SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex);
* \param texture The texture to be used for the sprite, must be a Texture enum SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex);
* \param isAnimated Whether the sprite is animated or not
* \param animationList The list of animations to be used for the sprite (list of maps mapping a string to an \ref Animation struct)
* \param defaultAnimation The default animation to be used for the sprite when it first gets loaded
* \param zIndex The z-index of the sprite, used for rendering order, in order to show up on the map, the zIndex must be higher than the layer you want it to show up on
* \param xOffset The x offset of the sprite relative to the transform component position, used for rendering position
* \param yOffset The y offset of the sprite relative to the transform component position, used for rendering position
* ### How to spritesheet animation:
*
* An animation sprite sheet consists of multiple sprites of the specified size (library supports 32x32) arranged in a grid.
* Each row of the grid represents one animation, and each column in a row is one frame of the animation.
* If a sprite sheet contains multiple animations with different frame counts,
* you can just leave the rest of the row blank.
* Be aware to specify the correct frame count in the animation struct!
* \sa Animation
*
* \image html Animations1.jpg "Example of a sprite sheet with 2 animations of 2 frames each"
*/
SpriteComponent( SpriteComponent(
Textures texture, Textures texture,
bool isAnimated, bool isAnimated,
std::map<std::string, std::unique_ptr<Animation>>* animationList, std::map<std::string, std::unique_ptr<Animation>>* animationList,
std::string defaultAnimation, std::string defaultAnimation,
int zIndex, int zIndex);
int xOffset = 0,
int yOffset = 0);
~SpriteComponent(); ~SpriteComponent();
void setTexture(Textures texture); void setTexture(Textures texture);
@ -93,9 +62,6 @@ public:
void init() override; void init() override;
void update(uint_fast16_t diffTime) override; void update(uint_fast16_t diffTime) override;
void draw() override; void draw() override;
//! \brief By name select which animation should be played (gets looped)
//! \param type name previously set to an animation in animationList
void playAnimation(std::string type); void playAnimation(std::string type);
void setDirection(Direction direction); void setDirection(Direction direction);
}; };

View File

@ -14,7 +14,6 @@ struct StatEffect {
uint32_t startTime; uint32_t startTime;
}; };
//! \brief Manages the lifecycle of temporary effects
class StatEffectsComponent : public Component{ class StatEffectsComponent : public Component{
public: public:
StatEffectsComponent() {}; StatEffectsComponent() {};

View File

@ -5,40 +5,22 @@
#include "Constants.h" #include "Constants.h"
#include "DataComponent.h" #include "DataComponent.h"
//! \brief The transform component is responsible for the position, direction and size of an entity. It is used to move the entity in the game world and to determine its size and position on the screen.
class TransformComponent : public Component class TransformComponent : public Component
{ {
public: public:
Vector2D position; // TODO: change to int to save CPU time -> possibly subpixel coordinates Vector2D position; // TODO: change to int to save CPU time -> possibly subpixel coordinates
//! \brief The direction in which the entity is moving. (0, 0) is the default and signifies no movement.
//! \brief access direction with direction.x and direction.y for each direction
//! \brief x = 1 for right, -1 for left
//! \brief y = 1 for down, -1 for up
Vector2D direction; Vector2D direction;
int height = 32; int height = 32;
int width = 32; int width = 32;
float scale = 1; int scale = 1;
//! \attention in order to allow an entity to move the stat "speed" must be set in the DataComponent (written exactly like that and set to any positive int value, 0 will lead to no movement, negative numbers to backwards movement) explicit TransformComponent(int scale = 1);
TransformComponent(float x, float y, int scale = 1);
//! \param scale base value is 1 (32x32px), size gets multiplied with scale TransformComponent(float x, float y, int w, int h, int scale = 1);
explicit TransformComponent(float scale = 1);
//! \param x x coordinate of spawnposition
//! \param y y coordinate of spawnposition
//! \param scale base value is 1 (32x32px per default), size gets multiplied with scale
TransformComponent(float x, float y, float scale = 1);
//! \param x x coordinate of spawnposition
//! \param y y coordinate of spawnposition
//! \param w add custom width
//! \param h add custom height
//! \param scale base value is 1 (32x32px per default), size gets multiplied with scale
TransformComponent(float x, float y, int w, int h, float scale = 1);
void init() override; void init() override;
/*! TODO: document usage of collision handler */
void update(uint_fast16_t diffTime) override; void update(uint_fast16_t diffTime) override;
void setPositionAfterCollision(Vector2D& positionChange); void setPositionAfterCollision(Vector2D& positionChange);
int getSpeed(); int getSpeed();

View File

@ -4,16 +4,6 @@ namespace vego {
extern GameInternal* game; extern GameInternal* game;
} }
/**
* \brief gives access to internal resources such as managers and handlers
* \details gives access to the following useful managers and handlers
* - this is a list
* - using markdown
* - since markdown is supported :)
*
* 1. also numbered
* 2. lists works
*/
inline GameInternal& VEGO_Game() { inline GameInternal& VEGO_Game() {
return *vego::game; return *vego::game;
}; };

View File

@ -9,7 +9,7 @@
ColliderComponent::ColliderComponent(const char* tag) ColliderComponent::ColliderComponent(const char* tag)
{ {
this->tag = tag; this->tag = tag;
this->collision = true; this->hasCollision = true;
this->hitboxScale = 1; this->hitboxScale = 1;
} }
@ -17,7 +17,7 @@ ColliderComponent::ColliderComponent(const char* tag, float hitboxScale) //addin
{ {
this->tag = tag; this->tag = tag;
this->hitboxScale = hitboxScale; this->hitboxScale = hitboxScale;
this->collision = true; this->hasCollision = true;
} }
void ColliderComponent::init() void ColliderComponent::init()
@ -26,6 +26,10 @@ void ColliderComponent::init()
entity->addComponent<TransformComponent>(); entity->addComponent<TransformComponent>();
} }
if (strcmp(this->tag, "projectile") == 0) {
this->isProjectile = true;
}
transform = &entity->getComponent<TransformComponent>(); transform = &entity->getComponent<TransformComponent>();
this->update(0); this->update(0);
} }
@ -42,5 +46,18 @@ void ColliderComponent::update(uint_fast16_t diffTime)
void ColliderComponent::removeCollision() void ColliderComponent::removeCollision()
{ {
this->collision = false; this->hasCollision = false;
}
void ColliderComponent::handleCollision(Vector2D& entityPos, SDL_Rect& entityCollider, SDL_Rect& componentCollider)
{
// collision to right of character
if (entityPos.x < componentCollider.x)
{
entityPos.x = componentCollider.x - entityCollider.w;
}
else // collision to left of character
{
entityPos.x = componentCollider.x + componentCollider.w;
}
} }

View File

@ -18,8 +18,8 @@ IntersectionBitSet CollisionHandler::getIntersection(Entity* entityA, Entity* en
!entityB->hasComponent<ColliderComponent>()) !entityB->hasComponent<ColliderComponent>())
return std::bitset<DIRECTION_C>(); return std::bitset<DIRECTION_C>();
SDL_Rect colliderA = entityA->getComponent<ColliderComponent>().getCollider(); SDL_Rect colliderA = entityA->getComponent<ColliderComponent>().collider;
SDL_Rect colliderB = entityB->getComponent<ColliderComponent>().getCollider(); SDL_Rect colliderB = entityB->getComponent<ColliderComponent>().collider;
colliderA.x += posModA.x; colliderA.x += posModA.x;
colliderA.y += posModA.y; colliderA.y += posModA.y;
@ -61,7 +61,7 @@ IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity, V
if (!entity->hasComponent<ColliderComponent>()) if (!entity->hasComponent<ColliderComponent>())
return std::bitset<DIRECTION_C>(); return std::bitset<DIRECTION_C>();
SDL_Rect* collider = &entity->getComponent<ColliderComponent>().getCollider(); SDL_Rect* collider = &entity->getComponent<ColliderComponent>().collider;
std::bitset<DIRECTION_C> intersections; std::bitset<DIRECTION_C> intersections;
@ -152,8 +152,8 @@ Entity* CollisionHandler::getAnyIntersection<Entity*>(
{ {
if (!entity->hasComponent<ColliderComponent>()) return nullptr; if (!entity->hasComponent<ColliderComponent>()) return nullptr;
for (auto& collider : getColliders(groupLabels, excludedEntities)) { for (auto& collider : getColliders(groupLabels, excludedEntities)) {
SDL_Rect rect = entity->getComponent<ColliderComponent>().getCollider() + posMod; SDL_Rect rect = entity->getComponent<ColliderComponent>().collider + posMod;
if (SDL_HasRectIntersection(&rect, &collider->getCollider())) { if (SDL_HasRectIntersection(&rect, &collider->collider)) {
return collider->entity; return collider->entity;
} }
} }
@ -175,8 +175,8 @@ bool CollisionHandler::getAnyIntersection<bool>(
{ {
if (!entity->hasComponent<ColliderComponent>()) return false; if (!entity->hasComponent<ColliderComponent>()) return false;
for (auto& collider : getColliders(groupLabels, excludedEntities)) { for (auto& collider : getColliders(groupLabels, excludedEntities)) {
SDL_Rect rect = entity->getComponent<ColliderComponent>().getCollider() + posMod; SDL_Rect rect = entity->getComponent<ColliderComponent>().collider + posMod;
if (SDL_HasRectIntersection(&rect, &collider->getCollider())) { if (SDL_HasRectIntersection(&rect, &collider->collider)) {
return true; return true;
} }
} }

View File

@ -253,6 +253,7 @@ void InputManager::registerAction(const std::string& actionName, const std::vect
for (const auto& key : keys) { for (const auto& key : keys) {
actionsByContextAndKey[context][key].emplace_back(storedAction); actionsByContextAndKey[context][key].emplace_back(storedAction);
} }
std::cout << "Registered action: " << storedAction << " in context: " << context << std::endl;
} }
std::vector<InputManager::InputAction*> InputManager::getActionsByKey(const Key key) const { std::vector<InputManager::InputAction*> InputManager::getActionsByKey(const Key key) const {
@ -270,6 +271,7 @@ std::vector<InputManager::InputAction*> InputManager::getActionsByKey(const Key
void InputManager::setActiveContext(const std::string& context) { void InputManager::setActiveContext(const std::string& context) {
activeContext = context; activeContext = context;
std::cout << "Active context set to: " << activeContext << std::endl;
} }
std::string InputManager::getActiveContext() const { std::string InputManager::getActiveContext() const {
@ -284,12 +286,14 @@ SDL_AppResult InputManager::handleEvent(SDL_EventType type, SDL_Event* const eve
{ return pair.second == event->key.scancode; }); { return pair.second == event->key.scancode; });
if (keyIt != keyMap.end()) { if (keyIt != keyMap.end()) {
std::cout << "in != keymap.end" << std::endl;
Key pressedKey = keyIt->first; Key pressedKey = keyIt->first;
auto keyActions = actionsByContextAndKey[activeContext]; auto keyActions = actionsByContextAndKey[activeContext];
auto it = keyActions.find(pressedKey); auto it = keyActions.find(pressedKey);
if (it != keyActions.end()) { if (it != keyActions.end()) {
for (auto& action : it->second) { for (auto& action : it->second) {
std::cout << "Action triggered: " << action->name << " in context: " << activeContext << std::endl;
action->callback(type == SDL_EVENT_KEY_UP); action->callback(type == SDL_EVENT_KEY_UP);
} }
} }

View File

@ -3,11 +3,6 @@
#include "VEGO.h" #include "VEGO.h"
InteractionComponent::InteractionComponent(std::function<void(void*,void*)> callback) : interactionCallback(callback) InteractionComponent::InteractionComponent(std::function<void(void*,void*)> callback) : interactionCallback(callback)
{
}
void InteractionComponent::init()
{ {
VEGO_Game().interactionManager->registerListener(this->entity->getComponentAsPointer<InteractionComponent>()); VEGO_Game().interactionManager->registerListener(this->entity->getComponentAsPointer<InteractionComponent>());
} }

View File

@ -162,15 +162,15 @@ void Map::loadTileLayer(const tmx::TileLayer& layer)
this->tileConstructors.insert(this->tileConstructors.end(), tileConstructorRange.begin(), tileConstructorRange.end()); this->tileConstructors.insert(this->tileConstructors.end(), tileConstructorRange.begin(), tileConstructorRange.end());
} }
void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool collision) void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision)
{ {
auto& tile(VEGO_Game().manager.addEntity()); auto& tile(VEGO_Game().manager.addEntity());
tile.addComponent<TransformComponent>(x, y, mapTileSize.x, mapTileSize.y, 1); tile.addComponent<TransformComponent>(x, y, mapTileSize.x, mapTileSize.y, 1);
tile.addComponent<SpriteComponent>(texturePath.c_str(), zIndex, v, u); // why does uv need to be reversed? tile.addComponent<SpriteComponent>(texturePath.c_str(), v, u, zIndex); // why does uv need to be reversed?
//TODO: also implement updated map stuff for this //TODO: also implement updated map stuff for this
if (collision) { if (hasCollision) {
// tag currently does not have a clear purposes, TODO: figure out appropriate tag name // tag currently does not have a clear purposes, TODO: figure out appropriate tag name
tile.addComponent<ColliderComponent>("hello I am a collider of a tile!"); tile.addComponent<ColliderComponent>("hello I am a collider of a tile!");
tile.addGroup((size_t)Entity::GroupLabel::MAPTILES); tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);

View File

@ -22,7 +22,7 @@ PickupManager::PickupManager(Manager* manager) : man(manager) {}
PickupManager::~PickupManager() {} PickupManager::~PickupManager() {}
void PickupManager::createPickupable(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture) { void PickupManager::createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture) {
auto& powerups(man->addEntity()); auto& powerups(man->addEntity());
powerups.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects powerups.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects
@ -39,8 +39,6 @@ void PickupManager::createPickupable(Vector2D pos, std::function<void (Entity*)>
powerups.addGroup((size_t)Entity::GroupLabel::POWERUPS); powerups.addGroup((size_t)Entity::GroupLabel::POWERUPS);
} }
// \internal
// \brief Calculates a random spawn position for the powerup
Vector2D PickupManager::calculateSpawnPosition() Vector2D PickupManager::calculateSpawnPosition()
{ {
Vector2D spawnPos = Vector2D(-1, -1); Vector2D spawnPos = Vector2D(-1, -1);
@ -54,7 +52,7 @@ Vector2D PickupManager::calculateSpawnPosition()
conflict = false; conflict = false;
for (auto cc : this->man->getGame()->collisionHandler->getColliders({ Entity::GroupLabel::MAPTILES })) for (auto cc : this->man->getGame()->collisionHandler->getColliders({ Entity::GroupLabel::MAPTILES }))
{ {
if (SDL_HasRectIntersection(&spawnRect, &cc->getCollider()) && strcmp(cc->getTag(), "projectile")) if (SDL_HasRectIntersection(&spawnRect, &cc->collider) && strcmp(cc->tag, "projectile"))
{ {
conflict = true; conflict = true;
break; break;

View File

@ -15,13 +15,19 @@
#include "Manager.h" #include "Manager.h"
#include "VEGO.h" #include "VEGO.h"
SpriteComponent::SpriteComponent(Textures texture, int zIndex, int xOffset, int yOffset) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) SpriteComponent::SpriteComponent(Textures texture, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
{ {
this->textureEnum = texture; this->textureEnum = texture;
this->path = ""; this->path = "";
} }
SpriteComponent::SpriteComponent(const char* path, int zIndex, int xOffset, int yOffset) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) { SpriteComponent::SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset)
{
this->textureEnum = texture;
this->path = "";
}
SpriteComponent::SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) {
this->path = path; this->path = path;
} }
@ -31,9 +37,7 @@ SpriteComponent::SpriteComponent(
bool isAnimated, bool isAnimated,
std::map<std::string, std::unique_ptr<Animation>>* animationMap, std::map<std::string, std::unique_ptr<Animation>>* animationMap,
std::string defaultAnimation, std::string defaultAnimation,
int zIndex, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
int xOffset,
int yOffset) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset)
{ {
animated = isAnimated; animated = isAnimated;
@ -94,10 +98,6 @@ void SpriteComponent::draw()
void SpriteComponent::playAnimation(std::string type) void SpriteComponent::playAnimation(std::string type)
{ {
if (animations == nullptr) {
SDL_SetError("playAnimation() was called on a sprite without any animations");
return;
}
this->animationIndex = animations->at(type)->index; this->animationIndex = animations->at(type)->index;
this->frames = animations->at(type)->frames; this->frames = animations->at(type)->frames;
this->speed = animations->at(type)->speed; this->speed = animations->at(type)->speed;

View File

@ -13,20 +13,20 @@
#include "SoundManager.h" #include "SoundManager.h"
TransformComponent::TransformComponent(float scale) TransformComponent::TransformComponent(int scale)
{ {
position.zero(); position.zero();
this->scale = scale; this->scale = scale;
} }
TransformComponent::TransformComponent(float x, float y, float scale) TransformComponent::TransformComponent(float x, float y, int scale)
{ {
this->position.x = x; this->position.x = x;
this->position.y = y; this->position.y = y;
this->scale = scale; this->scale = scale;
} }
TransformComponent::TransformComponent(float x, float y, int w, int h, float scale) TransformComponent::TransformComponent(float x, float y, int w, int h, int scale)
{ {
this->position.x = x; this->position.x = x;
this->position.y = y; this->position.y = y;
@ -51,8 +51,7 @@ void TransformComponent::update(uint_fast16_t diffTime)
direction.y * this->getSpeed() * multiplier * diffTime * (1.f/1000) direction.y * this->getSpeed() * multiplier * diffTime * (1.f/1000)
); );
if (this->entity->hasComponent<ColliderComponent>() if (this->entity->hasGroup((size_t)Entity::GroupLabel::PLAYERS)){
&& this->entity->getComponent<ColliderComponent>().hasCollision()){
this->setPositionAfterCollision(positionChange); this->setPositionAfterCollision(positionChange);
} }