SFML 2.0 – drawing with vector of sprites - c++

I'm trying to create a loop to draw 10 blocks on the screen, but nothing is showing. I got no error, so I think that the vector is not storing the sprites. I'm new to SFML, so I don't really know what I'm doing wrong.
sf::Texture bTexture;
sf::Texture bloqueTexture;
sf::Sprite bloqueSprite;
//create vector of blocks
std::vector<sf::Sprite> bricks(10, sf::Sprite(bloqueTexture));
fondo.setTexture(img_mgr.getImage("fondo.jpg"));
personaje.setTexture(img_mgr.getImage("jumper.png"));
personaje.setPosition(100,POSICION_TERRENO_Y);
bloqueSprite.setTexture(img_mgr.getImage("bloque.png"));
bloqueTexture.loadFromFile("Recursos/imagenes/bloque.png");
//Fill the vector with the texture
for (int i = 0; i < bricks.size(); i++)
{
bricks[i].setTexture(bloqueTexture);
bricks[i].setPosition(100 + (i * 45) , 320);
window.draw(bricks[i]);
}

2nd edit with final answer : if you want to display png files with SFML, save them 8bit.
Edit: I had some bad copy/paste in the second code, I fixed it
As SFML is made for multi media applications (mostly games), you need to refresh and draw to screen many times by second (that's frames). That being said, the basic approach is to have a main loop doing 3 things : handling inputs, updating your game logic and then drawing.
See the classic example from SFML's website :
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
Your texture loading and filling the vector have to be done before the main loop, and then between window.clear() and window.display you need to draw everything you want to display (your blocks).
You may end up with something like this :
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::Texture bTexture;
sf::Texture bloqueTexture;
sf::Sprite bloqueSprite;
//create vector of blocks
std::vector<sf::Sprite> bricks(10, sf::Sprite(bloqueTexture));
fondo.setTexture(img_mgr.getImage("fondo.jpg"));
personaje.setTexture(img_mgr.getImage("jumper.png"));
personaje.setPosition(100,POSICION_TERRENO_Y);
bloqueSprite.setTexture(img_mgr.getImage("bloque.png"));
bloqueTexture.loadFromFile("Recursos/imagenes/bloque.png");
for (int i = 0; i < bricks.size(); i++)
{
bricks[i].setTexture(bloqueTexture);
bricks[i].setPosition(100 + (i * 45) , 320);
}
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
for (int i = 0; i < bricks.size(); i++)
{
window.draw(bricks[i];
}
// Consider doing this :
// for(const auto& brick : bricks)
// window.draw(brick);
window.display();
}
return 0;
}

I think problem is with loading textures, try to check is loadFromFile function returning true.

Related

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.

SFML Window Resizing is very ugly

When I resize my sfml window, when I cut resize to make it smaller and resize to make it larger, it gives you a really weird effect.
How do I make the resizing more prettier? The code is from the installation tutorial for code::blocks.
Code (same as the code in the installation tutorial for code::blocks on the sfml website):
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
You need to manage the resize of the window. Otherwise the coordinates are wrong. Here is an excerpt of your code with the solution. Credits go to the author of this forum post, this is where I once found it when I was looking for a solution: https://en.sfml-dev.org/forums/index.php?topic=17747.0
Additionally you can set the new coordinates based on the new size. The link gives you more information.
// create own view
sf::View view = window.getDefaultView();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::Resized) {
// resize my view
view.setSize({
static_cast<float>(event.size.width),
static_cast<float>(event.size.height)
});
window.setView(view);
// and align shape
}
}

SFML update function not moving sprite

The current update function should be moving the sprite to the left 10 pixels every time it's called, but the sprite (cup1Sprite) is static and not moving. I tried using sprite.rotate(); and the sprite rotated every frame (which was expected), so something is wrong with the way I've written the update function for updating the sprite position. Can anyone suggest what's going wrong?
Code:
DrawCups.h
class DrawCups
{
public:
DrawCups(sf::RenderWindow& window);
~DrawCups();
void update();
void drawCup1();
private:
sf::RenderWindow& _window;
//Cup1
sf::Texture _cup1; // the texture which will contain our pixel data
sf::Sprite _cup1Sprite; // the sprite which will actually draw it
};
Update function in DrawCups.cpp
void DrawCups::update()
{
sf::Vector2f pos = this->_cup1Sprite.getPosition();
pos.x+=10;
this->_cup1Sprite.setPosition(pos);
}
main.cpp
int main()
{
sf::RenderWindow window(sf::VideoMode(1366, 768), "Sorting Algorithm Visualisation: SFML");
window.setFramerateLimit(60);
DrawCups drawToWindow(window);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
drawToWindow.update();
window.clear(sf::Color::White);
drawToWindow.drawBench();
drawToWindow.drawCup1();
window.display();
}
return 0;
}

SFML window.draw(); only shows up for a small time

I'm attempting to get a picture to display by using SFML (just a test run). The program can find the picture, and open a new window, but when it opens the window it only pops up for half a second then returns with 1. Here is the code (which is just their example that I tweaked):
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
sf::Texture Texture;
sf::Sprite Sprite;
if(!Texture.loadFromFile("resources/pepe.png"));
return 1;
Sprite.setTexture(Texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(Sprite);
window.display();
}
return 0;
}
I am assuming the error is coming from the return 1; after the loading, but I don't see what is wrong. Can someone post something that worked for them or give me tips on what may be going wrong?
Your code works just fine, except for the ; after the texture loading from a file, making your program always return 1, whatever was happening before.
It's a good idea to add error messages to know what's going wrong.
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
sf::Texture Texture;
sf::Sprite Sprite;
if(!Texture.loadFromFile("resources/pepe.png")){ // there was a ; here.
// making the code below always run.
std::cerr << "Error loading my texture" << std::endl;
return 1;
}
Sprite.setTexture(Texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){
window.close();
}
// you only get here when there is at least one event.
}
// but you always want to display to the screen.
window.clear();
window.draw(Sprite);
window.display();
}
return 0;
}
My rule of thumb is to always enclose code blocks with curly braces so you never make these kind of mistakes (or someone else changing your code is less prone to make that mistake).

SFML 2.0 - Drawing a starfield

I'm using sfml 2.0 to make a game. The background is going to be a starfield. Rather than use an image, I thought it might be neat to randomly generate a starfield each time the game starts up, so the background looks slightly different each time. Problem is, the way I'm currently doing it slows my game down A LOT. Does anyone know what is causing the speed hit? I've looked through the documentation to see what, but I haven't found anything...
Here's my code:
#include <SFML/Graphics.hpp>
#include "sfml helper/initialization_helpers.h"
#include "sfml helper/cursor_functions.h"
#include "sfml helper/global_event_handler.h"
#include "sfml helper/globals.h"
#include <cstdio>
int main(int argc, char* argv[])
{
try {
// some non-related preparations...
PrepareApplication(argv[0]);
float width = 640, height = 480;
sf::RenderWindow window(sf::VideoMode(width, height), "SFML Test", sf::Style::Close);
window.setFramerateLimit(60);
// Textures is a global object that has an internal std::map<string, sf::Texture>
Textures.add("ball.png", "ball");
sf::Sprite sprite;
sprite.setTexture(Textures.get("ball"));
// This is the snippet that generates the starfield
srand(time(NULL));
sf::Image starsImg;
starsImg.create(width, height, sf::Color::Black);
int numStars = rand() % 20 + 490;
for (int i = 0; i < numStars; i++) {
int x = rand() % (int)width;
int y = rand() % (int)height;
sf::Color color(255, 255, 255, rand() % 75 + 25);
starsImg.setPixel(x, y, color);
}
sf::Texture starsTexture;
starsTexture.loadFromImage(starsImg);
sf::Sprite stars;
stars.setTexture(starsTexture);
// main loop
while (window.isOpen()) {
if (Flags.isActive && Flags.inFocus) {
confineCursorToWindow(window);
} else {
freeCursor();
}
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Escape) {
Flags.isActive = (!Flags.isActive);
}
}
if (event.type == sf::Event::MouseMoved) {
sprite.setPosition(event.mouseMove.x, event.mouseMove.y);
}
// handles default events like sf::Event::WindowClosed
handleDefaultEventsForWindow(event, window);
}
window.clear();
window.draw(stars); // here's where I draw the stars
window.draw(sprite);
window.display();
}
} catch (const char* error) {
printf("%s\n", error);
exit(1);
}
return 0;
}
EDIT
I tried loading an image of a starfield and tried drawing that, the game still runs slow!
Also, by slow, I mean the sprite called "sprite" lags when following the mouse. Is that actually a speed issue?