SFML Touch position is not correct - c++

I am testing a touch in sfml on android using app called cxx droid. My code set's the RectangleShape where i press. But even when i make the position relative to window its not relative to it. I touch in place shape's pos in another place!
My Code :
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
Font font;
int main() {
font.loadFromFile("font.otf");
RenderWindow window(VideoMode(500,700),"My window",Style::Titlebar | Style::Close);
window.setFramerateLimit(60);
RectangleShape shape(Vector2f(300,40));
while(window.isOpen()) {
window.setView(window.getDefaultView());
Event event;
while(window.pollEvent(event)) {
if(event.type == event.Closed) {
window.close();
}
}
if(Touch::isDown(0)) {
shape.setPosition(Touch::getPosition(0,window).x,Touch::getPosition(0,window).y);
}
window.clear(Color::Green);
window.draw(shape);
window.display();
}
return 0;
}

If the top left corner of the shape is at the position you touch on screen then it is correct but you need to set the origin of the shape to the center of the shape.

a few weeks i had the samd problem
Your Rectangle needs a FloatRect
sf::FloatRect shapeRect = shape.getGlobalBounds;
Then you have to use mapPixelToCoords in the while(window.isOpen()); loop
sf::Vector2i pixelPos = sf::Touch::getPosition(0, window);
sf::Vector2f worldPos = window.mapPixelToCoords(pixelPos);
Then you use both things with contains
if(shapeRect.contains(worlPos))
{
// type your stuff in
}
Now the Touch have to work only in the Shape, hope this help you

Related

button in cpp sfml lib don't respond to my mouse input

I have to make Quarto game as a GUI program so firstly I wanted to make buttons in menu, but I don't know why it don't fill color when my mouse is at the button.
Code:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include<bits/stdc++.h>
using namespace std;
using namespace sf;
class button{
public:
bool isClicked=false;
int Yposition;
int Xposition;
bool isMouseOn=false;
};
int main(){
//Defining variables
Vector2i mouseWindowPosition;
//rendering window "window"
RenderWindow window(VideoMode(800,600), "Quarto game - menu", Style::Default);
window.display();
//setting vsync
window.setVerticalSyncEnabled(true);
//loading textures
Texture backgroundTexture;
backgroundTexture.loadFromFile("Resources/background.png");
//making sprites
Sprite backgroundSprite;
backgroundSprite.setTexture(backgroundTexture);
backgroundSprite.setPosition(0,0);
//making buttons and their colors
RectangleShape playButton(Vector2f(200.f,50.f));
playButton.setFillColor(Color(128,128,128));
playButton.setOutlineThickness(5.f);
playButton.setOutlineColor(Color(100,100,100));
button play;
//setting position of buttons
play.Xposition=70;
play.Yposition=200;
//game loop
while(window.isOpen()){
Event event;
playButton.setFillColor(Color(128,128,128));
play.isMouseOn=false;
while(window.pollEvent(event)){
if(event.type==Event::Closed){
window.close();
}
}
//Getting mouse position
mouseWindowPosition=Mouse::getPosition(window);
if(mouseWindowPosition.x<=play.Xposition && mouseWindowPosition.y<=play.Yposition && mouseWindowPosition.x>=play.Xposition+200 && mouseWindowPosition.y>=play.Yposition+50){
play.isMouseOn=true;
}
//Drawing to screen
window.clear();
window.draw(backgroundSprite);
if(play.isClicked==false){
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
}
if(play.isMouseOn==true){
playButton.setFillColor(Color(128,128,128));
}
window.display();
}
}
Is there any better way to make buttons in sfml?
The immediate reason why the button doesn't fill is your if the statement has the signs reversed for checking the box. Using this if statement instead should work:
//Getting mouse position
mouseWindowPosition=Mouse::getPosition(window);
if (mouseWindowPosition.x>=play.Xposition && mouseWindowPosition.y>=play.Yposition &&
mouseWindowPosition.x<=play.Xposition+200 && mouseWindowPosition.y<=play.Yposition+50){
//your code here
}
If you are not already aware, the x and y values are arranged like a table where positive y goes down instead of a cartesian coordinate system where positive y is up.
The other problem is the color you are updating your fill with is the same color of the fill, so changing that color will get you your desired fill.
Also, logic wise you should swap the statement
if (play.isMouseOn == true)
{
}
with the statement
if (play.isClicked == false)
{
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
window.display();
}
Here is a working code that changes the fill from grey to red when you hover above it:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
using namespace std;
using namespace sf;
class button
{
public:
bool isClicked = false;
int Yposition;
int Xposition;
bool isMouseOn = false;
};
int main()
{
//Defining variables
Vector2i mouseWindowPosition;
//rendering window "window"
RenderWindow window(VideoMode(800, 600), "Quarto game - menu", Style::Default);
window.display();
//setting vsync
window.setVerticalSyncEnabled(true);
//loading textures
Texture backgroundTexture;
backgroundTexture.loadFromFile("Resources/background.png");
//making sprites
Sprite backgroundSprite;
backgroundSprite.setTexture(backgroundTexture);
backgroundSprite.setPosition(0, 0);
//making buttons and their colors
RectangleShape playButton(Vector2f(200.f, 50.f));
playButton.setFillColor(Color(100, 100, 100));
playButton.setOutlineThickness(5.f);
playButton.setOutlineColor(Color(100, 100, 100));
button play;
//setting position of buttons
play.Xposition = 70;
play.Yposition = 200;
//game loop
while (window.isOpen())
{
Event event;
playButton.setFillColor(Color(128, 128, 128));
play.isMouseOn = false;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
{
window.close();
}
}
//Getting mouse position
mouseWindowPosition = Mouse::getPosition(window);
if (mouseWindowPosition.x >= play.Xposition && mouseWindowPosition.y >= play.Yposition && mouseWindowPosition.x <= play.Xposition + 200 && mouseWindowPosition.y <= play.Yposition + 50)
{
play.isMouseOn = true;
}
//Drawing to screen
window.clear();
window.draw(backgroundSprite);
if (play.isMouseOn == true)
{
playButton.setFillColor(Color(128, 0, 0));
}
if (play.isClicked == false)
{
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
window.display();
}
}
}

Falling sand simulation collision detection C++ and SFML

I could really use some help. I am trying to make a falling sand simulation and have some basic code down, but I can't figure how to do collision detection. Here is my code so far:
//SFML Include
#include <SFML/Graphics.hpp>
//Include Vectors
#include <vector>
//Main Loop
int main()
{
//Window Init
sf::RenderWindow window(sf::VideoMode(720, 480, 32), "Yip Yip Physics", sf::Style::Default);
//Global Envoirmental Variables
static float gravity = 0.25;
static float frict = 3;
//Particle Structures
struct Particle
{
//Shape
sf::RectangleShape rect;
//Cell Position
sf::Vector2f cell_pos;
//Vel and frict
float slide_vel = 3;
float grv_vel = 0;
//Init Particle (size, color and origin)
void init()
{
rect.setSize(sf::Vector2f(3, 3));
rect.setFillColor(sf::Color::Green);
rect.setOrigin(rect.getSize());
}
};
//Particle Setup
std::vector<Particle> particles;
//Window Loop
while (window.isOpen())
{
//Update
if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
{
//Make and Position Particle
Particle part;
part.rect.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
//Initalize the Particle and add to vector
part.init();
particles.push_back(part);
}
//Pixel Update
for (auto& p : particles)
{
//Draw in window
window.draw(p.rect);
}
//Display
window.display();
//Event Variable
sf::Event event;
//Window Event System
while (window.pollEvent(event))
{
//Close Window
if (event.type == sf::Event::Closed)
{
window.close();
}
}
//Window Clear
window.clear(sf::Color::Black);
}
//Return 0
return 0;
}
The code works in making the particles, putting them in a vector and drawing them to the screen, but I don't know where to go for collision. I don't know where to look and would really appreciate help on it or direction on where to find it. I have heard a bit about cellular automata but have no idea how to do it or if it's the best option.

Can't load image with SFML

Am trying to load an image with SFML using Xcode, but everytime I run the program, the window (which has been created using the code) flashes and disappears...
Here's the code I am using:
#include <SFML/Graphics.hpp>
#include <iostream>
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 1024
int main()
{
sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Orsome Game");
while(window.isOpen())
{
sf::Event e;
while(window.pollEvent(e))
{
switch (e.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
sf::Image image;
if(!image.loadFromFile("sprite.png")){
return -1;
}
window.clear(sf::Color(255,255,255));
window.display();
}
return EXIT_SUCCESS;
}
Have also put the image file where the c++ file is, but it still doesn't work!
I would put an sf::Style::Default in the RenderWindow arguments, straight after "Orsome Game" window name. Because you are using the pollEvent, that would allow you to exit the window by pressing the x button in the top right corner, like a default application layout.
Is the picture in the same directory as your solution file? Or your main.cpp?
It should be, of course.
And, maybe, try loading your image with Texture and Sprite, like this:
sf::Texture texture;
texture.loadFromFile("picturename.png");
sf::Sprite sprite;
sprite.setTexture(texture);
inside the while window is open loop.
To draw it:
// after window.clear() ...
//... your code
window.draw(sprite);
//... other things to draw
// and then, your window.display();
But, probably, your sf::Image should also work. Tell me how it goes
EDIT:
Try this code and see if the window opens.
Otherwise, that might be the problem of setting up the SFML on your computer and you will have to find some good tutorial on how to set it up properly! But let's see:
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(640, 640), "Test", Style::Default);
while (window.isOpen()) {
Event _event;
while (window.pollEvent(_event)) {
switch (_event.type) {
case Event::Closed:
window.close();
break;
}
}
window.clear();
// draw
// ...
window.display();
}
return 0;
}

SFML animation without keyboard input

I'm working on a project at the moment which is basically a visualisation of Sort algorithms to explain how they work (rather than an overview). I'm new to using the SFML (or even OpenGL) and have limited experience with the library, but what I'm trying to do is move the drawn sprite to different locations to show the sorting. I've looked over tutorials and examples, but they all take in keyboard input to move the sprite - something that isn't used in this project. Does anyone know exactly how to achieve this?
Here's the current code:
DrawCups.h
class DrawCups
{
public:
DrawCups(sf::RenderWindow& window);
~DrawCups();
void loadImage(const char* pathname, sf::Texture& texture, sf::Sprite& sprite);
void drawCup1();
private:
sf::RenderWindow& _window;
};
DrawCups.cpp (selected function)
void DrawCups::drawCup1()
{
// load our image
sf::Texture cup1; // the texture which will contain our pixel data
sf::Sprite cup1Sprite; // the sprite which will actually draw it
loadImage("./images/InsertionSort/red_cup_1.png", cup1, cup1Sprite);
cup1Sprite.setPosition(sf::Vector2f(150, 230));
_window.draw(cup1Sprite);
}
main.cpp
int main()
{
sf::RenderWindow window(sf::VideoMode(1366, 768), "Sorting Algorithm Visualisation: SFML");
window.setFramerateLimit(60);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color::White);
DrawCups drawToWindow(window);;
drawToWindow.drawCup1();
window.display();
}
return 0;
}
Create the image before the loop and update it before you draw it.
DrawCups drawToWindow(window); //Constructor creates the sprite
while (window.isOpen())
{
...
drawToWindow.update(); //Update the position
//Redraw
window.clear(sf::Color::White);
drawToWindow.drawCup1();
window.display();
}
I'm not sure what type of movement you want but the update function can be something like this:
void DrawCups::update()
{
sf::Vector2f pos = this->cup1Sprite.getPosition();
pos.x++; //Move 1 pixel to the left
this->cup1Sprite.setPosition(pos);
}
Obviously change the movement to suit your needs. Make smaller/larger updates if it's moving too fast or slow.

Mouse input isn't correct to world coordinates

There are probably millions of these questions but, I can't get the coordinates of the mouse so that they line up with the program coordinate system, when the window is re-sized. I've tried mapPixelToCoords() and getting the mouse coordinates using sf::Event::MouseButton or sf::Mouse, but to no avail.
This problem is most likely from my incompetence, but I can't figure it out for the life of me. Also, I need to do this to change the coordinates of a rectangle, not detecting whether a box is being hovered over, if it was the answer would be a lot easier to figure out I feel.
Edit:
Source Code:
//Standard C++:
#include <iostream>
//SFML:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Example");
sf::Event event;
sf::RectangleShape mousePoint;
mousePoint.setSize(sf::Vector2f(1, 1));
mousePoint.setFillColor(sf::Color::Red);
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) //Close window
{
window.close();
return 0;
}
if (event.type == sf::Event::MouseButtonPressed)
{
if (event.mouseButton.button == sf::Mouse::Left)
{
//Get the mouse position:
sf::Vector2i mouse = sf::Mouse::getPosition(window);
//Map Pixel to Coords:
window.mapPixelToCoords(mouse);
//Set position of the mouse to the rectangle:
mousePoint.setPosition(mouse.x, mouse.y);
}
}
}
window.clear();
window.draw(mousePoint);
window.display();
}
}
After some doubt, I have uploaded some simple source code, which demonstrates my point. When you click the LMB, it moves the rectangle to where the program thinks the mouse is. When the screen hasn't been scaled, it is correctly calibrated, but when it is changed, the rectangle moves to a point which is no where near where the mouse is.
As shown in the official documentation and the official tutorial section of SFML, you can use the mapPixelToCoords function to map pixel/screen coordinates to world coordinates.
The signature of the function is as following:
Vector2f sf::RenderTarget::mapPixelToCoords(const Vector2i& point) const
As such the usage would look something like that:
//Get the mouse position:
sf::Vector2i mouse = sf::Mouse::getPosition(window);
//Map Pixel to Coords:
sf::Vecotr2f mouse_world = window.mapPixelToCoords(mouse);
//Set position of the mouse to the rectangle:
mousePoint.setPosition(mouse_world);
In other words, the mapPixelToCoords function, takes a const sf::Vector2i& as parameter and returns a sf::Vector2f and the original vector is not being modified.
It's always recommended to take a closer look at the documentation if something doesn't work as expected.