mirror of
https://github.com/Nimac0/SDL_Minigame
synced 2026-01-12 05:43:43 +00:00
new main logic & new time keeping
This commit is contained in:
parent
625ac98a57
commit
25414524a0
@ -24,7 +24,7 @@ public:
|
||||
AssetManager(Manager* manager);
|
||||
~AssetManager();
|
||||
|
||||
void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity* owner);
|
||||
void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, const char* texturePath, Entity* owner);
|
||||
void createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, std::string texturePath);
|
||||
|
||||
Vector2D calculateSpawnPosition();
|
||||
|
||||
@ -22,7 +22,7 @@ public:
|
||||
ColliderComponent(const char* tag, float hitboxScale);
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
void removeCollision();
|
||||
|
||||
void handleCollision(Vector2D& characterPos, SDL_Rect& characterCollider, SDL_Rect& componentCollider);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
class Entity;
|
||||
|
||||
class Component
|
||||
@ -8,7 +9,7 @@ public:
|
||||
Entity* entity;
|
||||
|
||||
virtual void init() {}
|
||||
virtual void update() {}
|
||||
virtual void update(uint_fast16_t diffTime) {}
|
||||
|
||||
virtual ~Component() = default;
|
||||
};
|
||||
@ -59,7 +59,7 @@ public:
|
||||
explicit Entity(Manager& mManager) :
|
||||
manager(mManager) { };
|
||||
|
||||
void update() const; //!< Call each frame to update all components
|
||||
void update(uint_fast16_t diffTime) const; //!< Call each frame to update all components
|
||||
|
||||
bool isActive() const { return this->active; } //!< \sa destroy()
|
||||
//! Mark for destruction for Manager::refresh() and disables collision
|
||||
|
||||
@ -8,7 +8,7 @@ public:
|
||||
virtual ~Game() {}
|
||||
|
||||
virtual void init() = 0;
|
||||
virtual void update() = 0;
|
||||
virtual void update(uint_fast16_t diffTime) = 0;
|
||||
|
||||
GameInternal* gameInternal; //!< \deprecated
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <SDL3_mixer/SDL_mixer.h>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
@ -26,10 +27,10 @@ public:
|
||||
GameInternal();
|
||||
~GameInternal();
|
||||
|
||||
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
|
||||
SDL_AppResult init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
|
||||
|
||||
void handleEvents();
|
||||
void update();
|
||||
void update(Uint64 frameTime);
|
||||
void render();
|
||||
void clean();
|
||||
bool isRunning() const;
|
||||
@ -63,4 +64,6 @@ private:
|
||||
int counter = 0;
|
||||
bool running = true;
|
||||
SDL_Window* window;
|
||||
|
||||
Uint64 lastFrameTime = 0;
|
||||
};
|
||||
|
||||
@ -94,7 +94,7 @@ public:
|
||||
~InputComponent();
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
|
||||
bool isKeyDown(Key key);
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ class Manager
|
||||
public:
|
||||
Manager(GameInternal* game) : game(game) {};
|
||||
|
||||
void update(); //!< \sa Entity::update()
|
||||
void update(uint_fast16_t diffTime); //!< \sa Entity::update()
|
||||
//! Disables all functionality of entities marked for destruction
|
||||
//! \sa Entity::destroy()
|
||||
void refresh();
|
||||
|
||||
@ -9,7 +9,7 @@ public:
|
||||
PowerupComponent(std::function<void (Entity*)> func);
|
||||
~PowerupComponent() {};
|
||||
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
|
||||
private:
|
||||
std::function<void (Entity*)> pickupFunc;
|
||||
|
||||
@ -16,14 +16,14 @@ public:
|
||||
~ProjectileComponent() {}
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
|
||||
private:
|
||||
TransformComponent* transformComponent;
|
||||
|
||||
int range = 0;
|
||||
int speed = 0;
|
||||
int distance = 0;
|
||||
float speed = 0;
|
||||
float distance = 0;
|
||||
|
||||
Entity* owner = nullptr;
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ public:
|
||||
void setTexture(const char* path);
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
void draw() override;
|
||||
void playAnimation(std::string type);
|
||||
void setDirection(Direction direction);
|
||||
|
||||
@ -16,7 +16,7 @@ public:
|
||||
~StatEffectsComponent() {};
|
||||
|
||||
void init() override;
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
|
||||
void modifyStatDur(Stats stat, int duration, int value);
|
||||
|
||||
|
||||
@ -25,11 +25,11 @@ public:
|
||||
|
||||
void init() override;
|
||||
/*! TODO: document usage of collision handler */
|
||||
void update() override;
|
||||
void update(uint_fast16_t diffTime) override;
|
||||
void setPositionAfterCollision(Vector2D& positionChange);
|
||||
void modifySpeed(int8_t modifier);
|
||||
|
||||
private:
|
||||
int speed = 3;
|
||||
int speed = 180;
|
||||
int speedMod = 0;
|
||||
};
|
||||
|
||||
@ -46,7 +46,7 @@ Mix_Music* AssetManager::getMusic(std::string id)
|
||||
return music.at(id);
|
||||
}
|
||||
|
||||
void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity* owner) {
|
||||
void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, const char* texturePath, Entity* owner) {
|
||||
|
||||
auto& projectile(man->addEntity());
|
||||
projectile.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects
|
||||
|
||||
@ -31,10 +31,10 @@ void ColliderComponent::init()
|
||||
}
|
||||
|
||||
transform = &entity->getComponent<TransformComponent>();
|
||||
this->update();
|
||||
this->update(0);
|
||||
}
|
||||
|
||||
void ColliderComponent::update()
|
||||
void ColliderComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
collider.x = transform->position.x - (transform->width - transform->width * transform->scale * this->hitboxScale) / 2;
|
||||
collider.y = transform->position.y - (transform->width - transform->width * transform->scale * this->hitboxScale) / 2;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
#include "Component.h"
|
||||
#include <cstddef>
|
||||
|
||||
void Entity::update() const
|
||||
void Entity::update(uint_fast16_t diffTime) const
|
||||
{
|
||||
for (auto const& c : components) c->update();
|
||||
for (auto const& c : components) c->update(diffTime);
|
||||
}
|
||||
|
||||
bool Entity::hasGroup(Group mGroup)
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
#include "Game.h"
|
||||
#include "GameFactory.h"
|
||||
|
||||
#include <VEGO.h>
|
||||
|
||||
GameInternal::GameInternal() :
|
||||
manager(this),
|
||||
renderManager(),
|
||||
@ -25,7 +27,7 @@ GameInternal::GameInternal() :
|
||||
|
||||
GameInternal::~GameInternal() = default;
|
||||
|
||||
void GameInternal::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
|
||||
SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
|
||||
{
|
||||
GameInternal::assets = new AssetManager(&manager);
|
||||
GameInternal::textureManager = new TextureManager(&manager);
|
||||
@ -42,12 +44,12 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
|
||||
{
|
||||
std::cout << "ERROR. Subsystem couldnt be initialized! " << SDL_GetError() << std::endl;
|
||||
SDL_ClearError();
|
||||
return;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (Mix_Init(MIX_INIT_MP3) != MIX_INIT_MP3) {
|
||||
std::cout << "ERROR. Subsystem couldnt be initialized!" << std::endl;
|
||||
return;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow(title, width, height, flags);
|
||||
@ -55,7 +57,7 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
|
||||
{
|
||||
std::cout << "ERROR: Window couldnt be created! " << SDL_GetError() << std::endl;
|
||||
SDL_ClearError();
|
||||
return;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
// bad
|
||||
@ -72,7 +74,7 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
|
||||
{
|
||||
std::cout << "ERROR: Renderer couldnt be created! " << SDL_GetError() << std::endl;
|
||||
SDL_ClearError();
|
||||
return;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
|
||||
@ -80,7 +82,7 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
|
||||
{
|
||||
std::cout << "ERROR: Mixer couldnt be initialized! " << SDL_GetError() << std::endl;
|
||||
SDL_ClearError();
|
||||
return;
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
Mix_Volume(-1, MIX_MAX_VOLUME);
|
||||
@ -95,6 +97,8 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he
|
||||
|
||||
this->gameInstance = GameFactory::instance().create(this);
|
||||
this->gameInstance->init();
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void GameInternal::handleEvents()
|
||||
@ -111,12 +115,16 @@ void GameInternal::handleEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void GameInternal::update()
|
||||
void GameInternal::update(Uint64 frameTime)
|
||||
{
|
||||
manager.refresh();
|
||||
manager.update();
|
||||
|
||||
this->gameInstance->update(); // TODO: this might have to be split up into two update functions, before and after manager...
|
||||
uint_fast16_t diffTime = frameTime - this->lastFrameTime;
|
||||
manager.update(diffTime);
|
||||
|
||||
this->gameInstance->update(diffTime); // TODO: this might have to be split up into two update functions, before and after manager...
|
||||
|
||||
this->lastFrameTime = frameTime;
|
||||
}
|
||||
|
||||
void GameInternal::render()
|
||||
|
||||
@ -10,7 +10,7 @@ InputComponent::~InputComponent() = default;
|
||||
|
||||
void InputComponent::init(){}
|
||||
|
||||
void InputComponent::update()
|
||||
void InputComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
}
|
||||
|
||||
@ -27,9 +27,9 @@ void Manager::refresh()
|
||||
std::end(entities));
|
||||
}
|
||||
|
||||
void Manager::update()
|
||||
void Manager::update(uint_fast16_t diffTime)
|
||||
{
|
||||
for (auto& e : entities) e->update();
|
||||
for (auto& e : entities) e->update(diffTime);
|
||||
}
|
||||
|
||||
void Manager::addToGroup(Entity* mEntity, Group mGroup)
|
||||
|
||||
@ -12,7 +12,7 @@ PowerupComponent::PowerupComponent(std::function<void (Entity*)> func)
|
||||
this->pickupFunc = func;
|
||||
}
|
||||
|
||||
void PowerupComponent::update()
|
||||
void PowerupComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
Entity* player;
|
||||
if ((player = this->entity->getManager().getGame()->collisionHandler->getAnyIntersection<Entity*>(
|
||||
|
||||
@ -17,9 +17,9 @@ void ProjectileComponent::init()
|
||||
SoundManager::playSound(this->entity->getManager().getGame(), "throw_egg", true, PLAY_ONCE, MAX_VOLUME, -1);
|
||||
}
|
||||
|
||||
void ProjectileComponent::update()
|
||||
void ProjectileComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
distance += speed;
|
||||
distance += speed * diffTime * (1.f/1000);
|
||||
|
||||
IntersectionBitSet boundsIntersection = this->entity->getManager().getGame()->collisionHandler->getIntersectionWithBounds(entity);
|
||||
|
||||
@ -27,7 +27,7 @@ void ProjectileComponent::update()
|
||||
this->entity->destroy();
|
||||
}
|
||||
|
||||
if (distance > range) {
|
||||
if (distance > range && false) {
|
||||
this->entity->destroy();
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#include "SoundManager.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -59,14 +59,14 @@ void SpriteComponent::init()
|
||||
this->srcRect.x = this->textureXOffset * this->srcRect.w;
|
||||
this->srcRect.y = this->textureYOffset * this->srcRect.h;;
|
||||
|
||||
this->update();
|
||||
this->update(0);
|
||||
}
|
||||
|
||||
void SpriteComponent::update()
|
||||
void SpriteComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
// This code is not compatible for animated tiles
|
||||
if (animated) {
|
||||
srcRect.x = srcRect.w * static_cast<int>((SDL_GetTicks() / speed) % frames);
|
||||
srcRect.x = srcRect.w * static_cast<int>((SDL_GetTicks() / speed) % frames); // TODO: should not call SDL_GetTicks() but use diffTime
|
||||
|
||||
srcRect.y = animationIndex * transform->height;
|
||||
}
|
||||
|
||||
@ -8,16 +8,16 @@
|
||||
void StatEffectsComponent::init()
|
||||
{}
|
||||
|
||||
void StatEffectsComponent::update()
|
||||
void StatEffectsComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
for (int i = 0; i < MAX_STATS; i++)
|
||||
{
|
||||
if (this->buffs.at(i) == 0) continue;
|
||||
if (this->buffs.at(i) - 1 == 0)
|
||||
if (this->buffs.at(i) <= 0) continue;
|
||||
if (this->buffs.at(i) - diffTime <= 0)
|
||||
{
|
||||
this->resetStatValue((Stats)i);
|
||||
}
|
||||
this->buffs.at(i) -= 1;
|
||||
this->buffs.at(i) -= diffTime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ void StatEffectsComponent::modifyStatValue(Stats stat, int modifier) //modifier
|
||||
switch (stat)
|
||||
{
|
||||
case Stats::MOVEMENT_SPEED:
|
||||
this->entity->getComponent<TransformComponent>().modifySpeed(modifier);
|
||||
this->entity->getComponent<TransformComponent>().modifySpeed(modifier * 60);
|
||||
break;
|
||||
case Stats::ATTACK_SPEED:
|
||||
// this->entity->getComponent<KeyboardController>().modifyAtkSpeed(modifier);
|
||||
|
||||
@ -50,12 +50,12 @@ void TransformComponent::init()
|
||||
direction.zero();
|
||||
}
|
||||
|
||||
void TransformComponent::update()
|
||||
void TransformComponent::update(uint_fast16_t diffTime)
|
||||
{
|
||||
float multiplier = direction.x != 0 && direction.y != 0 ? 0.707 : 1; // normalizes vector; only works if directions are in increments of 45°
|
||||
Vector2D positionChange(
|
||||
direction.x * this->getSpeed() * multiplier,
|
||||
direction.y * this->getSpeed() * multiplier
|
||||
direction.x * this->getSpeed() * multiplier * diffTime * (1.f/1000),
|
||||
direction.y * this->getSpeed() * multiplier * diffTime * (1.f/1000)
|
||||
);
|
||||
|
||||
if (this->entity->hasGroup((size_t)Entity::GroupLabel::PLAYERS)){
|
||||
|
||||
48
src/_Init.cpp
Normal file
48
src/_Init.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "SDL3/SDL_init.h"
|
||||
#include <cstdint>
|
||||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
#include "VEGO.h"
|
||||
#include "Entity.h"
|
||||
#include "GameInternal.h"
|
||||
#include "Constants.h"
|
||||
|
||||
GameInternal* vego::game = nullptr;
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
||||
srand(time(NULL));
|
||||
bool playing = true;
|
||||
|
||||
*appstate = vego::game = new GameInternal();
|
||||
|
||||
return vego::game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false);
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate) {
|
||||
if (!vego::game->isRunning()) {
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
vego::game->handleEvents(); // bad
|
||||
|
||||
Uint64 frameStart = SDL_GetTicks();
|
||||
|
||||
vego::game->update(frameStart);
|
||||
vego::game->render();
|
||||
|
||||
int frameTime = SDL_GetTicks() - frameStart;
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
|
||||
vego::game->clean();
|
||||
}
|
||||
42
src/main.cpp
42
src/main.cpp
@ -1,42 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
#include "VEGO.h"
|
||||
#include "Entity.h"
|
||||
#include "GameInternal.h"
|
||||
#include "Constants.h"
|
||||
|
||||
GameInternal* vego::game = nullptr;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
srand(time(NULL));
|
||||
bool playing = true;
|
||||
|
||||
const int frameDelay = 1000 / FPS;
|
||||
|
||||
Uint32 frameStart;
|
||||
int frameTime;
|
||||
|
||||
vego::game = new GameInternal();
|
||||
|
||||
vego::game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false);
|
||||
while (vego::game->isRunning()) {
|
||||
frameStart = SDL_GetTicks();
|
||||
|
||||
vego::game->handleEvents();
|
||||
vego::game->update();
|
||||
vego::game->render();
|
||||
|
||||
frameTime = SDL_GetTicks() - frameStart;
|
||||
|
||||
if (frameDelay > frameTime) {
|
||||
SDL_Delay(frameDelay - frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
vego::game->clean();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user