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;
}
Related
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.
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();
}
}
Model class
class spaceshipModel {
private:
Vector2f position;
float speed, acceleration, energy, fuel;
public:
//Contructor
spaceshipModel() : position(0, 0), speed(0), acceleration(0), energy(0), fuel(0) {}
//Destructor
~spaceshipModel() {}
//Sets
void setPosition(float _x, float _y) { position.x = _x; position.y = _y; }
void setSpeed(float _speed) { speed = _speed; }
void setAcceleration(float _acceleration) { acceleration = _acceleration; }
void setEnergy(float _energy) { energy = _energy; }
void setFuel(float _fuel) { fuel = _fuel; }
//Gets
Vector2f getPosition() { return position; }
float getSpeed() { return speed; }
float getAcceleration() { return acceleration; }
float getEnergy() { return energy; }
float getFuel() { return fuel; }
};
View class
class spaceshipView {
private:
Texture* image;
Sprite sprite;
spaceshipModel model;
public:
//Constructor
spaceshipView() : image(0) {}
//Destructor
~spaceshipView() {}
//Setting the image
void setImage(Texture* _image) { image = _image; }
//Drawing the image
void drawImage(RenderWindow* _window) {
sprite.setTexture(*image);
sprite.setPosition(model.getPosition());
sprite.setScale(Vector2f(0.2f, 0.2f));
_window->draw(sprite);
_window->display();
}
};
Main
A left a lot of the code out, but I then call this in main:
int main() {
//Call instance of the Spaceship model
spaceshipModel shipModel;
//Call instance of the Spaceship view
spaceshipView shipView;
//Create the texture of the spaceship from file
Texture spaceship;
spaceship.loadFromFile("spaceship.png");
//Create the window
RenderWindow window(VideoMode(800, 600), "Spaceship with MVC");
//Run the program as long as the window is open
while (window.isOpen()) {
//Check all the window's events that were triggered since the last iteration of the loop
Event event;
while (window.pollEvent(event)) {
//"Close requested" event: we close the window
switch (event.type) {
//Window closed by pressing the X
case Event::Closed:
window.close();
break;
//Checking for key pressed event
case Event::KeyPressed:
//Pressing esc to close the window
if (event.key.code == Keyboard::Escape) {
window.close();
}
break;
//We don't process other types of events
default:
break;
}
//Clear screen with white BG
window.clear(Color::White);
//TESTING THE SETTING OF THE POSITION
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
shipModel.setPosition(100, 100);
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
//Set and draw the image
shipView.setImage(&spaceship);
shipView.drawImage(&window);
}
}
return 0;
}
The spaceship draws perfectly, but is only set at (0, 0). Even when setting the position to (100, 100) like it shows above. The image stays at (0, 0). As I'm using the getPosition function from the Model class in the View class, I don't think the data is being updated correctly, even when the cout test does show a change.
What am I doing wrong? Can someone give me some pointers?
In the code snippet above, shipModel object from main() and shipView.model are two distinct objects. You can either let your shipView be aware of the model using a setter in spaceshipView, or call shipView.model's methods directly.
I am trying to write a program which allows users to draw using the mouse. I have been trying many different ways to appropriately update the display using an object of sf::RenderWindow to call display() without much success. My loop where the drawing is occurring is calling display so fast it's causing massive flickering (confirmed that through testing). If I add a way to slow the call to display(), like using sf::Clock, then the drawing is only updated on the same delay as display() resulting in a stuttering effect. What I need is a way to update the display often enough to show drawing updates while also not causing a screen flicker.
Currently, I've got the display on a delay (at the bottom of the event polling switch statement) so flickering doesn't occur, but adding mainWindow.display(); to the void MainWindow::draw() function causes flickering as it updates too quickly. I had the drawing occurring on sf::Event::MouseMoved, but I tried changing it to see if that would help, and it did not.
Here's where all the drawing and event detection occurs:
MainWindow.h
#pragma once
#include "GraphPaper.h"
#include "stdafx.h"
class MainWindow
{
public:
MainWindow(short, short);
void close();
void start();
void moveCamera(sf::Keyboard::Key);
void draw(sf::Event);
void displayWindow(sf::Vector2i&);
private:
bool leftMousePressed, rightMousePressed, isExiting;
int r, g, b, mouseX, mouseY;
short height, width;
const short DRAWING_CRICLE_RADIUS = 10;
GraphPaper paper;
//DrawingBrush brush;
const sf::Color WHITE = sf::Color(255, 255, 255);
const sf::Color BLACK = sf::Color(0, 0, 0);
sf::CircleShape circle;
sf::Mouse cursor;
sf::Vector2i windowCenter;
sf::RenderWindow mainWindow;
sf::View view;
};
MainWindow.cpp:
#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"
MainWindow::MainWindow(short height, short width)
{
this->height = height;
this->width = width;
circle.setRadius(DRAWING_CRICLE_RADIUS);
circle.setFillColor(BLACK);
}
void MainWindow::start()
{
sf::Clock clock;
mainWindow.create(sf::VideoMode(height, width, 32), "Test");
sf::View view(sf::FloatRect(0,0,height,width));
mainWindow.setView(view);
leftMousePressed, rightMousePressed, isExiting = false;
sf::Event currentEvent;
sf::Vector2i windowCenter(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
while (!isExiting)
{
sf::Clock clock;
while (mainWindow.pollEvent(currentEvent))
{
switch (currentEvent.type)
{
case sf::Event::MouseMoved:
{
if (rightMousePressed == true)
{
std::cout << "Mouse Panned\n";
}
if (leftMousePressed == true)
{
draw(currentEvent);
}
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)
{
while (currentEvent.type != sf::Event::MouseButtonReleased)
{
std::cout << "Mouse is Drawing\n";
draw(currentEvent);
mainWindow.pollEvent(currentEvent);
}
}
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:
{
sf::Keyboard::Key keyPressed = currentEvent.key.code;
if(keyPressed == sf::Keyboard::Escape)
{
close();
}
else if(keyPressed == sf::Keyboard::Left || sf::Keyboard::Right ||
sf::Keyboard::Down || sf::Keyboard::Up ||
sf::Keyboard::A || sf::Keyboard::S ||
sf::Keyboard::D || sf::Keyboard::W)
{
moveCamera(keyPressed);
displayWindow(windowCenter);
}
break;
}
case sf::Event::Closed:
{
close();
break;
}
case sf::Event::Resized:
{
windowCenter = sf::Vector2i(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
break;
}
}
if (clock.getElapsedTime().asMilliseconds() >= 500)
{
clock.restart();
mainWindow.display();
}
}
}
}
void MainWindow::moveCamera(sf::Keyboard::Key keyPressed)
{
view = mainWindow.getView();
switch (keyPressed)
{
case sf::Keyboard::A:
case sf::Keyboard::Left:
{
view.move(-50, 0);
break;
}
case sf::Keyboard::D:
case sf::Keyboard::Right:
{
view.move(50, 0);
break;
}
case sf::Keyboard::W:
case sf::Keyboard::Up:
{
view.move(0, 50);
break;
}
case sf::Keyboard::S:
case sf::Keyboard::Down:
{
view.move(0, -50);
break;
}
}
mainWindow.setView(view);
}
void MainWindow::draw(sf::Event mouse)
{
circle.setPosition(mainWindow.mapPixelToCoords(sf::Vector2i(mouse.mouseMove.x, mouse.mouseMove.y)));
mainWindow.draw(circle);
}
void MainWindow::close()
{
std::cout << "Closing...\n";
mainWindow.close();
isExiting = true;
}
void MainWindow::displayWindow(sf::Vector2i& windowCenter)
{
mainWindow.clear(WHITE);
mainWindow.draw(paper.getSprite());
mainWindow.display();
cursor.setPosition(windowCenter);
}
You are missing an important part of the rendering loop. You should draw all parts every loop iteration. Right now you are only drawing your circle when it's changed.
Your code should look like this:
change circle position based on input
clear window
draw circle
display
In the following code a sprite can by clicked with left mouse button and then moved around freely. Then you have to hit the right button to "free" it again.
Now what is, if I want to use left button for removing the focus, instead of right button. Is this possible and how? I can't imagine, how to do it. Many thanks in advance.
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
int main()
{
sf::RenderWindow mMainWindow(sf::VideoMode(600,600), "Map", sf::Style::Close);
mMainWindow.setFramerateLimit(60);
mMainWindow.setKeyRepeatEnabled(false);
sf::Image image;
image.create(50, 50, sf::Color::Red);
sf::Texture texture;
texture.loadFromImage(image);
std::vector<sf::Sprite> EnemyVector;
sf::Sprite* focus = nullptr;
bool move = false;
while (mMainWindow.isOpen())
{
sf::Event event;
bool creating = false;
bool leftclicked = false;
bool rightclicked = false;
sf::Vector2i mousePos;
while (mMainWindow.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
mMainWindow.close();
break;
case sf::Event::KeyPressed:
creating = (event.key.code == sf::Keyboard::A);
break;
case sf::Event::MouseButtonPressed:
if (event.mouseButton.button == sf::Mouse::Left)
{
leftclicked = true;
mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
break;
}
if (event.mouseButton.button == sf::Mouse::Right)
{
rightclicked = true;
mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
break;
}
}
}
if (creating)
{
sf::Sprite sprite;
mousePos = (mousePos == sf::Vector2i(0, 0) ? sf::Mouse::getPosition(mMainWindow) : mousePos);
sprite.setTexture(texture);
sprite.setColor(sf::Color::Red);
sprite.setOrigin(static_cast<float>(sprite.getTextureRect().width) / 2, static_cast<float>(sprite.getTextureRect().height) / 2);
sprite.setPosition(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y));
focus=nullptr;
EnemyVector.push_back(sprite);
}
if (leftclicked)
{
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
if (enemy->getGlobalBounds().contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
{
focus = &(*enemy);
move = true;
break;
}
}
}
if(rightclicked)
{
focus = nullptr;
}
if(move)
{
if(focus!=nullptr)
{
focus->move((sf::Mouse::getPosition(mMainWindow).x - focus->getPosition().x),(sf::Mouse::getPosition(mMainWindow).y - focus->getPosition().y));
}
}
mMainWindow.clear();
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
mMainWindow.draw(*enemy);
}
mMainWindow.display();
}
return 0;
}
try this
if (leftclicked)
{
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
if (enemy->getGlobalBounds().contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
{
focus = &(*enemy);
move = !move;
break;
}
}
}