I recently started working on SFML. I just created a window then later started to separating my main code. First i wrote a window class.
Nothing special, just draws my window and prints mouse coordinates.
#include "Window.hpp"
#include <iostream>
Window::Window()
{
SetWindow(800,600, "JUST SFML");
}
void Window::SetWindow(unsigned int width, unsigned int height, sf::String title)
{
m_sfmlWindow.create(sf::VideoMode(width, height), title);
}
void Window::StartDrawing()
{
m_sfmlWindow.clear();
}
void Window::EndDrawing()
{
m_sfmlWindow.display();
}
bool Window::isClosed()
{
return !m_sfmlWindow.isOpen();
}
void Window::EventControl()
{
sf::Event event;
while (m_sfmlWindow.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
m_sfmlWindow.close();
}
if (event.type == sf::Event::MouseMoved)
{
std::cout << event.mouseMove.x << " , " << event.mouseMove.y << std::endl;
}
}
}
void Window::Draw(sf::Drawable& shape)
{
m_sfmlWindow.draw(shape);
}
Everything worked perfectly.
Then i tought i need a GameManager class that i can just use in my main class.
#include "GameManager.hpp"
GameManager::GameManager()
{
m_shape.setRadius(30.0f);
m_shape.setFillColor(sf::Color::Magenta);
m_incVal = 1.0f;
m_posX = 10.0f;
m_frameRate = 1.0f / 60.0f;
}
GameManager::~GameManager()
{
}
void GameManager::InputControl()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
m_incVal = 1.0f;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
m_incVal = -1.0f;
}
}
void GameManager::UpdateScene()
{
if (m_deltaTime.asSeconds() >= m_frameRate)
{
m_posX += m_incVal;
m_shape.setPosition(m_posX, 300);
m_deltaTime -= sf::seconds(m_frameRate);
}
}
void GameManager::DrawScene()
{
m_window.StartDrawing();
m_window.Draw(m_shape);
m_window.EndDrawing();
}
void GameManager::RestartClock()
{
m_deltaTime += m_clock.restart();
}
bool GameManager::isFinished()
{
return m_window.isClosed();
}
It was perfectly working when i use window object, later i've changed to gamemanager it start being not responding.. I can get keyboard inputs but not mouse move coordinates. Where am i make it wrong?
#include <SFML/Graphics.hpp>
#include "GameManager.hpp"
#include "Window.hpp"
int main()
{
GameManager gameManager;
while (!gameManager.isFinished())
{
gameManager.InputControl();
gameManager.UpdateScene();
gameManager.DrawScene();
gameManager.RestartClock();
}
/*
sf::CircleShape shape(100.0f);
shape.setFillColor(sf::Color::Magenta);
shape.setOutlineThickness(5.0f);
shape.setOutlineColor(sf::Color::White);
Window window;
while (!window.isClosed())
{
window.EventControl();
window.StartDrawing();
window.Draw(shape);
window.EndDrawing();
}
*/
return 0;
}
In order to receive events (such as the mouse moving), you need to call pollEvents on the window.
In your commented code, you were doing this through your Window::EventControl() method. Your new GameManager class isn't calling this, however, so you aren't receiving any events.
Related
I have this error at my project with threads and I dont know how to solve it. I tryed std::thread and sf::Thread. Could someone help please?
Im creating Animation object inside main class and through function runThread() I am trying to launch thread inside the Animation class.
Error log:
Failed to activate the window's context
Failed to activate OpenGL context
My solution
Main class
int main()
{
bool launchThreads = true;
sf::RenderWindow window(sf::VideoMode( 800, 600), "Title" );
Animation* anima = new Animation(window);
sf::Event event;
while(window.isOpen())
{
while (window.pollEvent(event))
{
anima->handleEvent(event);
if (event.type == sf::Event::Closed)
{
delete anima;
anima = nullptr;
window.close();
}
}
window.clear(sf::Color::Black);
here I am trying to launch that thread:
if (launchThreads)
{
anima->runThread();
launchThreads = false;
}
window.display();
}
return 0;
}
Animation.h :
class Animation
{
private:
sf::RenderWindow& window;
sf::RectangleShape* rectPtr;
sf::Vector2f mousePos;
sf::Thread thread;
public:
Animation(sf::RenderWindow& window);
void handleEvent(sf::Event event);
void runThread();
void handleDraw();
~Animation();
};
and Animation.cpp :
Animation::Animation(sf::RenderWindow& window) : thread(&Animation::handleDraw, this), window(window),rectPtr(nullptr), mousePos()
{
//sf::Thread thea(&handleDraw);
//thread = thea;
rectPtr = new sf::RectangleShape;
rectPtr->setSize(sf::Vector2f(100, 100));
rectPtr->setFillColor(sf::Color::Red);
}
void Animation::handleEvent(sf::Event event)
{
switch (event.type)
{
case sf::Event::MouseMoved:
mousePos = window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x, event.mouseMove.y));
break;
}
}
void Animation::runThread()
{
thread.launch();
}
void Animation::handleDraw()
{
for (size_t i = 0; i < 10; i++)
{
rectPtr->setPosition(i*110, 10);
if (rectPtr->getGlobalBounds().contains(mousePos))
{
rectPtr->setFillColor(sf::Color::Yellow);
}
else rectPtr->setFillColor(sf::Color::Red);
window.draw(*rectPtr);
}
}
Animation::~Animation()
{
thread.terminate();
delete rectPtr;
rectPtr = nullptr;
}
Solution:
Solved with moving function window.display(); inside handleDraw() and moving context there too by window.setActive(); App shows what it have to. But inside console there are still same errors.. Think I can Ignore them.
I'm doing an assignment at the moment and for it, I need to drag chess pieces on a board, the problem is that I have no idea how to make this work for more than one piece. I can compute the mouse position and I've been able to move just one piece but the code only works for that single piece. My question is how do I click on a piece, have it become the active piece until I release the mouse button. This won't work if I only check if it intersects with one piece because it isn't dynamic then. My code is a mess from me trying different things but here are some of the relevant parts.
Here is the setup for the sprites:
// load the texture and setup the sprite for the logo
void Game::setupSprite()
{
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
if (!m_boardTexture.loadFromFile("ASSETS\\IMAGES\\board.png"))
{
// simple error message if previous call fails
std::cout << "problem loading board" << std::endl;
}
m_boardSprite.setTexture(m_boardTexture);
m_boardSprite.setPosition(0.0f, 0.0f);
//pieces
if (!m_wkingTex.loadFromFile("ASSETS\\IMAGES\\PIECES\\wking.png"))
{
// simple error message if previous call fails
std::cout << "problem loading piece" << std::endl;
}
m_wking.setTexture(m_wkingTex);
m_wking.setPosition(0.0f, 0.0f);
sf::IntRect wkingRect(pieceRect);
}
If the mouse button is down
void Game::processMouseButtonDown(sf::Event t_event)
{
if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
std::cout << "Mouse button pressed\n";
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
if (isSpriteClicked() && !m_holdingPiece) {
m_holdingPiece = true;
}
}
}
Mouse button is up:
void Game::processMouseButtonUp(sf::Event t_event)
{
m_holdingPiece = false;
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
m_wking.setTextureRect(pieceRect);
}
If the sprite is clicked
bool Game::isSpriteClicked()
{
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
sf::FloatRect bounds(mouse.x, mouse.y, 1.0f, 1.0f);
if (bounds.intersects(wkingRect.I dont know what Im doing)) {
std::cout << "King has Been clicked!\n";
return true;
}
else {
return false;
}
}
And finally to move the sprite:
void Game::move()
{
if (m_holdingPiece) {
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
m_wking.setPosition(mouse);
}
}
Sorry if that seems like a lot of code, but I feel like it was all relevant to the problem.
Problem:
You have hardcoded all your variables so even if you create a list and iterate over it to run Game::move() it will move all the pieces instead of only one because the variable m_holdingPiece is the same for all pieces.
Solution:
You should use a more OOP aproach creating a class for the chess pieces while the Game class should probably just control when the game starts, when it ends and check whether moves are legal or not. Explaning all that would be too broad Stack Overflow and it's part of the work you must do, so I will just let an example of how a basic chessPiece class would be to make pieces dragabble.
Example:
Here is an example of how you can make a group of pieces draggable.
#include <SFML/Graphics.hpp>
#include <string>
class chessPiece: public sf::Drawable, public sf::Transformable
{
private:
sf::RenderWindow& window;
sf::Texture texture;
sf::Sprite sprite;
bool moving;
public:
chessPiece(sf::RenderWindow& windowRef, const std::string& fileName): window(windowRef)
{
if(!texture.loadFromFile(fileName))
exit(0);
this->sprite.setTexture(this->texture);
this->moving = false;
this->sprite.setScale(128/this->sprite.getGlobalBounds().width,128/this->sprite.getGlobalBounds().height);
}
chessPiece(chessPiece&& rval): window(rval.window)
{
this->texture = std::move(rval.texture);
this->sprite.setTexture(this->texture);
this->sprite.setScale(rval.sprite.getScale());
this->moving = std::move(rval.moving);
}
chessPiece(const chessPiece& lval): window(lval.window)
{
this->texture = lval.texture;
this->sprite.setTexture(this->texture);
this->sprite.setScale(lval.sprite.getScale());
this->moving = lval.moving;
}
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= this->getTransform();
target.draw(this->sprite,states);
}
void move(bool& movingAPiece)
{
sf::Vector2f mousePosition = window.mapPixelToCoords(sf::Mouse::getPosition(window));
if(this->moving)
{
this->setPosition(mousePosition.x - this->sprite.getGlobalBounds().width/2,mousePosition.y - this->sprite.getGlobalBounds().height/2);
if(!sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
{
this->moving = false;
movingAPiece = false;
}
}
else
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && mousePosition.x > this->getPosition().x &&
mousePosition.y > this->getPosition().y && mousePosition.x < this->getPosition().x + this->sprite.getGlobalBounds().width &&
mousePosition.y < this->getPosition().y + this->sprite.getGlobalBounds().height && !movingAPiece)
{
this->moving = true;
movingAPiece = true;
}
}
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(1000,500),"Window");
std::vector<chessPiece> pieces = {chessPiece(window,"white-king.png"),chessPiece(window,"white-pawn.png")};
pieces[0].setPosition(400,400);
bool movingAPiece = false;
while(true)
{
sf::Event event;
if(window.pollEvent(event))
if(event.type == sf::Event::Closed)
window.close();
for(unsigned int i = 0; i < pieces.size(); i++)
pieces[i].move(movingAPiece);
window.clear();
for(unsigned int i = 0; i < pieces.size(); i++)
window.draw(pieces[i]);
window.display();
}
}
I am trying to storesf::RectangleShape's into thestd::vectorand then draw each of them into thesf::RenderWindow.
Single rectangle shape is representing 1x1 tetromino and i would like to store it into the vector each time it reaches the bottom of the window. Then I would like to reset the position of the current tetromino to the default position.
I think I'm not even to able store it correctly. Each time the tetromino reaches the bottom it gives me this error message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Bellow please find my current code. I just started working on it and already got stuck.
Definitions.h
#pragma once
// Point structure
struct Point
{
int dim_x;
int dim_y;
};
// Field Dimensions
const int fieldRows = 10;
const int fieldColumns = 9;
const int pointSize = 50.f;
// For checkingEdges funntion within the Tetrnomino.h
enum Edge
{
leftEdge,
rightEdge,
noneEdge
};
Game.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Definitions.h"
#include "Tetromino.h"
class Game
{
public:
Game();
~Game();
// Game starter
void run();
// Accessors
bool running();
private:
// Updating and rendering the game window
void update();
void render();
// Initialization
void initVariables();
void initWindow();
void initBacgroundMusic();
// Polling
void pollEvents();
// Window logic stuff
sf::RenderWindow* _window;
sf::Event _event;
void drawStack();
// Bacground Music
sf::Music _ost;
// Tetromino + Its logic
Tetromino _T;
sf::Time delayTime = sf::milliseconds(300);
sf::Clock clock;
};
Tetromino.h
#pragma once
#include <SFML/Graphics.hpp>
#include <vector>
#include "Definitions.h"
class Tetromino
{
public:
Tetromino();
~Tetromino();
// Initialization
void initTetromino();
// Tetromonino logic
void moveTetromino();
Edge checkEdges();
// Getters & Setters
sf::RectangleShape getTetromino();
sf::RectangleShape getStackPart(int part);
int getStackSize();
void setTetromino(sf::RectangleShape &t);
private:
// The current tetromino
sf::RectangleShape _tetromino;
std::vector<sf::RectangleShape> _stack;
};
Game.cpp
#include "Game.h"
//-----Consturcotrs and Destructors-----//
Game::Game()
{
//Basic Initialization
_T.initTetromino();
initVariables();
}
Game::~Game()
{
delete _window;
}
//-----Private Functions-----//
void Game::run()
{
update();
render();
}
bool Game::running()
{
return _window->isOpen();
}
void Game::update()
{
sf::Time elapsed = clock.getElapsedTime();
pollEvents();
if (elapsed >= delayTime)
{
_T.moveTetromino();
clock.restart();
}
}
void Game::render()
{
_window->clear(sf::Color::White);
_window->draw(_T.getTetromino());
drawStack();
_window->display();
}
void Game::initVariables()
{
_window = nullptr;
initWindow();
initBacgroundMusic();
}
void Game::initWindow()
{
_window = new sf::RenderWindow(sf::VideoMode(fieldColumns * pointSize, fieldRows * pointSize), "Tetris v0.2", sf::Style::Default);
_window->setVerticalSyncEnabled(true);
_window->setFramerateLimit(60);
}
void Game::initBacgroundMusic()
{
_ost.openFromFile("../QT_SFML_Tetris/Music.ogg");
_ost.play();
_ost.setLoop(true);
_ost.setVolume(50.f);
}
void Game::pollEvents()
{
while (_window->pollEvent(_event))
{
if (_event.type == sf::Event::Closed) {_window->close();}
if (_event.type == sf::Event::KeyPressed)
{
if (_event.key.code == sf::Keyboard::Escape){_window->close();}
if (_event.key.code == sf::Keyboard::Left && _T.checkEdges() != leftEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x - pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Right && _T.checkEdges() != rightEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x + pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Down)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x, t.getPosition().y+ pointSize);
_T.setTetromino(t);
render();
}
}
}
}
**void Game::drawStack()**
{
for (unsigned int i = _T.getStackSize(); i > 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}
main.cpp
#include <Game.h>
int main()
{
Game game;
while (game.running())
{
game.run();
}
return 0;
}
Tetromino.cpp
#include "Tetromino.h"
//-----Consturcotrs and Destructors-----//
Tetromino::Tetromino()
{
}
Tetromino::~Tetromino()
{
}
//-----Public Functions-----//
void Tetromino::initTetromino()
{
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
_tetromino.setSize(sf::Vector2f(pointSize, pointSize));
_tetromino.setFillColor(sf::Color::Red);
}
void Tetromino::moveTetromino()
{
_tetromino.move(0.f, pointSize);
if (_tetromino.getPosition().y > fieldRows * pointSize - pointSize)
{
_stack.push_back(_tetromino);
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
}
}
Edge Tetromino::checkEdges()
{
if (_tetromino.getPosition().x == 0)
{
return leftEdge;
}
else if (_tetromino.getPosition().x == (fieldColumns * pointSize) - pointSize)
{
return rightEdge;
}
else return noneEdge;
}
sf::RectangleShape Tetromino::getTetromino()
{
return _tetromino;
}
sf::RectangleShape Tetromino::getStackPart(int part)
{
return _stack[part];
}
int Tetromino::getStackSize()
{
return _stack.size();
}
void Tetromino::setTetromino(sf::RectangleShape &t)
{
_tetromino = t;
}
I think the main issue could be within this line:
_stack.push_back(_tetromino);
In the drawStack() method you try to iterate backwards.
There is a reverse iterator doing this for you.
you have an off-by one error in your index calculation, which works only with an empty vector (exactly to prevent these errors you should use the iterator!)
You may want to read about iterators in C++ here is a small example.
According to your code it will look like (note that you need also a getStack()-method in Tetromino.hpp, returning the reference of the vector):
void Game::drawStack()
{
for (auto it = _T.getStack().rbegin(); it != _T.getStack().rend(); it++)
{
_window->draw(*it);
}
}
If you want to keep the index, I this is a fix:
void Game::drawStack()
{
for (int i = _T.getStackSize()-1; i >= 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}
My problem is that the function don't do what I want.
This "CreateWindow" function has the main loop. In the main loop I want a fixed background and, every time I press the H button, I want to draw a Card (sprite) on the background.
What's the problem here? My function draw the cards but when I press H the previous card is deleted and the next card is drawn.
This is something about the event I think, because every time an event happens (I move the mouse, I press an other key etc) the previous card is deleted...
I'm using sfml 2.0
Here is my implementation of the Graphic class
#include "Graphic.h"
#include "SFML/Graphics.hpp"
#include <iostream>
#include <string>
#include "Card.h"
#include <string>
#include <sstream>
Graphic::Graphic(int offset)
{
this->offset = offset;
}
Graphic::~Graphic()
{
//dtor
}
int Graphic::CreateWindow(sf::RenderWindow& window, Deck &deck0)
{
sf::Vector2i screenDimensions(800, 600);
//Dimensioni della window
window.create(sf::VideoMode(screenDimensions.x, screenDimensions.y), "BlackJack", sf::Style::Titlebar | sf::Style::Close);
int index = 0;
window.setKeyRepeatEnabled(false);
//settare il background
sf::Texture bTexture;
sf::Sprite bImage;
if(!bTexture.loadFromFile("Background.png"))
std::cout << "Error" << std::endl;
bImage.setTexture(bTexture);
bImage.setScale(1.0, (float)screenDimensions.y / bTexture.getSize().y);
//MAIN LOOP----------------------
while(window.isOpen())
{
sf::Event Event;
while(window.pollEvent(Event))
{
window.clear();
window.draw(bImage); // this is the function which draw the background
if (Event.type == sf::Event::Closed)
{
window.close();
}
if(Event.key.code == sf::Keyboard::H)
{
Card * y = deck0.dealFirst();
drawCard(window,y->graphNumber,y->getSeed(),offset);
offset = offset + 50;
}
window.display();
}
}
}
int Graphic::drawCard(sf::RenderWindow &window, int graphNumber, string seed, int offset)
{
std::ostringstream oss;
oss << graphNumber << seed << ".png";
std::string var = oss.str();
sf::Texture QHTexture;
sf::Sprite QHImage;
if(!QHTexture.loadFromFile(var))
std::cout<< "Error" <<std::endl;
QHImage.setTexture(QHTexture);
QHImage.setScale(0.5, 0.5);
QHImage.setPosition(offset + 100, 400);
window.draw(QHImage); //this is the function which draw the card's sprite
return 0;
}
Alright you shouldn't be drawing inside of your while(window.pollEvent()) loop, you should be drawing something like this:
while(window.isOpen())
{
sf::Event Event;
while(window.pollEvent(Event))
{
if (Event.type == sf::Event::Closed)
{
window.close();
}
if(Event.key.code == sf::Keyboard::H)
{
Card * y = deck0.dealFirst();
drawCard(window,y->graphNumber,y->getSeed(),offset);
offset = offset + 50;
}
}
window.clear();
window.draw(bImage); // this is the function which draw the background
window.display();
}
The way you were drawing your draw call will only happen if there is an SFML event, and will only ever clear if there is an sfml event(Which is ok if you dont want it to constantly render every frame... and aren't planning any kind of animations...).
So when you hit H an sfml event was being triggers that called your draw card function, however since your card is a local variable to the function you wrote, at the end of the function it is cleared out. You need to store your cards somewhere, such as a vector or list of sf::Sprite. So an example would be:
#include "Graphic.h"
#include "SFML/Graphics.hpp"
#include <iostream>
#include <string>
#include "Card.h"
#include <string>
#include <sstream>
Graphic::Graphic(int offset)
{
this->offset = offset;
}
Graphic::~Graphic()
{
//dtor
}
int Graphic::CreateWindow(sf::RenderWindow& window, Deck &deck0)
{
sf::Vector2i screenDimensions(800, 600);
//Dimensioni della window
window.create(sf::VideoMode(screenDimensions.x, screenDimensions.y), "BlackJack", sf::Style::Titlebar | sf::Style::Close);
int index = 0;
window.setKeyRepeatEnabled(false);
//settare il background
sf::Texture bTexture;
sf::Sprite bImage;
if(!bTexture.loadFromFile("Background.png"))
std::cout << "Error" << std::endl;
bImage.setTexture(bTexture);
bImage.setScale(1.0, (float)screenDimensions.y / bTexture.getSize().y);
//MAIN LOOP----------------------
while(window.isOpen())
{
sf::Event Event;
while(window.pollEvent(Event))
{
if (Event.type == sf::Event::Closed)
{
window.close();
}
if(Event.key.code == sf::Keyboard::H)
{
Card * y = deck0.dealFirst();
drawCard(window,y->graphNumber,y->getSeed(),offset);
offset = offset + 50;
}
}
window.clear();
window.draw(bImage); // this is the function which draw the background
for(int i = 0; i < cardList.size(); ++i)
{
window.draw(cardList[i]);
}
window.display();
}
}
int Graphic::drawCard(sf::RenderWindow &window, int graphNumber, string seed, int offset)
{
std::ostringstream oss;
oss << graphNumber << seed << ".png";
std::string var = oss.str();
sf::Texture QHTexture;
sf::Sprite QHImage;
if(!QHTexture.loadFromFile(var))
std::cout<< "Error" <<std::endl;
QHImage.setTexture(QHTexture);
QHImage.setScale(0.5, 0.5);
QHImage.setPosition(offset + 100, 400);
cardList.push_back(QHImage); //this adds the sprite to our list
return 0;
}
I was taking up the challenge of creating a program to use for graphing simple math equations using C++ and the SFML 2.3.2. graphics library, and I've got the graph paper texture rendering fine. However, the problem I've had is getting it to repeat itself as I scroll around.
I was using sf::View to get it to pan, and it works well, but as soon as it pans outside the pre-defined size of the sprite it's just a blank background.
I thought of trying to determine when I'm outside the bounds of the sprite, and then expanding the size of the sprite or moving it, but then drawings (such as a graph) won't persist if the sprite is changed/reset.
What I need to know is how to create a background of a texture, in this case graphing paper, that will tile/repeat in every direction, and allow drawings to be made on top of it that persist if they move off screen.
Code is below:
GraphPaper.h:
#pragma once
#include "stdafx.h"
class GraphPaper
{
public:
GraphPaper();
~GraphPaper();
bool isObjectLoaded();
sf::Sprite getSprite();
private:
void load(std::string filename);
bool isLoaded;
sf::Texture texture;
sf::Sprite sprite;
const std::string file = "images/Graph-Paper.png";
};
GraphPaper.cpp: This is where I create and load the needed sprite and texture.
I set the texture to repeat inside the "load(string filename)" method, but that only affects it within the bounds set by the sprite's rectangle.
#include "GraphPaper.h"
GraphPaper::GraphPaper() : isLoaded(false)
{
load(file);
assert(isObjectLoaded());
}
GraphPaper::~GraphPaper() {};
void GraphPaper::load(std::string filename)
{
if (texture.loadFromFile(filename) == false)
isLoaded = false;
else
{
texture.setRepeated(true);
sprite.setTexture(texture);
//Huge size to at least make it look like it's infinite,
//but a temporary solution.
sprite.setTextureRect(sf::IntRect(0,0,10000,10000));
isLoaded = true;
}
}
bool GraphPaper::isObjectLoaded()
{
return isLoaded;
}
sf::Sprite GraphPaper::getSprite()
{
return sprite;
}
MainWindow.h:
#pragma once
#include "GraphPaper.h"
#include "stdafx.h"
class MainWindow
{
public:
void close();
void start();
void moveCamera(sf::Event);
private:
bool leftMousePressed, rightMousePressed, isExiting;
int r, g, b, mouseX, mouseY;
GraphPaper paper;
const sf::Color white = sf::Color(255, 255, 255);
sf::RenderWindow mainWindow;
sf::View view;
};
MainWindow.cpp: This is what handles all the drawing, and, at the moment, all input processing. "start()" is simply called from the main method.
#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"
void MainWindow::start()
{
sf::RectangleShape rectangle = sf::RectangleShape(sf::Vector2f(120, 50));
rectangle.setFillColor(sf::Color(0,0,0));
mainWindow.create(sf::VideoMode(1024, 768, 32), "Test");
sf::View view(sf::FloatRect(0,0,1000,600));
mainWindow.setView(view);
leftMousePressed, rightMousePressed, isExiting = false;
sf::Event currentEvent;
mainWindow.clear(white);
mainWindow.draw(paper.getSprite());
mainWindow.display();
while (!isExiting)
{
while (mainWindow.pollEvent(currentEvent))
{
switch (currentEvent.type)
{
case sf::Event::MouseMoved:
{
if (rightMousePressed == true)
{
std::cout << "Mouse Panned\n";
}
if (leftMousePressed == true)
{
std::cout << "Mouse is Drawing\n";
}
break;
}
case sf::Event::MouseButtonPressed:
{
std::cout << "Mouse Pressed\n";
mouseX = currentEvent.mouseButton.x;
mouseY = currentEvent.mouseButton.y;
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
leftMousePressed = true;
}
else if (currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = true;
}
break;
}
case sf::Event::MouseButtonReleased:
{
std::cout << "Mouse Released\n";
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
leftMousePressed = false;
}
else if(currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = false;
}
break;
}
case sf::Event::KeyPressed:
{
if (currentEvent.key.code == sf::Keyboard::Escape)
{
close();
}
//No right movement yet, was testing.
else if (currentEvent.key.code == sf::Keyboard::Left)
{
moveCamera(currentEvent);
}
break;
}
case sf::Event::Closed:
{
close();
break;
}
}
}
}
}
void MainWindow::moveCamera(sf::Event key)
{
std::cout << "Inside moveCamera\n";
//No right movement yet, was testing.
//Movement is also hardcoded for testing as well.
view.move(100, 0);
mainWindow.setView(view);
mainWindow.clear(white);
mainWindow.draw(paper.getSprite());
mainWindow.display();
std::cout << "Leaving moveCamera\n";
}
void draw()
{
//mainWindow.draw();
}
void MainWindow::close()
{
std::cout << "Closing...\n";
mainWindow.close();
isExiting = true;
}