Initial commit after git corruption, old repo deleted.
This commit is contained in:
commit
125cd747fa
31 changed files with 1813 additions and 0 deletions
219
source/Game.cpp
Normal file
219
source/Game.cpp
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
* Game.cpp
|
||||||
|
*
|
||||||
|
* Created on: 05.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
#include "abstract/Actor.h"
|
||||||
|
#include "sprite/Cover.h"
|
||||||
|
#include "util/Loader.h"
|
||||||
|
#include "util/ResourceManager.h"
|
||||||
|
#include "util/String.h"
|
||||||
|
#include "util/Log.h"
|
||||||
|
|
||||||
|
/// Goal amount of frames per second.
|
||||||
|
const int Game::FPS_GOAL = 60;
|
||||||
|
|
||||||
|
/// Milliseconds per tick at FPS_GOAL.
|
||||||
|
const float Game::TICKS_GOAL = 1000 / Game::FPS_GOAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes game, including window and objects (sprites).
|
||||||
|
*/
|
||||||
|
Game::Game(const Vector2i& resolution) :
|
||||||
|
mWorld(b2Vec2(0, 0)),
|
||||||
|
mWindow(sf::VideoMode(resolution.x, resolution.y, 32), "Roguelike Shooter",
|
||||||
|
sf::Style::Close | sf::Style::Titlebar),
|
||||||
|
mView(Vector2f(0, 0), Vector2f(resolution)),
|
||||||
|
//mFps("test"),
|
||||||
|
mTileManager(mWorld),
|
||||||
|
mPlayer(mWorld, mCollection),
|
||||||
|
mElapsed(0),
|
||||||
|
mQuit(false),
|
||||||
|
mPaused(false) {
|
||||||
|
mWindow.setFramerateLimit(FPS_GOAL);
|
||||||
|
mWindow.setKeyRepeatEnabled(true);
|
||||||
|
for (int i = 0; i < 500; i += 50) {
|
||||||
|
mCollection.insert(std::shared_ptr<Sprite>(new Cover(Vector2f(i, i), Vector2i(20, 20),
|
||||||
|
mWorld)), Collection::LEVEL_STATIC);
|
||||||
|
}
|
||||||
|
mTileManager.generate();
|
||||||
|
mWorld.SetContactListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes window.
|
||||||
|
*/
|
||||||
|
Game::~Game() {
|
||||||
|
mWindow.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the game loop.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::loop() {
|
||||||
|
sf::Uint32 left = 0;
|
||||||
|
while (!mQuit) {
|
||||||
|
|
||||||
|
input();
|
||||||
|
|
||||||
|
for (; !mPaused && (left >= TICKS_GOAL); left -= TICKS_GOAL) {
|
||||||
|
Actor::think(TICKS_GOAL);
|
||||||
|
mWorld.Step(1.0f / FPS_GOAL, 8, 3);
|
||||||
|
|
||||||
|
mCollection.checkDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
//mFps.setString(getFps());
|
||||||
|
|
||||||
|
tick();
|
||||||
|
left += mElapsed;
|
||||||
|
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves ticks since last call.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::tick() {
|
||||||
|
mElapsed = mClock.restart().asMilliseconds();
|
||||||
|
if (mPaused) {
|
||||||
|
mElapsed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles general game input.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::input() {
|
||||||
|
sf::Event event;
|
||||||
|
while (mWindow.pollEvent(event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case sf::Event::Closed:
|
||||||
|
mQuit = true;
|
||||||
|
break;
|
||||||
|
case sf::Event::KeyPressed:
|
||||||
|
keyDown(event);
|
||||||
|
break;
|
||||||
|
case sf::Event::KeyReleased:
|
||||||
|
keyUp(event);
|
||||||
|
break;
|
||||||
|
case sf::Event::MouseButtonReleased:
|
||||||
|
mouseUp(event);
|
||||||
|
break;
|
||||||
|
case sf::Event::MouseMoved:
|
||||||
|
mPlayer.setCrosshairPosition(convertCoordinates(event.mouseMove.x, event.mouseMove.y));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles key up event. This is used for events that only fire once per keypress.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::keyUp(const sf::Event& event) {
|
||||||
|
switch (event.key.code) {
|
||||||
|
case sf::Keyboard::Escape:
|
||||||
|
mQuit = true;
|
||||||
|
break;
|
||||||
|
case sf::Keyboard::Space:
|
||||||
|
mPaused = !mPaused;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles key down event. This is used for any events that refire automatically.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::keyDown(const sf::Event& event) {
|
||||||
|
switch (event.key.code) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a screen coordinate to a world coordinate.
|
||||||
|
*/
|
||||||
|
sf::Vector2<float>
|
||||||
|
Game::convertCoordinates(int x, int y) {
|
||||||
|
return mWindow.convertCoords(Vector2i(x, y), mView);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles mouse key up events.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::mouseUp(const sf::Event& event) {
|
||||||
|
switch (event.mouseButton.button) {
|
||||||
|
case sf::Mouse::Left:
|
||||||
|
mPlayer.fire();
|
||||||
|
break;
|
||||||
|
case sf::Mouse::Right:
|
||||||
|
mPlayer.move(convertCoordinates(event.mouseButton.x, event.mouseButton.y));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders world and GUI.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::render() {
|
||||||
|
mWindow.clear();
|
||||||
|
|
||||||
|
mView.setCenter(mPlayer.getPosition());
|
||||||
|
|
||||||
|
// Render world and dynamic stuff.
|
||||||
|
mWindow.setView(mView);
|
||||||
|
|
||||||
|
mWindow.draw(mTileManager);
|
||||||
|
mWindow.draw(mCollection);
|
||||||
|
mWindow.draw(mPlayer);
|
||||||
|
|
||||||
|
// Render GUI and static stuff.
|
||||||
|
mWindow.setView(mWindow.getDefaultView());
|
||||||
|
|
||||||
|
//mWindow.draw(mFps);
|
||||||
|
|
||||||
|
mWindow.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current FPS as string.
|
||||||
|
*/
|
||||||
|
sf::String
|
||||||
|
Game::getFps() {
|
||||||
|
return str((mElapsed != 0) ? 1000.0f / mElapsed : 0.0f, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin of collision, call callback function on both objects.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::BeginContact(b2Contact* contact) {
|
||||||
|
Physical& first = *static_cast<Physical*>(contact->GetFixtureA()->GetBody()->GetUserData());
|
||||||
|
Physical& second = *static_cast<Physical*>(contact->GetFixtureB()->GetBody()->GetUserData());
|
||||||
|
|
||||||
|
if (!first.doesCollide(second) || !second.doesCollide(first)) {
|
||||||
|
contact->SetEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
first.onCollide(second, second.getCategory());
|
||||||
|
second.onCollide(first, first.getCategory());
|
||||||
|
}
|
71
source/Game.h
Normal file
71
source/Game.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Game.h
|
||||||
|
*
|
||||||
|
* Created on: 05.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_GAME_H_
|
||||||
|
#define DG_GAME_H_
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <Thor/Resources.hpp>
|
||||||
|
|
||||||
|
#include <Box2D/Box2D.h>
|
||||||
|
|
||||||
|
#include "TileManager.h"
|
||||||
|
#include "sprite/Player.h"
|
||||||
|
#include "util/Collection.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use vertex for tiles.
|
||||||
|
*/
|
||||||
|
class Game : private sf::NonCopyable, public b2ContactListener {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Game(const Vector2i& resolution);
|
||||||
|
~Game();
|
||||||
|
|
||||||
|
void loop();
|
||||||
|
void BeginContact(b2Contact* contact);
|
||||||
|
|
||||||
|
// Private functions.
|
||||||
|
private:
|
||||||
|
void input();
|
||||||
|
void render();
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
void keyDown(const sf::Event& event);
|
||||||
|
void keyUp(const sf::Event& event);
|
||||||
|
void mouseUp(const sf::Event& event);
|
||||||
|
|
||||||
|
sf::String getFps();
|
||||||
|
sf::Vector2<float> convertCoordinates(int x, int y);
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
static const int FPS_GOAL;
|
||||||
|
static const float TICKS_GOAL;
|
||||||
|
|
||||||
|
b2World mWorld;
|
||||||
|
|
||||||
|
sf::RenderWindow mWindow;
|
||||||
|
sf::Clock mClock;
|
||||||
|
sf::View mView;
|
||||||
|
//sf::Text mFps;
|
||||||
|
|
||||||
|
Collection mCollection;
|
||||||
|
TileManager mTileManager;
|
||||||
|
Player mPlayer;
|
||||||
|
|
||||||
|
/// Milliseconds since the last tick.
|
||||||
|
sf::Uint32 mElapsed;
|
||||||
|
|
||||||
|
bool mQuit;
|
||||||
|
bool mPaused;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DG_GAME_H_ */
|
116
source/TileManager.cpp
Executable file
116
source/TileManager.cpp
Executable file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* TileManager.cpp
|
||||||
|
*
|
||||||
|
* Created on: 08.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TileManager.h"
|
||||||
|
|
||||||
|
#include <Thor/Resources.hpp>
|
||||||
|
|
||||||
|
#include "util/Loader.h"
|
||||||
|
#include "util/ResourceManager.h"
|
||||||
|
#include "abstract/Sprite.h"
|
||||||
|
|
||||||
|
const Vector2i TileManager::TILE_SIZE = Vector2i(100, 100);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads tile resources.
|
||||||
|
*
|
||||||
|
* @param world Box2D world to create (physical) tiles in.
|
||||||
|
*/
|
||||||
|
TileManager::TileManager(b2World& world) :
|
||||||
|
mWorld(world) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a tile.
|
||||||
|
*
|
||||||
|
* @param pType Type of the tile to create.
|
||||||
|
* @param pPosition Position of the tile in tile coordinates.
|
||||||
|
* @param world Box2D world object.
|
||||||
|
*/
|
||||||
|
TileManager::Tile::Tile(Type type, const TilePosition& position, b2World& world) :
|
||||||
|
Sprite(getTexture(type), PhysicalData(Vector2f(position.x * TILE_SIZE.x, position.y * TILE_SIZE.y),
|
||||||
|
TILE_SIZE, world, CATEGORY_WORLD, (type == TYPE_FLOOR) ? MASK_NONE : MASK_ALL, false)),
|
||||||
|
mType(type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a texture key for a certain tile type.
|
||||||
|
*
|
||||||
|
* @param type The type of tile to load a resource key for.
|
||||||
|
* @return Resource key to the correct texture.
|
||||||
|
*/
|
||||||
|
std::shared_ptr<sf::Texture>
|
||||||
|
TileManager::Tile::getTexture(Type type) {
|
||||||
|
sf::String filename;
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_FLOOR:
|
||||||
|
filename = "floor.png";
|
||||||
|
break;
|
||||||
|
case TYPE_WALL:
|
||||||
|
filename = "wall.png";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new aurora::Exception("Invalid tile type.");
|
||||||
|
}
|
||||||
|
return ResourceManager::i().acquire(Loader::i().fromFile<sf::Texture>(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Type of this tile.
|
||||||
|
*/
|
||||||
|
TileManager::Type
|
||||||
|
TileManager::Tile::getType() const {
|
||||||
|
return mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the tile with tile width/height as a unit.
|
||||||
|
*/
|
||||||
|
TileManager::TilePosition
|
||||||
|
TileManager::Tile::getTilePosition() const {
|
||||||
|
return TilePosition(getPosition().x / TILE_SIZE.x, getPosition().y / TILE_SIZE.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the world with predefined tiles.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TileManager::generate() {
|
||||||
|
for (int x = 0; x < 10; x++)
|
||||||
|
for (int y = 0; y < 10; y++)
|
||||||
|
setTile(TilePosition(x, y), TYPE_WALL);
|
||||||
|
|
||||||
|
for (int x = 1; x < 9; x++)
|
||||||
|
for (int y = 1; y < 9; y++)
|
||||||
|
setTile(TilePosition(x, y), TYPE_FLOOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a tile at the position. Deletes an existing tile first if one is at the position.
|
||||||
|
*
|
||||||
|
* @param position Grid coordinate of the tile (not pixel coordinate).
|
||||||
|
* @param type Type of tile to be inserted.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TileManager::setTile(const TilePosition& position, Type type) {
|
||||||
|
for (auto it = mTiles.begin(); it != mTiles.end(); it++) {
|
||||||
|
if ((*it)->getTilePosition() == position) {
|
||||||
|
mTiles.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mTiles.push_back(std::unique_ptr<Tile>(new Tile(type, position, mWorld)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \copydoc sf::Drawable::draw
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TileManager::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||||
|
for (auto it = mTiles.begin(); it != mTiles.end(); it++) {
|
||||||
|
target.draw((**it), states);
|
||||||
|
}
|
||||||
|
}
|
79
source/TileManager.h
Executable file
79
source/TileManager.h
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* TileManager.h
|
||||||
|
*
|
||||||
|
* Created on: 08.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_TILEMANAGER_H_
|
||||||
|
#define DG_TILEMANAGER_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <Box2D/Box2D.h>
|
||||||
|
|
||||||
|
#include "util/Vector.h"
|
||||||
|
#include "abstract/Sprite.h"
|
||||||
|
|
||||||
|
class TileManager : public sf::Drawable {
|
||||||
|
// Public constants.
|
||||||
|
public:
|
||||||
|
/// The size of a single tile (pixels).
|
||||||
|
static const Vector2i TILE_SIZE;
|
||||||
|
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
TileManager(b2World& world);
|
||||||
|
|
||||||
|
void generate();
|
||||||
|
|
||||||
|
// Private types.
|
||||||
|
private:
|
||||||
|
enum Type {
|
||||||
|
TYPE_FLOOR,
|
||||||
|
TYPE_WALL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses the length/width of a tile as a unit.
|
||||||
|
*/
|
||||||
|
typedef Vector2i TilePosition;
|
||||||
|
|
||||||
|
class Tile;
|
||||||
|
|
||||||
|
// Private functions.
|
||||||
|
private:
|
||||||
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
void setTile(const TilePosition& position, Type type);
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
b2World& mWorld;
|
||||||
|
std::vector<std::unique_ptr<Tile> > mTiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds information about a single tile.
|
||||||
|
*/
|
||||||
|
class TileManager::Tile : public Sprite {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Tile(Type type, const TilePosition& position, b2World& world);
|
||||||
|
|
||||||
|
Type getType() const;
|
||||||
|
TilePosition getTilePosition() const;
|
||||||
|
|
||||||
|
static std::shared_ptr<sf::Texture> getTexture(Type type);
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
Type mType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DG_TILEMANAGER_H_ */
|
41
source/abstract/Actor.cpp
Executable file
41
source/abstract/Actor.cpp
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Actor.cpp
|
||||||
|
*
|
||||||
|
* Created on: 02.09.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Actor.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
std::vector<Actor*> Actor::mInstances = std::vector<Actor*>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves pointer to this instance in static var for think().
|
||||||
|
*/
|
||||||
|
Actor::Actor() {
|
||||||
|
mInstances.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes pointer from think() static var.
|
||||||
|
*/
|
||||||
|
Actor::~Actor() {
|
||||||
|
auto it = std::find(mInstances.begin(), mInstances.end(), this);
|
||||||
|
assert(it != mInstances.end());
|
||||||
|
mInstances.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls onThink on all Actor instances.
|
||||||
|
*
|
||||||
|
* @param elapsedTime Amount of time to simulate.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Actor::think(float elapsedTime) {
|
||||||
|
for (auto i : mInstances) {
|
||||||
|
i->onThink(elapsedTime);
|
||||||
|
}
|
||||||
|
}
|
38
source/abstract/Actor.h
Executable file
38
source/abstract/Actor.h
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Actor.h
|
||||||
|
*
|
||||||
|
* Created on: 02.09.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_ACTOR_H_
|
||||||
|
#define DG_ACTOR_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides think function for AI.
|
||||||
|
*/
|
||||||
|
class Actor {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Actor();
|
||||||
|
virtual ~Actor() = 0;
|
||||||
|
|
||||||
|
static void think(float elapsedTime);
|
||||||
|
|
||||||
|
// Protected functions.
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Implement this function for any (regular) AI computations.
|
||||||
|
*
|
||||||
|
* @param elapsedTime Amount of time to simulate.
|
||||||
|
*/
|
||||||
|
virtual void onThink(float elapsedTime) = 0;
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
static std::vector<Actor*> mInstances;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_ACTOR_H_ */
|
166
source/abstract/Physical.cpp
Executable file
166
source/abstract/Physical.cpp
Executable file
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* Physical.cpp
|
||||||
|
*
|
||||||
|
* Created on: 11.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Physical.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <Thor/Vectors.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes Box2D body.
|
||||||
|
*
|
||||||
|
* @param data Data needed for construction.
|
||||||
|
*/
|
||||||
|
Physical::Physical(const PhysicalData& data) :
|
||||||
|
mDelete(false) {
|
||||||
|
assert(data.size != Vector2i());
|
||||||
|
assert(data.category);
|
||||||
|
|
||||||
|
b2BodyDef bodyDef;
|
||||||
|
// not moving -> static body
|
||||||
|
// moving -> dynamic body
|
||||||
|
// bullet -> kinematic body
|
||||||
|
bodyDef.type = (data.moving) ?
|
||||||
|
(data.bullet)
|
||||||
|
? b2_dynamicBody
|
||||||
|
: b2_dynamicBody
|
||||||
|
: b2_staticBody;
|
||||||
|
bodyDef.position = vector(data.position);
|
||||||
|
bodyDef.allowSleep = true;
|
||||||
|
bodyDef.fixedRotation = true;
|
||||||
|
bodyDef.bullet = data.bullet;
|
||||||
|
bodyDef.userData = this;
|
||||||
|
|
||||||
|
mBody = data.world.CreateBody(&bodyDef);
|
||||||
|
|
||||||
|
b2PolygonShape boxShape;
|
||||||
|
boxShape.SetAsBox(pixelToMeter(data.size.x) / 2, pixelToMeter(data.size.y) / 2);
|
||||||
|
|
||||||
|
b2FixtureDef fixtureDef;
|
||||||
|
fixtureDef.shape = &boxShape;
|
||||||
|
fixtureDef.density = 1.0f;
|
||||||
|
fixtureDef.filter.categoryBits = data.category;
|
||||||
|
fixtureDef.filter.maskBits = ~data.maskExclude;
|
||||||
|
fixtureDef.restitution = 0;
|
||||||
|
|
||||||
|
mBody->CreateFixture(&fixtureDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes body from world.
|
||||||
|
*/
|
||||||
|
Physical::~Physical() {
|
||||||
|
mBody->GetWorld()->DestroyBody(mBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes container.
|
||||||
|
*
|
||||||
|
* @link Physical::PhysicalData
|
||||||
|
*/
|
||||||
|
Physical::PhysicalData::PhysicalData( const Vector2f& position, const Vector2i& size,
|
||||||
|
b2World& world, uint16 category, uint16 maskExclude, bool moving, bool bullet) :
|
||||||
|
position(position),
|
||||||
|
size(size),
|
||||||
|
world(world),
|
||||||
|
category(category),
|
||||||
|
maskExclude(maskExclude),
|
||||||
|
moving(moving),
|
||||||
|
bullet(bullet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the sprite (center).
|
||||||
|
*/
|
||||||
|
Vector2f
|
||||||
|
Physical::getPosition() const {
|
||||||
|
return vector(mBody->GetPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the movement speed of the body.
|
||||||
|
*/
|
||||||
|
Vector2f
|
||||||
|
Physical::getSpeed() const {
|
||||||
|
return vector(mBody->GetLinearVelocity());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the rotation of the body (converted to an SFML angle).
|
||||||
|
*/
|
||||||
|
float
|
||||||
|
Physical::getAngle() const {
|
||||||
|
return - thor::toDegree(mBody->GetAngle());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this object should be deleted.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Physical::getDelete() const {
|
||||||
|
return mDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16
|
||||||
|
Physical::getCategory() const {
|
||||||
|
return mBody->GetFixtureList()->GetFilterData().categoryBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method filters collisions with other physicals. Implement it if you want to
|
||||||
|
* limit collisions to/with certain objects. Default implementation always returns true.
|
||||||
|
*
|
||||||
|
* @param other The Physical this object is about to collide with.
|
||||||
|
* @return True if the objects should collide.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Physical::doesCollide(Physical& other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a collision with another body occured. Override this method
|
||||||
|
* to manage collision events.
|
||||||
|
*
|
||||||
|
* @param other Reference to the other Physical in the collision.
|
||||||
|
* @param category The Category of the other object (as passed in constructor).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Physical::onCollide(Physical& other, uint16 type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true to mark this object for deletion from the world.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Physical::setDelete(bool value) {
|
||||||
|
mDelete = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets movement speed and direction of the body. Set either value to zero to stop movement.
|
||||||
|
*
|
||||||
|
* @param direction The direction the body moves in, does not have to be normalized.
|
||||||
|
* @param speed The value of the movement speed to be used.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Physical::setSpeed(Vector2f direction, float speed) {
|
||||||
|
if (direction != Vector2f()) {
|
||||||
|
direction = thor::unitVector<float>(direction);
|
||||||
|
}
|
||||||
|
direction *= speed;
|
||||||
|
mBody->SetLinearVelocity(vector(direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the angle of the body based on the direction of a vector.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Physical::setAngle(float angle) {
|
||||||
|
mBody->SetTransform(mBody->GetPosition(), - thor::toRadian(angle));
|
||||||
|
}
|
90
source/abstract/Physical.h
Executable file
90
source/abstract/Physical.h
Executable file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Physical.h
|
||||||
|
*
|
||||||
|
* Created on: 11.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_PHYSICAL_H_
|
||||||
|
#define DG_PHYSICAL_H_
|
||||||
|
|
||||||
|
#include <Box2D/Box2D.h>
|
||||||
|
|
||||||
|
#include "../util/Vector.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object with physical properties.
|
||||||
|
*
|
||||||
|
* @warning May only handle bodies with one fixture.
|
||||||
|
*/
|
||||||
|
class Physical {
|
||||||
|
// Public types.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* POD container that carries all data required to construct this class.
|
||||||
|
*/
|
||||||
|
class PhysicalData {
|
||||||
|
public:
|
||||||
|
PhysicalData() = default;
|
||||||
|
PhysicalData(const Vector2f& position, const Vector2i& size, b2World& world,
|
||||||
|
uint16 category, uint16 maskExclude, bool moving, bool bullet = false);
|
||||||
|
const Vector2f& position; //< World position of the body in pixel coordinates.
|
||||||
|
const Vector2i& size; //< Pixel size of the body.
|
||||||
|
b2World& world; //< Box2D world object.
|
||||||
|
uint16 category; //< The category for collision filtering. Only one may be set. @link Physical::Category
|
||||||
|
uint16 maskExclude; //< All categories set here will have collisions disabled with this object.
|
||||||
|
bool moving; //< True if the body may move on its own (player, monster).
|
||||||
|
bool bullet; //< True if the object is a bullet.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Categories of physical objects, for Box2D collision filtering.
|
||||||
|
*
|
||||||
|
* @warning An object may only have one category.
|
||||||
|
*/
|
||||||
|
enum Category {
|
||||||
|
CATEGORY_NONSOLID = 0,
|
||||||
|
CATEGORY_WORLD = 1 << 1,
|
||||||
|
CATEGORY_ACTOR = 1 << 2,
|
||||||
|
CATEGORY_PARTICLE = 1 << 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common Box2D collision masking values.
|
||||||
|
*/
|
||||||
|
enum Mask {
|
||||||
|
MASK_NONE = 0xffff, //< Disables any collisions.
|
||||||
|
MASK_ALL = 0 //< Enables all collisions.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Physical(const PhysicalData& data);
|
||||||
|
virtual ~Physical() = 0;
|
||||||
|
|
||||||
|
Vector2f getPosition() const;
|
||||||
|
Vector2f getSpeed() const;
|
||||||
|
float getAngle() const;
|
||||||
|
bool getDelete() const;
|
||||||
|
uint16 getCategory() const;
|
||||||
|
|
||||||
|
virtual bool doesCollide(Physical& other);
|
||||||
|
virtual void onCollide(Physical& other, uint16 category);
|
||||||
|
|
||||||
|
// Protected functions.
|
||||||
|
protected:
|
||||||
|
void setDelete(bool value);
|
||||||
|
void setSpeed(Vector2f direction, float speed);
|
||||||
|
void setAngle(float angle);
|
||||||
|
|
||||||
|
// Protected variables.
|
||||||
|
protected:
|
||||||
|
// Currently protected to allow for (debug only) direct player input.
|
||||||
|
b2Body* mBody;
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
bool mDelete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_PHYSICAL_H_ */
|
58
source/abstract/Sprite.cpp
Normal file
58
source/abstract/Sprite.cpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Sprite.cpp
|
||||||
|
*
|
||||||
|
* Created on: 22.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Sprite.h"
|
||||||
|
|
||||||
|
#include "../util/Loader.h"
|
||||||
|
#include "../util/Log.h"
|
||||||
|
#include "../util/String.h"
|
||||||
|
#include "../util/ResourceManager.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads sprite from ResourceManager, sets world position.
|
||||||
|
*
|
||||||
|
* @param texturePath Relative path to the texture file in the resource folder.
|
||||||
|
*/
|
||||||
|
Sprite::Sprite(const sf::String& texturePath, const PhysicalData& data) :
|
||||||
|
Physical(data),
|
||||||
|
mTexture(ResourceManager::i().acquire(Loader::i().fromFile<sf::Texture>(texturePath))),
|
||||||
|
mSize(data.size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads sprite from ResourceManager, sets world position. Use this if the texture has already been loaded.
|
||||||
|
*
|
||||||
|
* @param texture Pointer to the texture to be used (must already be loaded).
|
||||||
|
*/
|
||||||
|
Sprite::Sprite(const std::shared_ptr<sf::Texture>& texture, const PhysicalData& data) :
|
||||||
|
Physical(data),
|
||||||
|
mTexture(texture),
|
||||||
|
mSize(data.size) {
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Does nothing.
|
||||||
|
*/
|
||||||
|
Sprite::~Sprite() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \copydoc sf::Drawable::draw
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Sprite::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||||
|
// Create a temporary shape to apply box2d body transformations to.
|
||||||
|
sf::RectangleShape shape = sf::RectangleShape(Vector2f(mSize));
|
||||||
|
shape.setTexture(&*mTexture, true);
|
||||||
|
shape.setOrigin(Vector2f(mSize.x / 2, mSize.y / 2));
|
||||||
|
shape.setTextureRect(sf::IntRect(Vector2i(0, 0), mSize));
|
||||||
|
|
||||||
|
shape.setPosition(getPosition());
|
||||||
|
shape.setRotation(getAngle());
|
||||||
|
|
||||||
|
target.draw(shape, states);
|
||||||
|
}
|
36
source/abstract/Sprite.h
Normal file
36
source/abstract/Sprite.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Sprite.h
|
||||||
|
*
|
||||||
|
* Created on: 22.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_SPRITE_H_
|
||||||
|
#define DG_SPRITE_H_
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <Thor/Resources.hpp>
|
||||||
|
|
||||||
|
#include "Physical.h"
|
||||||
|
#include "../util/Vector.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a drawable object.
|
||||||
|
*
|
||||||
|
* Handles drawing to world.
|
||||||
|
*/
|
||||||
|
class Sprite : public sf::Drawable, public Physical {
|
||||||
|
public:
|
||||||
|
Sprite(const sf::String& texturePath, const PhysicalData& data);
|
||||||
|
Sprite(const std::shared_ptr<sf::Texture>& texture, const PhysicalData& data);
|
||||||
|
virtual ~Sprite() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
|
||||||
|
std::shared_ptr<sf::Texture> mTexture;
|
||||||
|
Vector2i mSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_SPRITE_H_ */
|
45
source/effects/Bullet.cpp
Executable file
45
source/effects/Bullet.cpp
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Bullet.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Bullet.h"
|
||||||
|
|
||||||
|
#include "../util/Log.h"
|
||||||
|
|
||||||
|
const float Bullet::SPEED = 500.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places a bullet in the world.
|
||||||
|
*
|
||||||
|
* @param position World position of the bullet.
|
||||||
|
* @param world Box2d world.
|
||||||
|
* @param texture Texture to display for bullet.
|
||||||
|
*/
|
||||||
|
Bullet::Bullet(const Vector2f& position, b2World& world,
|
||||||
|
const std::shared_ptr<sf::Texture>& texture, Physical& shooter, float direction) :
|
||||||
|
Particle(texture, PhysicalData(position, Vector2i(20, 20), world, CATEGORY_PARTICLE,
|
||||||
|
CATEGORY_PARTICLE, true, true)),
|
||||||
|
mShooter(shooter) {
|
||||||
|
setSpeed(angle(direction), SPEED);
|
||||||
|
setAngle(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copydoc Physical::onCollide
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Bullet::onCollide(Physical& other, uint16 type) {
|
||||||
|
// Make sure we do not damage twice.
|
||||||
|
if (!getDelete()) {
|
||||||
|
// Call onShot on other, with damage as param.
|
||||||
|
setDelete(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Bullet::doesCollide(Physical& other) {
|
||||||
|
return &other != &mShooter;
|
||||||
|
}
|
31
source/effects/Bullet.h
Executable file
31
source/effects/Bullet.h
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Bullet.h
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_BULLET_H_
|
||||||
|
#define DG_BULLET_H_
|
||||||
|
|
||||||
|
#include "../particle/Particle.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bullet particle fired by a weapon, may damage actors.
|
||||||
|
*/
|
||||||
|
class Bullet : public Particle {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Bullet(const Vector2f& position, b2World& world, const std::shared_ptr<sf::Texture>& texture,
|
||||||
|
Physical& shooter, float direction);
|
||||||
|
|
||||||
|
void onCollide(Physical& other, uint16 category);
|
||||||
|
bool doesCollide(Physical& other);
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
static const float SPEED;
|
||||||
|
Physical& mShooter;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_BULLET_H_ */
|
38
source/items/Weapon.cpp
Executable file
38
source/items/Weapon.cpp
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Weapon.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Weapon.h"
|
||||||
|
|
||||||
|
#include "../util/Collection.h"
|
||||||
|
#include "../effects/Bullet.h"
|
||||||
|
#include "../util/Loader.h"
|
||||||
|
#include "../util/ResourceManager.h"
|
||||||
|
|
||||||
|
Weapon::Weapon(Physical& holder, Collection& collection, b2World& world) :
|
||||||
|
Emitter(collection),
|
||||||
|
mHolder(holder),
|
||||||
|
mBulletTexture(ResourceManager::i().acquire(Loader::i().fromFile<sf::Texture>("bullet.png"))),
|
||||||
|
mWorld(world) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Weapon::~Weapon() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call on any button press/refire.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Weapon::fire() {
|
||||||
|
// Only call if has ammo, consider firing rate etc.
|
||||||
|
emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Particle>
|
||||||
|
Weapon::createParticle() {
|
||||||
|
return std::shared_ptr<Particle>(new Bullet(mHolder.getPosition(), mWorld, mBulletTexture,
|
||||||
|
mHolder, mHolder.getAngle()));
|
||||||
|
}
|
37
source/items/Weapon.h
Executable file
37
source/items/Weapon.h
Executable file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Weapon.h
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_WEAPON_H_
|
||||||
|
#define DG_WEAPON_H_
|
||||||
|
|
||||||
|
#include <Thor/Particles.hpp>
|
||||||
|
|
||||||
|
#include "../abstract/Physical.h"
|
||||||
|
#include "../particle/Emitter.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading mechanism:
|
||||||
|
* - pass enum value and load mapped xml
|
||||||
|
* - pass xml filename
|
||||||
|
*/
|
||||||
|
class Weapon : public Emitter {
|
||||||
|
public:
|
||||||
|
Weapon(Physical& holder, Collection& collection, b2World& world);
|
||||||
|
~Weapon();
|
||||||
|
|
||||||
|
void fire();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<Particle> createParticle();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Physical& mHolder;
|
||||||
|
std::shared_ptr<sf::Texture> mBulletTexture;
|
||||||
|
b2World& mWorld;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_WEAPON_H_ */
|
23
source/main.cpp
Normal file
23
source/main.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* main.cpp
|
||||||
|
*
|
||||||
|
* Created on: 19.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "util/Loader.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates Game object.
|
||||||
|
*/
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
Loader::i().setFolder("resources/");
|
||||||
|
Loader::i().setSubFolder<sf::Texture>("textures/");
|
||||||
|
|
||||||
|
Game game(Vector2i(800, 600));
|
||||||
|
|
||||||
|
game.loop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
23
source/particle/Emitter.cpp
Executable file
23
source/particle/Emitter.cpp
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Emitter.cpp
|
||||||
|
*
|
||||||
|
* Created on: 15.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Emitter.h"
|
||||||
|
|
||||||
|
Emitter::Emitter(Collection& collection) :
|
||||||
|
mCollection(collection) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Emitter::~Emitter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new particle into the system, using createParticle().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Emitter::emit() {
|
||||||
|
mCollection.insert(createParticle(), Collection::LEVEL_PARTICLE);
|
||||||
|
}
|
32
source/particle/Emitter.h
Executable file
32
source/particle/Emitter.h
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Emitter.h
|
||||||
|
*
|
||||||
|
* Created on: 15.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_EMITTER_H_
|
||||||
|
#define DG_EMITTER_H_
|
||||||
|
|
||||||
|
#include "../abstract/Physical.h"
|
||||||
|
#include "../util/Collection.h"
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
class Emitter {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Emitter(Collection& collection);
|
||||||
|
virtual ~Emitter();
|
||||||
|
|
||||||
|
// Protected functions.
|
||||||
|
protected:
|
||||||
|
void emit();
|
||||||
|
/// Creates a particle. Allows to use a user-defined particle class and custom settings.
|
||||||
|
virtual std::shared_ptr<Particle> createParticle() = 0;
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
Collection& mCollection;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_EMITTER_H_ */
|
16
source/particle/Particle.cpp
Executable file
16
source/particle/Particle.cpp
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Particle.cpp
|
||||||
|
*
|
||||||
|
* Created on: 15.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
Particle::Particle(const std::shared_ptr<sf::Texture>& texture, const PhysicalData& data) :
|
||||||
|
Sprite(texture, data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle::~Particle() {
|
||||||
|
}
|
||||||
|
|
22
source/particle/Particle.h
Executable file
22
source/particle/Particle.h
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Particle.h
|
||||||
|
*
|
||||||
|
* Created on: 15.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_PARTICLE_H_
|
||||||
|
#define DG_PARTICLE_H_
|
||||||
|
|
||||||
|
#include "../abstract/Sprite.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prototype for a particle.
|
||||||
|
*/
|
||||||
|
class Particle : public Sprite {
|
||||||
|
public:
|
||||||
|
Particle(const std::shared_ptr<sf::Texture>& texture, const PhysicalData& data);
|
||||||
|
virtual ~Particle();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_PARTICLE_H_ */
|
13
source/sprite/Cover.cpp
Executable file
13
source/sprite/Cover.cpp
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* Cover.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Cover.h"
|
||||||
|
|
||||||
|
Cover::Cover(const Vector2f& position, const Vector2i& size, b2World& world) :
|
||||||
|
Sprite("cover.png", PhysicalData(position, size, world, CATEGORY_WORLD, MASK_ALL, false)) {
|
||||||
|
}
|
||||||
|
|
21
source/sprite/Cover.h
Executable file
21
source/sprite/Cover.h
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Cover.h
|
||||||
|
*
|
||||||
|
* Created on: 12.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_COVER_H_
|
||||||
|
#define DG_COVER_H_
|
||||||
|
|
||||||
|
#include "../abstract/Sprite.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wall that can be placed anywhere (not limited by tiles) and have any (rectangular) size.
|
||||||
|
*/
|
||||||
|
class Cover : public Sprite {
|
||||||
|
public:
|
||||||
|
Cover(const Vector2f& position, const Vector2i& size, b2World& world);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_COVER_H_ */
|
74
source/sprite/Player.cpp
Normal file
74
source/sprite/Player.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Player.cpp
|
||||||
|
*
|
||||||
|
* Created on: 21.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
|
#include <Thor/Vectors.hpp>
|
||||||
|
|
||||||
|
#include "../util/Vector.h"
|
||||||
|
#include "../items/Weapon.h"
|
||||||
|
|
||||||
|
const float Player::SPEED = 100.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes Sprite.
|
||||||
|
*/
|
||||||
|
Player::Player(b2World& world, Collection& collection) :
|
||||||
|
Sprite("player.png", PhysicalData(Vector2f(200.0f, 100.0f), Vector2i(50, 50), world,
|
||||||
|
CATEGORY_ACTOR, MASK_ALL, true)),
|
||||||
|
mWeapon(*this, collection, world),
|
||||||
|
mDestination(Vector2i(50, 50)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the point where to look and shoot at.
|
||||||
|
*
|
||||||
|
* @param Absolute world coordinates of the crosshair.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Player::setCrosshairPosition(const Vector2f& position) {
|
||||||
|
mCrosshairPosition = position - getPosition();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Fire the attacked Weapon, emitting a Bullet object.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Player::fire() {
|
||||||
|
mWeapon.fire();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the player to a destination point.
|
||||||
|
*
|
||||||
|
* @param destination Absolute world coordinate of the destination point.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Player::move(const Vector2f& destination) {
|
||||||
|
mDestination = destination;
|
||||||
|
// Convert to relative destination.
|
||||||
|
setSpeed(mDestination - getPosition(), SPEED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Player::onThink(float elapsedTime) {
|
||||||
|
// Stop if we are close enough.
|
||||||
|
if (thor::length(mDestination - getPosition()) < 1.0f) {
|
||||||
|
setSpeed(Vector2f(), 0);
|
||||||
|
}
|
||||||
|
// Look towards crosshair.
|
||||||
|
setAngle(angle(mCrosshairPosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop movement if we collide with anything except bullets.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Player::onCollide(Physical& other, uint16 category) {
|
||||||
|
if (category != CATEGORY_PARTICLE) {
|
||||||
|
mDestination = getPosition();
|
||||||
|
}
|
||||||
|
}
|
46
source/sprite/Player.h
Normal file
46
source/sprite/Player.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Player.h
|
||||||
|
*
|
||||||
|
* Created on: 21.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_PLAYER_H_
|
||||||
|
#define DG_PLAYER_H_
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include "../abstract/Actor.h"
|
||||||
|
#include "../abstract/Sprite.h"
|
||||||
|
#include "../items/Weapon.h"
|
||||||
|
#include "../util/Vector.h"
|
||||||
|
|
||||||
|
class Sprite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player object.
|
||||||
|
*/
|
||||||
|
class Player : public Sprite, public Actor {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
Player(b2World& world, Collection& collection);
|
||||||
|
|
||||||
|
void setCrosshairPosition(const Vector2f& position);
|
||||||
|
void fire();
|
||||||
|
void move(const Vector2f& destination);
|
||||||
|
|
||||||
|
// Protected functions.
|
||||||
|
protected:
|
||||||
|
void onCollide(Physical& other, uint16 category);
|
||||||
|
void onThink(float elapsedTime);
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
static const float SPEED;
|
||||||
|
Weapon mWeapon; //< Weapon object used for Player::fire().
|
||||||
|
Vector2f mDestination; //< Absolute position of the movement destination.
|
||||||
|
Vector2f mCrosshairPosition; //< Relative position of the point to fire at (mouse cursor).
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_PLAYER_H_ */
|
65
source/util/Collection.cpp
Executable file
65
source/util/Collection.cpp
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Collection.cpp
|
||||||
|
*
|
||||||
|
* Created on: 29.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Collection.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a drawable into the group. Drawables should only be handled with shared_ptr.
|
||||||
|
* An object can't be inserted more than once at the same level.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Collection::insert(std::shared_ptr<Sprite> drawable, Level level) {
|
||||||
|
auto item = std::find(mDrawables[level].begin(), mDrawables[level].end(), drawable);
|
||||||
|
if (item == mDrawables[level].end()) {
|
||||||
|
mDrawables[level].push_back(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a drawable from the group.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Collection::remove(std::shared_ptr<Sprite> drawable) {
|
||||||
|
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
|
||||||
|
auto item = std::find(v->second.begin(), v->second.end(), drawable);
|
||||||
|
if (item != v->second.end()) {
|
||||||
|
v->second.erase(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes any sprites which return true for getDelete().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Collection::checkDelete() {
|
||||||
|
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
|
||||||
|
for (auto item = v->second.begin(); item != v->second.end(); ) {
|
||||||
|
if ((*item)->getDelete()) {
|
||||||
|
item = v->second.erase(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws all elements in the group.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Collection::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||||
|
for (auto v = mDrawables.begin(); v != mDrawables.end(); v++) {
|
||||||
|
for (auto item : v->second) {
|
||||||
|
target.draw(static_cast<sf::Drawable&>(*item), states);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
48
source/util/Collection.h
Executable file
48
source/util/Collection.h
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Collection.h
|
||||||
|
*
|
||||||
|
* Created on: 29.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_COLLECTION_H_
|
||||||
|
#define DG_COLLECTION_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include "../abstract/Sprite.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of sprites, which can be put into different layers.
|
||||||
|
*/
|
||||||
|
class Collection : public sf::Drawable {
|
||||||
|
// Public types.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Determines in what order sprites are rendered, dynamics and actors should be on top.
|
||||||
|
*/
|
||||||
|
enum Level {
|
||||||
|
LEVEL_STATIC,
|
||||||
|
LEVEL_PARTICLE,
|
||||||
|
LEVEL_ACTOR
|
||||||
|
};
|
||||||
|
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
void insert(std::shared_ptr<Sprite> drawable, Level level);
|
||||||
|
void remove(std::shared_ptr<Sprite> drawable);
|
||||||
|
void checkDelete();
|
||||||
|
|
||||||
|
// Private functions.
|
||||||
|
private:
|
||||||
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
std::map<Level, std::vector<std::shared_ptr<Sprite> > > mDrawables;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_COLLECTION_H_ */
|
137
source/util/Loader.h
Executable file
137
source/util/Loader.h
Executable file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Loader.h
|
||||||
|
*
|
||||||
|
* Created on: 13.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_LOADER_H_
|
||||||
|
#define DG_LOADER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
#include <Thor/Resources.hpp>
|
||||||
|
|
||||||
|
#include "Singleton.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows to set default resource folders and subfolders, which means that these
|
||||||
|
* folders only have to be set once, and not be included in the creation of every single
|
||||||
|
* resource key.
|
||||||
|
*
|
||||||
|
* If the general resource folder or a specific resource folder is not set, the current
|
||||||
|
* directory is searched.
|
||||||
|
*
|
||||||
|
* R is any resource that can be loaded with Thor's resource loader.
|
||||||
|
*
|
||||||
|
* Any folder/file parameter can be a full path and is relative to the current directory,
|
||||||
|
* or the directory set by the higher variables.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Loader l;
|
||||||
|
* l.setFolder("resources/");
|
||||||
|
* l.setSubFolder<sf::Texture>("textures/");
|
||||||
|
* thor::ResourceKey<sf::Texture> t = l.fromFile<sf::Texture>("myimage.png");
|
||||||
|
*
|
||||||
|
* ResourceManager r;
|
||||||
|
* r.acquire(t); // This loads from "resources/textures/myimage.png".
|
||||||
|
* // folder subfolder file
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
class Loader : public Singleton<Loader> {
|
||||||
|
// Public functions.
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets the general resource folder path.
|
||||||
|
*/
|
||||||
|
inline void setFolder(const std::string& folder) {mFolder = folder;};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the resource subfolder for the specific type.
|
||||||
|
*/
|
||||||
|
template <typename R> void
|
||||||
|
setSubFolder(std::string path) {
|
||||||
|
getLoader<R>()->setSubFolder(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a resource from a file, looking in the specific resource folder for this type.
|
||||||
|
*/
|
||||||
|
template <typename T> thor::ResourceKey<T>
|
||||||
|
fromFile(const std::string& file) {
|
||||||
|
return static_cast<SpecificLoader<T>* >(getLoader<T>().get())->fromFile(mFolder, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private types.
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* We need this to save templates of different types in the same container.
|
||||||
|
*/
|
||||||
|
class LoaderBase {
|
||||||
|
public:
|
||||||
|
virtual void setSubFolder(const std::string& path) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class forwards the loading of each individual type to Thor.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class SpecificLoader : public LoaderBase {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets the subfolder for the current type.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setSubFolder(const std::string& path) {
|
||||||
|
mSubfolder = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a resource from file via Thor.
|
||||||
|
*
|
||||||
|
* @param folder The general resource folder
|
||||||
|
* @param file Path/name of the file within the resource subfolder.
|
||||||
|
*/
|
||||||
|
thor::ResourceKey<T>
|
||||||
|
fromFile(const std::string& folder, const std::string& file) {
|
||||||
|
return thor::Resources::fromFile<T>(folder + mSubfolder + file);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mSubfolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Private functions.
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* For Singleton behaviour.
|
||||||
|
*/
|
||||||
|
Loader() = default;
|
||||||
|
friend class Singleton<Loader>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the correct loader for each template type, creates it if it does not exist.
|
||||||
|
*/
|
||||||
|
template <typename T> std::unique_ptr<LoaderBase>&
|
||||||
|
getLoader() {
|
||||||
|
auto loader = mLoaders.find(typeid(T));
|
||||||
|
if (loader != mLoaders.end()) {
|
||||||
|
return static_cast<std::unique_ptr<LoaderBase>&>(loader->second);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (*mLoaders.insert(std::pair<std::type_index, std::unique_ptr<LoaderBase> >
|
||||||
|
(typeid(T), std::unique_ptr<LoaderBase>(new SpecificLoader<T>))).first).second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Private variables.
|
||||||
|
private:
|
||||||
|
std::string mFolder;
|
||||||
|
std::map<std::type_index, std::unique_ptr<LoaderBase> > mLoaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_LOADER_H_ */
|
37
source/util/Log.h
Normal file
37
source/util/Log.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Log.h
|
||||||
|
*
|
||||||
|
* Created on: 25.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_LOG_H_
|
||||||
|
#define DG_LOG_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def LOG_E(str)
|
||||||
|
* Log an error to the error stream.
|
||||||
|
*/
|
||||||
|
#define LOG_E(str) std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " \"" << str << "\"" << std::endl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def LOG_E(str)
|
||||||
|
* Log a warning to the output stream.
|
||||||
|
*/
|
||||||
|
#define LOG_W(str) std::cout << "Warning: " << __FILE__ << ":" << __LINE__ << " \"" << str << "\"" << std::endl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def LOG_E(str)
|
||||||
|
* Log a debug message to the output stream.
|
||||||
|
*/
|
||||||
|
#define LOG_D(str) std::cout << "Debug: " << __FILE__ << ":" << __LINE__ << " \"" << str << "\"" << std::endl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def LOG_E(str)
|
||||||
|
* Log an info to the output stream.
|
||||||
|
*/
|
||||||
|
#define LOG_I(str) std::cout << "Info: " << __FILE__ << ":" << __LINE__ << " \"" << str << "\"" << std::endl
|
||||||
|
|
||||||
|
#endif /* DG_LOG_H_ */
|
26
source/util/ResourceManager.h
Normal file
26
source/util/ResourceManager.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* ResourceManager.h
|
||||||
|
*
|
||||||
|
* Created on: 22.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_RESOURCEMANAGER_H_
|
||||||
|
#define DG_RESOURCEMANAGER_H_
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <Thor/Resources.hpp>
|
||||||
|
|
||||||
|
#include "Singleton.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and manages all resources by providing Singleton access to Thor ResourceManager.
|
||||||
|
*/
|
||||||
|
class ResourceManager : public thor::MultiResourceCache, public Singleton<ResourceManager> {
|
||||||
|
private:
|
||||||
|
friend class Singleton<ResourceManager>;
|
||||||
|
ResourceManager() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_RESOURCEMANAGER_H_ */
|
31
source/util/Singleton.h
Normal file
31
source/util/Singleton.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Singleton.h
|
||||||
|
*
|
||||||
|
* Created on: 04.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_SINGLETON_H_
|
||||||
|
#define DG_SINGLETON_H_
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template class for inheriting singleton behaviour.
|
||||||
|
*
|
||||||
|
* To use, just make a subclass with only a private default constructor and Singleton<T>
|
||||||
|
* as friend class.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class Singleton : public sf::NonCopyable {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Get the instance of this class.
|
||||||
|
*/
|
||||||
|
static T& i() {
|
||||||
|
static T s;
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DG_SINGLETON_H_ */
|
50
source/util/String.h
Normal file
50
source/util/String.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* String.h
|
||||||
|
*
|
||||||
|
* Created on: 19.07.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this as a replacement for std::to_string as MingW does not support it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DG_STRING_H_
|
||||||
|
#define DG_STRING_H_
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts any value to a string.
|
||||||
|
*
|
||||||
|
* @param val Any variable.
|
||||||
|
* @return val converted to string.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
sf::String
|
||||||
|
str(T val) {
|
||||||
|
std::stringstream out;
|
||||||
|
out << val;
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts floating point variable to string,
|
||||||
|
*
|
||||||
|
* @param val Any floating point variable.
|
||||||
|
* @param digits Number of decimal places to round to.
|
||||||
|
* @return val converted to string.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
sf::String
|
||||||
|
str(T val, int digits) {
|
||||||
|
std::stringstream out;
|
||||||
|
out.precision(digits);
|
||||||
|
out << val;
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DG_STRING_H_ */
|
84
source/util/Vector.h
Executable file
84
source/util/Vector.h
Executable file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Vector.h
|
||||||
|
*
|
||||||
|
* Created on: 03.08.2012
|
||||||
|
* Author: Felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VECTOR_H_
|
||||||
|
#define VECTOR_H_
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
#include <Box2D/Box2D.h>
|
||||||
|
|
||||||
|
#include <Thor/Vectors.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D floating point vector with x/y members.
|
||||||
|
*/
|
||||||
|
typedef sf::Vector2f Vector2f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D integer vector with x/y members.
|
||||||
|
*/
|
||||||
|
typedef sf::Vector2i Vector2i;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant for conversion between Box2D vectors and SFML vectors.
|
||||||
|
*/
|
||||||
|
static const int PIXELS_PER_METER = 25;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a distance from pixels to meters.
|
||||||
|
*/
|
||||||
|
inline float
|
||||||
|
pixelToMeter(float in) {
|
||||||
|
return in / PIXELS_PER_METER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a distance from meters to pixels.
|
||||||
|
*/
|
||||||
|
inline float
|
||||||
|
meterToPixel(float in) {
|
||||||
|
return in * PIXELS_PER_METER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts Box2D metric vector to SFML pixel vector.
|
||||||
|
*/
|
||||||
|
inline Vector2f
|
||||||
|
vector(const b2Vec2& in) {
|
||||||
|
return Vector2f(meterToPixel(in.x), meterToPixel(in.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts SFML pixel vector to Box2D metric vector.
|
||||||
|
*/
|
||||||
|
inline b2Vec2
|
||||||
|
vector(const Vector2f& in) {
|
||||||
|
return b2Vec2(pixelToMeter(in.x), pixelToMeter(in.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a vector to an SFML angle with the same direction.
|
||||||
|
*/
|
||||||
|
inline float
|
||||||
|
angle(Vector2f in) {
|
||||||
|
return 180 - thor::toDegree(atan2(in.x, in.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an SFML angle to a unit vector with the same direction.
|
||||||
|
*/
|
||||||
|
inline Vector2f
|
||||||
|
angle(float in) {
|
||||||
|
in = thor::toRadian(180 - in);
|
||||||
|
return Vector2f(sin(in), cos(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VECTOR_H_ */
|
Reference in a new issue