mirror of
https://github.com/kuhyx/testsAndMisc-archive.git
synced 2026-07-04 15:03:04 +02:00
feat: add SFMLEngine
This commit is contained in:
parent
8333a455e2
commit
a3a61328aa
21
CPP/SFMLEngine/LICENSE
Normal file
21
CPP/SFMLEngine/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Krzysztof Rudnicki
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
BIN
CPP/SFMLEngine/helloWorld/app
Executable file
BIN
CPP/SFMLEngine/helloWorld/app
Executable file
Binary file not shown.
24
CPP/SFMLEngine/helloWorld/hello.cpp
Normal file
24
CPP/SFMLEngine/helloWorld/hello.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
|
||||
sf::CircleShape shape(100.f);
|
||||
shape.setFillColor(sf::Color::Green);
|
||||
|
||||
while (window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.clear();
|
||||
window.draw(shape);
|
||||
window.display();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
CPP/SFMLEngine/helloWorld/hello.o
Normal file
BIN
CPP/SFMLEngine/helloWorld/hello.o
Normal file
Binary file not shown.
6
CPP/SFMLEngine/helloWorld/makefile
Normal file
6
CPP/SFMLEngine/helloWorld/makefile
Normal file
@ -0,0 +1,6 @@
|
||||
compile:./hello.cpp
|
||||
g++ -c ./hello.cpp
|
||||
g++ hello.o -o app -lsfml-graphics -lsfml-window -lsfml-system
|
||||
|
||||
run:
|
||||
./app
|
||||
42
CPP/SFMLEngine/makingAGameTick/Classes/Other/resources.hpp
Normal file
42
CPP/SFMLEngine/makingAGameTick/Classes/Other/resources.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef RESOURCES_HPP
|
||||
#define RESOURCES_HPP
|
||||
|
||||
#include <assert.h>
|
||||
// Mostly Chapter 2
|
||||
// Handles resource management
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Textures // This gives us a scope for the enumerators which allows us to write Textures::Airplane instead of just Airplane to avoid name collisions in the global scope
|
||||
{
|
||||
enum ID
|
||||
{
|
||||
Eagle,
|
||||
Raptor,
|
||||
Desert
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Resource, typename Identifier>
|
||||
class ResourceHolder
|
||||
{
|
||||
public:
|
||||
void load(Identifier id, const std::string& filename);
|
||||
Resource& get(Identifier id);
|
||||
const Resource& get(Identifier id) const;
|
||||
template <typename Parameter>
|
||||
void load(Identifier id, const std::string& filename, const Parameter& secondParameter);
|
||||
// Second parameter can be of sf::Shader::Type or std::string&
|
||||
private:
|
||||
std::map< Identifier, std::unique_ptr<Resource> > mResourceMap;
|
||||
// unique_ptr are class templates that act like pointers, this allows us to work with heavyweight objects without copying them all the time, or we can store classes that are non-cpyable like sf::Shader
|
||||
};
|
||||
|
||||
typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
|
||||
|
||||
|
||||
|
||||
#include "resources.inl"
|
||||
|
||||
#endif // RESOURCES_HPP
|
||||
46
CPP/SFMLEngine/makingAGameTick/Classes/Other/resources.inl
Normal file
46
CPP/SFMLEngine/makingAGameTick/Classes/Other/resources.inl
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef RESOURCES_INL
|
||||
#define RESOURCES_INL
|
||||
|
||||
template <typename Resource, typename Identifier>
|
||||
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
|
||||
// Function to load a resource, it takes one parameter for filename and one for identifier
|
||||
{
|
||||
std::unique_ptr<Resource> resource(new Resource()); // Create sf:Texture and store it in the unique pointer
|
||||
if(!resource -> loadFromFile(filename))// Load the resource from the filename
|
||||
{
|
||||
throw std::runtime_error(TEXTURE_LOAD_ERROR + filename);
|
||||
}
|
||||
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource))); // Insert resource into map mResourceMap, std::move used to take ownership from resource variable and transfer it to std::make_pair(), std::move moves the resource into a new place and removes it from earlier place https://en.cppreference.com/w/cpp/utility/move
|
||||
assert(inserted.second);
|
||||
}
|
||||
|
||||
template <typename Resource, typename Identifier>
|
||||
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) // returns a reference to a resource
|
||||
{
|
||||
auto found = mResourceMap.find(id); // find returns an iterator to the found element or end() if nothing was found
|
||||
assert(found != mResourceMap.end());
|
||||
return *found -> second; // We have to access the second member of the pointer, then we deference it and get a resource
|
||||
}
|
||||
|
||||
template <typename Resource, typename Identifier>
|
||||
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) const // we need to be able to invoke get() also if we only have a pointer/reference to the const ResourceHolder<Resource, Identifier>, it returns const Resource so the resource cannot be changed by caller
|
||||
{
|
||||
auto found = mResourceMap.find(id); // find returns an iterator to the found element or end() if nothing was found
|
||||
assert(found != mResourceMap.end());
|
||||
return *found -> second; // We have to access the second member of the pointer, then we deference it and get a resource
|
||||
}
|
||||
|
||||
template <typename Resource, typename Identifier>
|
||||
template <typename Parameter>
|
||||
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename, const Parameter& secondParameter) // loads Shaders
|
||||
{
|
||||
std::unique_ptr<Resource> resource(new Resource()); // Create sf:Texture and store it in the unique pointer
|
||||
if(!resource -> loadFromFile(filename, secondParameter))// Load the resource from the filename
|
||||
{
|
||||
throw std::runtime_error(TEXTURE_LOAD_ERROR + filename);
|
||||
}
|
||||
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource))); // Insert resource into map mResourceMap, std::move used to take ownership from resource variable and transfer it to std::make_pair(), std::move moves the resource into a new place and removes it from earlier place https://en.cppreference.com/w/cpp/utility/move
|
||||
assert(inserted.second);
|
||||
}
|
||||
|
||||
#endif // RESOURCES_INL
|
||||
94
CPP/SFMLEngine/makingAGameTick/Classes/Other/world.cpp
Normal file
94
CPP/SFMLEngine/makingAGameTick/Classes/Other/world.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef WORLD_CPP // ZA WARUDO
|
||||
#define WORLD_CPP
|
||||
|
||||
#include <cstddef> // std::size_t
|
||||
#include "../SceneNodeDerrivatives/SpriteNode.hpp"
|
||||
#include "../SceneNodeDerrivatives/entity.hpp"
|
||||
|
||||
World::World(sf::RenderWindow& window)
|
||||
: mWindow(window)
|
||||
, mWorldView(window.getDefaultView())
|
||||
, mWorldBounds
|
||||
(
|
||||
WORLD_LEFT_X_POSITION,
|
||||
WORLD_TOP_Y_POSITION,
|
||||
mWorldView.getSize().x,
|
||||
WORLD_HEIGHT
|
||||
)
|
||||
, mSpawnPosition
|
||||
(
|
||||
mWorldView.getSize().x / 2.f,
|
||||
mWorldBounds.height - mWorldView.getSize().y
|
||||
)
|
||||
, mScrollSpeed ( WORLD_SCROLL_SPEED )
|
||||
, mPlayerAircraft(nullptr)
|
||||
{
|
||||
loadTextures();
|
||||
buildScene();
|
||||
mWorldView.setCenter(mSpawnPosition);
|
||||
}
|
||||
|
||||
void World::loadTextures()
|
||||
{
|
||||
mTextures.load(Textures::Eagle, PATH_TO_EAGLE_TEXTURE);
|
||||
mTextures.load(Textures::Raptor, PATH_TO_RAPTOR_TEXTURE);
|
||||
mTextures.load(Textures::Desert, PATH_TO_DESERT_TEXTURE);
|
||||
}
|
||||
|
||||
void World::buildScene()
|
||||
{
|
||||
for (std::size_t i = 0; i < LayerCount; i++) // initialization of scene layers, iterate through array of layer node pointers
|
||||
{
|
||||
SceneNode::ScenePointer layer(new SceneNode());
|
||||
mSceneLayers[i] = layer.get(); // initialize elments of this arry
|
||||
|
||||
mSceneGraph.attachChild(std::move(layer)); // attach new node to the scene graph's root node
|
||||
}
|
||||
|
||||
sf::Texture& texture = mTextures.get(Textures::Desert);
|
||||
sf::IntRect textureRect(mWorldBounds);
|
||||
texture.setRepeated(true); // make desert texture repeat itself
|
||||
|
||||
std::unique_ptr<SpriteNode> backgroundSprite(new SpriteNode(texture, textureRect)); // SpriteNode class that links to the desrt texture, our sprite will be as big as the whole world because we passed the texture rectangle
|
||||
backgroundSprite -> setPosition(mWorldBounds.left, mWorldBounds.top);
|
||||
mSceneLayers[Background] -> attachChild(std::move(backgroundSprite));
|
||||
|
||||
// Adding airplanes
|
||||
std::unique_ptr<Aircraft> leader(new Aircraft(Aircraft::Eagle, mTextures)); // we create the player's airplane
|
||||
mPlayerAircraft = leader.get();
|
||||
mPlayerAircraft -> setPosition(mSpawnPosition); // Set player position
|
||||
mPlayerAircraft -> SetVelocity(PLAYER_SIDEWARD_VELOCITY, mScrollSpeed); // forward velocity equals scroll speed, sideward velocity equals PLAYER_SIDEWARD_VELOCITY
|
||||
mSceneLayers[Air] -> attachChild(std::move(leader)); // we attach the plane to the Air scene layer
|
||||
|
||||
std::unique_ptr<Aircraft> leftEscort(new Aircraft(Aircraft::Raptor, mTextures)); // create new airplane
|
||||
leftEscort -> setPosition(LEFT_ESCORT_X_POSITION, LEFT_ESCORT_Y_POSITION); // Set new airplane position
|
||||
mPlayerAircraft -> attachChild(std::move(leftEscort)); // leftEscort is now a child of player aircraft and it will folow it!
|
||||
|
||||
std::unique_ptr<Aircraft> rightEscort(new Aircraft(Aircraft::Raptor, mTextures)); // create new airplane
|
||||
rightEscort -> setPosition(RIGHT_ESCORT_X_POSITION, RIGHT_ESCORT_Y_POSITION); // Set new airplane position
|
||||
mPlayerAircraft -> attachChild(std::move(rightEscort)); // leftEscort is now a child of player aircraft and it will folow it!
|
||||
}
|
||||
|
||||
void World::draw()
|
||||
{
|
||||
mWindow.setView(mWorldView);
|
||||
mWindow.draw(mSceneGraph);
|
||||
}
|
||||
|
||||
void World::update(sf::Time deltaTime) // controls world scrolling and entity movement
|
||||
{
|
||||
mWorldView.move(0.f, mScrollSpeed * deltaTime.asSeconds());
|
||||
|
||||
sf::Vector2f position = mPlayerAircraft -> getPosition();
|
||||
sf::Vector2f velocity = mPlayerAircraft -> getVelocity();
|
||||
|
||||
if(position.x <= mWorldBounds.left + WORLD_MAX_DISTANCE_FROM_BOUNDARY || position.x >= mWorldBounds.left + mWorldBounds.width - WORLD_MAX_DISTANCE_FROM_BOUNDARY) // if the player gets too close to world bounds make its velocity negative so it comes back
|
||||
{
|
||||
velocity.x = -velocity.x;
|
||||
mPlayerAircraft -> SetVelocity(velocity);
|
||||
}
|
||||
|
||||
mSceneGraph.update(deltaTime); // mSceneGraph actaully applies these velocities
|
||||
}
|
||||
|
||||
#endif // WORLD_CPP
|
||||
42
CPP/SFMLEngine/makingAGameTick/Classes/Other/world.hpp
Normal file
42
CPP/SFMLEngine/makingAGameTick/Classes/Other/world.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef WORLD_HPP // ZA WARUDO
|
||||
#define WORLD_HPP
|
||||
|
||||
#include <array>
|
||||
#include "../SceneNodeDerrivatives/SceneNode.hpp"
|
||||
#include "../SceneNodeDerrivatives/aircraft.hpp"
|
||||
|
||||
class World : private sf::NonCopyable // We only have one world and we do not want to copy it #StopClimateChange amiright
|
||||
{
|
||||
public:
|
||||
explicit World(sf::RenderWindow& window);
|
||||
void update(sf::Time deltaTime);
|
||||
void draw();
|
||||
private:
|
||||
void loadTextures();
|
||||
void buildScene();
|
||||
|
||||
private:
|
||||
enum Layer
|
||||
{
|
||||
Background,
|
||||
Air,
|
||||
LayerCount
|
||||
};
|
||||
|
||||
private:
|
||||
sf::RenderWindow& mWindow; // reference to the render window
|
||||
sf::View mWorldView; // current world's view
|
||||
TextureHolder mTextures; // All the textures needed inside the world
|
||||
SceneNode mSceneGraph;
|
||||
std::array<SceneNode*, LayerCount> mSceneLayers; // Pointers to access the scene graph's layerr nodes
|
||||
|
||||
sf::FloatRect mWorldBounds; // Bounding rectangle of the world
|
||||
sf::Vector2f mSpawnPosition; // Where player plane appears in the beginning
|
||||
float mScrollSpeed; // Speed with which the world is scrolled
|
||||
Aircraft* mPlayerAircraft; // Pointer to player aircraft
|
||||
};
|
||||
|
||||
// std::array is a class template for fixed size static arrays, same functionality, performance as C arrays but allows copies, assignment, passing or returning objects from the function, additional safety and usefull methods like size(), begin() or end()
|
||||
|
||||
#include "world.cpp"
|
||||
#endif // WORLD_HPP
|
||||
@ -0,0 +1,86 @@
|
||||
#ifndef SCENE_NODE_CPP
|
||||
#define SCENE_NODE_CPP
|
||||
|
||||
|
||||
void SceneNode::attachChild(ScenePointer child) // takes ownership of the scene node
|
||||
{
|
||||
child -> mParent = this;
|
||||
mChildren.push_back(std::move(child));
|
||||
}
|
||||
|
||||
SceneNode::ScenePointer SceneNode::detachChild(const SceneNode& node) // finds node, releases it and returns it to caller
|
||||
{
|
||||
auto found = std::find_if
|
||||
(
|
||||
mChildren.begin(), mChildren.end(),
|
||||
[&] (ScenePointer& p) -> bool { return p.get() == &node; }
|
||||
);
|
||||
// This is lambda expression
|
||||
// [&] (ScenePointer& p) -> bool { return p.get() == &node; }
|
||||
// [&] - how many and in what way will the lambda expression have access to the variables in surrounding scope, [] - no variables [&] - all variables by reference [=] - all variables by value
|
||||
// (ScenePointer& p) - parameters passed to the function
|
||||
// -> bool - return type
|
||||
// function body encolsed in {}
|
||||
assert(found != mChildren.end()); // We check validity of the iterator of the found element
|
||||
|
||||
ScenePointer result = std::move(*found); // we move the found node out of the container to result
|
||||
result -> mParent = nullptr; // node's parent is set to null pointer
|
||||
mChildren.erase(found); // we erase this element from the container
|
||||
return result; // and we return the pointer to the node
|
||||
}
|
||||
|
||||
void SceneNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SceneNode::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
states.transform *= getTransform();
|
||||
// *= combines the parent's absolute transform with the relative one of the current node;
|
||||
// states.transform contains the absolute world transform
|
||||
drawCurrent(target, states); // now we can draw the derived object using states, this is similar to how sf::Sprite handles transforms
|
||||
|
||||
for (const ScenePointer& child : mChildren)
|
||||
{
|
||||
child -> draw(target, states); // we also need to draw all the child nodes
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::updateCurrent(sf::Time deltaTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SceneNode::updateChildren(sf::Time deltaTime)
|
||||
{
|
||||
for (const ScenePointer& child : mChildren)
|
||||
{
|
||||
child -> update(deltaTime); // we also need to draw all the child nodes
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::update(sf::Time deltaTime)
|
||||
{
|
||||
updateCurrent(deltaTime);
|
||||
updateChildren(deltaTime);
|
||||
}
|
||||
|
||||
sf::Transform SceneNode::getWorldTransform() const
|
||||
{
|
||||
sf::Transform transform = sf::Transform::Identity; // sf::Transform::Identity represents the identity transform - it does not have any effecft on the object, it is not necessary in the code but it clarifies how transforms are applied
|
||||
for (const SceneNode* node = this; node != nullptr; node = node -> mParent)
|
||||
{
|
||||
transform = node -> getTransform() * transform;
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
sf::Vector2f SceneNode::getWorldPosition() const
|
||||
{
|
||||
return getWorldTransform() * sf::Vector2f();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,39 @@
|
||||
#ifndef SCENE_NODE_HPP
|
||||
#define SCENE_NODE_HPP
|
||||
|
||||
class SceneNode : public sf::Transformable, public sf::Drawable, private sf::NonCopyable
|
||||
// we derrive from transformable - to be able to store and modify position, rotation and scale
|
||||
// we derrive from drawable - to be able to draw it on screen
|
||||
// we derrive from noncopyable - so that copy constructor and copy assignemnt operators are disabled
|
||||
// This is used to create scene graph (tree data structure) in order to manage transform hierarchies
|
||||
{
|
||||
public:
|
||||
typedef std::unique_ptr<SceneNode> ScenePointer; // element types must be complete types and we do not want to manage memory ourselves so we use std::unique_ptr
|
||||
public:
|
||||
//SceneNode();
|
||||
void attachChild(ScenePointer child);
|
||||
ScenePointer detachChild(const SceneNode& node);
|
||||
void update(sf::Time deltaTime);
|
||||
private:
|
||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; // we override draw() function of sf::Drawable
|
||||
// Virtual functions are member functions whose behavior can be overridden in derived classes
|
||||
// draw() function allows our class to be used like this:
|
||||
/*
|
||||
sf::RenderWindow window(...); // window class calls our draw() function
|
||||
SceneNode::ScenePointer node(...);
|
||||
window.draw(*node);
|
||||
*/
|
||||
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; // draws only the current object, and not the children
|
||||
virtual void updateCurrent(sf::Time deltaTime); // we reuse scene graph to reach all entities with world update, this one updates current node
|
||||
void updateChildren(sf::Time deltaTime); // this one updates child nodes
|
||||
sf::Transform getWorldTransform() const; // it takes into account all the parent transform
|
||||
sf::Vector2f getWorldPosition() const;
|
||||
private:
|
||||
std::vector<ScenePointer> mChildren;
|
||||
SceneNode* mParent;
|
||||
|
||||
};
|
||||
|
||||
#include "SceneNode.cpp"
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,19 @@
|
||||
#ifndef SPRITE_NODE_CPP
|
||||
#define SPRITE_NODE_CPP
|
||||
|
||||
SpriteNode::SpriteNode(const sf::Texture& texture)
|
||||
: mSprite(texture)
|
||||
{
|
||||
}
|
||||
|
||||
SpriteNode::SpriteNode(const sf::Texture& texture, const sf::IntRect& textureRect)
|
||||
: mSprite(texture, textureRect)
|
||||
{
|
||||
}
|
||||
|
||||
void SpriteNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
target.draw(mSprite, states);
|
||||
}
|
||||
|
||||
#endif // SPRITE_NODE_CPP
|
||||
@ -0,0 +1,20 @@
|
||||
#ifndef SPRITE_NODE_HPP
|
||||
#define SPRITE_NODE_HPP
|
||||
|
||||
class SpriteNode : public SceneNode
|
||||
{
|
||||
public:
|
||||
explicit SpriteNode(const sf::Texture& texture);
|
||||
SpriteNode(const sf::Texture& texture, const sf::IntRect& rectangle);
|
||||
|
||||
private:
|
||||
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||
|
||||
private:
|
||||
sf::Sprite mSprite;
|
||||
};
|
||||
|
||||
|
||||
#include "SpriteNode.cpp"
|
||||
|
||||
#endif // SPRITE_NODE_HPP
|
||||
@ -0,0 +1,32 @@
|
||||
#ifndef AIRCRAFT_CPP
|
||||
#define AIRCRAFT_CPP
|
||||
|
||||
Textures::ID toTextureID(Aircraft::Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Aircraft::Eagle:
|
||||
return Textures::Eagle;
|
||||
|
||||
case Aircraft::Raptor:
|
||||
return Textures::Raptor;
|
||||
|
||||
default:
|
||||
return Textures::Eagle;
|
||||
}
|
||||
return Textures::Eagle;
|
||||
}
|
||||
|
||||
|
||||
Aircraft::Aircraft(Type type, const TextureHolder& textures) : mType(type), mSprite(textures.get(toTextureID(type)))
|
||||
{
|
||||
sf::FloatRect bounds = mSprite.getLocalBounds(); // we get local bounding rectangle which means that we do not take transforms into account, as opposed to getGlobalBounds()
|
||||
mSprite.setOrigin(bounds.width / 2.f, bounds.height / 2.f); // we want to set origin of the sprite to the middle of a rectangle around it
|
||||
}
|
||||
|
||||
void Aircraft::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
target.draw(mSprite, states);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,25 @@
|
||||
#ifndef AIRCRAFT_HPP
|
||||
#define AIRCRAFT_HPP
|
||||
|
||||
#include "entity.hpp"
|
||||
|
||||
class Aircraft : public Entity
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Eagle,
|
||||
Raptor
|
||||
};
|
||||
public:
|
||||
explicit Aircraft(Type type, const TextureHolder& textures);
|
||||
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||
|
||||
private:
|
||||
Type mType;
|
||||
sf::Sprite mSprite;
|
||||
|
||||
};
|
||||
|
||||
#include "aircraft.cpp"
|
||||
#endif
|
||||
@ -0,0 +1,25 @@
|
||||
#ifndef ENTITY_CPP
|
||||
#define ENTITY_CPP
|
||||
|
||||
void Entity::SetVelocity(sf::Vector2f velocity)
|
||||
{
|
||||
mVelocity = velocity;
|
||||
}
|
||||
|
||||
void Entity::SetVelocity(float velocityX, float velocityY)
|
||||
{
|
||||
mVelocity.x = velocityX;
|
||||
mVelocity.y = velocityY;
|
||||
}
|
||||
|
||||
sf::Vector2f Entity::getVelocity() const
|
||||
{
|
||||
return mVelocity;
|
||||
}
|
||||
|
||||
void Entity::updateCurrent(sf::Time deltaTime)
|
||||
{
|
||||
move(mVelocity * deltaTime.asSeconds()); // shortcut for setPosition(getPosition() + offset)
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,21 @@
|
||||
#ifndef ENTITY_HPP
|
||||
#define ENTITY_HPP
|
||||
#include "SceneNode.hpp"
|
||||
#include "SceneNode.cpp"
|
||||
|
||||
class Entity : public SceneNode
|
||||
{
|
||||
public:
|
||||
void SetVelocity(sf::Vector2f velocity);
|
||||
void SetVelocity(float velocityX, float velocityY);
|
||||
sf::Vector2f getVelocity() const;
|
||||
|
||||
private:
|
||||
sf::Vector2f mVelocity; // default ocnstructor initializes this vector to a zero vector
|
||||
virtual void updateCurrent(sf::Time deltaTime);
|
||||
|
||||
};
|
||||
|
||||
#include "entity.cpp"
|
||||
|
||||
#endif
|
||||
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Desert.jpg
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Desert.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Eagle.png
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Eagle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Player.png
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Player.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Raptor.png
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Raptor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Raptor.xcf
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/Textures/Raptor.xcf
Normal file
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
BIN
CPP/SFMLEngine/makingAGameTick/app
Executable file
BIN
CPP/SFMLEngine/makingAGameTick/app
Executable file
Binary file not shown.
10
CPP/SFMLEngine/makingAGameTick/basic.cpp
Normal file
10
CPP/SFMLEngine/makingAGameTick/basic.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef BASIC_CPP
|
||||
#define BASIC_CPP
|
||||
#include <iostream>
|
||||
|
||||
void print(const std::string s)
|
||||
{
|
||||
std::cout << s << std::endl;
|
||||
}
|
||||
|
||||
#endif // BASIC_CPP
|
||||
BIN
CPP/SFMLEngine/makingAGameTick/constants
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/constants
Normal file
Binary file not shown.
47
CPP/SFMLEngine/makingAGameTick/constants.hpp
Normal file
47
CPP/SFMLEngine/makingAGameTick/constants.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef CONSTANTS_HPP
|
||||
#define CONSTANTS_HPP
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
// Paths
|
||||
const std::string PATH_TO_PLAYER_TEXTURE = "Textures/Player.png";
|
||||
const std::string PATH_TO_EAGLE_TEXTURE = "Textures/Eagle.png";
|
||||
const std::string PATH_TO_RAPTOR_TEXTURE = "Textures/Raptor.png";
|
||||
const std::string PATH_TO_DESERT_TEXTURE = "Textures/Desert.jpg";
|
||||
|
||||
// Player constants
|
||||
const float PLAYER_RADIUS = 40;
|
||||
const float PLAYER_X_POSITION = 100;
|
||||
const float PLAYER_Y_POSITION = 100;
|
||||
const sf::Color PLAYER_COLOR = sf::Color::Cyan;
|
||||
const float PLAYER_SIDEWARD_VELOCITY = 40;
|
||||
|
||||
// Other sprites constants
|
||||
const float LEFT_ESCORT_X_POSITION = -80;
|
||||
const float LEFT_ESCORT_Y_POSITION = 50;
|
||||
const float RIGHT_ESCORT_X_POSITION = -LEFT_ESCORT_X_POSITION;
|
||||
const float RIGHT_ESCORT_Y_POSITION = LEFT_ESCORT_Y_POSITION;
|
||||
|
||||
// Movement constants
|
||||
// const sf::Vector2f INITIAL_MOVEMENT (0.f, 0.f);
|
||||
|
||||
const float MOVING_UP_SPEED = -100;
|
||||
const float MOVING_DOWN_SPEED = -MOVING_UP_SPEED;
|
||||
const float MOVING_RIGHT_SPEED = 100;
|
||||
const float MOVING_LEFT_SPEED = -MOVING_RIGHT_SPEED;
|
||||
|
||||
// Time constants
|
||||
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f); // 1 frame is 1 / 60 of the second so we get 60 frames in a second
|
||||
|
||||
// Error strings
|
||||
const std::string TEXTURE_LOAD_ERROR = "TextureHolder::load - Failed to load ";
|
||||
|
||||
// World constants
|
||||
const float WORLD_LEFT_X_POSITION = 0;
|
||||
const float WORLD_TOP_Y_POSITION = 0;
|
||||
// const float WORLD_WIDTH = 0; by default mWorldView.getSize().x
|
||||
const float WORLD_HEIGHT = 2000;
|
||||
const float WORLD_SCROLL_SPEED = -1;
|
||||
const float WORLD_MAX_DISTANCE_FROM_BOUNDARY = 150;
|
||||
|
||||
#endif // CONSTANTS_HPP
|
||||
161
CPP/SFMLEngine/makingAGameTick/game.cpp
Normal file
161
CPP/SFMLEngine/makingAGameTick/game.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#ifndef GAME_CPP
|
||||
#define GAME_CPP
|
||||
|
||||
#include <vector>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "constants.hpp"
|
||||
#include "./Classes/Other/resources.hpp"
|
||||
#include "./Classes/Other/world.hpp"
|
||||
#include "./Classes/SceneNodeDerrivatives/SceneNode.hpp"
|
||||
#include "./Classes/SceneNodeDerrivatives/SpriteNode.hpp"
|
||||
#include "./Classes/SceneNodeDerrivatives/entity.hpp"
|
||||
#include "./Classes/SceneNodeDerrivatives/aircraft.hpp"
|
||||
#include "basic.cpp"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Game : private sf::NonCopyable
|
||||
{
|
||||
public:
|
||||
Game(); // Sets up player radius, position and fill color
|
||||
void run(); // runs the processEvents, update and render methods
|
||||
|
||||
private:
|
||||
void processEvents(); // playerInput, mainLoop
|
||||
void update(sf::Time deltaTime); // code that updates the game
|
||||
void render(); // code that renders the game
|
||||
void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);
|
||||
bool mIsMovingUp = false;
|
||||
bool mIsMovingRight = false;
|
||||
bool mIsMovingLeft = false;
|
||||
bool mIsMovingDown = false;
|
||||
private:
|
||||
sf::RenderWindow mWindow;
|
||||
TextureHolder mTexture;
|
||||
sf::Sprite mPlayer;
|
||||
World mWorld;
|
||||
};
|
||||
|
||||
Game::Game()
|
||||
: mWindow(sf::VideoMode(640, 480), "World", sf::Style::Close)
|
||||
, mWorld(mWindow)
|
||||
/* , mFont()
|
||||
, mStatisticsText()
|
||||
, mStatisticsUpdateTime()
|
||||
, mStatisticsNumFrames(0)
|
||||
*/
|
||||
{
|
||||
/* mFont.loadFromFile("Media/Sansation.ttf");
|
||||
mStatisticsText.setFont(mFont);
|
||||
mStatisticsText.setPosition(5.f, 5.f);
|
||||
mStatisticsText.setCharacterSize(10);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// Resposible for managing game loop - fetching input form the window system, updating the world, and ordering the rendering of the game
|
||||
void Game::run()
|
||||
{
|
||||
/* Other useful frame rate related tecnhiques:
|
||||
sf::sleep - interrupts the execution for a given time, not very accurate
|
||||
sf::RenderWindow::setFramerateLimit() - tries to achieve the frame rate by calling sf::sleep, nice for testing purposes
|
||||
sf::RenderWindow::setVerticalSyncEnabled() - enables V-sync which adapts the rate of graphical updates from sf::RenderWindow::display() to the refresh rate of the monitor
|
||||
*/
|
||||
sf::Clock clock;
|
||||
sf::Time timeSinceLastUpdateFunction = sf::Time::Zero;
|
||||
while (mWindow.isOpen()) // this loop calls the render method
|
||||
{
|
||||
processEvents();
|
||||
timeSinceLastUpdateFunction += clock.restart();
|
||||
while(timeSinceLastUpdateFunction > TIME_PER_FRAME) // fixed time stamps
|
||||
// this loop collects user input and computes game logic
|
||||
{
|
||||
timeSinceLastUpdateFunction -= TIME_PER_FRAME;
|
||||
processEvents();
|
||||
update(TIME_PER_FRAME);
|
||||
}
|
||||
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
const std::vector < pair<bool, sf::Keyboard::Key> > PLAYER_MOVEMENT =
|
||||
{
|
||||
{mIsMovingUp, sf::Keyboard::W},
|
||||
{mIsMovingDown, sf::Keyboard::S},
|
||||
{mIsMovingLeft, sf::Keyboard::A},
|
||||
{mIsMovingRight, sf::Keyboard::D}
|
||||
}
|
||||
*/
|
||||
|
||||
void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
|
||||
{
|
||||
if (key == sf::Keyboard::W) mIsMovingUp = isPressed;
|
||||
else if (key == sf::Keyboard::S) mIsMovingDown = isPressed;
|
||||
else if (key == sf::Keyboard::A) mIsMovingLeft = isPressed;
|
||||
else if (key == sf::Keyboard::D) mIsMovingRight = isPressed;
|
||||
}
|
||||
|
||||
void Game::processEvents()
|
||||
{
|
||||
sf::Event event;
|
||||
while (mWindow.pollEvent(event)) // mainLoop/gameLoop
|
||||
{
|
||||
// each time while loop iterates it means that we got a new event registered by the window.
|
||||
switch (event.type)
|
||||
{
|
||||
case sf::Event::KeyPressed:
|
||||
handlePlayerInput(event.key.code, true);
|
||||
break;
|
||||
case sf::Event::KeyReleased:
|
||||
handlePlayerInput(event.key.code, false);
|
||||
break;
|
||||
case sf::Event::Closed:
|
||||
mWindow.close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::update(sf::Time deltaTime)
|
||||
{
|
||||
|
||||
sf::Vector2f movement (0.f, 0.f); // movement from the origin of the current coordinate system, in this case origin is the shape's positon
|
||||
movement.y += mIsMovingUp * MOVING_UP_SPEED + mIsMovingDown * MOVING_DOWN_SPEED;
|
||||
movement.x += mIsMovingLeft * MOVING_LEFT_SPEED + mIsMovingRight * MOVING_RIGHT_SPEED;
|
||||
mPlayer.move(movement * deltaTime.asSeconds());
|
||||
// from physics formula distance = speed * time
|
||||
// this allows us to move exactly the distance we want it to move in one second, no matter what computer are we on
|
||||
// delta time / time step - time that has elapsed since the last frame
|
||||
// mWorldView.move(0.f, mScrollSpeed * deltaTime.asSeconds()); we scroll up the map, we update both the map and the player so he does not get left behind, we multiple by time to ensure that we have the same speed of n pixels per second no matter the simulation frame rate
|
||||
}
|
||||
|
||||
void Game::render()
|
||||
{
|
||||
mWindow.clear();
|
||||
mWorld.draw();
|
||||
|
||||
mWindow.setView(mWindow.getDefaultView());
|
||||
// mWindow.draw(mStatisticsText);
|
||||
mWindow.display();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
Game game;
|
||||
game.run();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "\nEXCEPTION: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GAME_CPP
|
||||
BIN
CPP/SFMLEngine/makingAGameTick/game.o
Normal file
BIN
CPP/SFMLEngine/makingAGameTick/game.o
Normal file
Binary file not shown.
9
CPP/SFMLEngine/makingAGameTick/makefile
Normal file
9
CPP/SFMLEngine/makingAGameTick/makefile
Normal file
@ -0,0 +1,9 @@
|
||||
CXXFLAGS = -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings -Wcast-qual -Wunreachable-code -pedantic -Wswitch-default -Wno-unused-parameter
|
||||
# https://stackoverflow.com/a/3376483
|
||||
|
||||
compile:./game.cpp
|
||||
g++ $(CXXFLAGS) -c ./game.cpp
|
||||
g++ game.o -o app -lsfml-graphics -lsfml-window -lsfml-system
|
||||
|
||||
run:
|
||||
./app
|
||||
BIN
CPP/SFMLEngine/minimalExample/app
Executable file
BIN
CPP/SFMLEngine/minimalExample/app
Executable file
Binary file not shown.
34
CPP/SFMLEngine/minimalExample/example.cpp
Normal file
34
CPP/SFMLEngine/minimalExample/example.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// SFML is split into 5 modules:
|
||||
// #include <SFML/Graphics.hpp>
|
||||
// #include <SFML/Audio.hpp>
|
||||
// #include <SFML/System.hpp>
|
||||
// #include <SFML/Window.hpp>
|
||||
// #include <SFML/Network.hpp>
|
||||
// We can include them like this or we can include just a specific header file:
|
||||
// #include <SFML/Audio/Sound.hpp>
|
||||
// Each module is compiled to separate library, it can be built for release or debug, linked statically or dynamically
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
sf::RenderWindow window(sf::VideoMode(640, 480), "SFML Application");
|
||||
sf::CircleShape shape;
|
||||
const float CIRCLE_RADIUS = 40;
|
||||
shape.setRadius(CIRCLE_RADIUS);
|
||||
const float CIRCLE_POSITION_X = 100;
|
||||
const float CIRCLE_POSITION_Y = 100;
|
||||
shape.setPosition(CIRCLE_POSITION_X, CIRCLE_POSITION_Y);
|
||||
shape.setFillColor(sf::Color::Cyan);
|
||||
while(window.isOpen())
|
||||
{
|
||||
sf::Event event;
|
||||
while(window.pollEvent(event))
|
||||
{
|
||||
if(event.type == sf::Event::Closed) window.close();
|
||||
}
|
||||
window.clear();
|
||||
window.draw(shape);
|
||||
window.display();
|
||||
}
|
||||
}
|
||||
BIN
CPP/SFMLEngine/minimalExample/example.o
Normal file
BIN
CPP/SFMLEngine/minimalExample/example.o
Normal file
Binary file not shown.
6
CPP/SFMLEngine/minimalExample/makefile
Normal file
6
CPP/SFMLEngine/minimalExample/makefile
Normal file
@ -0,0 +1,6 @@
|
||||
compile:./example.cpp
|
||||
g++ -c ./example.cpp
|
||||
g++ example.o -o app -lsfml-graphics -lsfml-window -lsfml-system
|
||||
|
||||
run:
|
||||
./app
|
||||
3
CPP/SFMLEngine/readme.md
Normal file
3
CPP/SFMLEngine/readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Textures and Audio used:
|
||||
## Space Game Starter Set by [hc](https://opengameart.org/users/hc) - https://opengameart.org/content/space-game-starter-set
|
||||
## 100 seamless textures by [Mitch Featherston](http://pdtextures.blogspot.com/) (Submitted by [Clint Bellanger](https://opengameart.org/users/clint-bellanger) - https://opengameart.org/content/100-seamless-textures
|
||||
Loading…
Reference in New Issue
Block a user