Hello!
I'm new to this forums, and a little green to SFML, but I wanted to post what I have so far in terms of a SFML engine. A lot of the code is from scratch, but a few parts like the camera class are based off of a tutorial I found on dreamincode:
Ignition engine:
#pragma once
#include <SFML\Graphics.hpp>
#include <exception>
////////////////////////////////////////////////////////////////////////////////////////////////
// Ignition 2D Engine v 1.01 ///////////////////////////////////////////////////////////////////
// Written in C++ & SFML by John Lawson ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
namespace Ignition
{ class Texture_Manager
{ public:
Texture_Manager();
private:
std::vector<sf::Texture*> Texture_list;
public:
void Add_texture(sf::Texture * iTexture);
void Smooth_texture(unsigned int index, bool smooth);
sf::Texture * Get_texture(unsigned int index);
~Texture_Manager();
};
class CSprite
{ public:
CSprite(sf::Texture * texture, float iox, float ioy);
CSprite(sf::Texture * texture, float iox, float ioy, unsigned int a, unsigned int b, unsigned int c, unsigned int d);
protected:
sf::Sprite * Object_sprite;
virtual void Frame(float dt); // Frame updater to be defined in derived classes.
public: // Similar virtual for checking whether the object is in
virtual bool In_render(sf::IntRect rBounds); // the area to be drawn
float Get_theta();
sf::Vector2i Get_pos();
float Get_x();
float Get_y();
void Set_theta(float itheta);
void Set_position(float ix, float iy);
void Colour_sprite(int red, int green, int blue, int alpha);
void Colour_sprite(int red, int green, int blue);
void Draw_sprite(int x, int y, sf::RenderWindow * rwindow);
void Draw_sprite(sf::RenderWindow * rwindow);
~CSprite();
};
class Camera
{ public:
Camera(unsigned int h, unsigned int w, unsigned int pofs_x, unsigned int pofs_y);
Camera(unsigned int h, unsigned int w, unsigned int pofs_x, unsigned int pofs_y, CSprite * iTgt);
Camera(unsigned int h, unsigned int w, float ispeed, unsigned int pofs_x, unsigned int pofs_y);
Camera(unsigned int h, unsigned int w, float ispeed, unsigned int pofs_x, unsigned int pofs_y, CSprite * iTgt);
void Translate_camera(int x,int y);
void Translate_camera_center(int x, int y);
void Camera_goto(int x,int y); // dont worry, not that kind of goto
void Camera_center_goto(int x, int y); // Sends the camera to a coordinate in "the world"
void Update_camera();
void Set_cam_tgt(sf::Vector2i iPos);
sf::Vector2i* Get_cam_pos();
sf::Vector2i* Get_cam_size();
sf::Vector2i* Get_Cam_port_ofs();
sf::IntRect Get_cam_window();
CSprite * this_cTgt;
private:
sf::Vector2f * Cam_pos;
sf::Vector2i * Cam_size;
sf::Vector2f * Cam_tgt;
sf::Vector2i * Cam_port_ofs; // Offset from standard render position in the portal window
float speed; // Not strictly necessary, but I may want the camera to have a "lag" motion behind the target, probably great for ConquerSpace
public: // velocity, speed, dammit. Must respect physics, augh!!!
friend class Ignition_Engine;
~Camera();
};
class Portal
{ public:
Portal(unsigned int h, unsigned int w, int bpp, std::string wTitle); // The cake is a lie, apparently.
void Add_camera_view(Camera * iCam); // Least, nobody ever gave me any for coding anything.
sf::RenderWindow * pPortal;
std::vector<Camera*> Cam_views;
public:
~Portal(); // But this is a triumph :)
};
struct Portal_arg
{ unsigned int h, w;
int bpp;
std::string ptitle;
};
class Ignition_Engine
{ public:
Ignition_Engine(void (*function)(Ignition_Engine* ithis));
void Ignition(std::vector<std::string> Load_paths, unsigned int h, unsigned int w, int bpp, std::string wTitle);
void Ignition(std::vector<std::string> Load_paths, std::vector<Portal_arg> Portal_args, unsigned int h, unsigned int w, int bpp, std::string wTitle);
Texture_Manager Manager;
std::vector<Camera*> Engine_cams;
Portal * Main_portal;
std::vector<Portal*> Sub_portals;
void Load_texture(std::string file_path);
void Register_sprite(CSprite * iSprite);
std::vector<CSprite*> Sprite_Objects;
CSprite * eTgt; // The primary engine target (ie, usually the current player input that we want to follow);
private:
bool Start(unsigned int h, unsigned int w, int bpp, std::string wTitle); // Engine Start (The Engines are on!)
void Loop(); // Main Loop()
void Render_frame(); // { Renders the graphical output
void Process_input(); // Handle user input
void Update(); // Update program internals
public: // }
~Ignition_Engine(void);
};
void Construct_portal(unsigned int h, unsigned int w, int bpp, std::string wTitle, Ignition_Engine * this_engine);
}
#include "Ignition_Engine.h"
#include <math.h>
#include <vector>
// Ignition Engine ///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Ignition::Ignition_Engine::Ignition_Engine(void (*function)(Ignition_Engine* ithis))
{ (*function)(this); // Pass in the new arguments to the engine starting up
}
void Ignition::Ignition_Engine::Ignition(std::vector<std::string> Load_paths, unsigned int h, unsigned int w, int bpp, std::string wTitle)
{ if (!Start(h, w, bpp, wTitle))
{ throw "Ignition_Failure";
}
else
{ for (std::vector<std::string>::iterator it = Load_paths.begin(); it != Load_paths.end(); ++it)
{ Load_texture(*it);
}
Loop();
}
} // Lights this candle. Yeah baby. Yeah.
void Ignition::Ignition_Engine::Ignition(std::vector<std::string> Load_paths, std::vector<Portal_arg> Portal_args, unsigned int h, unsigned int w, int bpp, std::string wTitle)
{ if (!Start(h, w, bpp, wTitle))
{ throw "Ignition_Failure";
}
else
{ for (std::vector<std::string>::iterator it = Load_paths.begin(); it != Load_paths.end(); ++it)
{ Load_texture(*it);
}
for (std::vector<Portal_arg>::iterator itArg = Portal_args.begin(); itArg != Portal_args.end(); ++itArg)
{ Construct_portal(itArg->h, itArg->w, itArg->bpp, itArg->ptitle);
}
Loop();
}
} // Lights this candle. Yeah baby. Yeah.
void Ignition::Ignition_Engine::Load_texture(std::string file_path)
{ sf::Texture * Tex; // Trustworthy files of course
Tex = new sf::Texture();
Tex->loadFromFile(file_path);
Manager.Add_texture(Tex);
} // Load a texture into the managed list
void Ignition::Ignition_Engine::Register_sprite(CSprite * iSprite)
{ Sprite_Objects.push_back(iSprite);
} // Register a sprite... for iteration of members inheriting from parent class CSprite
bool Ignition::Ignition_Engine::Start(unsigned int h, unsigned int w, int bpp, std::string wTitle)
{ Main_portal = new Portal(Engine_cams, h, w, bpp, wTitle);
if(!(Main_portal->pPortal))
{ return false;
}
else
{ return true;
}
}
void Ignition::Ignition_Engine::Loop()
{ while(Main_portal->pPortal->isOpen())
{ Process_input();
Update();
Render_frame();
}
}
void Ignition::Ignition_Engine::Render_frame()
{ for (std::vector<Portal*>::iterator it = Sub_portals.begin(); it != Sub_portals.end(); ++it)
{ (*it)->pPortal->clear();
} Main_portal->pPortal->clear();
sf::Vector2i * rend_ofs;
for (std::vector<Portal*>::iterator itPortal = Sub_portals.begin(); itPortal != Sub_portals.end(); ++itPortal)
{ for (std::vector<Camera*>::iterator itCamera = (*itPortal)->Cam_views.begin(); itCamera != (*itPortal)->Cam_views.end(); ++itCamera)
{ if(!((*itCamera)->Cam_tgt))
{ (*itCamera)->this_cTgt = eTgt;
(*itCamera)->Cam_tgt = new sf::Vector2f(eTgt->Get_pos());
}
for (std::vector<CSprite*>::iterator itSprites = Sprite_Objects.begin(); itSprites != Sprite_Objects.begin(); ++itSprites)
{ if ((*itSprites)->In_render((*(*itCamera)->Get_cam_window())) == true)
{ rend_ofs = new sf::Vector2i( *((*itCamera)->Get_Cam_port_ofs()) + ((*itSprites)->Get_pos()) );
(*itSprites)->Draw_sprite((rend_ofs)->x, (rend_ofs)->y, (*itPortal)->pPortal);
delete rend_ofs;
}
}
}
}
}
void Ignition::Ignition_Engine::Process_input()
{ sf::Event Input_Events;
while(Main_portal->pPortal->pollEvent(Input_Events))
{ if (Input_Events.type == sf::Event::Closed)
{ this->~Ignition_Engine();
}
}
}
void Ignition::Ignition_Engine::Update()
{
}
Ignition::Ignition_Engine::~Ignition_Engine(void)
{ for (std::vector<CSprite*>::iterator it = Sprite_Objects.begin(); it != Sprite_Objects.end(); ++it)
{ delete *it;
} Sprite_Objects.clear();
Manager.~Texture_Manager();
for (std::vector<Portal*>::iterator itPortal = Sub_portals.begin(); itPortal != Sub_portals.end(); ++itPortal)
{ delete (*itPortal);
} delete Main_portal;
}
// Ignition::Texture manager class ///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Ignition::Texture_Manager::Texture_Manager()
{
}
void Ignition::Texture_Manager::Add_texture(sf::Texture * iTexture)
{ Texture_list.push_back(iTexture);
}
void Ignition::Texture_Manager::Smooth_texture(unsigned int index, bool smooth)
{ Texture_list[index]->setSmooth(smooth);
}
sf::Texture * Ignition::Texture_Manager::Get_texture(unsigned int index)
{ return Texture_list[index];
}
Ignition::Texture_Manager::~Texture_Manager()
{ for(std::vector<sf::Texture*>::iterator it = Texture_list.begin(); it != Texture_list.end(); ++it)
{ delete *it;
} Texture_list.clear();
}
// Ignition::Sprite parent class /////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Ignition::CSprite::CSprite(sf::Texture * texture, float iox, float ioy)
{ Object_sprite = new sf::Sprite();
Object_sprite->setTexture(*texture);
Object_sprite->setOrigin(iox, ioy); // Reset the origin by given coordinates
} // Constructs the Tile object and assigns it the texture that it uses
Ignition::CSprite::CSprite(sf::Texture * texture, float iox, float ioy, unsigned int a, unsigned int b, unsigned int c, unsigned int d)
{ Object_sprite->setTexture(*texture);
Object_sprite->setTextureRect(sf::IntRect(a, b, c, d)); // Explicitly defining the texture coordinates of the sprite in the given texture
Object_sprite->setOrigin(iox, ioy); // Reset the origin by given coordinates
} // Constructs the Tile object and assigns it the texture that it uses
float Ignition::CSprite::Get_theta()
{ return (Object_sprite->getRotation());
} // Get the rotation of the sprite as float.
sf::Vector2i Ignition::CSprite::Get_pos()
{ sf::Vector2i pos((int)Get_x(),(int)Get_y());
return pos;
}
float Ignition::CSprite::Get_x()
{ return (Object_sprite->getPosition().x);
}
float Ignition::CSprite::Get_y()
{ return (Object_sprite->getPosition().y);
}
void Ignition::CSprite::Set_theta(float itheta)
{ Object_sprite->setRotation(itheta);
}
void Ignition::CSprite::Set_position(float ix, float iy)
{ Object_sprite->setPosition(ix, iy);
}
void Ignition::CSprite::Colour_sprite(int red, int green, int blue, int alpha)
{ Object_sprite->setColor(sf::Color(red, green, blue, alpha));
}
void Ignition::CSprite::Colour_sprite(int red, int green, int blue)
{ Object_sprite->setColor(sf::Color(red, green, blue));
}
void Ignition::CSprite::Draw_sprite(int x, int y, sf::RenderWindow * rwindow)
{ Object_sprite->setPosition(x, y);
rwindow->draw(*Object_sprite);
}
void Ignition::CSprite::Draw_sprite(sf::RenderWindow * rwindow)
{ rwindow->draw(*Object_sprite);
}
Ignition::CSprite::~CSprite()
{ delete Object_sprite;
}
// Ignition::Portal class ////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Ignition::Portal::Portal(unsigned int h, unsigned int w, int bpp, std::string wTitle)
{ pPortal = new sf::RenderWindow(sf::VideoMode(w, h, bpp), wTitle);
}
void Ignition::Portal::Add_camera_view(Camera * iCam)
{ Cam_views.push_back(iCam);
}
Ignition::Portal::~Portal()
{ Cam_views.clear();
pPortal->close();
delete pPortal;
}
// Ignition::Camera class ////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Ignition::Camera::Camera(unsigned int h, unsigned int w, unsigned int pofs_x, unsigned int pofs_y)
{ Cam_size = new sf::Vector2i(w, h);
Cam_pos = new sf::Vector2f(0.000, 0.000);
Cam_port_ofs = new sf::Vector2i(pofs_x, pofs_y);
speed = 1.000;
}
Ignition::Camera::Camera(unsigned int h, unsigned int w, unsigned int pofs_x, unsigned int pofs_y, CSprite * iTgt)
{ Cam_size = new sf::Vector2i(w, h);
Cam_pos = new sf::Vector2f(0.000, 0.000);
Cam_port_ofs = new sf::Vector2i(pofs_x, pofs_y);
speed = 1.000;
this_cTgt = iTgt;
Cam_tgt = new sf::Vector2f((this_cTgt->Get_pos()));
}
Ignition::Camera::Camera(unsigned int h, unsigned int w, float ispeed, unsigned int pofs_x, unsigned int pofs_y)
{ Cam_size = new sf::Vector2i(w, h);
Cam_pos = new sf::Vector2f(0.000, 0.000);
Cam_port_ofs = new sf::Vector2i(pofs_x, pofs_y);
speed = ispeed;
}
Ignition::Camera::Camera(unsigned int h, unsigned int w, float ispeed, unsigned int pofs_x, unsigned int pofs_y, CSprite * iTgt)
{ Cam_size = new sf::Vector2i(w, h);
Cam_pos = new sf::Vector2f(0.000, 0.000);
Cam_port_ofs = new sf::Vector2i(pofs_x, pofs_y);
speed = ispeed;
this_cTgt = iTgt;
Cam_tgt = new sf::Vector2f((this_cTgt->Get_pos()));
}
void Ignition::Camera::Translate_camera(int x, int y)
{ Cam_pos->x = (float)x;
Cam_pos->y = (float)y;
Cam_tgt = Cam_pos;
}
void Ignition::Camera::Translate_camera_center(int x, int y)
{ x -= ((Cam_size->x)/(2));
y -= ((Cam_size->y)/(2));
Cam_pos->x = (float)x;
Cam_pos->y = (float)y;
Cam_tgt = Cam_pos;
}
void Ignition::Camera::Camera_goto(int x, int y)
{ Cam_tgt->x = (float)x;
Cam_tgt->y = (float)y;
}
void Ignition::Camera::Camera_center_goto(int x, int y)
{ x -= ((Cam_size->x)/(2));
y -= ((Cam_size->y)/(2));
Cam_tgt->x = x;
Cam_tgt->y = y;
}
void Ignition::Camera::Update_camera()
{ struct coords
{ float l, dl;
}x, y, d;
x.l = (float)(Cam_tgt->x - Cam_pos->x);
y.l = (float)(Cam_tgt->y - Cam_pos->y);
if (d.l <= 1)
{ Cam_pos = Cam_tgt;
} // The snap-to case when the locations are close enough. Not really sure if this is worth it, but maybe overshooting is a problem otherwise
else
{ d.l = sqrt((pow(x.l, 2))+(pow(y.l, 2)));
d.dl = (((d.l)*(speed))/60);
if (d.dl < 1.0f)
{ d.dl = 1.0f;
}
x.dl = ((x.l)*(d.dl/d.l)); // Similar triangles method
y.dl = ((y.l)*(d.dl/d.l)); // to get v components
Cam_pos->x += x.dl;
Cam_pos->y += y.dl;
}
}
void Ignition::Camera::Set_cam_tgt(sf::Vector2i iPos)
{ Cam_tgt->x = iPos.x;
Cam_tgt->y = iPos.y;
}
sf::Vector2i* Ignition::Camera::Get_cam_pos()
{ sf::Vector2i * output = new sf::Vector2i((int)((Cam_pos)->x),(int)((Cam_pos)->y));
return output;
}
sf::Vector2i* Ignition::Camera::Get_cam_size()
{ return Cam_size;
}
sf::Vector2i* Ignition::Camera::Get_Cam_port_ofs()
{ return Cam_port_ofs;
}
sf::IntRect Ignition::Camera::Get_cam_window()
{ sf::IntRect cWindow((Cam_pos->x),(Cam_pos->y),(Cam_size->x),(Cam_size->y));
return cWindow;
}
Ignition::Camera::~Camera()
{ delete Cam_tgt;
delete Cam_size;
delete Cam_pos;
delete Cam_port_ofs;
}
// Ignition Engine - Functions() /////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void Ignition::Construct_portal(unsigned int h, unsigned int w, int bpp, std::string wTitle, Ignition_Engine * this_engine)
{ Portal * iPort = new Portal(h, w, bpp, wTitle);
this_engine->Sub_portals.push_back(iPort);
}
Any thoughts on the progress so far are welcome