diff --git a/Bin/VC10/VC10.vcxproj b/Bin/VC10/VC10.vcxproj index 6107e44..0d589d9 100644 --- a/Bin/VC10/VC10.vcxproj +++ b/Bin/VC10/VC10.vcxproj @@ -99,6 +99,7 @@ <ClInclude Include="..\..\src\Level\Level.h" /> <ClInclude Include="..\..\src\Level\MapTile.h" /> <ClInclude Include="..\..\src\Level\Tileset.h" /> + <ClInclude Include="..\..\Src\Level\Warp.h" /> <ClInclude Include="..\..\src\Main\Game.h" /> <ClInclude Include="..\..\src\Main\TitleScreen.h" /> <ClInclude Include="..\..\src\Math\FPS.h" /> @@ -182,6 +183,11 @@ <Project>{b4a2ecf2-d1e0-4e73-a59f-bcce49c37cc6}</Project> </ProjectReference> </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\Src\Level\Warp.cpp"> + <FileType>Document</FileType> + </ClCompile> + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/Bin/VC10/VC10.vcxproj.filters b/Bin/VC10/VC10.vcxproj.filters index 8424bb1..c44ee77 100644 --- a/Bin/VC10/VC10.vcxproj.filters +++ b/Bin/VC10/VC10.vcxproj.filters @@ -195,6 +195,9 @@ <ClInclude Include="..\..\src\UI\Menu.h"> <Filter>UI</Filter> </ClInclude> + <ClInclude Include="..\..\Src\Level\Warp.h"> + <Filter>Level</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\src\Main\main.cpp"> @@ -317,5 +320,8 @@ <ClCompile Include="..\..\src\UI\Menu.cpp"> <Filter>UI</Filter> </ClCompile> + <ClCompile Include="..\..\Src\Level\Warp.cpp"> + <Filter>Level</Filter> + </ClCompile> </ItemGroup> </Project> \ No newline at end of file diff --git a/Data/Img/OpenArt/woodland_indoor_0.png b/Data/Img/OpenArt/woodland_indoor_0.png new file mode 100644 index 0000000..d176d81 Binary files /dev/null and b/Data/Img/OpenArt/woodland_indoor_0.png differ diff --git a/Data/Map/Ugly.tmx b/Data/Map/Ugly.tmx index 0444e8e..c7240e3 100644 --- a/Data/Map/Ugly.tmx +++ b/Data/Map/Ugly.tmx @@ -57,11 +57,18 @@ eJztl8ESwyAIRJP//+leemA6oIC7BhvejIemlV0QNb2upir3d2TnZeYyyHi5lYHWYsaWc5ha2TpFNFZ0Inn86jCY5SGf7exbK8bMm/xs/darZ3lA1yGSR0ZzpI/cvzvy8PiIxNR8ovaaxxsrDxSM+LP9dSnfIzQ1ndWY6L70ajLy0OqP0rHOCkadGHW3YiPvHQZe/dH6R+Iw8Xiovh5VPEiifrS9m723VkF4qNDj/5AHsi+eXgvpRT47ich6sOu9Yz13vEecmAdDI3IXN03TNE3zHqz3z9GoSOa/cUVOywPVJ5m5qJ5k9XamBitarF5YzaPK+RLVP+n8a5rmnXwA7bUBUA== </data> </layer> - <objectgroup name="NPCs" width="50" height="50"> + <objectgroup name="Events" width="50" height="50"> <object name="NPC!!!" type="NPC" x="544" y="320" width="32" height="32"> <properties> <property name="image" value="Player"/> </properties> </object> + <object name="Warp to house" type="warp" x="605" y="188" width="34" height="59"> + <properties> + <property name="map" value="../Data/Map/house.tmx"/> + <property name="x" value="7"/> + <property name="y" value="13"/> + </properties> + </object> </objectgroup> </map> diff --git a/Data/Map/house.tmx b/Data/Map/house.tmx new file mode 100644 index 0000000..b384d25 --- /dev/null +++ b/Data/Map/house.tmx @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<map version="1.0" orientation="orthogonal" width="15" height="15" tilewidth="32" tileheight="32"> + <tileset firstgid="1" name="woodland_indoor_0" tilewidth="32" tileheight="32"> + <image source="../Img/OpenArt/woodland_indoor_0.png" width="512" height="512"/> + </tileset> + <tileset firstgid="257" name="CollisionTileset" tilewidth="32" tileheight="32"> + <image source="../Img/CollisionTileset.png" width="32" height="32"/> + </tileset> + <layer name="Layer 1" width="15" height="15"> + <data encoding="base64" compression="zlib"> + eJy10dEJgDAMBNDrCI5gZtFOou4/gvGvHHc1flh4EEJC4dIANALRUxYBps9WAabPQoDpV1R3xxdUvxlzC6pn/3CeQTXv8Y04N5ehumc1vy+zzN3zb9W7Pba0pz7Zde9IZ7omMzc2PRZ3 + </data> + </layer> + <layer name="Layer 2" width="15" height="15"> + <data encoding="base64" compression="zlib"> + eJxjYEAFzAz4gRwQywOxApR/DojPA/EFIBYmoFcPiPWB2ADKvwfE94H4AQF92PS+A+L3ROjDpvcfEP8nUu8oYGBoAeJWIG7Do2YpGgaBg0A8BYinAvE0ID5Mgp0gvUugZi0jUe9QAwA5/BXY + </data> + </layer> + <layer name="Layer 3" width="15" height="15"> + <data encoding="base64" compression="zlib"> + eJxjYBheQAWIVcnUawLEplR0CzLgAWJeMvXKALEsFd1CT7AciDuAuGugHTKIAQBabAK+ + </data> + </layer> + <layer name="Collision" width="15" height="15"> + <data encoding="base64" compression="zlib"> + eJxjZGRgYCQRgwCpetD1IgNc4vjUIJtHql5c8oQArjCgtl5iw54YfcQCWugdKPcQaz419eKLL0JqAIUTAME= + </data> + </layer> + <objectgroup name="Events" width="15" height="15"> + <object name="Warp to village" type="warp" x="210" y="433" width="61" height="34"> + <properties> + <property name="map" value="../Data/Map/Ugly.tmx"/> + <property name="x" value="19"/> + <property name="y" value="7"/> + </properties> + </object> + </objectgroup> +</map> diff --git a/src/Actor/Actor.cpp b/src/Actor/Actor.cpp index 6abb573..ea1bd76 100644 --- a/src/Actor/Actor.cpp +++ b/src/Actor/Actor.cpp @@ -4,7 +4,7 @@ #include "../Sound/SoundEffect.h" #include "../Level/Level.h" -Actor::Actor(const Level* level) { +Actor::Actor(Level* level) { _level = level; _stepSFX[0] = sfxManager.Load("../Data/SFX/step_cloth1.wav"); @@ -13,9 +13,10 @@ Actor::Actor(const Level* level) { _stepSFX[3] = sfxManager.Load("../Data/SFX/step_cloth4.wav"); _lastStepSFXPlayed = -1; - _velocity = 4.0f; - _direction = FRONT; - _preventMovement = NONE; + _velocity = 4.0f; + _direction = FRONT; + _preventMovement = NONE; + _distanceTraveled = 0; x = 0.0f; y = 0.0f; @@ -62,6 +63,10 @@ void Actor::Update(float dt) { float collisionYOffset = GetMaxHeight() / 2.0f; if(x != oldX || y != oldY) { + float dx = x - oldX; + float dy = y - oldY; + _distanceTraveled += sqrtf(dx*dx + dy*dy); + if(_level->CheckCollision(x, y + collisionYOffset, GetAnimation()->GetMaxWidth(), GetAnimation()->GetMaxHeight() - collisionYOffset)) { x = oldX; y = oldY; diff --git a/src/Actor/Actor.h b/src/Actor/Actor.h index 3ca3b1f..831caf4 100644 --- a/src/Actor/Actor.h +++ b/src/Actor/Actor.h @@ -24,9 +24,11 @@ public: HURT }; - Actor(const Level* level); + Actor(Level* level); ~Actor(void); + void SetLevel(Level* level) { _level = level; } + void LoadSprites(const String& basename); virtual void Update(float dt); @@ -50,7 +52,7 @@ protected: AnimatingSprite* GetAnimation(void); - const Level* _level; + Level* _level; float _velocity; @@ -62,6 +64,8 @@ protected: Facing _direction; Facing _preventMovement; + float _distanceTraveled; + float x; float y; diff --git a/src/Actor/NPC.cpp b/src/Actor/NPC.cpp index 673b8fe..cc76dac 100644 --- a/src/Actor/NPC.cpp +++ b/src/Actor/NPC.cpp @@ -1,6 +1,6 @@ #include "NPC.h" -NPC::NPC(const Level* level) : Actor(level) { +NPC::NPC(Level* level) : Actor(level) { } NPC::~NPC(void) { diff --git a/src/Actor/NPC.h b/src/Actor/NPC.h index f5b3d61..222dc57 100644 --- a/src/Actor/NPC.h +++ b/src/Actor/NPC.h @@ -4,7 +4,7 @@ class NPC : public Actor { public: - NPC(const Level* level); + NPC(Level* level); ~NPC(void); void Update(float dt); diff --git a/src/Actor/Player.cpp b/src/Actor/Player.cpp index 4df4aaa..c420d04 100644 --- a/src/Actor/Player.cpp +++ b/src/Actor/Player.cpp @@ -1,7 +1,10 @@ #include "Player.h" #include "../IO/Input.h" +#include "../Level/Level.h" +#include "../Level/Warp.h" +#include "../Main/Game.h" -Player::Player(const Level* level) : Actor(level) { +Player::Player(Level* level) : Actor(level) { _direction = Actor::RIGHT; } @@ -10,6 +13,14 @@ Player::~Player(void) { void Player::Update(float dt) { Actor::Update(dt); + + if(_distanceTraveled > 32.0f) { + Warp* warp = _level->CheckWarp(x, y, GetMaxWidth(), GetMaxHeight()); + if(warp) { + _level->GetGame()->Warp(warp->GetTargetMap(), warp->GetTargetX(), warp->GetTargetY()); + _distanceTraveled = 0; + } + } } void Player::Render(void) { diff --git a/src/Actor/Player.h b/src/Actor/Player.h index 7c0d20e..0f4c599 100644 --- a/src/Actor/Player.h +++ b/src/Actor/Player.h @@ -9,7 +9,7 @@ class Level; class Player : public Actor{ public: - Player(const Level* level); + Player(Level* level); ~Player(void); void Update(float dt); diff --git a/src/Level/Level.cpp b/src/Level/Level.cpp index e2f7ffe..123da3a 100644 --- a/src/Level/Level.cpp +++ b/src/Level/Level.cpp @@ -4,10 +4,12 @@ #include "Level.h" #include "Layer.h" #include "Tileset.h" +#include "Warp.h" #include "../Sound/Music.h" #include "../System/Debug.h" #include "../TMXParser/Tmx.h" #include "../Actor/NPC.h" +#include "../Math/Rect.h" #ifdef _WIN32 #ifndef strcasecmp @@ -18,7 +20,8 @@ #endif #endif -Level::Level() { +Level::Level(Game* game) { + _game = game; _width = 0; _height = 0; _tileWidth = 0; @@ -41,7 +44,12 @@ Level::~Level() { for(std::list<NPC*>::iterator i = _npcs.begin(); i != _npcs.end(); ++i) { delete (*i); } - _npcs.end(); + _npcs.clear(); + + for(std::list<Warp*>::iterator i = _warps.begin(); i != _warps.end(); ++i) { + delete (*i); + } + _warps.clear(); if(_collisions) { delete[] _collisions; @@ -134,6 +142,15 @@ bool Level::Load(const std::string& filename) { npc->SetXY(tmxObject->GetX(), tmxObject->GetY()); _npcs.push_back(npc); } + else if(!strncasecmp(tmxObject->GetName().c_str(), "Warp", 4)) { + Warp* warp = new Warp(); + warp->SetXY(tmxObject->GetX(), tmxObject->GetY()); + warp->SetWidthHeight(tmxObject->GetWidth(), tmxObject->GetHeight()); + warp->SetTargetMap(tmxObject->GetProperties().GetLiteralProperty("map").c_str()); + warp->SetTargetX(tmxObject->GetProperties().GetNumericProperty("x") * 32); + warp->SetTargetY(tmxObject->GetProperties().GetNumericProperty("y") * 32); + _warps.push_back(warp); + } } } @@ -172,8 +189,8 @@ void Level::Draw(int xOffset, int yOffset) { } bool Level::CheckCollision(float x, float y, float w, float h) const { - if(x < 0.0f || x > (float)(_width * _tileWidth) || - y < 0.0f || y > (float)(_height * _tileHeight)) { + if(x < 0.0f || x >= (float)((_width - 1) * _tileWidth) || + y < 0.0f || y >= (float)((_height - 1) * _tileHeight)) { return true; } @@ -222,3 +239,17 @@ bool Level::CheckCollision(float x, float y, float w, float h) const { return false; } + +Warp* Level::CheckWarp(float x, float y, float w, float h) const { + Rect objectArea(x, y, w, h); + for(std::list<Warp*>::const_iterator i = _warps.cbegin(); i != _warps.cend(); ++i) { + Warp* warp = (*i); + Rect warpArea( + warp->GetX(), warp->GetY(), + warp->GetWidth(), warp->GetHeight()); + if(warpArea.CollidesWith(objectArea)) { + return warp; + } + } + return NULL; +} \ No newline at end of file diff --git a/src/Level/Level.h b/src/Level/Level.h index f3ddf8e..7e6da0a 100644 --- a/src/Level/Level.h +++ b/src/Level/Level.h @@ -3,31 +3,37 @@ #include <string> #include <list> +class Game; class Layer; class Tileset; class Music; class NPC; +class Warp; class Level { public: - Level(); - ~Level(); + Level(Game* game); + ~Level(void); bool Load(const std::string& filename); - void PlayBGM(); + void PlayBGM(void); void Update(float dt); void Draw(int xOffset, int yOffset); + Game* GetGame() { return _game; } + int GetWidth() const { return _width; } int GetHeight() const { return _height; } int GetTileWidth() const { return _tileWidth; } int GetTileHeight() const { return _tileHeight; } - bool CheckCollision(float x, float y, float w, float h) const; + bool CheckCollision(float x, float y, float w, float h) const; + Warp* CheckWarp(float x, float y, float w, float h) const; private: + Game* _game; int _width; int _height; int _tileWidth; @@ -35,6 +41,7 @@ private: std::list<Layer*> _layers; std::list<Tileset*> _tilesets; std::list<NPC*> _npcs; + std::list<Warp*> _warps; Music* _bgm; bool* _collisions; }; diff --git a/src/Level/Warp.cpp b/src/Level/Warp.cpp new file mode 100644 index 0000000..9700968 --- /dev/null +++ b/src/Level/Warp.cpp @@ -0,0 +1,11 @@ +#include "Warp.h" + +Warp::Warp(void) { + x = 0; + y = 0; + w = 0; + h = 0; + _targetMap = ""; + _targetX = 0; + _targetY = 0; +} diff --git a/src/Level/Warp.h b/src/Level/Warp.h new file mode 100644 index 0000000..ed78330 --- /dev/null +++ b/src/Level/Warp.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../System/String.h" +#include "../Math/Vec2.h" + +class Warp { +public: + Warp(void); + + int GetX(void) const { return x; } + int GetY(void) const { return y; } + int GetWidth(void) const { return w; } + int GetHeight(void) const { return h; } + void SetX(int x) { this->x = x; } + void SetY(int y) { this->y = y; } + void SetXY(int x, int y) { SetX(x); SetY(y); } + void SetWidth(int w) { this->w = w; } + void SetHeight(int h) { this->h = h;} + void SetWidthHeight(int w, int h) { SetWidth(w); SetHeight(h); } + + const String& GetTargetMap() const { return _targetMap;} + void SetTargetMap(const String& targetMap) { _targetMap = targetMap; } + + int GetTargetX(void) const { return _targetX; } + int GetTargetY(void) const { return _targetY; } + void SetTargetX(int targetX) { _targetX = targetX; } + void SetTargetY(int targetY) { _targetY = targetY; } + void SetTargetXY(int targetX, int targetY) { SetTargetX(targetX); SetTargetY(targetY); } + +private: + int x; + int y; + int w; + int h; + + String _targetMap; + int _targetX; + int _targetY; +}; diff --git a/src/Main/Game.cpp b/src/Main/Game.cpp index 91e50e8..06c92fc 100644 --- a/src/Main/Game.cpp +++ b/src/Main/Game.cpp @@ -22,11 +22,8 @@ #include "TitleScreen.h" Game::Game(void) { - _level = new Level(); + _level = new Level(this); _player = new Player(_level); - _NPC = new NPC(_level); - - _NPC->SetXY(30.0f, 30.0f); _testFont = new Font(); @@ -72,7 +69,6 @@ void Game::Render(void) { void Game::Shutdown(void) { Debug::logger->message("\n ----- Cleaning Engine -----"); delete _testFont; - delete _NPC; delete _player; delete _level; if(_inGameMenu) { @@ -103,6 +99,23 @@ void Game::OnResize(int width, int height) { glLoadIdentity(); } +void Game::Warp(const String& mapName, int x, int y) { + Level* newLevel = new Level(this); + + if(!newLevel->Load(mapName.GetPointer())) { + delete newLevel; + return; + } + + delete _level; + _level = newLevel; + + _player->SetXY(x, y); + _player->SetLevel(_level); + + _level->PlayBGM(); +} + void Game::UpdateTitle(float dt) { _titleScreen->Update(dt); @@ -144,7 +157,6 @@ void Game::UpdateGame(float dt) { } } else { _player->Update(dt); - _NPC->Update(dt); _level->Update(dt); } } @@ -166,26 +178,39 @@ void Game::RenderGame(void) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - float windowCenterX = ((float)windowWidth / 2.0f) - ((float)_player->GetMaxWidth() / 2.0f); - float windowCenterY = ((float)windowHeight / 2.0f) - ((float)_player->GetMaxHeight() / 2.0f); + float xOffset; + float yOffset; - float xOffset = _player->GetX() - windowCenterX; - float yOffset = _player->GetY() - windowCenterY; + int levelWidthPixels = _level->GetWidth() * _level->GetTileWidth(); + int levelHeightPixels = _level->GetHeight() * _level->GetTileHeight(); - float maxXOffset = (_level->GetWidth() * _level->GetTileWidth()) - (float)windowWidth; - float maxYOffset = (_level->GetHeight() * _level->GetTileHeight()) - (float)windowHeight; + if(levelWidthPixels < windowWidth && levelHeightPixels < windowHeight) { + xOffset = levelWidthPixels / 2 - windowWidth / 2; + yOffset = levelHeightPixels / 2 - windowHeight / 2; + glTranslatef((int)-xOffset, (int)-yOffset, 0.0f); + } + else + { + float windowCenterX = ((float)windowWidth / 2.0f) - ((float)_player->GetMaxWidth() / 2.0f); + float windowCenterY = ((float)windowHeight / 2.0f) - ((float)_player->GetMaxHeight() / 2.0f); - if(xOffset < 0.0f) xOffset = 0.0f; - if(yOffset < 0.0f) yOffset = 0.0f; - if(xOffset > maxXOffset) xOffset = maxXOffset; - if(yOffset > maxYOffset) yOffset = maxYOffset; + xOffset = _player->GetX() - windowCenterX; + yOffset = _player->GetY() - windowCenterY; - glTranslatef((int)-xOffset, (int)-yOffset, 0.0f); + float maxXOffset = (float)(levelWidthPixels - windowWidth); + float maxYOffset = (float)(levelHeightPixels - windowHeight); + + if(xOffset < 0.0f) xOffset = 0.0f; + if(yOffset < 0.0f) yOffset = 0.0f; + if(xOffset > maxXOffset) xOffset = maxXOffset; + if(yOffset > maxYOffset) yOffset = maxYOffset; + + glTranslatef((int)-xOffset, (int)-yOffset, 0.0f); + } // Render our shit.. _level->Draw(xOffset, yOffset); _player->Render(); - _NPC->Render(); _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f); _testFont->RenderText( _player->GetX() - 5, @@ -214,7 +239,6 @@ void Game::NewGame(void) { _level->PlayBGM(); _player->LoadSprites("Player"); - _NPC->LoadSprites("Player"); _testFont->Load("../Data/Font/Fairydust.ttf", 16); _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/Main/Game.h b/src/Main/Game.h index 4f056c1..995efc1 100644 --- a/src/Main/Game.h +++ b/src/Main/Game.h @@ -1,6 +1,5 @@ #pragma once #include "../IO/Input.h" -#include "../Actor/NPC.h" #include "../Actor/Player.h" #include "../Font/Font.h" @@ -24,6 +23,8 @@ public: void OnResize(int width, int height); + void Warp(const String& mapName, int x, int y); + bool IsRunning() { return _running; } void SetRunning(bool running) { _running = running; } @@ -40,7 +41,6 @@ private: Font* _testFont; Player* _player; - NPC* _NPC; Level* _level; TitleScreen* _titleScreen; diff --git a/src/Math/Rect.h b/src/Math/Rect.h index bf7d281..31eb3b1 100644 --- a/src/Math/Rect.h +++ b/src/Math/Rect.h @@ -1,5 +1,7 @@ #pragma once +#include "Vec2.h" + struct Rect { float x; @@ -14,4 +16,20 @@ struct Rect this->w = w; this->h = h; } + + bool CollidesWith(const Rect& other) const { + if(x > (other.x + other.w)) + return false; + + if(y > (other.y + other.h)) + return false; + + if((x + w) < other.x) + return false; + + if((y + h) < other.y) + return false; + + return true; + } };