SFML:Problem with displaying 2 Rectangles - c++

I want create light blue background so I draw 2 rectangles (blue and white).
But when I execute program i see only black screen.Also my video adapter is fully loaded.
Code:
int main() {
srand(time(NULL));
RenderWindow window(sf::VideoMode(500, 500), "Fish!",sf::Style::Close|sf::Style::Resize);
RectangleShape water(Vector2f(500,500));
RectangleShape background(Vector2f(500,500));
background.setFillColor(Color(255,255,255,3));
water.setFillColor(Color(5,45,255,1));
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case (sf::Event::Resized):
break;
case (sf::Event::Closed):
window.close();
break;
}
}
window.clear();
window.draw(background);
window.draw(water);
window.display();
}
I need window.clear function because i want insert some object later on the screen!

Related

How to "set the origin" of a Transform in sfml

I have a problem using sfml where it seems sf::Transforms get applied relative to the origin of whole coordinate system and not the origin of the sprite/thing being transformed.
For example in the two following example I expect the same behavior and it's not what happens.
(differences in bold, most of rest just serves to actually display a sfml window with a circle that gets scaled down when space is pressed)
First Example : here the circle is scaled down towards the top left corner of the window
#include &ltSFML/Graphics.hpp&gt
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 800), "Example");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
shape.setPosition(400, 400);
sf::Transform t;
t.scale( 9/10.f , 9/10.f);
sf::Transform t_n;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){
window.close();
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) {
t_n = t_n * t;
}
}
}
window.clear();
window.draw(shape, t_n);
window.display();
}
return 0;
}
Second Example : Here the circle is scaled down towards the top left corner of its bounding box : this is the kind of behavior I want to achieve but using Transforms
#include &ltSFML/Graphics.hpp&gt
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 800), "Example");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
shape.setPosition(400, 400);
// no Transforms need declaring
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){
window.close();
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) {
shape.scale(9/10.f, 9/10.f);
}
}
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
note: this is a possible duplicate of Transformations igrnores sf::Sprite's origin , but the only answer to this thread is my own, and the solution I suggest is really not ideal.

SFML can't load an image

Here is my code:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Sprites!");
sf::Texture playerTex;
playerTex.loadFromFile("Textures/player_ship.png");
sf::Sprite playerSprite;
playerSprite.setTexture(playerTex);
playerSprite.setScale(1.5, 1.5);
playerSprite.setPosition(100, 100);
playerSprite.setOrigin(32, 32);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(playerSprite);
window.display();
}
}
When I run this code, SFML opens a blank window (it should have a sprite) and when this window closes, it returns the error Failed to load image ".
I have the Textures folder located in multiple directories so it should be able to see it. I've already tried re-copying the textures and reinstalling SFML. How do I fix it??

SFML Pixel Perfect Collision limited to a view?

In this code I have one view (white, zoom 2) and the original window, also one sprite for a car and one sprite for a wall...
#include <SFML/Graphics.hpp>
#include "collision.hpp"
#define windowWidth 1000
#define windowHeight 600
int main()
{
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "SFML Views");
sf::View view(sf::FloatRect(0,0, windowWidth, windowHeight));
view.zoom(2);
// car
sf::Texture imgCar;
Collision::CreateTextureAndBitmask(imgCar, "carro.png" );
sf::Sprite car;
car.setTexture(imgCar);
car.setPosition(0, (windowHeight - imgCar.getSize().y) / 2);
// wall
sf::Texture imgWall;
Collision::CreateTextureAndBitmask( imgWall, "barreira.png" );
sf::Sprite wall;
wall.setTexture(imgWall);
wall.setPosition(windowWidth - imgWall.getSize().x, 0);
sf::RectangleShape background (sf::Vector2f(windowWidth, windowHeight));
background.setFillColor(sf::Color::White);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
if (!Collision::PixelPerfectTest(car, wall))
car.move(0.1, 0);
window.clear();
window.setView(view);
window.draw(background);
window.setView(window.getDefaultView());
window.draw(car);
window.draw(wall);
window.display();
}
return 0;
}
... if both car and wall are related with the main window, I get a perfect car collision with the wall. (see image).
Now if I put the car inside the view ...
window.clear();
window.setView(view);
window.draw(background);
window.draw(car);
window.setView(window.getDefaultView());
window.draw(wall);
window.display();
... the collision is detected as if the wall were within the boundaries of the view (which is zoomed in) (see image).
How can I make the collision detection independent of the view?

SFML 2.4.2 Co-ordinate system offset

I am writing a small program using SFML which draws a 5 x 5 rectangle at any point specified by clicking the mouse.
I am using mapPixelToCoords() to map the mouse coordinates to the pixels as recommended in the documentation, however I am still encountering a weird offset between the coordinates and the actual shape which is drawn.
The offset varies on different parts of the window (it is not a constant x,y value).
I would like the rectangle to be drawn precisely under the mouse pointer, how do I go about removing this offset?
This is the code I'm using to draw the rectangle on click:
Screenshot of offset in the window
int main(){
sf::RenderWindow window(sf::VideoMode(800, 720), "SFML window");
sf::Event event;
//Rectangle to be drawn on the screen
sf::RectangleShape someRect;
someRect.setFillColor(sf::Color(0, 0, 0));
someRect.setSize({ 5, 5 });
someRect.setPosition(100, 120);
while (window.isOpen())
{
if (!windowStarted) {
event.type = sf::Event::Closed;
}
while (window.pollEvent(event))
{
// Close window: exit
if (event.type == sf::Event::Closed) {
window.close();
}
if (event.type == sf::Event::MouseButtonPressed) {
someRect.setPosition(window.mapPixelToCoords(sf::Mouse::getPosition(window)));
}
}
window.clear(sf::Color(255, 255, 255));
window.draw(someRect);
window.display();
}
return 0;
}

(2.3.1) Set scale of background texture to renderwindow size

Just started learning SFML (so please bear with me).
I have made a RenderWindow object, and I have a image I want to fit perfectly to that window.
By searching through the documentation, I found the sf::Sprite::SetScale function. Is this the right function to do it? But how do I set the scale of the sprite to the scale of the RenderWindow, when the RenderWindow object size is set in pixels? Do I have to get the scale of the RenderWindow, and then assign the background sprite to that scale or?
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(600, 300), "Simple Game");
sf::Texture BackgroundTexture;
sf::Sprite background;
//background.setScale(0.2, 0.2); <--- how?
if(!BackgroundTexture.loadFromFile("media/background.png"))
{
return -1;
}
else
{
background.setTexture(BackgroundTexture);
}
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
window.close();
}
}
window.clear();
window.draw(background);
window.display();
}
}
The scale factor you need is simply the ratio between the window size and the texture size. sf::Texture has a getSize function, as has sf::RenderWindow. Simply get the sizes of both, calculate the ratio and use it to set the scale of the sprite, like this:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(600, 300), "Simple Game");
sf::Texture BackgroundTexture;
sf::Sprite background;
sf::Vector2u TextureSize; //Added to store texture size.
sf::Vector2u WindowSize; //Added to store window size.
if(!BackgroundTexture.loadFromFile("background.png"))
{
return -1;
}
else
{
TextureSize = BackgroundTexture.getSize(); //Get size of texture.
WindowSize = window.getSize(); //Get size of window.
float ScaleX = (float) WindowSize.x / TextureSize.x;
float ScaleY = (float) WindowSize.y / TextureSize.y; //Calculate scale.
background.setTexture(BackgroundTexture);
background.setScale(ScaleX, ScaleY); //Set scale.
}
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
window.close();
}
}
window.clear();
window.draw(background);
window.display();
}
}