Added Vector2 class to replace sf::Vector2, featuring comparison operator.

This commit is contained in:
Felix Ableitner 2013-08-07 17:39:43 +02:00
parent 602cc605e8
commit e469211e95
36 changed files with 271 additions and 230 deletions

View file

@ -23,14 +23,14 @@ const int Game::FPS_GOAL = 60;
*/
Game::Game(tgui::Window& window) :
mWindow(window),
mWorldView(sf::Vector2f(0, 0), mWindow.getView().getSize()),
mWorldView(Vector2f(0, 0), mWindow.getView().getSize()),
mGenerator(mWorld, mPathfinder),
mQuit(false),
mPaused(false) {
mWindow.setFramerateLimit(FPS_GOAL);
mWindow.setKeyRepeatEnabled(false);
mGenerator.generateCurrentAreaIfNeeded(sf::Vector2f());
mGenerator.generateCurrentAreaIfNeeded(Vector2f());
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mPathfinder,
mGenerator.getPlayerSpawn()));
mPlayer->setLeftGadget(std::shared_ptr<Gadget>(new Heal()));
@ -221,9 +221,9 @@ Game::keyDown(const sf::Event& event) {
/**
* Converts a screen coordinate to a world coordinate.
*/
sf::Vector2<float>
Vector2<float>
Game::convertCoordinates(int x, int y) {
return mWindow.mapPixelToCoords(sf::Vector2i(x, y), mWorldView);
return mWindow.mapPixelToCoords(Vector2i(x, y), mWorldView);
}
void

View file

@ -36,7 +36,7 @@ private:
void mouseDown(const sf::Event& event);
void mouseUp(const sf::Event& event);
sf::Vector2<float> convertCoordinates(int x, int y);
Vector2<float> convertCoordinates(int x, int y);
void updateGui();
private:

View file

@ -32,7 +32,7 @@ Pathfinder::astarArea(Area* start, Area* end) const {
assert(start);
assert(end);
auto heuristic_cost_estimate = [](Area* start, Area* end) {
return thor::length(sf::Vector2f(end->center - start->center));
return thor::length(Vector2f(end->center - start->center));
};
std::set<Area*> closed;
@ -91,37 +91,37 @@ Pathfinder::astarArea(Area* start, Area* end) const {
* @param radius Radius of the moving object.
* @return Path from end to start (path from start to end in reverse order).
*/
std::vector<sf::Vector2f>
Pathfinder::getPath(const sf::Vector2f& start, const sf::Vector2f& end,
std::vector<Vector2f>
Pathfinder::getPath(const Vector2f& start, const Vector2f& end,
float radius) const {
if (!getArea(end))
return std::vector<sf::Vector2f>();
return std::vector<Vector2f>();
std::vector<Portal*> portals = astarArea(getArea(start), getArea(end));
if (portals.empty())
return std::vector<sf::Vector2f>();
std::vector<sf::Vector2f> path;
return std::vector<Vector2f>();
std::vector<Vector2f> path;
path.push_back(end);
for (auto p : portals) {
// Find the point on the line of the portal closest to the previous point.
sf::Vector2f startToEnd = sf::Vector2f(p->end - p->start);
float percentage = thor::dotProduct(startToEnd, path.back() - sf::Vector2f(p->start)) /
Vector2f startToEnd = Vector2f(p->end - p->start);
float percentage = thor::dotProduct(startToEnd, path.back() - Vector2f(p->start)) /
thor::squaredLength(startToEnd);
sf::Vector2f point;
Vector2f point;
if (percentage < 0 || percentage > 1.0f) {
if (thor::squaredLength(sf::Vector2f(p->start) - path.back()) <
thor::squaredLength(sf::Vector2f(p->end) - path.back())) {
if (thor::squaredLength(Vector2f(p->start) - path.back()) <
thor::squaredLength(Vector2f(p->end) - path.back())) {
thor::setLength(startToEnd, WALL_DISTANCE_MULTIPLIER * radius);
point = sf::Vector2f(p->start) + startToEnd;
point = Vector2f(p->start) + startToEnd;
}
else {
thor::setLength(startToEnd, WALL_DISTANCE_MULTIPLIER * radius);
point = sf::Vector2f(p->end) - startToEnd;
point = Vector2f(p->end) - startToEnd;
}
}
else
point = sf::Vector2f(p->start) + startToEnd * percentage;
point = Vector2f(p->start) + startToEnd * percentage;
// Take two points on a line orthogonal to the portal.
thor::setLength(startToEnd, radius);
@ -148,7 +148,7 @@ Pathfinder::insertArea(const sf::FloatRect& rect) {
rect.top * Tile::TILE_SIZE.y - Tile::TILE_SIZE.y / 2.0f,
rect.width * Tile::TILE_SIZE.x,
rect.height * Tile::TILE_SIZE.y);
a.center = sf::Vector2f(a.area.left + a.area.width / 2,
a.center = Vector2f(a.area.left + a.area.width / 2,
a.area.top + a.area.height / 2);
mAreas.push_back(a);
}
@ -174,8 +174,8 @@ Pathfinder::generatePortals() {
.getOverlap(Interval::IntervalFromPoints(other.area.top,
other.area.top + other.area.height));
if (overlap.getLength() > 0) {
portal.start = sf::Vector2f(other.area.left, overlap.start);
portal.end = sf::Vector2f(other.area.left, overlap.end);
portal.start = Vector2f(other.area.left, overlap.start);
portal.end = Vector2f(other.area.left, overlap.end);
it.portals.push_back(portal);
}
}
@ -185,8 +185,8 @@ Pathfinder::generatePortals() {
.getOverlap(Interval::IntervalFromPoints(other.area.top,
other.area.top + other.area.height));
if (overlap.getLength() > 0) {
portal.start = sf::Vector2f(it.area.left, overlap.start);
portal.end = sf::Vector2f(it.area.left, overlap.end);
portal.start = Vector2f(it.area.left, overlap.start);
portal.end = Vector2f(it.area.left, overlap.end);
it.portals.push_back(portal);
}
}
@ -196,8 +196,8 @@ Pathfinder::generatePortals() {
.getOverlap(Interval::IntervalFromPoints(other.area.left,
other.area.left + other.area.width));
if (overlap.getLength() > 0) {
portal.start = sf::Vector2f(overlap.start, other.area.top);
portal.end = sf::Vector2f(overlap.end, other.area.top);
portal.start = Vector2f(overlap.start, other.area.top);
portal.end = Vector2f(overlap.end, other.area.top);
it.portals.push_back(portal);
}
}
@ -207,8 +207,8 @@ Pathfinder::generatePortals() {
.getOverlap(Interval::IntervalFromPoints(other.area.left,
other.area.left + other.area.width));
if (overlap.getLength() > 0) {
portal.start = sf::Vector2f(overlap.start, it.area.top);
portal.end = sf::Vector2f(overlap.end, it.area.top);
portal.start = Vector2f(overlap.start, it.area.top);
portal.end = Vector2f(overlap.end, it.area.top);
it.portals.push_back(portal);
}
}
@ -220,7 +220,7 @@ Pathfinder::generatePortals() {
* Returns the area where point is in.
*/
Pathfinder::Area*
Pathfinder::getArea(const sf::Vector2f& point) const {
Pathfinder::getArea(const Vector2f& point) const {
for (auto& area : mAreas) {
if (area.area.contains(point))
// Make the return value non-const for convenience.
@ -236,8 +236,8 @@ Pathfinder::getArea(const sf::Vector2f& point) const {
void
Pathfinder::draw(sf::RenderTarget& target, sf::RenderStates states) const {
for (auto& area : mAreas) {
sf::RectangleShape rect(sf::Vector2f(area.area.width, area.area.height));
rect.setPosition(sf::Vector2f(area.area.left, area.area.top));
sf::RectangleShape rect(Vector2f(area.area.width, area.area.height));
rect.setPosition(Vector2f(area.area.left, area.area.top));
rect.setFillColor(sf::Color(area.area.width * 30, 127, 0, 96));
target.draw(rect);
}

View file

@ -11,6 +11,8 @@
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include "util/Vector.h"
/**
* Used to find paths between points in the world.
*
@ -25,11 +27,11 @@ private:
public:
void insertArea(const sf::FloatRect& rect);
void generatePortals();
std::vector<sf::Vector2f> getPath(const sf::Vector2f& start,
const sf::Vector2f& end, float radius) const;
std::vector<Vector2f> getPath(const Vector2f& start,
const Vector2f& end, float radius) const;
private:
Area* getArea(const sf::Vector2f& point) const;
Area* getArea(const Vector2f& point) const;
std::vector<Portal*> astarArea(Area* start, Area* end) const;
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
@ -44,8 +46,8 @@ private:
* Redundant data as portals are saved twice.
*/
struct Pathfinder::Portal {
sf::Vector2f start;
sf::Vector2f end;
Vector2f start;
Vector2f end;
Area* area;
};
@ -54,7 +56,7 @@ struct Pathfinder::Portal {
*/
struct Pathfinder::Area {
sf::FloatRect area;
sf::Vector2f center;
Vector2f center;
std::vector<Portal> portals;
};

View file

@ -52,7 +52,7 @@ World::remove(std::shared_ptr<Sprite> drawable) {
* Returns all characters that are within maxDistance from position.
*/
std::vector<std::shared_ptr<Character> >
World::getCharacters(const sf::Vector2f& position, float maxDistance) const {
World::getCharacters(const Vector2f& position, float maxDistance) const {
std::vector<std::shared_ptr<Character> > visible;
for (const auto& it : mCharacters) {
if (position == it->getPosition())
@ -81,7 +81,7 @@ World::step(int elapsed) {
it--;
}
// Don't run collision tests if sprite is not moving.
else if ((*it)->getSpeed() != sf::Vector2f())
else if ((*it)->getSpeed() != Vector2f())
applyMovement(*it, elapsed);
}
}
@ -93,7 +93,7 @@ World::step(int elapsed) {
*/
void
World::applyMovement(std::shared_ptr<Sprite> sprite, int elapsed) {
sf::Vector2f offset = sprite->getSpeed() * (elapsed / 1000.0f);
Vector2f offset = sprite->getSpeed() * (elapsed / 1000.0f);
for (auto w = mDrawables.begin(); w != mDrawables.end(); w++) {
for (const auto& other : w->second) {
if (sprite == other)
@ -158,19 +158,19 @@ World::draw(sf::RenderTarget& target, sf::RenderStates states) const {
* @return True if the ray was not blocked.
*/
bool
World::raycast(const sf::Vector2f& lineStart,
const sf::Vector2f& lineEnd) const {
World::raycast(const Vector2f& lineStart,
const Vector2f& lineEnd) const {
assert(lineStart != lineEnd);
sf::Vector2f lineCenter = lineStart + 0.5f * (lineEnd - lineStart);
Vector2f lineCenter = lineStart + 0.5f * (lineEnd - lineStart);
for (const auto& it : mDrawables.at(Sprite::Category::CATEGORY_WORLD)) {
if (!it->collisionEnabled(Sprite::CATEGORY_ACTOR))
continue;
sf::Vector2f axis = it->getPosition() - lineCenter;
if (axis == sf::Vector2f())
Vector2f axis = it->getPosition() - lineCenter;
if (axis == Vector2f())
return false;
axis = thor::unitVector(axis);
sf::Vector2f halfsize = it->getSize() / 2.0f;
Vector2f halfsize = it->getSize() / 2.0f;
float rectPosProjected = thor::dotProduct(axis, it->getPosition());
float lineStartProjected = thor::dotProduct(axis, lineStart);
float lineEndProjected = thor::dotProduct(axis, lineEnd);
@ -180,7 +180,7 @@ World::raycast(const sf::Vector2f& lineStart,
float rectHalfWidthProjected = std::max(
abs(thor::dotProduct(axis, halfsize)),
abs(thor::dotProduct(axis,
sf::Vector2f(halfsize.x, -halfsize.y))));
Vector2f(halfsize.x, -halfsize.y))));
Interval line = Interval::IntervalFromPoints(lineStartProjected,
lineEndProjected);
Interval rect = Interval::IntervalFromRadius(rectPosProjected,
@ -196,7 +196,7 @@ World::raycast(const sf::Vector2f& lineStart,
* Returns the item closest to position after linear search.
*/
std::shared_ptr<Item>
World::getNearestItem(const sf::Vector2f& position) const {
World::getNearestItem(const Vector2f& position) const {
std::shared_ptr<Item> closest;
float distance = std::numeric_limits<float>::max();
for (const auto& v : mDrawables) {

View file

@ -28,10 +28,10 @@ public:
void step(int elapsed);
void think(int elapsed);
std::vector<std::shared_ptr<Character> >
getCharacters(const sf::Vector2f& position, float maxDistance) const;
bool raycast(const sf::Vector2f& lineStart,
const sf::Vector2f& lineEnd) const;
std::shared_ptr<Item> getNearestItem(const sf::Vector2f& position) const;
getCharacters(const Vector2f& position, float maxDistance) const;
bool raycast(const Vector2f& lineStart,
const Vector2f& lineEnd) const;
std::shared_ptr<Item> getNearestItem(const Vector2f& position) const;
private:

View file

@ -23,7 +23,7 @@ const float Character::ITEM_PICKUP_MAX_DISTANCE_SQUARED = 2500.0f;
/**
* Saves pointer to this instance in static var for think().
*/
Character::Character(const sf::Vector2f& position, Category category,
Character::Character(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config, World& world,
Pathfinder& pathfinder) :
Circle(position, category, mask, config),
@ -133,7 +133,7 @@ Character::releaseTrigger() {
* @return True if a path was found.
*/
bool
Character::setDestination(const sf::Vector2f& destination) {
Character::setDestination(const Vector2f& destination) {
mPath = mPathfinder.getPath(getPosition(), destination, getRadius());
return !mPath.empty();
}
@ -152,7 +152,7 @@ Character::move() {
if (thor::length(mPath.back() - getPosition()) < POINT_REACHED_DISTANCE) {
mPath.pop_back();
if (mPath.empty())
setSpeed(sf::Vector2f(), 0);
setSpeed(Vector2f(), 0);
}
}
@ -168,7 +168,7 @@ Character::isMoving() const {
* Tests if a target is visible from the current position.
*/
bool
Character::isVisible(const sf::Vector2f& target) const {
Character::isVisible(const Vector2f& target) const {
return mWorld.raycast(getPosition(), target);
}
@ -284,7 +284,6 @@ Character::pickUpItem() {
mRightGadget = mLeftGadget;
mLeftGadget = gadget;
}
// TODO: implement (or just make invisible?)
mWorld.remove(item);
}
else {

View file

@ -31,7 +31,7 @@ public:
static const float VISION_DISTANCE;
public:
explicit Character(const sf::Vector2f& position, Category category,
explicit Character(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config, World& world,
Pathfinder& pathfinder);
virtual ~Character() = 0;
@ -45,9 +45,9 @@ protected:
float getMovementSpeed() const;
void pullTrigger();
void releaseTrigger();
bool setDestination(const sf::Vector2f& destination);
bool setDestination(const Vector2f& destination);
bool isMoving() const;
bool isVisible(const sf::Vector2f& target) const;
bool isVisible(const Vector2f& target) const;
std::vector<std::shared_ptr<Character> > getCharacters() const;
int getMagazineAmmo() const;
int getTotalAmmo() const;
@ -90,8 +90,8 @@ private:
std::shared_ptr<Weapon> mActiveWeapon;
std::shared_ptr<Gadget> mLeftGadget;
std::shared_ptr<Gadget> mRightGadget;
std::vector<sf::Vector2f> mPath; //< Contains nodes to reach a set destination.
sf::Vector2f mLastPosition;
std::vector<Vector2f> mPath; //< Contains nodes to reach a set destination.
Vector2f mLastPosition;
Faction mFaction;
};

View file

@ -10,10 +10,10 @@
#include "Rectangle.h"
#include "../util/Yaml.h"
Circle::Circle(const sf::Vector2f& position, Category category,
Circle::Circle(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config,
const sf::Vector2f& direction) :
Sprite(position, category, mask, config.get("size", sf::Vector2f()),
const Vector2f& direction) :
Sprite(position, category, mask, config.get("size", Vector2f()),
config.get("texture", std::string()), direction) {
}
@ -23,7 +23,7 @@ Circle::Circle(const sf::Vector2f& position, Category category,
*/
bool
Circle::testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
Rectangle* rect = dynamic_cast<Rectangle*>(other.get());
Circle* circle = dynamic_cast<Circle*>(other.get());
if (circle != nullptr)

View file

@ -18,13 +18,13 @@ class Yaml;
*/
class Circle : public CollisionModel, public Sprite {
public:
explicit Circle(const sf::Vector2f& position, Category category,
explicit Circle(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config,
const sf::Vector2f& direction = sf::Vector2f(0, 0));
const Vector2f& direction = Vector2f(0, 0));
virtual ~Circle() = default;
bool testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
float getRadius() const;
};

View file

@ -29,10 +29,10 @@ CollisionModel::~CollisionModel() {
*/
bool
CollisionModel::testCollision(const Circle& circle, const Rectangle& rect,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
sf::Vector2f halfSize = rect.getSize() / 2.0f;
sf::Vector2f rectNewPos = rect.getPosition() + offsetSecond;
sf::Vector2f circleRotatedPos = circle.getPosition() + offsetFirst - rectNewPos;
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
Vector2f halfSize = rect.getSize() / 2.0f;
Vector2f rectNewPos = rect.getPosition() + offsetSecond;
Vector2f circleRotatedPos = circle.getPosition() + offsetFirst - rectNewPos;
circleRotatedPos = thor::rotatedVector(circleRotatedPos, -rect.mShape.getRotation());
circleRotatedPos += rectNewPos;
@ -44,7 +44,7 @@ CollisionModel::testCollision(const Circle& circle, const Rectangle& rect,
.getOverlap(Interval::IntervalFromRadius(rectNewPos.y, halfSize.y))
.getLength();
offsetFirst += ((circleRotatedPos.y > rectNewPos.y) ? 1.0f : - 1.0f) *
thor::rotatedVector(sf::Vector2f(0, overlapY), rect.mShape.getRotation());
thor::rotatedVector(Vector2f(0, overlapY), rect.mShape.getRotation());
return overlapY > 0;
}
// Same here (just switched x/y).
@ -55,14 +55,14 @@ CollisionModel::testCollision(const Circle& circle, const Rectangle& rect,
.getOverlap(Interval::IntervalFromRadius(rectNewPos.x, halfSize.x))
.getLength();
offsetFirst += ((circleRotatedPos.x > rectNewPos.x) ? 1.0f : - 1.0f) *
thor::rotatedVector(sf::Vector2f(overlapX, 0), rect.mShape.getRotation());
thor::rotatedVector(Vector2f(overlapX, 0), rect.mShape.getRotation());
return overlapX > 0;
}
// Test if the circle is colliding with a corner of the rectangle, using
// the same method as circle-circle collision (distance to corner instead
// of radius.
else {
sf::Vector2f axis(thor::unitVector(rectNewPos - circleRotatedPos));
Vector2f axis(thor::unitVector(rectNewPos - circleRotatedPos));
// Use correct vector for corner projections (positive/negative
// direction does not matter).
@ -72,7 +72,7 @@ CollisionModel::testCollision(const Circle& circle, const Rectangle& rect,
rectHalfSizeProjected = thor::dotProduct(axis, halfSize);
else
rectHalfSizeProjected = thor::dotProduct(axis,
sf::Vector2f(halfSize.x, -halfSize.y));
Vector2f(halfSize.x, -halfSize.y));
Interval projectedCircle = Interval::IntervalFromRadius(
thor::dotProduct(axis, circleRotatedPos),
@ -100,8 +100,8 @@ CollisionModel::testCollision(const Circle& circle, const Rectangle& rect,
*/
bool
CollisionModel::testCollision(const Circle& first, const Circle& second,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
sf::Vector2f axis(thor::unitVector(second.getPosition() + offsetFirst -
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
Vector2f axis(thor::unitVector(second.getPosition() + offsetFirst -
(first.getPosition() + offsetSecond)));
Interval projectedFirst = Interval::IntervalFromRadius(
thor::dotProduct(axis, first.getPosition() + offsetFirst),
@ -125,6 +125,6 @@ CollisionModel::testCollision(const Circle& first, const Circle& second,
*/
bool
CollisionModel::testCollision(const Rectangle& first, const Rectangle& second,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
return false;
}

View file

@ -11,7 +11,7 @@
class Circle;
class Rectangle;
#include <SFML/System.hpp>
#include "../util/Vector.h"
/**
* Abstract class providing helper functions to test for collisions between shapes.
@ -24,11 +24,11 @@ public:
protected:
static bool testCollision(const Circle& circle, const Rectangle& rect,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
static bool testCollision(const Circle& first, const Circle& second,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
static bool testCollision(const Rectangle& first, const Rectangle& second,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
};
#endif /* DG_COLLISIONMODEL_H_ */

View file

@ -10,10 +10,10 @@
#include "Circle.h"
#include "../util/Yaml.h"
Rectangle::Rectangle(const sf::Vector2f& position, Category category,
Rectangle::Rectangle(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config,
const sf::Vector2f& direction) :
Sprite(position, category, mask, config.get("size", sf::Vector2f()),
const Vector2f& direction) :
Sprite(position, category, mask, config.get("size", Vector2f()),
config.get("texture", std::string()), direction) {
}
@ -23,7 +23,7 @@ Rectangle::Rectangle(const sf::Vector2f& position, Category category,
*/
bool
Rectangle::testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
Rectangle* rect = dynamic_cast<Rectangle*>(other.get());
Circle* circle = dynamic_cast<Circle*>(other.get());
if (circle != nullptr)

View file

@ -18,13 +18,13 @@ class Yaml;
*/
class Rectangle : public CollisionModel, public Sprite {
public:
explicit Rectangle(const sf::Vector2f& position, Category category,
explicit Rectangle(const Vector2f& position, Category category,
unsigned short mask, const Yaml& config,
const sf::Vector2f& direction = sf::Vector2f(0, 0));
const Vector2f& direction = sf::Vector2f(0, 0));
virtual ~Rectangle() = default;
bool testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
};
#endif /* DG_RECTANGLE_H_ */

View file

@ -13,14 +13,14 @@
#include "../util/Log.h"
#include "../util/ResourceManager.h"
Sprite::Sprite(const sf::Vector2f& position, Category category,
unsigned short mask, const sf::Vector2f& size,
const std::string& texture, const sf::Vector2f& direction) :
Sprite::Sprite(const Vector2f& position, Category category,
unsigned short mask, const Vector2f& size,
const std::string& texture, const Vector2f& direction) :
mCategory(category),
mMask(mask) {
mShape.setSize(size);
mShape.setOrigin(size / 2.0f);
mShape.setTextureRect(sf::IntRect(sf::Vector2i(), sf::Vector2i(size)));
mShape.setTextureRect(sf::IntRect(Vector2i(), Vector2i(size)));
setPosition(position);
setDirection(direction);
try {
@ -37,7 +37,7 @@ Sprite::Sprite(const sf::Vector2f& position, Category category,
/**
* Returns the position of the sprite (center).
*/
sf::Vector2f
Vector2f
Sprite::getPosition() const {
return mShape.getPosition();
}
@ -45,7 +45,7 @@ Sprite::getPosition() const {
/**
* Returns the movement speed of the sprite.
*/
sf::Vector2f
Vector2f
Sprite::getSpeed() const {
return mSpeed;
}
@ -53,9 +53,9 @@ Sprite::getSpeed() const {
/**
* Returns the angle of the sprite.
*/
sf::Vector2f
Vector2f
Sprite::getDirection() const {
return thor::rotatedVector(sf::Vector2f(0, - 1), mShape.getRotation());
return thor::rotatedVector(Vector2f(0, - 1), mShape.getRotation());
}
/**
@ -78,10 +78,10 @@ Sprite::getCategory() const {
* Returns the size of the sprite as a vector (bottom left to top right),
* does not consider rotation.
*/
sf::Vector2f
Vector2f
Sprite::getSize() const {
sf::FloatRect bounds = mShape.getLocalBounds();
return sf::Vector2f(bounds.width, bounds.height);
return Vector2f(bounds.width, bounds.height);
}
void
@ -127,8 +127,8 @@ Sprite::setDelete(bool value) {
* @param speed Movement speed in pixels per second.
*/
void
Sprite::setSpeed(sf::Vector2f direction, float speed) {
if (direction != sf::Vector2f())
Sprite::setSpeed(Vector2f direction, float speed) {
if (direction != Vector2f())
thor::setLength(direction, speed);
mSpeed = direction;
}
@ -138,8 +138,8 @@ Sprite::setSpeed(sf::Vector2f direction, float speed) {
* but is otherwise meaningless.
*/
void
Sprite::setDirection(const sf::Vector2f& direction) {
if (direction != sf::Vector2f())
Sprite::setDirection(const Vector2f& direction) {
if (direction != Vector2f())
mShape.setRotation(thor::polarAngle(direction) + 90);
}
@ -147,6 +147,6 @@ Sprite::setDirection(const sf::Vector2f& direction) {
* Sets the position of thr Sprite.
*/
void
Sprite::setPosition(const sf::Vector2f& position) {
Sprite::setPosition(const Vector2f& position) {
mShape.setPosition(position);
}

View file

@ -12,6 +12,8 @@
#include <SFML/Graphics.hpp>
#include "../util/Vector.h"
/**
* An sprite that is rendered in the world.
*/
@ -38,30 +40,30 @@ public:
// Public functions.
public:
explicit Sprite(const sf::Vector2f& position, Category category,
unsigned short mask, const sf::Vector2f& size,
const std::string& texture, const sf::Vector2f& direction);
explicit Sprite(const Vector2f& position, Category category,
unsigned short mask, const Vector2f& size,
const std::string& texture, const Vector2f& direction);
virtual ~Sprite() = default;
sf::Vector2f getPosition() const;
sf::Vector2f getSpeed() const;
sf::Vector2f getDirection() const;
Vector2f getPosition() const;
Vector2f getSpeed() const;
Vector2f getDirection() const;
bool getDelete() const;
Category getCategory() const;
sf::Vector2f getSize() const;
Vector2f getSize() const;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
bool collisionEnabled(Category category) const;
bool isInside(const sf::FloatRect& rect) const;
virtual bool testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) = 0;
Vector2f& offsetFirst, const Vector2f& offsetSecond) = 0;
virtual void onCollide(std::shared_ptr<Sprite> other);
protected:
void setDelete(bool value);
void setSpeed(sf::Vector2f direction, float speed);
void setDirection(const sf::Vector2f& direction);
void setPosition(const sf::Vector2f& position);
void setSpeed(Vector2f direction, float speed);
void setDirection(const Vector2f& direction);
void setPosition(const Vector2f& position);
private:
friend class CollisionModel;
@ -69,7 +71,7 @@ private:
sf::RectangleShape mShape;
std::shared_ptr<sf::Texture> mTexture;
sf::Vector2f mSpeed;
Vector2f mSpeed;
Category mCategory;
unsigned short mMask;
bool mDelete = false;

View file

@ -20,8 +20,8 @@
* @param world Box2d world.
* @param texture Texture to display for bullet.
*/
Bullet::Bullet(const sf::Vector2f& position, Character& shooter,
sf::Vector2f direction, const Yaml& config, float speed,
Bullet::Bullet(const Vector2f& position, Character& shooter,
Vector2f direction, const Yaml& config, float speed,
float damage, float maxRange) :
Circle(position, CATEGORY_PARTICLE, ~CATEGORY_PARTICLE,
config, thor::rotatedVector(direction, -90.0f)),

View file

@ -18,8 +18,8 @@ class Yaml;
*/
class Bullet : public Circle {
public:
explicit Bullet(const sf::Vector2f& position, Character& shooter,
sf::Vector2f direction, const Yaml& config, float speed,
explicit Bullet(const Vector2f& position, Character& shooter,
Vector2f direction, const Yaml& config, float speed,
float damage, float maxRange);
void onCollide(std::shared_ptr<Sprite> other);
@ -29,7 +29,7 @@ private:
const int mDamage;
const float mSpeed;
const float mMaxRangeSquared;
sf::Vector2f mStartPoint;
Vector2f mStartPoint;
};
#endif /* DG_BULLET_H_ */

View file

@ -37,27 +37,24 @@ Generator::Generator(World& world, Pathfinder& pathfinder) :
* GENERATE_AREA_SIZE and GENERATE_AREA_RANGE).
*/
void
Generator::generateCurrentAreaIfNeeded(const sf::Vector2f& playerPosition) {
auto compare = [](const sf::Vector2i& a, const sf::Vector2i& b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
};
std::map<sf::Vector2i, float, decltype(compare)> open(compare);
std::set<sf::Vector2i, decltype(compare)> closed(compare);
Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition) {
std::map<Vector2i, float> open;
std::set<Vector2i> closed;
sf::Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x),
Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x),
(int) floor(playerPosition.y / Tile::TILE_SIZE.y));
start /= GENERATE_AREA_SIZE;
auto makePair = [&start](const sf::Vector2i& point) {
return std::make_pair(point, thor::length(sf::Vector2f(point - start)));
auto makePair = [&start](const Vector2i& point) {
return std::make_pair(point, thor::length(Vector2f(point - start)));
};
open.insert(makePair(start));
while (!open.empty()) {
auto intComp = [](const std::pair<sf::Vector2i, float>& left,
const std::pair<sf::Vector2i, float>& right) {
auto intComp = [](const std::pair<Vector2i, float>& left,
const std::pair<Vector2i, float>& right) {
return left.second < right.second;
};
sf::Vector2i current =
Vector2i current =
std::min_element(open.begin(), open.end(), intComp)->first;
float distance = open[current];
open.erase(current);
@ -65,8 +62,8 @@ Generator::generateCurrentAreaIfNeeded(const sf::Vector2f& playerPosition) {
if (!mGenerated[current.x][current.y] && distance <= GENERATE_AREA_RANGE) {
mGenerated[current.x][current.y] = true;
sf::IntRect area(current * GENERATE_AREA_SIZE -
sf::Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE) / 2,
sf::Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE));
Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE) / 2,
Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE));
generateTiles(area);
for (const auto& enemyPosition : getEnemySpawns(area)) {
float distance = thor::length(enemyPosition - playerPosition);
@ -76,14 +73,14 @@ Generator::generateCurrentAreaIfNeeded(const sf::Vector2f& playerPosition) {
}
}
if (mGenerated[current.x][current.y] && distance <= GENERATE_AREA_RANGE) {
if (closed.find(sf::Vector2i(current.x + 1, current.y)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x + 1, current.y)));
if (closed.find(sf::Vector2i(current.x, current.y + 1)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x, current.y + 1)));
if (closed.find(sf::Vector2i(current.x - 1, current.y)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x - 1, current.y)));
if (closed.find(sf::Vector2i(current.x, current.y - 1)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x, current.y - 1)));
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
open.insert(makePair(Vector2i(current.x + 1, current.y)));
if (closed.find(Vector2i(current.x, current.y + 1)) == closed.end())
open.insert(makePair(Vector2i(current.x, current.y + 1)));
if (closed.find(Vector2i(current.x - 1, current.y)) == closed.end())
open.insert(makePair(Vector2i(current.x - 1, current.y)));
if (closed.find(Vector2i(current.x, current.y - 1)) == closed.end())
open.insert(makePair(Vector2i(current.x, current.y - 1)));
}
}
}
@ -94,16 +91,16 @@ Generator::generateCurrentAreaIfNeeded(const sf::Vector2f& playerPosition) {
*
* FIXME: Some nodes are selected more than once.
*/
std::vector<sf::Vector2i>
Generator::createMinimalSpanningTree(const sf::Vector2i& start,
std::vector<Vector2i>
Generator::createMinimalSpanningTree(const Vector2i& start,
const float limit) {
std::vector<sf::Vector2i> open;
std::vector<sf::Vector2i> selected;
std::vector<Vector2i> open;
std::vector<Vector2i> selected;
open.push_back(start);
float totalWeight = 0.0f;
while (totalWeight < limit) {
sf::Vector2i current;
Vector2i current;
float minValue = std::numeric_limits<float>::max();
for (auto& o : open) {
if (mTileNoise.getNoise(o.x, o.y) + 1.0f < minValue) {
@ -115,15 +112,15 @@ Generator::createMinimalSpanningTree(const sf::Vector2i& start,
selected.push_back(current);
totalWeight += minValue;
auto insertOnlyNew = [&open, &selected](const sf::Vector2i& v) {
auto insertOnlyNew = [&open, &selected](const Vector2i& v) {
if (std::find(open.begin(), open.end(), v) == open.end()
&& std::find(selected.begin(), selected.end(), v) == selected.end())
open.push_back(v);
};
insertOnlyNew(sf::Vector2i(current.x + 1, current.y));
insertOnlyNew(sf::Vector2i(current.x, current.y + 1));
insertOnlyNew(sf::Vector2i(current.x - 1, current.y));
insertOnlyNew(sf::Vector2i(current.x, current.y - 1));
insertOnlyNew(Vector2i(current.x + 1, current.y));
insertOnlyNew(Vector2i(current.x, current.y + 1));
insertOnlyNew(Vector2i(current.x - 1, current.y));
insertOnlyNew(Vector2i(current.x, current.y - 1));
}
return selected;
}
@ -144,19 +141,19 @@ Generator::generateTiles(const sf::IntRect& area) {
assert(area.width && !(area.width & (area.width - 1)));
assert(area.height && !(area.height & (area.height - 1)));
sf::Vector2i start;
Vector2i start;
float minValue = std::numeric_limits<float>::max();
// Find lowest value for tree start.
for (int x = area.left; x < area.left + area.width; x++)
for (int y = area.top; y < area.top + area.height; y++) {
if (mTileNoise.getNoise(x, y) + 1.0f < minValue) {
start = sf::Vector2i(x, y);
start = Vector2i(x, y);
minValue = mTileNoise.getNoise(x, y) + 1.0f;
}
}
std::vector<sf::Vector2i> selected = createMinimalSpanningTree(start, 12.0f);
std::vector<Vector2i> selected = createMinimalSpanningTree(start, 12.0f);
// For rooms, take minimum bounding box of spanning tree.
@ -191,22 +188,22 @@ Generator::generateTiles(const sf::IntRect& area) {
*
* @param area Area for which enemy spawns should be returned.
*/
std::vector<sf::Vector2f>
std::vector<Vector2f>
Generator::getEnemySpawns(const sf::IntRect& area) {
auto compare = [](const sf::Vector2f& a, const sf::Vector2f& b) {
auto compare = [](const Vector2f& a, const Vector2f& b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
};
std::set<sf::Vector2f, decltype(compare)> ret(compare);
std::set<Vector2f, decltype(compare)> ret(compare);
for (int x = area.left; x < area.left + area.width; x++) {
for (int y = area.top; y < area.top + area.height; y++) {
if (mCharacterNoise.getNoise(x, y) < -0.85f) {
sf::Vector2i tilePosition = findClosestFloor(sf::Vector2i(x, y));
ret.insert(sf::Vector2f(tilePosition.x * Tile::TILE_SIZE.x,
Vector2i tilePosition = findClosestFloor(Vector2i(x, y));
ret.insert(Vector2f(tilePosition.x * Tile::TILE_SIZE.x,
tilePosition.y * Tile::TILE_SIZE.y));
}
}
}
return std::vector<sf::Vector2f>(ret.begin(), ret.end());
return std::vector<Vector2f>(ret.begin(), ret.end());
}
/**
@ -245,10 +242,10 @@ Generator::generateAreas(const sf::IntRect& area) {
/**
* Returns a valid position (floor) for the player to spawn at.
*/
sf::Vector2f
Vector2f
Generator::getPlayerSpawn() const {
sf::Vector2i spawn = findClosestFloor(sf::Vector2i(0, 0));
return sf::Vector2f(spawn.x * Tile::TILE_SIZE.x,
Vector2i spawn = findClosestFloor(Vector2i(0, 0));
return Vector2f(spawn.x * Tile::TILE_SIZE.x,
spawn.y * Tile::TILE_SIZE.y);
}
@ -258,25 +255,22 @@ Generator::getPlayerSpawn() const {
* @warn Will fail if no floor tile has been generated yet.
* @position Point to start search for a floor tile from.
*/
sf::Vector2i
Generator::findClosestFloor(const sf::Vector2i& position) const {
auto compare = [](const sf::Vector2i& a, const sf::Vector2i& b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
};
std::map<sf::Vector2i, float, decltype(compare)> open(compare);
std::set<sf::Vector2i, decltype(compare)> closed(compare);
sf::Vector2i start = position;
auto makePair = [&start](const sf::Vector2i& point) {
return std::make_pair(point, thor::length(sf::Vector2f(point - start)));
Vector2i
Generator::findClosestFloor(const Vector2i& position) const {
std::map<Vector2i, float> open;
std::set<Vector2i> closed;
Vector2i start = position;
auto makePair = [&start](const Vector2i& point) {
return std::make_pair(point, thor::length(Vector2f(point - start)));
};
open.insert(makePair(start));
while (!open.empty()) {
auto intComp = [](const std::pair<sf::Vector2i, float>& left,
const std::pair<sf::Vector2i, float>& right) {
auto intComp = [](const std::pair<Vector2i, float>& left,
const std::pair<Vector2i, float>& right) {
return left.second < right.second;
};
sf::Vector2i current = std::min_element(open.begin(), open.end(), intComp)->first;
Vector2i current = std::min_element(open.begin(), open.end(), intComp)->first;
open.erase(current);
closed.insert(current);
if (mTiles.count(current.x) != 0 &&
@ -285,17 +279,17 @@ Generator::findClosestFloor(const sf::Vector2i& position) const {
return current;
}
else {
if (closed.find(sf::Vector2i(current.x + 1, current.y)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x + 1, current.y)));
if (closed.find(sf::Vector2i(current.x, current.y + 1)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x, current.y + 1)));
if (closed.find(sf::Vector2i(current.x - 1, current.y)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x - 1, current.y)));
if (closed.find(sf::Vector2i(current.x, current.y - 1)) == closed.end())
open.insert(makePair(sf::Vector2i(current.x, current.y - 1)));
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
open.insert(makePair(Vector2i(current.x + 1, current.y)));
if (closed.find(Vector2i(current.x, current.y + 1)) == closed.end())
open.insert(makePair(Vector2i(current.x, current.y + 1)));
if (closed.find(Vector2i(current.x - 1, current.y)) == closed.end())
open.insert(makePair(Vector2i(current.x - 1, current.y)));
if (closed.find(Vector2i(current.x, current.y - 1)) == closed.end())
open.insert(makePair(Vector2i(current.x, current.y - 1)));
}
}
// No floor tile found in the entire world.
assert(false);
return sf::Vector2i();
return Vector2i();
}

View file

@ -12,6 +12,7 @@
#include "../sprites/Tile.h"
#include "SimplexNoise.h"
#include "../util/Vector.h"
class World;
class Pathfinder;
@ -22,9 +23,9 @@ class Pathfinder;
class Generator {
public:
explicit Generator(World& world, Pathfinder& pathfinder);
void generateCurrentAreaIfNeeded(const sf::Vector2f& position);
sf::Vector2f getPlayerSpawn() const;
std::vector<sf::Vector2f> getEnemySpawns(const sf::IntRect& area);
void generateCurrentAreaIfNeeded(const Vector2f& position);
Vector2f getPlayerSpawn() const;
std::vector<Vector2f> getEnemySpawns(const sf::IntRect& area);
private:
typedef std::map<int, std::map<int, Tile::Type> > array;
@ -32,9 +33,9 @@ private:
private:
void generateAreas(const sf::IntRect& area);
void generateTiles(const sf::IntRect& area);
sf::Vector2i findClosestFloor(const sf::Vector2i& position) const;
std::vector<sf::Vector2i> createMinimalSpanningTree(
const sf::Vector2i& start, const float limit);
Vector2i findClosestFloor(const Vector2i& position) const;
std::vector<Vector2i> createMinimalSpanningTree(
const Vector2i& start, const float limit);
private:
static const int GENERATE_AREA_SIZE;

View file

@ -9,18 +9,18 @@
#include "../World.h"
Item::Item(const sf::Vector2f& size, const std::string& texture) :
Sprite(sf::Vector2f(), CATEGORY_NONSOLID, MASK_NONE, size, texture,
sf::Vector2f()) {
Item::Item(const Vector2f& size, const std::string& texture) :
Sprite(Vector2f(), CATEGORY_NONSOLID, MASK_NONE, size, texture,
Vector2f()) {
}
void
Item::drop(const sf::Vector2f& position) {
Item::drop(const Vector2f& position) {
setPosition(position);
}
bool
Item::testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond) {
Vector2f& offsetFirst, const Vector2f& offsetSecond) {
return false;
}

View file

@ -14,12 +14,12 @@ class World;
class Item : public Sprite {
public:
Item(const sf::Vector2f& size, const std::string& texture);
Item(const Vector2f& size, const std::string& texture);
virtual ~Item() {};
void drop(const sf::Vector2f& position);
void drop(const Vector2f& position);
bool testCollision(std::shared_ptr<Sprite> other,
sf::Vector2f& offsetFirst, const sf::Vector2f& offsetSecond);
Vector2f& offsetFirst, const Vector2f& offsetSecond);
};
#endif /* DG_ITEM_H_ */

View file

@ -20,7 +20,7 @@ Shield::onUse(Character& character) {
mCharacter = &character;
if (mRotatingShield)
mRotatingShield->setDelete(true);
sf::Vector2f offset = mCharacter->getDirection() * mCharacter->getRadius();
Vector2f offset = mCharacter->getDirection() * mCharacter->getRadius();
mRotatingShield = std::shared_ptr<RotatingShield>(
new RotatingShield(mCharacter->getPosition() + offset));
mCharacter->mWorld.insert(mRotatingShield);

View file

@ -14,7 +14,7 @@
#include "../util/Yaml.h"
Weapon::Weapon(World& world, Character& holder, const Yaml& config) :
Item(sf::Vector2f(80, 30), "weapon.png"),
Item(Vector2f(80, 30), "weapon.png"),
mWorld(world),
mHolder(&holder),
mName(config.get("name", std::string())),
@ -154,15 +154,15 @@ Weapon::setHolder(Character& holder) {
*/
void
Weapon::insertProjectile(float angle) {
sf::Vector2f offset(mHolder->getDirection() * mHolder->getRadius());
Vector2f offset(mHolder->getDirection() * mHolder->getRadius());
float spread = (mHolder->getSpeed() == sf::Vector2f())
float spread = (mHolder->getSpeed() == Vector2f())
? mSpread
: mSpreadMoving;
std::uniform_real_distribution<float> distribution(- spread, spread);
angle += distribution(mGenerator) + 90.0f;
sf::Vector2f direction(thor::rotatedVector(mHolder->getDirection(), angle));
Vector2f direction(thor::rotatedVector(mHolder->getDirection(), angle));
std::shared_ptr<Sprite> projectile(new Bullet(mHolder->getPosition() + offset,
*mHolder, direction, mProjectile, mProjectileSpeed,

View file

@ -9,7 +9,7 @@
#include "../util/Yaml.h"
Corpse::Corpse(const sf::Vector2f& position) :
Corpse::Corpse(const Vector2f& position) :
Circle(position, CATEGORY_NONSOLID, MASK_NONE, Yaml("corpse.yaml")) {
}

View file

@ -12,7 +12,7 @@
class Corpse : public Circle {
public:
explicit Corpse(const sf::Vector2f& position);
explicit Corpse(const Vector2f& position);
};
#endif /* DG_CORPSE_H_ */

View file

@ -12,7 +12,7 @@
#include "../util/Yaml.h"
Enemy::Enemy(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position) :
const Vector2f& position) :
Character(position, CATEGORY_ACTOR, MASK_ALL, Yaml("enemy.yaml"), world,
pathfinder) {
}
@ -41,6 +41,6 @@ Enemy::onThink(int elapsed) {
}
else {
releaseTrigger();
setSpeed(sf::Vector2f(), 0);
setSpeed(Vector2f(), 0);
}
}

View file

@ -15,7 +15,7 @@ class World;
class Enemy : public Character {
public:
explicit Enemy(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position);
const Vector2f& position);
private:
virtual void onThink(int elapsed) override;

View file

@ -15,7 +15,7 @@
* Initializes Sprite.
*/
Player::Player(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position) :
const Vector2f& position) :
Character(position, CATEGORY_ACTOR, MASK_ALL, Yaml("player.yaml"), world,
pathfinder),
mDirection(0) {
@ -27,7 +27,7 @@ Player::Player(World& world, Pathfinder& pathfinder,
* @param Absolute world coordinates of the crosshair.
*/
void
Player::setCrosshairPosition(const sf::Vector2f& position) {
Player::setCrosshairPosition(const Vector2f& position) {
mCrosshairPosition = position - getPosition();
}
@ -46,7 +46,7 @@ Player::setDirection(Direction direction, bool unset) {
mDirection = mDirection | direction;
// Convert directions into a vector.
sf::Vector2f dirVec(0, 0);
Vector2f dirVec(0, 0);
if (mDirection & Direction::RIGHT)
dirVec.x += 1.0f;
if (mDirection & Direction::LEFT)
@ -59,7 +59,7 @@ Player::setDirection(Direction direction, bool unset) {
}
void
Player::setDestination(const sf::Vector2f& destination) {
Player::setDestination(const Vector2f& destination) {
mDirection = 0;
Character::setDestination(destination);
}

View file

@ -29,13 +29,13 @@ public:
public:
explicit Player(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position);
const Vector2f& position);
void setCrosshairPosition(const sf::Vector2f& position);
void setCrosshairPosition(const Vector2f& position);
using Character::pullTrigger;
using Character::releaseTrigger;
void setDirection(Direction direction, bool unset);
void setDestination(const sf::Vector2f& destination);
void setDestination(const Vector2f& destination);
using Character::getMagazineAmmo;
using Character::getTotalAmmo;
using Character::getWeaponName;
@ -56,7 +56,7 @@ private:
void onThink(int elapsed) override;
private:
sf::Vector2f mCrosshairPosition; //< Relative position of the point to fire at (mouse cursor).
Vector2f mCrosshairPosition; //< Relative position of the point to fire at (mouse cursor).
unsigned char mDirection; //< Current movement direction for direct control.
};

View file

@ -9,7 +9,7 @@
#include "../util/Yaml.h"
RotatingShield::RotatingShield(const sf::Vector2f& position) :
RotatingShield::RotatingShield(const Vector2f& position) :
Rectangle(position, CATEGORY_WORLD, MASK_ALL,
Yaml("rotating_shield.yaml")) {
}

View file

@ -12,7 +12,7 @@
class RotatingShield : public Rectangle {
public:
explicit RotatingShield(const sf::Vector2f& position);
explicit RotatingShield(const Vector2f& position);
private:
using Sprite::setDelete;

View file

@ -14,7 +14,7 @@
#include "../util/Yaml.h"
#include "../World.h"
const sf::Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75);
const Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75);
/**
* Constructs a tile.
@ -24,7 +24,7 @@ const sf::Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75);
* @param world Box2D world object.
*/
Tile::Tile(Type type, int x, int y) :
Rectangle(sf::Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.y),
Rectangle(Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.y),
CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0,
Yaml(getConfig(type))),
mType(type) {

View file

@ -26,7 +26,7 @@ public:
Type getType() const;
public:
static const sf::Vector2i TILE_SIZE; //< Tile size in pixels.
static const Vector2i TILE_SIZE; //< Tile size in pixels.
public:
static std::string getConfig(Type type);

44
source/util/Vector.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Vector.h
*
* Created on: 07.08.2013
* Author: Felix
*/
#ifndef DG_VECTOR_H_
#define DG_VECTOR_H_
#include <SFML/System.hpp>
/**
* Vector class with comparison operator. All other operators are inherited
* from sf::Vector2.
*/
template <typename T>
class Vector2 : public sf::Vector2<T> {
public:
Vector2() : sf::Vector2<T>() {};
Vector2(T x, T y) : sf::Vector2<T>(x, y) {};
/**
* Implicitly catches and converts any vectors that have been converted to
* sf::Vector2 (as done by arithmethic operations defined by sf::Vector2).
*/
template <typename U>
Vector2(const sf::Vector2<U>& vector) : sf::Vector2<T>(vector) {};
};
/**
* Comparison operator meant for containers like std::set.
*
* Provides a clearly defined, but otherwise meaningless sorting of vectors.
*/
template <typename T>
bool operator <(const Vector2<T>& left, const Vector2<T>& right) {
return left.x < right.x || (left.x == right.x && left.y < right.y);
}
typedef Vector2<int> Vector2i;
typedef Vector2<float> Vector2f;
#endif /* DG_VECTOR_H_ */

View file

@ -13,9 +13,8 @@
#include <yaml-cpp/yaml.h>
#include <SFML/System.hpp>
#include "Log.h"
#include "Vector.h"
/**
* Interface to a YAML file.
@ -45,12 +44,12 @@ private:
* Error handling is done in Yaml::get.
*/
namespace {
void operator>>(const YAML::Node& node, sf::Vector2i& vector) {
void operator>>(const YAML::Node& node, Vector2i& vector) {
node[0] >> vector.x;
node[1] >> vector.y;
}
void operator>>(const YAML::Node& node, sf::Vector2f& vector) {
void operator>>(const YAML::Node& node, Vector2f& vector) {
node[0] >> vector.x;
node[1] >> vector.y;
}