From e20929ffa974efdf4e3e52bb3c1e1651e4e7d977 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 11 Oct 2018 15:17:45 +0100 Subject: [PATCH] Camera now applied to more render calls and started a demo --- TODO.txt | 2 + crumpet-engine/crumpet-engine.h | 2 + crumpet-engine/entity.h | 4 +- crumpet-engine/main.cpp | 69 +++++++++++++++++---------------- crumpet-engine/renderer.cpp | 39 ++++++++++++------- crumpet-engine/renderer.h | 9 ++++- crumpet-engine/sprite.cpp | 32 ++++++++++++++- crumpet-engine/sprite.h | 16 ++++++++ 8 files changed, 121 insertions(+), 52 deletions(-) diff --git a/TODO.txt b/TODO.txt index c9b91c5..1914e45 100644 --- a/TODO.txt +++ b/TODO.txt @@ -8,6 +8,7 @@ x -> complete [ ] Memory leak in rendering pipeline **TODO** +[ ] Comment the code [ ] Fix entity / sprite resizing [x] Add sprite methods to entity [x] Remove member initialization lists from Sprite and Entity, use Vec2* instead @@ -34,6 +35,7 @@ x -> complete [x] Render to GameWorld coordinates instead of screen coordinates [-] Each entity and sprite should store a reference to Camera [ ] Fix zoom in the camera + [ ] Objects that are off the screen, do not get rendered [ ] GameWorld class with coordinate system [?] Switch between camera modes on GameWorld [ ] Multiple scenes stored as levels diff --git a/crumpet-engine/crumpet-engine.h b/crumpet-engine/crumpet-engine.h index 318a159..004f49b 100644 --- a/crumpet-engine/crumpet-engine.h +++ b/crumpet-engine/crumpet-engine.h @@ -3,3 +3,5 @@ #include "game.h" #include "timer.h" #include "sprite.h" + +#undef main diff --git a/crumpet-engine/entity.h b/crumpet-engine/entity.h index 7491a3c..35648ed 100644 --- a/crumpet-engine/entity.h +++ b/crumpet-engine/entity.h @@ -47,8 +47,8 @@ public: virtual ~Entity(); protected: Renderer* m_renderer; - // std::string PATH = "C:/Users/Ben/Desktop/crumpet-engine"; - std::string PATH = "E:/Games/crumpet-engine"; + std::string PATH = "C:/Users/Ben/Desktop/crumpet-engine"; + // std::string PATH = "E:/Games/crumpet-engine"; private: std::string m_name; diff --git a/crumpet-engine/main.cpp b/crumpet-engine/main.cpp index fe3981a..862db4c 100644 --- a/crumpet-engine/main.cpp +++ b/crumpet-engine/main.cpp @@ -1,7 +1,5 @@ #include "crumpet-engine.h" -#undef main - #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 @@ -11,42 +9,33 @@ int main(int argc, char** argv) { game.AddCamera("free", &camera); game.UseCamera("free"); Timer timer; - - Entity rect("rect", game.renderer, PolyDrawType::DRAW_FILLED_RECT); - rect.SetDrawColour(new Vec4(35, 89, 89, 255)); - rect.SetRect(new Rect(130, 20, 100, 100)); - - Entity lines("lines", game.renderer, PolyDrawType::DRAW_LINES); - lines.SetDrawColour(new Vec4(164, 66, 244, 255)); - lines.AddVecPoint(new Vec4(1, 1, 3323, 5335)); - lines.AddVecPoint(new Vec4(626, 1, 333, 344)); - lines.AddVecPoint(new Vec4(1, 23, 645, 5335)); - - Sprite sans("sans", game.renderer, SpriteType::SPRITE_ANIMATED); - sans.LoadSpriteTextures("/resources/sans-undertale-spritesheet.png"); - sans.UseSpriteSheet(SpriteState::STATE_FRONT, 30, 9, 230, 300, 10, 4); - sans.UseSpriteSheet(SpriteState::STATE_RIGHT, 30, 320, 170, 300, 10, 4); - sans.UseSpriteSheet(SpriteState::STATE_LEFT, 40, 640, 170, 300, 10, 4); - sans.Pos = &Vec2(100, 100); Sprite explosion("explosion", game.renderer ,SpriteType::SPRITE_ANIMATED); explosion.LoadSpriteTextures("/resources/explosion.png"); explosion.UseSpriteSheet(SpriteState::STATE_DEFAULT, 1, 260, 64, 63, 0, 16); explosion.ResizeSpriteStateByFactor(SpriteState::STATE_DEFAULT, 4); + Sprite woman("woman", game.renderer, SpriteType::SPRITE_ANIMATED); + woman.LoadSpriteTextures("/resources/woman-spritesheet.png"); + woman.UseSpriteSheet(SpriteState::STATE_DEFAULT, 15, 1, 45, 105, 35, 14); + woman.ResizeSpriteStateByFactor(SpriteState::STATE_DEFAULT, 4); + woman.UseSpriteSheet(SpriteState::STATE_STANDING, 19, 109, 45, 105, 35, 2); + woman.ResizeSpriteStateByFactor(SpriteState::STATE_STANDING, 4); + woman.UseSpriteSheet(SpriteState::STATE_ACCELERATING, 19, 214, 74, 105, 1, 5); + woman.ResizeSpriteStateByFactor(SpriteState::STATE_ACCELERATING, 4); + woman.UseSpriteSheet(SpriteState::STATE_RUNNING, 0, 321, 77, 105, 3, 10); + woman.ResizeSpriteStateByFactor(SpriteState::STATE_RUNNING, 4); + + + woman.SetSpriteState(SpriteState::STATE_RUNNING); + + int i = 0; + int runningDirection = 0; // 0 = standing, 1 = right, 2 = left while (!game.renderer->IsDisplayClosed()) { game.PollEvents(); if (timer.GetTimeElapsed() >= game.TargetMsPerUpdate) { // Constant update rate, despite framerate - const Uint8 *state = SDL_GetKeyboardState(NULL); - if (state[SDL_SCANCODE_D]) { - sans.Spritestate = SpriteState::STATE_RIGHT; - sans.Pos->x += 10; - } else if (state[SDL_SCANCODE_A]) { - sans.Spritestate = SpriteState::STATE_LEFT; - sans.Pos->x -= 10; - } else sans.Spritestate = SpriteState::STATE_FRONT; if (state[SDL_SCANCODE_UP]) { camera.TranslateViewY(-10); @@ -66,18 +55,32 @@ int main(int argc, char** argv) { } if (timer.ticks % 5 == 0) { - sans.TickAninmation(); - explosion.TickAninmation(); + // explosion.TickAninmation(); + + i++; + // Slower animation speed for standing than everything else + if (woman.Spritestate == SpriteState::STATE_STANDING) { + if (timer.ticks % 60 == 0) { + woman.TickAninmation(); + } + } else { + woman.TickAninmation(); + } + // After inital loading sprite, switches to silouette + if (i > 14 && woman.Spritestate == SpriteState::STATE_DEFAULT) { + woman.SetSpriteState(SpriteState::STATE_STANDING); + i = 0; + } } timer.Tick(); } game.renderer->RenderClear(); - sans.Render(); - explosion.Render(); - rect.Render(); - lines.Render(); + + // explosion.Render(); + woman.Render(); + game.renderer->RenderUpdate(); } diff --git a/crumpet-engine/renderer.cpp b/crumpet-engine/renderer.cpp index 8e44bcf..76239be 100644 --- a/crumpet-engine/renderer.cpp +++ b/crumpet-engine/renderer.cpp @@ -25,13 +25,15 @@ void Renderer::SetRendererColour(Vec4* col) { } void Renderer::RenderEmptyRect(Rect* rect) { - SDL_Rect temp{ rect->GetX() - ActiveCamera->GetX(), rect->GetY() - ActiveCamera->GetY(), rect->GetW(), rect->GetH() }; - SDL_RenderDrawRect(this->SDLRenderer, &temp); + Rect temp{ rect->GetX() - ActiveCamera->GetX(), rect->GetY() - ActiveCamera->GetY(), rect->GetW(), rect->GetH() }; + SDL_RenderDrawRect(this->SDLRenderer, temp.ToSDLRect()); + temp.~Rect(); } void Renderer::RenderFilledRect(Rect* rect) { - SDL_Rect temp{ rect->GetX() - ActiveCamera->GetX(), rect->GetY() - ActiveCamera->GetY(), rect->GetW(), rect->GetH() }; - SDL_RenderFillRect(this->SDLRenderer, &temp); + Rect temp{ rect->GetX() - ActiveCamera->GetX(), rect->GetY() - ActiveCamera->GetY(), rect->GetW(), rect->GetH() }; + SDL_RenderFillRect(this->SDLRenderer, temp.ToSDLRect()); + temp.~Rect(); } void Renderer::RenderLines(std::vector points) { @@ -41,31 +43,40 @@ void Renderer::RenderLines(std::vector points) { } void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* texture) { - //Zoom implimentation (BROKEN) - // SDL_Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW() * ActiveCamera->Zoom, toRect->GetH() * ActiveCamera->Zoom }; - SDL_Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW(), toRect->GetH() }; - SDL_RenderCopy(SDLRenderer, texture, fromRect->ToSDLRect(), &toSDLRect); + // Zoom implimentation (BROKEN) + //SDL_Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW() * ActiveCamera->Zoom, toRect->GetH() * ActiveCamera->Zoom }; + Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW(), toRect->GetH() }; + SDL_RenderCopy(SDLRenderer, texture, fromRect->ToSDLRect(), toSDLRect.ToSDLRect()); + toSDLRect.~Rect(); } -//TODO: apply camera renderer to these next 3 methiods +// TODO: apply camera renderer to these next 3 methiods void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface) { SDL_Texture* texture = SDL_CreateTextureFromSurface(SDLRenderer, surface); - SDL_RenderCopy(SDLRenderer, texture, fromRect->ToSDLRect(), toRect->ToSDLRect()); + Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW(), toRect->GetH() }; + SDL_RenderCopy(SDLRenderer, texture, fromRect->ToSDLRect(), toSDLRect.ToSDLRect()); SDL_DestroyTexture(texture); + toSDLRect.~Rect(); } -void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* texture, const double angle, Vec2* rotationCenter) { +void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* texture, const double angle, Vec2* rotationCenter, SDL_RendererFlip flip = SDL_FLIP_NONE) { SDL_Point temp = { rotationCenter->x, rotationCenter->y }; SDL_Point* center = new SDL_Point(temp); - SDL_RenderCopyEx(SDLRenderer, texture, fromRect->ToSDLRect(), toRect->ToSDLRect(), angle, center, SDL_FLIP_NONE); + Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW(), toRect->GetH() }; + SDL_RenderCopyEx(SDLRenderer, texture, fromRect->ToSDLRect(), toSDLRect.ToSDLRect(), angle, center, flip); + delete center; + toSDLRect.~Rect(); } -void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface, const double angle, Vec2* rotationCenter) { +void Renderer::RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface, const double angle, Vec2* rotationCenter, SDL_RendererFlip flip = SDL_FLIP_NONE) { SDL_Point temp = { rotationCenter->x, rotationCenter->y }; SDL_Point* center = new SDL_Point(temp); SDL_Texture* texture = SDL_CreateTextureFromSurface(SDLRenderer, surface); - SDL_RenderCopyEx(SDLRenderer, texture, fromRect->ToSDLRect(), toRect->ToSDLRect(), angle, center, SDL_FLIP_NONE); + Rect toSDLRect{ toRect->GetX() - ActiveCamera->GetX(), toRect->GetY() - ActiveCamera->GetY(), toRect->GetW(), toRect->GetH() }; + SDL_RenderCopyEx(SDLRenderer, texture, toSDLRect.ToSDLRect(), toRect->ToSDLRect(), angle, center, flip); SDL_DestroyTexture(texture); + delete center; + toSDLRect.~Rect(); } void Renderer::ApplyCameraToScene(Camera* camera) { diff --git a/crumpet-engine/renderer.h b/crumpet-engine/renderer.h index 0d8f69a..f55bce6 100644 --- a/crumpet-engine/renderer.h +++ b/crumpet-engine/renderer.h @@ -14,13 +14,18 @@ public: Camera* ActiveCamera; void SetRendererColour(Vec4* col); + + // TODO: for the render pipeline, each method should work out if a rectangle + //is off the screen and then it will render it only if it is on + //the screen, alternitavely i could have a helper method that takes + //a rectangle and works out if it's off the screen or not void RenderEmptyRect(Rect* rect); void RenderFilledRect(Rect* rect); void RenderLines(std::vector points); void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* texture); void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface); - void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* surface, const double angle, Vec2* rotationCenter); - void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface, const double angle, Vec2* rotationCenter); + void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Texture* surface, const double angle, Vec2* rotationCenter, SDL_RendererFlip flip); + void RenderTexture(Rect* fromRect, Rect* toRect, SDL_Surface* surface, const double angle, Vec2* rotationCenter, SDL_RendererFlip flip); void ApplyCameraToScene(Camera* camera); diff --git a/crumpet-engine/sprite.cpp b/crumpet-engine/sprite.cpp index 81d3933..3f228a9 100644 --- a/crumpet-engine/sprite.cpp +++ b/crumpet-engine/sprite.cpp @@ -53,6 +53,28 @@ void Sprite::TickAninmation() { if (m_currentFrame > m_spriteMaps[Spritestate].size()) m_currentFrame = 1; } +void Sprite::SetSpriteState(SpriteState state) { + Spritestate = state; +} + +void Sprite::FlipSprite(SDL_RendererFlip flip) { + Flip = flip; +} + +void Sprite::UnflipSprite() { + Flip = SDL_FLIP_NONE; +} + +void Sprite::FlipSpriteH() { + if (Flip != SDL_FLIP_HORIZONTAL) Flip = SDL_FLIP_NONE; + else Flip = SDL_FLIP_HORIZONTAL; +} + +void Sprite::FlipSpriteV() { + if (Flip != SDL_FLIP_VERTICAL) Flip = SDL_FLIP_NONE; + else Flip = SDL_FLIP_VERTICAL; +} + // TODO: get this and the next method done correct //at the moment the SpriteState(i) will just check for //sprites with that state, and if they exist it will @@ -89,12 +111,20 @@ void Sprite::Move(Vec2* offset) { Pos->y += offset->y; } +void Sprite::MoveX(int offset) { + Pos->x += offset; +} + +void Sprite::MoveY(int offset) { + Pos->y += offset; +} + void Sprite::Render() { Rect* currentFrameClip = m_spriteMaps[Spritestate][m_currentFrame]; Vec2* currentRenderSize = m_spriteSize[Spritestate]; Rect currentFrameDest(Pos->x, Pos->y, currentRenderSize->x, currentRenderSize->y); - m_renderer->RenderTexture(currentFrameClip, ¤tFrameDest, m_spriteSheetTexture); + m_renderer->RenderTexture(currentFrameClip, ¤tFrameDest, m_spriteSheetTexture, 0, &Vec2(0,0), Flip); } Sprite::~Sprite() { diff --git a/crumpet-engine/sprite.h b/crumpet-engine/sprite.h index e3c8dc5..bf221d4 100644 --- a/crumpet-engine/sprite.h +++ b/crumpet-engine/sprite.h @@ -11,6 +11,16 @@ enum struct SpriteType { enum struct SpriteState { STATE_DEFAULT, + STATE_WALKING, + STATE_ACCELERATING, + STATE_RUNNING, + STATE_DECELERATING, + STATE_STANDING, + STATE_TURNING, + STATE_TURNING_LEFTTORIGHT, + STATE_TURNING_RIGHTTOLEFT, + STATE_STANDING_LEFT, + STATE_STANDING_RIGHT, STATE_LEFT, STATE_ACCELERATING_LEFT, STATE_RUNNING_LEFT, @@ -41,11 +51,17 @@ public: SpriteType Spritetype = SpriteType::SPRITE_DEFAULT; SpriteState Spritestate = SpriteState::STATE_DEFAULT; + SDL_RendererFlip Flip = SDL_FLIP_NONE; bool LoadSpriteTextures(std::string path); void UseSpriteSheet(SpriteState state, int startX, int startY, int width, int height, int separation, int frames); void TickAninmation(SpriteState state); void TickAninmation(); + void SetSpriteState(SpriteState state); + void FlipSprite(SDL_RendererFlip flip); + void UnflipSprite(); + void FlipSpriteH(); + void FlipSpriteV(); void ResizeSprites(Vec2* newSize); void ResizeSpritesByFactor(float factor);