[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">
<image source="../Img/AwesomeTileset.png" width="256" height="128"/>
</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">
<data encoding="base64" compression="zlib">
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=
</data>
</layer>
<layer name="Collision" width="60" height="60">
<data encoding="base64" compression="zlib">
eJzt1MEKgCAMANBd/f8f7hripoSYh/cgarKNaKOIiPa6YhD3Z1VeJPFKv1Pa5N4/Z3Vfzv6wa77ZnG+db/8uVU5Vl32XWb9TqrlkOVVd1uemfc7i0U7O9ndUu9IPdhj9Z+wbAAAAAAAAAAAAAACwywOaowOg
</data>
</layer>
</map>

View File

@ -2,8 +2,11 @@
#include "Actor.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[1] = sfxManager.Load("../Data/SFX/step_cloth2.wav");
_stepSFX[2] = sfxManager.Load("../Data/SFX/step_cloth3.wav");
@ -54,10 +57,16 @@ void Actor::Update(float dt) {
float oldX = x;
float oldY = y;
// We should check for collisions now.
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) {
GetAnimation()->SetCurrentAnimation(1);

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
#include "Player.h"
#include "../IO/Input.h"
Player::Player(void) : Actor() {
Player::Player(const Level* level) : Actor(level) {
_direction = Actor::RIGHT;
}
@ -34,11 +34,4 @@ void Player::Move(float dt) {
_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{
public:
Player(void);
Player(const Level* level);
~Player(void);
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) {
_maxWidth = 0;
_maxHeight = 0;
for(int i = 0; i < frames; i++) {
String tempFilename;
tempFilename = "";
@ -62,6 +64,8 @@ void AnimatingSprite::LoadAnimatingSprite(const char* filename, const char* sequ
}
_sprites[_spriteCounter] = new Sprite();
_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++;
}
_numberOfFrames = frames;

View File

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

View File

@ -13,6 +13,7 @@ Level::Level() {
_tileWidth = 0;
_tileHeight = 0;
_bgm = NULL;
_collisions = NULL;
}
Level::~Level() {
@ -26,6 +27,11 @@ Level::~Level() {
}
_tilesets.clear();
if(_collisions) {
delete[] _collisions;
_collisions = NULL;
}
if(_bgm) {
musicManager.Destroy(_bgm);
_bgm = NULL;
@ -59,8 +65,23 @@ bool Level::Load(const std::string& filename) {
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++) {
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(
tmxLayer->GetWidth(), tmxLayer->GetHeight(),
@ -114,3 +135,55 @@ void Level::Draw(int xOffset, int 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 GetTileHeight() const { return _tileHeight; }
bool CheckCollision(float x, float y, float w, float h) const;
private:
int _width;
int _height;
@ -32,4 +34,5 @@ private:
std::list<Layer*> _layers;
std::list<Tileset*> _tilesets;
Music* _bgm;
bool* _collisions;
};

View File

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