From 3565d69c463c39b05b4612ca3d3557139d91e310 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 30 Sep 2012 17:49:57 +0200 Subject: [PATCH] check blocking flags of tiles in map state --- src/main.cpp | 2 +- src/map/Area.cpp | 13 +++++++++++++ src/map/Area.h | 3 ++- src/map/Entity.cpp | 7 ++++--- src/map/Entity.h | 1 + src/map/Map.cpp | 21 +++++++++++++++++++++ src/map/Map.h | 2 ++ src/map/MapState.cpp | 34 ++++++++++++++++++++++++++++++---- 8 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fa1318..fe975de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -326,7 +326,7 @@ int main(int argc, char **argv) { Sprite mapMaximSprite(mapMaximImg, 32, 64); Entity mapMaxim; mapMaxim.SetSprite(&mapMaximSprite); - mapMaxim.Position() = Vector(80, 160); + mapMaxim.Position() = Vector(80, 128); InitScreen screen(width, height); diff --git a/src/map/Area.cpp b/src/map/Area.cpp index a1ae680..292b895 100644 --- a/src/map/Area.cpp +++ b/src/map/Area.cpp @@ -10,6 +10,8 @@ #include "Tile.h" #include "../graphics/Sprite.h" +#include + using geometry::Vector; namespace map { @@ -21,6 +23,17 @@ Area::Area() } + +const Tile &Area::TileAt(const geometry::Vector &offset) const { + int tileIndex(offset.Y() * width + offset.X()); + if (tileIndex < numTiles) { + return tiles[tileIndex]; + } else { + throw std::out_of_range("tile index out of range"); + } +} + + void Area::Render(SDL_Surface *dest, const graphics::Sprite *tileset, const Vector &inOffset) const { for (int i(0); i < numTiles; ++i) { Vector offset( diff --git a/src/map/Area.h b/src/map/Area.h index 9834f5c..9832809 100644 --- a/src/map/Area.h +++ b/src/map/Area.h @@ -10,7 +10,7 @@ #include "fwd.h" #include "../geometry/Vector.h" -#include "../graphics/fwd.h" +#include "../graphics/Sprite.h" #include @@ -25,6 +25,7 @@ public: public: int Width() const { return width; } int Height() const { return numTiles / width + (numTiles % width ? 1 : 0); } + const Tile &TileAt(const geometry::Vector &) const; void Render(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector &offset) const; diff --git a/src/map/Entity.cpp b/src/map/Entity.cpp index 0e1b822..391c711 100644 --- a/src/map/Entity.cpp +++ b/src/map/Entity.cpp @@ -55,7 +55,7 @@ void Entity::UpdateVelocity() { bool Entity::TileLock(int width, int height) const { Vector tilePosition( position.X() - (width / 2), - position.Y() - height); + position.Y()); return (tilePosition.X() % width == 0) && (tilePosition.Y() % height == 0); } @@ -66,10 +66,11 @@ void Entity::Update(float deltaT) { void Entity::Render(SDL_Surface *dest, const Vector &offset) const { + // TODO: configurable sprite offsets if (animation.Running()) { - animation.DrawCenterBottom(dest, offset + position); + animation.DrawCenter(dest, offset + position); } else { - sprite->DrawCenterBottom(dest, offset + position, orientation); + sprite->DrawCenter(dest, offset + position, orientation); } } diff --git a/src/map/Entity.h b/src/map/Entity.h index 2bc6aac..e1ede97 100644 --- a/src/map/Entity.h +++ b/src/map/Entity.h @@ -43,6 +43,7 @@ public: const graphics::AnimationRunner &Animation() const { return animation; } void SetOrientation(Orientation); + Orientation GetOrientation() const { return orientation; } void SetSpeed(float); bool TileLock(int width, int height) const; diff --git a/src/map/Map.cpp b/src/map/Map.cpp index 450c004..2e05e8b 100644 --- a/src/map/Map.cpp +++ b/src/map/Map.cpp @@ -10,6 +10,8 @@ #include "Area.h" #include "../graphics/Sprite.h" +#include + using geometry::Vector; namespace map { @@ -23,6 +25,25 @@ Map::Map() } +const Area &Map::AreaAt(const Vector &offset) const { + if (numAreas > 0) { + Vector tileOffset(offset.X() / tileset->Width(), offset.Y() / tileset->Height()); + Vector areaOffset(tileOffset.X() / areas[0].Width(), tileOffset.Y() / areas[0].Height()); + int areaIndex(areaOffset.Y() * width + areaOffset.X()); + if (areaIndex < numAreas) { + return areas[areaIndex]; + } + } + throw std::out_of_range("area offset out of bounds"); +} + +const Tile &Map::TileAt(const Vector &offset) const { + const Area &area(AreaAt(offset)); + Vector tileOffset((offset.X() / tileset->Width()) % area.Width(), (offset.Y() / tileset->Height()) % area.Height()); + return area.TileAt(tileOffset); +} + + void Map::Render(SDL_Surface *dest, const Vector &inOffset) const { // TODO: skip invisible areas for (int i(0); i < numAreas; ++i) { diff --git a/src/map/Map.h b/src/map/Map.h index 92c866b..340c76c 100644 --- a/src/map/Map.h +++ b/src/map/Map.h @@ -24,6 +24,8 @@ public: public: const graphics::Sprite *Tileset() const { return tileset; } + const Area &AreaAt(const geometry::Vector &) const; + const Tile &TileAt(const geometry::Vector &) const; void Render(SDL_Surface *dest, const geometry::Vector &offset) const; diff --git a/src/map/MapState.cpp b/src/map/MapState.cpp index 6ef2be7..9a94731 100644 --- a/src/map/MapState.cpp +++ b/src/map/MapState.cpp @@ -8,6 +8,7 @@ #include "MapState.h" #include "Map.h" +#include "Tile.h" #include "../app/Application.h" #include "../app/Input.h" @@ -54,18 +55,43 @@ void MapState::HandleEvents(const Input &input) { if (!controlled) return; if (!controlled->TileLock(map->Tileset()->Width(), map->Tileset()->Height())) return; + bool down(false); if (input.IsDown(Input::PAD_UP)) { controlled->SetOrientation(Entity::ORIENTATION_NORTH); - controlled->SetSpeed(walkingSpeed); + down = true; } else if (input.IsDown(Input::PAD_RIGHT)) { controlled->SetOrientation(Entity::ORIENTATION_EAST); - controlled->SetSpeed(walkingSpeed); + down = true; } else if (input.IsDown(Input::PAD_DOWN)) { controlled->SetOrientation(Entity::ORIENTATION_SOUTH); - controlled->SetSpeed(walkingSpeed); + down = true; } else if (input.IsDown(Input::PAD_LEFT)) { controlled->SetOrientation(Entity::ORIENTATION_WEST); - controlled->SetSpeed(walkingSpeed); + down = true; + } + + if (down) { + const Tile &tile(map->TileAt(controlled->Position())); + bool blocked(false); + switch (controlled->GetOrientation()) { + case Entity::ORIENTATION_NORTH: + blocked = tile.BlocksNorth(); + break; + case Entity::ORIENTATION_EAST: + blocked = tile.BlocksEast(); + break; + case Entity::ORIENTATION_SOUTH: + blocked = tile.BlocksSouth(); + break; + case Entity::ORIENTATION_WEST: + blocked = tile.BlocksWest(); + break; + } + if (!blocked) { + controlled->SetSpeed(walkingSpeed); + } else { + controlled->SetSpeed(0.0f); + } } else { controlled->SetSpeed(0.0f); } -- 2.39.2