[Add] Tile based collisions.

This commit is contained in:
Tamir Atias 2012-04-17 20:23:48 +03:00
parent e35cb64246
commit 8028320cef
13 changed files with 117 additions and 17 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

View File

@ -6,6 +6,9 @@
<tileset firstgid="1" name="AwesomeTileset" tilewidth="64" tileheight="64"> <tileset firstgid="1" name="AwesomeTileset" tilewidth="64" tileheight="64">
<image source="../Img/AwesomeTileset.png" width="256" height="128"/> <image source="../Img/AwesomeTileset.png" width="256" height="128"/>
</tileset> </tileset>
<tileset firstgid="9" name="Collision" tilewidth="64" tileheight="64">
<image source="../Img/CollisionTileset.png" width="64" height="64"/>
</tileset>
<layer name="Tile Layer 1" width="60" height="60"> <layer name="Tile Layer 1" width="60" height="60">
<data encoding="base64" compression="zlib"> <data encoding="base64" compression="zlib">
eJzt0MENgDAQA8EA13/NtHCBoFhiHvv3uMYYx4+qgA28vLy8vLzVbPfOVV2Nup/MtNv95o/Zkr1f/PfUewbFy8vLy8ubEC8vLy8vb0K8vLy8vLwJ8fLy8vLyJsTLy8vLy5sQLy8vLy9vQry8vLy8a703oRIWWw== eJzt0MENgDAQA8EA13/NtHCBoFhiHvv3uMYYx4+qgA28vLy8vLzVbPfOVV2Nup/MtNv95o/Zkr1f/PfUewbFy8vLy8ubEC8vLy8vb0K8vLy8vLwJ8fLy8vLyJsTLy8vLy5sQLy8vLy9vQry8vLy8a703oRIWWw==
@ -16,4 +19,9 @@
eJztleEOgjAMBrcfwPu/sTGhSf06tDNCNd4lDZDNdrdOaK21xUXbr+sexnowb5F5mzzP5LuKe70uV1tTd/ej3+nYKmMz+a7C77Wtz/rR9zjqr+/bqK+jfFrz6v4enb/eHn03FzZP8/jQfbFcbfB8JeZr9a0v2t+R7yZ5/Bz9n2h/K1x9be+rY0fnWX09+j7wc6rfVx5/zqrO3JksyfgnsnsyE/9Ela9+QzTOYtb31Tqz8ey8farGaP/e8f0mMuvHNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D761/IrvDT5XCI0= eJztleEOgjAMBrcfwPu/sTGhSf06tDNCNd4lDZDNdrdOaK21xUXbr+sexnowb5F5mzzP5LuKe70uV1tTd/ej3+nYKmMz+a7C77Wtz/rR9zjqr+/bqK+jfFrz6v4enb/eHn03FzZP8/jQfbFcbfB8JeZr9a0v2t+R7yZ5/Bz9n2h/K1x9be+rY0fnWX09+j7wc6rfVx5/zqrO3JksyfgnsnsyE/9Ela9+QzTOYtb31Tqz8ey8farGaP/e8f0mMuvHNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D7614BvBNw++teAbwTcPvrXgG8E3D761/IrvDT5XCI0=
</data> </data>
</layer> </layer>
<layer name="Collision" width="60" height="60">
<data encoding="base64" compression="zlib">
eJzt1MEKgCAMANBd/f8f7hripoSYh/cgarKNaKOIiPa6YhD3Z1VeJPFKv1Pa5N4/Z3Vfzv6wa77ZnG+db/8uVU5Vl32XWb9TqrlkOVVd1uemfc7i0U7O9ndUu9IPdhj9Z+wbAAAAAAAAAAAAAACwywOaowOg
</data>
</layer>
</map> </map>

View File

@ -2,8 +2,11 @@
#include "Actor.h" #include "Actor.h"
#include "../Sound/SoundEffect.h" #include "../Sound/SoundEffect.h"
#include "../Level/Level.h"
Actor::Actor(const Level* level) {
_level = level;
Actor::Actor(void) {
_stepSFX[0] = sfxManager.Load("../Data/SFX/step_cloth1.wav"); _stepSFX[0] = sfxManager.Load("../Data/SFX/step_cloth1.wav");
_stepSFX[1] = sfxManager.Load("../Data/SFX/step_cloth2.wav"); _stepSFX[1] = sfxManager.Load("../Data/SFX/step_cloth2.wav");
_stepSFX[2] = sfxManager.Load("../Data/SFX/step_cloth3.wav"); _stepSFX[2] = sfxManager.Load("../Data/SFX/step_cloth3.wav");
@ -54,10 +57,16 @@ void Actor::Update(float dt) {
float oldX = x; float oldX = x;
float oldY = y; float oldY = y;
// We should check for collisions now.
Move(dt); Move(dt);
if(x != oldX || y != oldY) {
if(_level->CheckCollision(x, y, GetAnimation()->GetMaxWidth(), GetAnimation()->GetMaxHeight())) {
x = oldX;
y = oldY;
return;
}
}
if(x != oldX || y != oldY) { if(x != oldX || y != oldY) {
GetAnimation()->SetCurrentAnimation(1); GetAnimation()->SetCurrentAnimation(1);

View File

@ -6,6 +6,7 @@
#include "../Math/Vec2.h" #include "../Math/Vec2.h"
class SoundEffect; class SoundEffect;
class Level;
class Actor { class Actor {
public: public:
@ -23,7 +24,7 @@ public:
HURT HURT
}; };
Actor(void); Actor(const Level* level);
~Actor(void); ~Actor(void);
void LoadSprites(const String& basename); void LoadSprites(const String& basename);
@ -47,6 +48,8 @@ protected:
AnimatingSprite* GetAnimation(void); AnimatingSprite* GetAnimation(void);
const Level* _level;
float _velocity; float _velocity;
AnimatingSprite* _actorLeft; AnimatingSprite* _actorLeft;
@ -61,6 +64,7 @@ protected:
float y; float y;
private: private:
SoundEffect* _stepSFX[4]; SoundEffect* _stepSFX[4];
int _lastStepSFXPlayed; int _lastStepSFXPlayed;

View File

@ -1,6 +1,6 @@
#include "NPC.h" #include "NPC.h"
NPC::NPC(void) : Actor() { NPC::NPC(const Level* level) : Actor(level) {
} }
NPC::~NPC(void) { NPC::~NPC(void) {

View File

@ -4,7 +4,7 @@
class NPC : public Actor { class NPC : public Actor {
public: public:
NPC(void); NPC(const Level* level);
~NPC(void); ~NPC(void);
void Update(float dt); void Update(float dt);

View File

@ -1,7 +1,7 @@
#include "Player.h" #include "Player.h"
#include "../IO/Input.h" #include "../IO/Input.h"
Player::Player(void) : Actor() { Player::Player(const Level* level) : Actor(level) {
_direction = Actor::RIGHT; _direction = Actor::RIGHT;
} }
@ -34,11 +34,4 @@ void Player::Move(float dt) {
_direction = Actor::FRONT; _direction = Actor::FRONT;
} }
if(KeyDown(SDLK_LSHIFT)) {
// Run!
_velocity += 3;
}
if(KeyUp(SDLK_LSHIFT)) {
_velocity -= 3;
}
} }

View File

@ -7,7 +7,7 @@
class Player : public Actor{ class Player : public Actor{
public: public:
Player(void); Player(const Level* level);
~Player(void); ~Player(void);
void Update(float dt); void Update(float dt);

View File

@ -49,6 +49,8 @@ void AnimatingSprite::Update(float dt) {
void AnimatingSprite::LoadAnimatingSprite(const char* filename, const char* sequence, int frames, float animationSpeed) { void AnimatingSprite::LoadAnimatingSprite(const char* filename, const char* sequence, int frames, float animationSpeed) {
_maxWidth = 0;
_maxHeight = 0;
for(int i = 0; i < frames; i++) { for(int i = 0; i < frames; i++) {
String tempFilename; String tempFilename;
tempFilename = ""; tempFilename = "";
@ -62,6 +64,8 @@ void AnimatingSprite::LoadAnimatingSprite(const char* filename, const char* sequ
} }
_sprites[_spriteCounter] = new Sprite(); _sprites[_spriteCounter] = new Sprite();
_sprites[_spriteCounter]->LoadSprite((const char*)tempFilename); _sprites[_spriteCounter]->LoadSprite((const char*)tempFilename);
if(_sprites[_spriteCounter]->GetWidth() > _maxWidth) _maxWidth = _sprites[_spriteCounter]->GetWidth();
if(_sprites[_spriteCounter]->GetHeight() > _maxHeight) _maxHeight = _sprites[_spriteCounter]->GetHeight();
_spriteCounter++; _spriteCounter++;
} }
_numberOfFrames = frames; _numberOfFrames = frames;

View File

@ -16,6 +16,9 @@ public:
int GetTotalFrames(void) { return _sequence->GetAnimation(_currentAnimation)->frameEnd; } int GetTotalFrames(void) { return _sequence->GetAnimation(_currentAnimation)->frameEnd; }
Sprite* GetCurrentFrameSprite(void) { return _sprites[_currentFrame - 1]; } Sprite* GetCurrentFrameSprite(void) { return _sprites[_currentFrame - 1]; }
int GetMaxWidth(void) const { return _maxWidth; }
int GetMaxHeight(void) const { return _maxHeight; }
void Update(float dt); void Update(float dt);
void Render(void); void Render(void);
@ -34,4 +37,7 @@ private:
int _numberOfFrames; int _numberOfFrames;
const char* _currentAnimation; const char* _currentAnimation;
int _maxWidth;
int _maxHeight;
}; };

View File

@ -13,6 +13,7 @@ Level::Level() {
_tileWidth = 0; _tileWidth = 0;
_tileHeight = 0; _tileHeight = 0;
_bgm = NULL; _bgm = NULL;
_collisions = NULL;
} }
Level::~Level() { Level::~Level() {
@ -26,6 +27,11 @@ Level::~Level() {
} }
_tilesets.clear(); _tilesets.clear();
if(_collisions) {
delete[] _collisions;
_collisions = NULL;
}
if(_bgm) { if(_bgm) {
musicManager.Destroy(_bgm); musicManager.Destroy(_bgm);
_bgm = NULL; _bgm = NULL;
@ -59,9 +65,24 @@ bool Level::Load(const std::string& filename) {
tilesetMap.insert(std::pair<const Tmx::Tileset*, Tileset*>(tmxTileset, tileset)); tilesetMap.insert(std::pair<const Tmx::Tileset*, Tileset*>(tmxTileset, tileset));
} }
_collisions = new bool[_width * _height];
for(int i = 0; i < (_width * _height); i++) {
_collisions[i] = false;
}
for(int i = 0; i < map.GetNumLayers(); i++) { for(int i = 0; i < map.GetNumLayers(); i++) {
const Tmx::Layer* tmxLayer = map.GetLayer(i); const Tmx::Layer* tmxLayer = map.GetLayer(i);
if(!stricmp(tmxLayer->GetName().c_str(), "collision")) {
for(int x = 0; x < _width; x++) {
for(int y = 0; y < _height; y++) {
Tmx::MapTile tile = tmxLayer->GetTile(x, y);
_collisions[y * _width + x] = tile.gid != 0;
}
}
continue;
}
Layer* layer = new Layer( Layer* layer = new Layer(
tmxLayer->GetWidth(), tmxLayer->GetHeight(), tmxLayer->GetWidth(), tmxLayer->GetHeight(),
_tileWidth, _tileHeight); _tileWidth, _tileHeight);
@ -114,3 +135,55 @@ void Level::Draw(int xOffset, int yOffset) {
(*i)->Draw(xOffset, yOffset); (*i)->Draw(xOffset, 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)) {
return true;
}
int tileX;
int tileY;
// Check Top Left
tileX = (int)(x / (float)_tileWidth);
tileY = (int)(y / (float)_tileHeight);
if(tileX >= 0 && tileX < _width &&
tileY >= 0 && tileY < _height) {
if(_collisions[tileY * _width + tileX]) {
return true;
}
}
// Check Top Right
tileX = (int)((x + w) / (float)_tileWidth);
tileY = (int)(y / (float)_tileHeight);
if(tileX >= 0 && tileX < _width &&
tileY >= 0 && tileY < _height) {
if(_collisions[tileY * _width + tileX]) {
return true;
}
}
// Check Bottom Right
tileX = (int)((x + w) / (float)_tileWidth);
tileY = (int)((y + h) / (float)_tileHeight);
if(tileX >= 0 && tileX < _width &&
tileY >= 0 && tileY < _height) {
if(_collisions[tileY * _width + tileX]) {
return true;
}
}
// Check Bottom Left
tileX = (int)(x / (float)_tileWidth);
tileY = (int)((y + h) / (float)_tileHeight);
if(tileX >= 0 && tileX < _width &&
tileY >= 0 && tileY < _height) {
if(_collisions[tileY * _width + tileX]) {
return true;
}
}
return false;
}

View File

@ -24,6 +24,8 @@ public:
int GetTileWidth() const { return _tileWidth; } int GetTileWidth() const { return _tileWidth; }
int GetTileHeight() const { return _tileHeight; } int GetTileHeight() const { return _tileHeight; }
bool CheckCollision(float x, float y, float w, float h) const;
private: private:
int _width; int _width;
int _height; int _height;
@ -32,4 +34,5 @@ private:
std::list<Layer*> _layers; std::list<Layer*> _layers;
std::list<Tileset*> _tilesets; std::list<Tileset*> _tilesets;
Music* _bgm; Music* _bgm;
bool* _collisions;
}; };

View File

@ -16,9 +16,9 @@
#include "Game.h" #include "Game.h"
Game::Game(void) { Game::Game(void) {
_player = new Player();
_NPC = new NPC();
_level = new Level(); _level = new Level();
_player = new Player(_level);
_NPC = new NPC(_level);
_NPC->SetXY(30.0f, 30.0f); _NPC->SetXY(30.0f, 30.0f);