From 4df29d19e51bc5fb331abaa51377063f6f863cc4 Mon Sep 17 00:00:00 2001 From: demo Date: Wed, 26 Apr 2017 20:18:23 +0100 Subject: [PATCH] - players are no longer passable - refactor items/players to use int32_t properties instead of int16_t - update pathFinder code - update player code - update properties - update walk code - use stint16 everywhere - update gamefiles (player now walks at normal speed, etc) --- gamefiles/level/town/levelObjects.json | 2 +- gamefiles/level/town/players2.json | 2 +- src/Actions/ActPlayer.h | 27 +++ src/Game/Item.cpp | 6 +- src/Game/LevelCell.h | 2 + src/Game/LevelMap.cpp | 49 +++-- src/Game/LevelMap.h | 6 +- src/Game/PathFinder.cpp | 93 +++++++++- src/Game/PathFinder.h | 13 +- src/Game/Player.cpp | 242 +++++++++++++++++-------- src/Game/Player.h | 68 +++---- src/Parser/Game/ParseLevelObject.cpp | 2 +- src/Parser/Game/ParsePlayer.cpp | 12 +- src/Parser/ParseAction.cpp | 7 + 14 files changed, 384 insertions(+), 147 deletions(-) diff --git a/gamefiles/level/town/levelObjects.json b/gamefiles/level/town/levelObjects.json index 624b2801..f7433962 100755 --- a/gamefiles/level/town/levelObjects.json +++ b/gamefiles/level/town/levelObjects.json @@ -27,7 +27,7 @@ { "id": "l15", "name": "Down to hell", - "mapPosition": [41, 80], + "mapPosition": [41, 79], "texture": "empty", "textureRect": [32, 32], "action": { "name": "load", "file": ["level/l15/load.json", "positionPlayer", "[7, 7]"] } diff --git a/gamefiles/level/town/players2.json b/gamefiles/level/town/players2.json index a9ab12ee..a7e6cc1a 100755 --- a/gamefiles/level/town/players2.json +++ b/gamefiles/level/town/players2.json @@ -72,7 +72,7 @@ "id": "griswold", "class": "blacksmith", "name": "Griswold the blacksmith", - "mapPosition": [62, 64], + "mapPosition": [62, 63], "action": { "name": "load", "file": "towners/griswold/panel.json" }, "inventory": [ { diff --git a/src/Actions/ActPlayer.h b/src/Actions/ActPlayer.h index acd59e77..7fdf3966 100755 --- a/src/Actions/ActPlayer.h +++ b/src/Actions/ActPlayer.h @@ -82,6 +82,7 @@ class ActPlayerMove : public Action auto player = level->getPlayerOrCurrent(idPlayer); if (player != nullptr) { + player->clearWalkPath(); player->MapPosition(*level, position); if (resetDirection == true) { @@ -221,3 +222,29 @@ class ActPlayerSetProperty : public Action return true; } }; + +class ActPlayerSetSpeed : public Action +{ +private: + std::string idPlayer; + std::string idLevel; + int speed; + +public: + ActPlayerSetSpeed(const std::string& idPlayer_, const std::string& idLevel_, + int speed_) : idPlayer(idPlayer_), idLevel(idLevel_), speed(speed_) {} + + virtual bool execute(Game& game) + { + auto level = game.Resources().getLevel(idLevel); + if (level != nullptr) + { + auto player = level->getPlayerOrCurrent(idPlayer); + if (player != nullptr) + { + player->setWalkSpeed(speed); + } + } + return true; + } +}; diff --git a/src/Game/Item.cpp b/src/Game/Item.cpp index 780cb297..d781efb9 100755 --- a/src/Game/Item.cpp +++ b/src/Game/Item.cpp @@ -26,10 +26,10 @@ void Item::executeAction(Game& game) const void Item::MapPosition(Level& level, const MapCoord& pos) { - auto oldObj = level.Map()[mapPosition.x][mapPosition.y].getObject(this); - level.Map()[mapPosition.x][mapPosition.y].deleteObject(this); + auto oldObj = level.Map()[mapPosition].getObject(this); + level.Map()[mapPosition].deleteObject(this); mapPosition = pos; - level.Map()[mapPosition.x][mapPosition.y].addFront(oldObj); + level.Map()[mapPosition].addFront(oldObj); } void Item::update(Game& game, Level& level) diff --git a/src/Game/LevelCell.h b/src/Game/LevelCell.h index d06626bf..86679d01 100755 --- a/src/Game/LevelCell.h +++ b/src/Game/LevelCell.h @@ -41,6 +41,8 @@ class LevelCell std::shared_ptr back() const; std::shared_ptr front() const; + bool hasObjects() const { return objects.empty() == false; } + std::shared_ptr getObject(LevelObject* obj) const; template diff --git a/src/Game/LevelMap.cpp b/src/Game/LevelMap.cpp index 02c02a62..2ad57484 100755 --- a/src/Game/LevelMap.cpp +++ b/src/Game/LevelMap.cpp @@ -154,29 +154,53 @@ MapCoord LevelMap::getTile(const sf::Vector2f& coords) const return MapCoord((Coord)isoPosX, (Coord)isoPosY); } -std::queue LevelMap::getPath(const MapCoord& a, const MapCoord& b) const +std::vector LevelMap::getPath(const MapCoord& a, const MapCoord& b) const { - std::queue path; + std::vector path; + + if (a == b) + { + path.push_back(a); + return path; + } MapSearchNode start(this, a.x, a.y, PlayerDirection::All); MapSearchNode end(this, b.x, b.y, PlayerDirection::All); + MapSearchNode endOrig(end); - if (end.IsPassableIgnoreObject() == false) + if (end.IsValid() == false) { return path; } + if (end.IsPassable() == false) + { + if (((*this)[b]).hasObjects() == true) + { + if (start.GoalDistanceEstimateC(end) == 1.f || + getNearestPassableEndNode(start, end) == false) + { + path.push_back(b); + return path; + } + if (end.IsPassableIgnoreObject() == false) + { + return path; + } + } + else + { + return path; + } + } PathFinder pathFinder(PATH_FINDER_MAX); pathFinder.SetStartAndGoalStates(start, end); unsigned int SearchState; - do { SearchState = pathFinder.SearchStep(); - - auto StepCount = pathFinder.GetStepCount(); - if (StepCount == PATH_FINDER_MAX) + if (pathFinder.GetStepCount() == PATH_FINDER_MAX) { pathFinder.CancelSearch(); } @@ -184,16 +208,19 @@ std::queue LevelMap::getPath(const MapCoord& a, const MapCoord& b) con if (SearchState == PathFinder::SEARCH_STATE_SUCCEEDED) { - auto node = pathFinder.GetSolutionStart(); - + if (endOrig.IsPassable() == false) + { + path.push_back(MapCoord(endOrig.x, endOrig.y)); + } + auto node = pathFinder.GetSolutionEnd(); while (true) { if (node == nullptr) { break; } - path.push(MapCoord(node->x, node->y)); - node = pathFinder.GetSolutionNext(); + path.push_back(MapCoord(node->x, node->y)); + node = pathFinder.GetSolutionPrev(); }; pathFinder.FreeSolutionNodes(); } diff --git a/src/Game/LevelMap.h b/src/Game/LevelMap.h index 765f6362..c1aa685b 100755 --- a/src/Game/LevelMap.h +++ b/src/Game/LevelMap.h @@ -5,7 +5,6 @@ #include "Helper2D.h" #include "LevelCell.h" #include "MapCoord.h" -#include #include "TileSet.h" #include "Sol.h" #include @@ -44,6 +43,9 @@ class LevelMap return Misc::Helper2D(*this, x, get); } + LevelCell& operator[] (MapCoord coord) { return get(coord.x, coord.y, *this); } + const LevelCell& operator[] (MapCoord coord) const { return get(coord.x, coord.y, *this); } + Coord Width() const { return mapSize.x; } Coord Height() const { return mapSize.y; } @@ -54,5 +56,5 @@ class LevelMap sf::Vector2f getCoord(const MapCoord& tile) const; MapCoord getTile(const sf::Vector2f& coords) const; - std::queue getPath(const MapCoord& a, const MapCoord& b) const; + std::vector getPath(const MapCoord& a, const MapCoord& b) const; }; diff --git a/src/Game/PathFinder.cpp b/src/Game/PathFinder.cpp index af889305..78dd350c 100755 --- a/src/Game/PathFinder.cpp +++ b/src/Game/PathFinder.cpp @@ -2,19 +2,24 @@ #include #include "LevelMap.h" -bool MapSearchNode::IsPassableIgnoreObject() +bool MapSearchNode::IsValid() const { - if (x >= 0 && + return (x >= 0 && x < map->Width() && y >= 0 && - y < map->Height()) + y < map->Height()); +} + +bool MapSearchNode::IsPassableIgnoreObject() const +{ + if (IsValid() == true) { return (*map)[(Coord)x][(Coord)y].PassableIgnoreObject(); } return false; } -bool MapSearchNode::IsPassable(int16_t x_, int16_t y_) +bool MapSearchNode::IsPassable(int16_t x_, int16_t y_) const { if (x_ >= 0 && x_ < map->Width() && @@ -31,11 +36,16 @@ bool MapSearchNode::IsSameState(MapSearchNode& rhs) return ((x == rhs.x) && (y == rhs.y)); } -float MapSearchNode::GoalDistanceEstimate(MapSearchNode& nodeGoal) +float MapSearchNode::GoalDistanceEstimateC(const MapSearchNode& nodeGoal) const { return (float)(std::abs(x - nodeGoal.x) + std::abs(y - nodeGoal.y)); } +float MapSearchNode::GoalDistanceEstimate(MapSearchNode& nodeGoal) +{ + return GoalDistanceEstimateC(nodeGoal); +} + bool MapSearchNode::IsGoal(MapSearchNode& nodeGoal) { return ((x == nodeGoal.x) && (y == nodeGoal.y)); @@ -97,7 +107,7 @@ bool MapSearchNode::GetSuccessors(AStarSearch* astarsearch, MapSe return true; } -float MapSearchNode::GetCost(MapSearchNode& successor) +float MapSearchNode::GetCost() const { if (IsPassable(x, y) == true) { @@ -105,3 +115,74 @@ float MapSearchNode::GetCost(MapSearchNode& successor) } return 9.f; } + +float MapSearchNode::GetCost(MapSearchNode& successor) +{ + return GetCost(); +} + +const bool addNearestSuccessor(std::vector& neighbours, + int16_t x_, int16_t y_, MapSearchNode parent) +{ + MapSearchNode neighbour(parent); + neighbour.x = x_; + neighbour.y = y_; + if ((neighbour.IsPassable() == true) && !((parent.x == x_) && (parent.y == y_))) + { + neighbours.push_back(neighbour); + return true; + } + return false; +} + +bool getNearestPassableEndNode(const MapSearchNode& start, MapSearchNode& end) +{ + std::vector neighbours; + + bool canWalkLeft = addNearestSuccessor(neighbours, end.x - 1, end.y, end); + bool canWalkRight = addNearestSuccessor(neighbours, end.x + 1, end.y, end); + bool canWalkUp = addNearestSuccessor(neighbours, end.x, end.y - 1, end); + bool canWalkDown = addNearestSuccessor(neighbours, end.x, end.y + 1, end); + + if (canWalkLeft == true) + { + if (canWalkUp == true) + { + addNearestSuccessor(neighbours, end.x - 1, end.y - 1, end); + } + if (canWalkDown == true) + { + addNearestSuccessor(neighbours, end.x - 1, end.y + 1, end); + } + } + if (canWalkRight == true) + { + if (canWalkUp == true) + { + addNearestSuccessor(neighbours, end.x + 1, end.y - 1, end); + } + if (canWalkDown == true) + { + addNearestSuccessor(neighbours, end.x + 1, end.y + 1, end); + } + } + + std::sort(neighbours.begin(), neighbours.end(), + [&start](const MapSearchNode& lhs, const MapSearchNode& rhs) + { + float costA = lhs.GetCost() + lhs.GoalDistanceEstimateC(start); + float costB = rhs.GetCost() + rhs.GoalDistanceEstimateC(start); + return costA < costB; + }); + + if (neighbours.empty() == true) + { + return false; + } + if (neighbours.front().IsPassable() == false) + { + return false; + } + end = neighbours.front(); + return true; +} diff --git a/src/Game/PathFinder.h b/src/Game/PathFinder.h index 3891a4f8..000e47ef 100755 --- a/src/Game/PathFinder.h +++ b/src/Game/PathFinder.h @@ -23,9 +23,14 @@ class MapSearchNode MapSearchNode(const LevelMap* map_, int16_t x_, int16_t y_, const PlayerDirection& direction_) : map(map_), x(x_), y(y_), direction(direction_) {} - bool IsPassableIgnoreObject(); - bool IsPassable() { return IsPassable(x, y); } - bool IsPassable(int16_t x_, int16_t y_); + bool IsValid() const; + + bool IsPassableIgnoreObject() const; + bool IsPassable() const { return IsPassable(x, y); } + bool IsPassable(int16_t x_, int16_t y_) const; + + float GoalDistanceEstimateC(const MapSearchNode& nodeGoal) const; + float GetCost() const; float GoalDistanceEstimate(MapSearchNode& nodeGoal); bool IsGoal(MapSearchNode& nodeGoal); @@ -34,4 +39,6 @@ class MapSearchNode bool IsSameState(MapSearchNode& rhs); }; +bool getNearestPassableEndNode(const MapSearchNode& start, MapSearchNode& end); + typedef AStarSearch PathFinder; diff --git a/src/Game/Player.cpp b/src/Game/Player.cpp index 9bf3c565..8d040606 100755 --- a/src/Game/Player.cpp +++ b/src/Game/Player.cpp @@ -7,94 +7,163 @@ #include "Level.h" #include "Utils.h" -sf::Vector2f Player::getBasePosition() const +void Player::calculateRange() { - return sf::Vector2f( - std::round(sprite.getPosition().x + (float)(sprite.getTextureRect().width / 2)), - std::round(sprite.getPosition().y + (float)(sprite.getTextureRect().height - LevelMap::TileSize() / 2))); -} - -void Player::executeAction(Game& game) const -{ - if (action != nullptr) + celTexture = class_->getCelTexture(palette); + if (celTexture != nullptr + && direction < PlayerDirection::Size) { - game.Events().addBack(action); + celIdx = class_->getStatusCelIndex(status); + auto numFrames = celTexture->size(celIdx); + if (direction == PlayerDirection::All) + { + frameRange.first = 0; + frameRange.second = numFrames; + } + else + { + auto period = (numFrames / 8); + frameRange.first = (size_t)direction * period; + frameRange.second = frameRange.first + period; + } + } + else + { + celIdx = 0; + frameRange.first = 0; + frameRange.second = 0; } } -void Player::MapPosition(Level& level, const MapCoord& pos) +void Player::updateDrawPosition(sf::Vector2f pos) { - auto oldObj = level.Map()[mapPosition.x][mapPosition.y].getObject(this); - level.Map()[mapPosition.x][mapPosition.y].deleteObject(this); - mapPosition = pos; - level.Map()[mapPosition.x][mapPosition.y].addBack(oldObj); + pos.x += (float)(-(sprite.getTextureRect().width / 2)) + LevelMap::TileSize(); + pos.y += (float)(224 - (sprite.getTextureRect().height - LevelMap::TileSize())); + sprite.setPosition(pos); } -void Player::updateWalkPath(Game& game, Level& level, const sf::Vector2u& texSize) +void Player::updateTexture() { - if (walkPath.empty() == true) + if (currentFrame < frameRange.first || currentFrame >= frameRange.second) { - setStatus(PlayerStatus::Stand1); + currentFrame = frameRange.first; } - else + if (currentFrame < celTexture->size(celIdx)) { - setStatus(PlayerStatus::Walk1); + sprite.setTexture(celTexture->get(celIdx, currentFrame), true); } + currentFrame++; +} - if (walkPath.empty() == false) +void Player::updateWalkPath(Game& game, Level& level) +{ + auto newDrawPos = drawPosA; + + beginning: + if (drawPosA == drawPosB) { - const auto& nextMapPos = walkPath.front(); - if (walkPath.size() == 1) + if (walkPath.empty() == true) { - const auto levelObj = level.Map()[nextMapPos.x][nextMapPos.y].front(); - if (levelObj != nullptr) + setStatus(PlayerStatus::Stand1); + } + while (walkPath.empty() == false) + { + const auto& nextMapPos = walkPath.back(); + if (walkPath.size() == 1) { - levelObj->executeAction(game); - walkPath.pop(); - return; + const auto levelObj = level.Map()[nextMapPos.x][nextMapPos.y].front(); + if (levelObj != nullptr) + { + levelObj->executeAction(game); + walkPath.pop_back(); + return; + } } - } + if (nextMapPos == mapPosition) + { + walkPath.pop_back(); + continue; + } + setStatus(PlayerStatus::Walk1); + setDirection(getPlayerDirection(mapPosition, nextMapPos)); + MapPosition(level, nextMapPos); - setDirection(getPlayerDirection(mapPosition, nextMapPos)); - MapPosition(level, nextMapPos); - walkPath.pop(); + currPositionStep = 0.125f; + goto beginning; + } } - - auto drawPos = level.Map().getCoord(mapPosition); - drawPos.x += (float)(-((int)texSize.x / 2)) + LevelMap::TileSize(); - drawPos.y += (float)(224 - ((int)texSize.y - LevelMap::TileSize())); - sprite.setPosition(drawPos); -} - -void Player::update(Game& game, Level& level) -{ - auto rect = sprite.getGlobalBounds(); - if (enableHover == true) + else { - if (level.HasMouseInside() == true && - rect.contains(level.MousePositionf()) == true) + newDrawPos.x -= std::round((drawPosA.x - drawPosB.x) * currPositionStep); + newDrawPos.y -= std::round((drawPosA.y - drawPosB.y) * currPositionStep); + + if (currPositionStep >= 1.f) { - if (hovered == false) + if (walkPath.empty() == false) + { + walkPath.pop_back(); + } + else { - hovered = true; - level.setHoverObject(this); - level.executeHoverEnterAction(game); + setStatus(PlayerStatus::Stand1); } + drawPosA = drawPosB; + newDrawPos = drawPosB; } else { - if (hovered == true) - { - hovered = false; - if (level.getHoverObject() == this) - { - level.setHoverObject(nullptr); - level.executeHoverLeaveAction(game); - } - } + currPositionStep += 0.125f; } } + updateDrawPosition(newDrawPos); +} + +void Player::setWalkSpeed(int fps) +{ + fps = std::max(std::min(fps, 1000), 1); + walkTime = sf::seconds(1.f / (float)fps); +} +void Player::setWalkPath(const std::vector& walkPath_) +{ + if (walkPath_.empty() == true) + { + return; + } + walkPath = walkPath_; + if (walkPath.empty() == false) + { + mapPositionMoveTo = walkPath.front(); + } +} + +sf::Vector2f Player::getBasePosition() const +{ + return sf::Vector2f( + std::round(sprite.getPosition().x + (float)(sprite.getTextureRect().width / 2)), + std::round(sprite.getPosition().y + (float)(sprite.getTextureRect().height - LevelMap::TileSize() / 2))); +} + +void Player::executeAction(Game& game) const +{ + if (action != nullptr) + { + game.Events().addBack(action); + } +} + +void Player::MapPosition(Level& level, const MapCoord& pos) +{ + auto oldObj = level.Map()[mapPosition].getObject(this); + level.Map()[mapPosition].deleteObject(this); + drawPosA = level.Map().getCoord(mapPosition); + mapPosition = pos; + drawPosB = level.Map().getCoord(mapPosition); + level.Map()[mapPosition].addBack(oldObj); +} + +void Player::update(Game& game, Level& level) +{ if (celTexture == nullptr || frameRange.first > frameRange.second) { @@ -102,28 +171,51 @@ void Player::update(Game& game, Level& level) } // add delta time - currentTime += game.getElapsedTime(); + currentFrameTime += game.getElapsedTime(); // if current time is bigger then the frame time advance one frame - if (currentTime >= frameTime) + if (currentFrameTime >= frameTime) { // reset time, but keep the remainder - currentTime = sf::microseconds(currentTime.asMicroseconds() % frameTime.asMicroseconds()); + currentFrameTime = sf::microseconds(currentFrameTime.asMicroseconds() % frameTime.asMicroseconds()); - if (rect.width > 0 && rect.height > 0) - { - updateWalkPath(game, level, sf::Vector2u((unsigned)rect.width, (unsigned)rect.height)); - } + updateTexture(); + } + + currentWalkTime += game.getElapsedTime(); - currentFrame++; - if (currentFrame < frameRange.first || currentFrame >= frameRange.second) + // if current time is bigger then the frame time advance one frame + if (currentWalkTime >= walkTime) + { + // reset time, but keep the remainder + currentWalkTime = sf::microseconds(currentFrameTime.asMicroseconds() % walkTime.asMicroseconds()); + + updateWalkPath(game, level); + } + if (enableHover == false) + { + return; + } + if (level.HasMouseInside() == true && + sprite.getGlobalBounds().contains(level.MousePositionf()) == true) + { + if (hovered == false) { - currentFrame = frameRange.first; + hovered = true; + level.setHoverObject(this); + level.executeHoverEnterAction(game); } - - if (currentFrame < celTexture->size(celIdx)) + } + else + { + if (hovered == true) { - sprite.setTexture(celTexture->get(celIdx, currentFrame), true); + hovered = false; + if (level.getHoverObject() == this) + { + level.setHoverObject(nullptr); + level.executeHoverLeaveAction(game); + } } } } @@ -591,11 +683,11 @@ bool Player::addGold(const Level& level, LevelObjValue amount) } newItem->setItemPropertyByHash(ItemProp::Gold, goldVal); - size_t invIdx = 0; - size_t itemIdx = 0; - if (getItemSlot(*newItem, invIdx, itemIdx) == true) + size_t invIdx2 = 0; + size_t itemIdx2 = 0; + if (getItemSlot(*newItem, invIdx2, itemIdx2) == true) { - inventories[invIdx].set(itemIdx, newItem); + inventories[invIdx2].set(itemIdx2, newItem); amount -= goldVal; gold += goldVal; } diff --git a/src/Game/Player.h b/src/Game/Player.h index 47de0b79..72d48c26 100755 --- a/src/Game/Player.h +++ b/src/Game/Player.h @@ -6,7 +6,6 @@ #include "LevelObject.h" #include #include "PlayerClass.h" -#include class Player : public LevelObject { @@ -14,8 +13,11 @@ class Player : public LevelObject sf::Sprite sprite; MapCoord mapPosition; MapCoord mapPositionMoveTo; + sf::Vector2f drawPosA; + sf::Vector2f drawPosB; + float currPositionStep = 0.f; - std::queue walkPath; + std::vector walkPath; std::shared_ptr class_; @@ -30,7 +32,10 @@ class Player : public LevelObject size_t currentFrame{ 0 }; sf::Time frameTime{ sf::milliseconds(50) }; - sf::Time currentTime; + sf::Time currentFrameTime; + + sf::Time walkTime{ sf::milliseconds(66) }; + sf::Time currentWalkTime; std::shared_ptr action; @@ -73,35 +78,9 @@ class Player : public LevelObject LevelObjValue resistFire{ 0 }; LevelObjValue resistLightning{ 0 }; - void calculateRange() - { - celTexture = class_->getCelTexture(palette); - if (celTexture != nullptr - && direction < PlayerDirection::Size) - { - celIdx = class_->getStatusCelIndex(status); - auto numFrames = celTexture->size(celIdx); - if (direction == PlayerDirection::All) - { - frameRange.first = 0; - frameRange.second = numFrames; - } - else - { - auto period = (numFrames / 8); - frameRange.first = (size_t)direction * period; - frameRange.second = frameRange.first + period; - } - } - else - { - celIdx = 0; - frameRange.first = 0; - frameRange.second = 0; - } - } + void calculateRange(); - void updateWalkPath(Game& game, Level& level, const sf::Vector2u& texSize); + void updateWalkPath(Game& game, Level& level); bool parseInventoryAndItem(const std::string& str, std::string& props, size_t& invIdx, size_t& itemIdx) const; @@ -120,14 +99,21 @@ class Player : public LevelObject return sf::Vector2f((float)sprite.getTextureRect().width, (float)sprite.getTextureRect().height); } - virtual const MapCoord& MapPosition() const { return mapPosition; } + virtual const MapCoord& MapPosition() const + { + if (walkPath.empty() == false) + { + return walkPath.back(); + } + return mapPosition; + } virtual void MapPosition(const MapCoord& pos) { mapPosition = pos; } void MapPosition(Level& level, const MapCoord& pos); const MapCoord& MapPositionMoveTo() const { return mapPositionMoveTo; } virtual void executeAction(Game& game) const; - virtual bool Passable() const { return true; } + virtual bool Passable() const { return false; } virtual void setAction(const std::shared_ptr& action_) { action = action_; } virtual bool Hoverable() const { return enableHover; } @@ -156,14 +142,14 @@ class Player : public LevelObject return setPlayerProperty(prop.c_str(), value); } - void setWalkPath(const std::queue walkPath_) - { - walkPath = walkPath_; - if (walkPath.empty() == false) - { - mapPositionMoveTo = walkPath.back(); - } - } + void updateDrawPosition(sf::Vector2f pos); + void updateDrawPosition() { updateDrawPosition(drawPosA); } + + void updateTexture(); + + void setWalkSpeed(int fps); + void clearWalkPath() { walkPath = {}; } + void setWalkPath(const std::vector& walkPath_); void setDirection(PlayerDirection direction_) { diff --git a/src/Parser/Game/ParseLevelObject.cpp b/src/Parser/Game/ParseLevelObject.cpp index 6545785b..98c4a1ff 100755 --- a/src/Parser/Game/ParseLevelObject.cpp +++ b/src/Parser/Game/ParseLevelObject.cpp @@ -32,7 +32,7 @@ namespace Parser { return; } - auto& mapCell = level->Map()[mapPos.x][mapPos.y]; + auto& mapCell = level->Map()[mapPos]; if (mapCell.getObject() != nullptr) { diff --git a/src/Parser/Game/ParsePlayer.cpp b/src/Parser/Game/ParsePlayer.cpp index d38d3c8f..5564b47a 100755 --- a/src/Parser/Game/ParsePlayer.cpp +++ b/src/Parser/Game/ParsePlayer.cpp @@ -153,9 +153,9 @@ namespace Parser { return; } - auto& mapCell = level->Map()[mapPos.x][mapPos.y]; + auto& mapCell = level->Map()[mapPos]; - if (mapCell.Passable() == false) + if (mapCell.getObject() != nullptr) { return; } @@ -170,11 +170,17 @@ namespace Parser player->applyDefaults(); - player->MapPosition(mapPos); mapCell.addBack(player); + player->MapPosition(mapPos); + player->MapPosition(*level, mapPos); + + player->updateTexture(); + player->updateDrawPosition(); player->Hoverable(getBoolKey(elem, "enableHover", true)); + player->setWalkSpeed(getIntKey(elem, "speed", 15)); + player->setDirection(getPlayerDirectionKey(elem, "direction")); player->setStatus(getPlayerStatusKey(elem, "status")); player->setPalette(getUIntKey(elem, "palette")); diff --git a/src/Parser/ParseAction.cpp b/src/Parser/ParseAction.cpp index 6de54773..8690ee14 100755 --- a/src/Parser/ParseAction.cpp +++ b/src/Parser/ParseAction.cpp @@ -847,6 +847,13 @@ namespace Parser getStringKey(elem, "property"), getVariableKey(elem, "value")); } + case str2int16("player.setSpeed"): + { + return std::make_shared( + getStringKey(elem, "id"), + getStringKey(elem, "idLevel"), + getIntKey(elem, "speed", 30)); + } case str2int16("quest.add"): { auto quest = parseQuestObj(game, elem);