diff --git a/Chapter01/Game.vcxproj b/Chapter01/Game.vcxproj index e16204f8..030533ff 100644 --- a/Chapter01/Game.vcxproj +++ b/Chapter01/Game.vcxproj @@ -21,19 +21,19 @@ {BC508D87-495F-4554-932D-DD68388B63CC} Win32Proj Game - 10.0.16299.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode diff --git a/Chapter02/AnimSpriteComponent.cpp b/Chapter02/AnimSpriteComponent.cpp index 8b5f15e9..0fb67826 100644 --- a/Chapter02/AnimSpriteComponent.cpp +++ b/Chapter02/AnimSpriteComponent.cpp @@ -13,6 +13,9 @@ AnimSpriteComponent::AnimSpriteComponent(Actor* owner, int drawOrder) :SpriteComponent(owner, drawOrder) , mCurrFrame(0.0f) , mAnimFPS(24.0f) + , mCurrentAnimation(-1) + , mNextAnimationTimer(0.f) + , mCanChangeAnimation(true) { } @@ -20,16 +23,34 @@ void AnimSpriteComponent::Update(float deltaTime) { SpriteComponent::Update(deltaTime); - if (mAnimTextures.size() > 0) + if (!mCanChangeAnimation) + { + mNextAnimationTimer += deltaTime; + + if (mNextAnimationTimer > 0.5f) + { + mCanChangeAnimation = true; + mNextAnimationTimer = 0.f; + } + } + + if (!mAnimTextures.empty()) { // Update the current frame based on frame rate // and delta time mCurrFrame += mAnimFPS * deltaTime; // Wrap current frame if needed - while (mCurrFrame >= mAnimTextures.size()) + while (mCurrFrame >= mAnimSpriteInfos[mCurrentAnimation].end + 1) { - mCurrFrame -= mAnimTextures.size(); + if (!mAnimSpriteInfos[mCurrentAnimation].looping) + { + mCurrFrame = mAnimSpriteInfos[mCurrentAnimation].end; + } + else + { + mCurrFrame -= mAnimSpriteInfos[mCurrentAnimation].end - mAnimSpriteInfos[mCurrentAnimation].start; + } } // Set the current texture @@ -37,13 +58,34 @@ void AnimSpriteComponent::Update(float deltaTime) } } -void AnimSpriteComponent::SetAnimTextures(const std::vector& textures) +void AnimSpriteComponent::SetAnimTextures(const std::vector& textures, bool looping) { - mAnimTextures = textures; - if (mAnimTextures.size() > 0) + if (!textures.empty()) { + mCurrFrame = mAnimTextures.size(); + mAnimSpriteInfos.emplace_back(mCurrFrame, (mCurrFrame + textures.size() - 1), looping); + + SDL_Log("Animation start: %i Animation end: %i", mAnimSpriteInfos.back().start, mAnimSpriteInfos.back().end); + + mAnimTextures.insert(mAnimTextures.end(), textures.begin(), textures.end()); + // Set the active texture to first frame - mCurrFrame = 0.0f; - SetTexture(mAnimTextures[0]); + SetTexture(mAnimTextures[mCurrFrame]); + mCurrentAnimation++; + } +} + +void AnimSpriteComponent::NextAnimation() +{ + if (mAnimSpriteInfos.size() > 1 && mCanChangeAnimation) + { + if (++mCurrentAnimation == mAnimSpriteInfos.size()) + { + mCurrentAnimation = 0; + } + + SetTexture(mAnimTextures[mAnimSpriteInfos[mCurrentAnimation].start]); + + mCanChangeAnimation = false; } } diff --git a/Chapter02/AnimSpriteComponent.h b/Chapter02/AnimSpriteComponent.h index d5aa387a..0d2b13a7 100644 --- a/Chapter02/AnimSpriteComponent.h +++ b/Chapter02/AnimSpriteComponent.h @@ -9,6 +9,20 @@ #pragma once #include "SpriteComponent.h" #include + +struct AnimSpriteInfo +{ + AnimSpriteInfo(int start, int end, bool looping) + :start(start) + ,end(end) + ,looping(looping) + {} + + int start; + int end; + bool looping; +}; + class AnimSpriteComponent : public SpriteComponent { public: @@ -16,10 +30,11 @@ class AnimSpriteComponent : public SpriteComponent // Update animation every frame (overriden from component) void Update(float deltaTime) override; // Set the textures used for animation - void SetAnimTextures(const std::vector& textures); + void SetAnimTextures(const std::vector& textures, bool looping = true); // Set/get the animation FPS float GetAnimFPS() const { return mAnimFPS; } void SetAnimFPS(float fps) { mAnimFPS = fps; } + void NextAnimation(); private: // All textures in the animation std::vector mAnimTextures; @@ -27,4 +42,11 @@ class AnimSpriteComponent : public SpriteComponent float mCurrFrame; // Animation frame rate float mAnimFPS; + + int mCurrentAnimation; + + std::vector mAnimSpriteInfos; + + float mNextAnimationTimer; + bool mCanChangeAnimation; }; diff --git a/Chapter02/Game.cpp b/Chapter02/Game.cpp index 2bf0af03..93835cdc 100644 --- a/Chapter02/Game.cpp +++ b/Chapter02/Game.cpp @@ -13,6 +13,7 @@ #include "SpriteComponent.h" #include "Ship.h" #include "BGSpriteComponent.h" +#include "TileMapComponent.h" Game::Game() :mWindow(nullptr) @@ -179,6 +180,13 @@ void Game::LoadData() }; bg->SetBGTextures(bgtexs); bg->SetScrollSpeed(-200.0f); + // Create Tilemap + TileMapComponent* tm = new TileMapComponent(temp); + //tm->LoadTilemap("Assets/MapLayer3.csv", GetTexture("Assets/Tiles.png"), 32); + //tm = new TileMapComponent(temp); + tm->LoadTilemap("Assets/MapLayer2.csv", GetTexture("Assets/Tiles.png"), 32); + tm = new TileMapComponent(temp); + tm->LoadTilemap("Assets/MapLayer1.csv", GetTexture("Assets/Tiles.png"), 32); } void Game::UnloadData() diff --git a/Chapter02/Game.vcxproj b/Chapter02/Game.vcxproj index 35c39009..a4776960 100644 --- a/Chapter02/Game.vcxproj +++ b/Chapter02/Game.vcxproj @@ -20,6 +20,7 @@ + @@ -30,24 +31,25 @@ + {BC508D87-495F-4554-932D-DD68388B63CC} Win32Proj Game - 10.0.16299.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode diff --git a/Chapter02/Game.vcxproj.filters b/Chapter02/Game.vcxproj.filters index 760534ef..c557d1f7 100644 --- a/Chapter02/Game.vcxproj.filters +++ b/Chapter02/Game.vcxproj.filters @@ -34,6 +34,9 @@ Source Files + + Source Files + @@ -60,5 +63,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Chapter02/Ship.cpp b/Chapter02/Ship.cpp index 5daca54a..dc6cf967 100644 --- a/Chapter02/Ship.cpp +++ b/Chapter02/Ship.cpp @@ -16,14 +16,24 @@ Ship::Ship(Game* game) ,mDownSpeed(0.0f) { // Create an animated sprite component - AnimSpriteComponent* asc = new AnimSpriteComponent(this); - std::vector anims = { + asc = new AnimSpriteComponent(this); + std::vector shipAnimation = { game->GetTexture("Assets/Ship01.png"), game->GetTexture("Assets/Ship02.png"), game->GetTexture("Assets/Ship03.png"), game->GetTexture("Assets/Ship04.png"), }; - asc->SetAnimTextures(anims); + asc->SetAnimTextures(shipAnimation); + + std::vector walkingAnimation = { + game->GetTexture("Assets/Character01.png"), + game->GetTexture("Assets/Character02.png"), + game->GetTexture("Assets/Character03.png"), + game->GetTexture("Assets/Character04.png"), + game->GetTexture("Assets/Character05.png"), + game->GetTexture("Assets/Character06.png"), + }; + asc->SetAnimTextures(walkingAnimation, false); } void Ship::UpdateActor(float deltaTime) @@ -75,4 +85,8 @@ void Ship::ProcessKeyboard(const uint8_t* state) { mDownSpeed -= 300.0f; } + if (state[SDL_SCANCODE_E]) + { + asc->NextAnimation(); + } } diff --git a/Chapter02/Ship.h b/Chapter02/Ship.h index 8a34e962..5ca0330e 100644 --- a/Chapter02/Ship.h +++ b/Chapter02/Ship.h @@ -19,4 +19,5 @@ class Ship : public Actor private: float mRightSpeed; float mDownSpeed; + class AnimSpriteComponent* asc; }; \ No newline at end of file diff --git a/Chapter02/TileMapComponent.cpp b/Chapter02/TileMapComponent.cpp new file mode 100644 index 00000000..e4971104 --- /dev/null +++ b/Chapter02/TileMapComponent.cpp @@ -0,0 +1,93 @@ +#include "TileMapComponent.h" +#include "Actor.h" +#include +#include +#include + +TileMapComponent::TileMapComponent(Actor* owner, int drawOrder) +:SpriteComponent(owner, drawOrder) +{ +} + +void TileMapComponent::Draw(SDL_Renderer* renderer) +{ + if (mTexture) + { + SDL_Rect dsrect; + dsrect.w = mTileSize; + dsrect.h = mTileSize; + for (int i = 0; i < mLoadedCSV.size(); i++) + { + dsrect.y = i * mTileSize; + for (int j = 0; j < mLoadedCSV[i].size(); j++) + { + if (mLoadedCSV[i][j] > -1) + { + dsrect.x = j * mTileSize; + + // Draw (have to convert angle from radians to degrees, and clockwise to counter) + SDL_RenderCopyEx(renderer, + mTexture, + &mTileRects[mLoadedCSV[i][j]], + &dsrect, + -Math::ToDegrees(mOwner->GetRotation()), + nullptr, + SDL_FLIP_NONE); + } + } + } + } +} + +void TileMapComponent::LoadTilemap(std::string&& CSVPath, SDL_Texture* tilemapTexture, int tileSize) +{ + mTexture = tilemapTexture; + mTileSize = tileSize; + + SDL_QueryTexture(tilemapTexture, nullptr, nullptr, &mTexWidth, &mTexHeight); + + // Split the texture in to tiles to use with a csv tilemap. + int tilesW = mTexWidth / tileSize; + int tilesH = mTexHeight / tileSize; + for (int i = 0; i < tilesH; i++) + { + for (int j = 0; j < tilesW; j++) + { + SDL_Rect tilerect; + tilerect.x = j * tileSize; + tilerect.y = i * tileSize; + tilerect.w = tileSize; + tilerect.h = tileSize; + + mTileRects.emplace_back(std::move(tilerect)); + } + } + + std::cout << "Tiles loaded: " << mTileRects.size() << std::endl; + + // Load desired tiles from csv file. + std::ifstream fin(std::move(CSVPath)); + std::string s; + char cstring[4]; + while (std::getline(fin, s)) + { + std::istringstream ss; + ss.str(s); + std::vector CSVLine; + while (ss.getline(cstring, 4, ',')) + { + CSVLine.emplace_back(stoi(std::string(cstring))); + } + mLoadedCSV.emplace_back(std::move(CSVLine)); + } + + // Print loaded tilemap to console. + for (auto& intvec : mLoadedCSV) + { + for (int i : intvec) + { + std::cout << i; + } + std::cout << std::endl; + } +} diff --git a/Chapter02/TileMapComponent.h b/Chapter02/TileMapComponent.h new file mode 100644 index 00000000..c4d82d16 --- /dev/null +++ b/Chapter02/TileMapComponent.h @@ -0,0 +1,20 @@ +#pragma once +#include "SpriteComponent.h" +#include +#include +#include "Math.h" + + + +class TileMapComponent : public SpriteComponent +{ +public: + TileMapComponent(Actor* owner, int drawOrder = 50); + void LoadTilemap(std::string&& CSVPath, SDL_Texture* tilemapTexture, int tileSize); + virtual void Draw(SDL_Renderer* renderer); +private: + std::vector> mLoadedCSV; + std::vector mTileRects; + int mTileSize; +}; +