SFML update function not moving sprite - c++

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;
}

Related

Clunky movement on transformable objects SFML

So I am working on a game in SFML and am having a weird problem with movement. I have implemented a delta time so the movement speed is constant but I have this weird issue where I press a move key, the object jumps by speed units, pauses, then proceeds to move smoothly. I haven't been able to find much on this as I don't really know what problems I should be looking for. Here is a copy of my current code.
#include <SFML/Graphics.hpp>
#include "Player.h"
#include <iostream>
#include <vector>
void handleKeyPress(sf::Event &event, Player &player, float dt);
int main() {
sf::ContextSettings settings;
settings.antialiasingLevel = 16;
sf::RenderWindow window(sf::VideoMode(800, 600), "Title", sf::Style::Default, settings);
sf::Event event;
Player player;
player.setPosition(100, 100);
sf::Clock dtClock;
while (window.isOpen()) {
float dt = dtClock.getElapsedTime().asSeconds();
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
handleKeyPress(event, player, dt);
window.clear(sf::Color::Black);
//drawing happens hear
window.draw(player);
//end of frame
window.display();
dtClock.restart();
}
}
}
void handleKeyPress(sf::Event& event, Player& player, float dt) {
sf::Vector2f moveVector(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
moveVector.x = -player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
moveVector.x = player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
moveVector.y = -player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
moveVector.y = player.speed;
player.move(moveVector * dt);
}
Note that player is just an SFML Transformable object/drawable object.
Your main is mixing event processing and state updates with drawing, which makes it hard to respect the fractional updates you intend to do with dt.
The code below undoes that: it first eats all events, then updates the game state, then draws.
In order to have smooth movement, you need to remember the Player velocity depending on which keys are pressed/released:
Add a velocity vector to Player
Change handleKeyPress to modify the velocity appropriately. Pay attention to multiple keypresses, eg up + right = (+1, +1)
Add an update method to player that adds a dt fraction of velocity to position.
Change it to:
while (window.isOpen()) {
float dt = dtClock.getElapsedTime().asSeconds();
// process events
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
} else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased) {
// rewrite this to update player.velocity depending on what key is pressed if released
handleKeyPress(event, player, dt);
}
}
// apply dt * player.velocity to player.position
player.update(dt);
// draw
window.clear(sf::Color::Black);
//drawing happens hear
window.draw(player);
// restart the dtclock here, as display() will pause for a bit
dtClock.restart();
//end of frame
window.display();
}

C++ and SFML, no instance of the overloaded function "sf::RenderWindow.draw()" matches the argument list

I am currently trying to make a simple pong game with SFML in C++. I consistently get the error in the main file.
#include <iostream>
#include "Ball.h"
Ball b;
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1200, 600), "My window");
// 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
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
// clear the window with black color
window.clear(sf::Color::Black);
// draw everything here...
window.draw(b);
// end the current frame
window.display();
}
return 0;
}
This is the ball.h file:
#pragma once
#include <iostream>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class Ball
{
public:
double x, y;
int Radius;
void Render(int Rad, sf::Color BallColour) {
sf::CircleShape shape(Rad);
// set the shape color to green
shape.setFillColor(BallColour);
}
};
I am unsure as to why the error occurs. Any help would be appreciated.
You had not call function of render, you just wrote window.draw(b), and programm dont know what do you mean. In Ball.h you should write:
#pragma once
#include <iostream>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
class Ball
{
public:
double x, y;
int Radius;
void Render(int Rad, RenderWindow& window) {
sf::CircleShape shape(Rad);
// set the shape color to green
shape.setFillColor(sf::Color::Green);
shape.setPosition(600, 300);//SETTING POSITION OF THE BALL
window.draw(shape);//if you know what is reference on variable, you will understand what is it
}
};
And in your main.cpp you shhould call your function Render:
#include <iostream>
#include "Ball.h"
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1200, 600), "My window");
Ball b; //I advice you to create object of class in main function
// 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
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
// clear the window with black color
window.clear(sf::Color::Black);
b.Render(10, window);// give the function reference on window
// end the current frame
window.display();
}
return 0;
}
sf::RenderWindow::draw requires an implementation of sf::Drawable. You can either pass sf::CircleShape (it's a sf::Drawable) directly or implement sf::Drawable and delegate the call.
class Ball : public sf::Drawable {
public:
double x, y;
int Radius;
void draw(sf::RenderTarget& target, sf::RenderStates states) const override {
sf::CircleShape shape(Radius);
shape.setFillColor(BallColour);
shape.draw(target, states);
}
};

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.

Trying to make Animated Sprite Class; Sprite Won't Move

So, I was trying to create a class in C++ for an animated sprite that uses spritesheets for input, and when trying to move the sprite, it just sort of bounces back. It won't save to the position.
I tried using .setPostion() but that still bounces back to where it was. I have no other methods of moving the sprite implemented, nor updating it or anything else. The part in concern in the member function run, which is void is:
//if statement
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
curranim[2] = Right;
playerSprite.setPosition(playerSprite.getPosition().x + walkingSpeed, 0);
}
window.draw(playerSprite);
//spritesheet.cpp ends here
Now here is my main function:
int main()
{
sf::RenderWindow Window(sf::VideoMode(900, 600), "RPG");
animsprite sprite("dragon.png", 1, Window);
sprite.setWalkSpeed(10);
sf::Event Event;
while (Window.isOpen())
{
while (Window.pollEvent(Event))
{
switch (Event.type)
{
case sf::Event::Closed:
Window.close();
break;
}
}
Window.clear();
sprite.run(Window);
Window.display();
}
return 0;
}
Will I be stuck to repeating my code forever or is there a fix?

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.