[Add] Tile based collisions.
This commit is contained in:
parent
e35cb64246
commit
8028320cef
BIN
Data/Img/CollisionTileset.png
Normal file
BIN
Data/Img/CollisionTileset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 921 B |
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "NPC.h"
|
||||
|
||||
NPC::NPC(void) : Actor() {
|
||||
NPC::NPC(const Level* level) : Actor(level) {
|
||||
}
|
||||
|
||||
NPC::~NPC(void) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
class NPC : public Actor {
|
||||
public:
|
||||
NPC(void);
|
||||
NPC(const Level* level);
|
||||
~NPC(void);
|
||||
|
||||
void Update(float dt);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
class Player : public Actor{
|
||||
public:
|
||||
Player(void);
|
||||
Player(const Level* level);
|
||||
~Player(void);
|
||||
|
||||
void Update(float dt);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user