Sprite isn't moving - c++

I'm new to programming and, since I find it easier to learn doing, I was playing around with C++ and SFML. I was trying to get a sprite to move, but for some reason, I can't do it. I've tried everything I found, but no luck. Anyone know why this isn't working? I'm using Visual Studio 2012 Express and SFML 2.1, by the way.
int main()
{
sf::RenderWindow window(sf::VideoMode(1000, 800), "Project");
window.setFramerateLimit(30);
glEnable(GL_TEXTURE_2D);
window.clear(sf::Color::White);
window.display();
sf::Texture charMain;
if (!charMain.loadFromFile("Images/playerFrontSprite.png"))
{
return 1;
}
sf::Sprite charaMain;
charaMain.setPosition(500.f , 500.f);
charaMain.setTexture(charMain);
window.draw(charaMain);
window.display();
sf::Font cavefont;
sf::Font::Font(cavefont);
if (!cavefont.loadFromFile("Cave-Story.ttf"))
return 1;
while (window.isOpen())
{
sf::Event playerAction;
while (window.pollEvent(playerAction))
{
switch(playerAction.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
std::cout << "sf::Event::KeyPressed" << std::endl;
switch(playerAction.key.code)
{
case sf::Keyboard::W:
charaMain.move(0 , 1);
break;
case sf::Keyboard::A:
charaMain.move(-1 , 0);
break;
case sf::Keyboard::S:
charaMain.move(0 , -1);
break;
case sf::Keyboard::D:
charaMain.move(1 , 0);
break;
}
break;
}
}
}
}

Your problem is that you're moving the object, but you're not drawing it on the screen at its new position. Your drawing code is outside the main loop, so it never gets called after you move the sprite, so you never see the effects.
You basically need to pull the rendering code (ie. window.draw(charaMain) and window.display()) inside the while (window.isOpen()) loop, outside the event handling loop.

Related

How does window.clear() works in SFML when making a character move in the screen?

Well, I've been watching a tutorial on how to use SFML. I'm currently learning to move a sprite in the screen. Before adding window.clear(); every time I moved the sprite it left like a trail, like if the sprite was a brush. Then the tutorial man said to add window.clear BEFORE window.draw(player);
Could you please explain the logic behind that? Like, the window gets cleared, then draws the character and the displays it. Here is the code:
#include <SFML/Graphics.hpp>
#include <iostream>
int main() {
sf::RenderWindow window(sf::VideoMode(1920, 1080), "Screen", sf::Style::Default);
sf::RectangleShape player(sf::Vector2f(100.0f, 100.0f));
player.setFillColor(sf::Color::Green);
//run 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 evnt;
while (window.pollEvent(evnt)) {
switch (evnt.type) {
case sf::Event::Closed:
window.close();
break;
case sf::Event::Resized:
printf("New window width: %i New window height: %i\n", evnt.size.width, evnt.size.height);
break;
case sf::Event::TextEntered:
if (evnt.text.unicode < 128) {
printf("%c", evnt.text.unicode);
}
}
// "close requested" event: we close the window
if (evnt.type == sf::Event::Closed)
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)){
player.move(0.0f, -0.1f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
player.move(-0.1f, 0.0f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
player.move(0.0f, 0.1f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) {
player.move(0.1f, 0.0f);
}
window.clear();
window.draw(player);
window.display();
}
return 0;
}
The logic behind sf::RenderWindow::clear() is actually quite simple. The reason you see a trail behind the sprite without clear is because you redraw the sprite again without getting rid of the old one. Clearing the screen gets rid of anything that was already on the screen, so you end up with a blank canvas to redraw everything on in its updated position. The character, which is your sprite, isn't actually moving, it is constantly getting redrawn in a new position on the window.

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?

Render issues when resetting mouse position inside of a switch case with sfml

I'm making a basic breakout game using SFML in order to familiarize myself with C++ (moving up from C). Inside the game loop, I've placed an event poll that leads to a switch statement. When the mouse is moved, the switch-case will retrieve the mouse xy change and move the paddle accordingly, like so:
while (window.isOpen())
{
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
}
break;
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x) * sensitivity, 0));
break;
}
}
sf::Mouse::setPosition(windowOffset, window);
window.clear();
window.draw(paddle);
window.display();
}
Now, that works just fine and dandy, but I'm resetting the mouse position to the center of the window on every loop, which isn't necessary if the mouse hasn't moved. So, I tried moving sf::Mouse::setPosition() into the switch statement, underneath paddle.move, like so:
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x) * sensitivity, 0));
sf::Mouse::setPosition(windowOffset, window);
break;
However, when I rebuild the project, I now get a blank white window.
So, my question is: What's causing this to happen?
edit(minimal complete code)
int WinMain()
{
sf::Vector2i windowRes(700, 900);
sf::Vector2i windowOffset(350, 450);
sf::ContextSettings settings;
sf::RectangleShape paddle;
paddle.setSize(sf::Vector2f(150, 20));
paddle.setOrigin(350, 0);
paddle.setPosition(350, 825);
sf::RenderWindow window(sf::VideoMode(windowRes.x, windowRes.y), "Breakout", sf::Style::Default, settings);
window.setMouseCursorVisible(false);
sf::Mouse::setPosition(windowOffset, window);
sf::Event event;
while (window.isOpen())
{
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
}
break;
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x), 0));
//sf::Mouse::setPosition(windowOffset, window);
break;
}
}
sf::Mouse::setPosition(windowOffset, window);
window.clear();
window.draw(paddle);
window.display();
}
return 0;
}
So, through some tinkering, it seems that sf::MOUSE::setposition() generates an event.type of sf::Event::MouseMoved, which would be added to the event queue, causing an infinite loop.

Managing multiple RenderWindow's in sfml

I seem to be having a bit of trouble when managing multiple windows in SFML C++. When I try to manage multiple windows, they both open correctly and I can interact in the larger one, however, the smaller one, which upon creation is overlapping the larger window, I can not interact with until I move the large window away. An image is below to help with the visual. Also below is the main loop for my code.
The main loop of the code is as follows:
while (MainWin.isOpen() || F1Menu.isOpen())
{
sf::Event Event;
if (MainWin.pollEvent(Event))
{
switch (Event.type)
{
case sf::Event::Closed:
MainWin.close();
if (F1Menu.isOpen())
F1Menu.close();
break;
case sf::Event::Resized:
MainView.reset(sf::FloatRect(0.f, 0.f, (MainWin.getSize().x*0.9f), (MainWin.getSize().y*0.9)));
MainWin.setView(MainView);
break;
case sf::Event::KeyPressed:
if (Event.key.code == sf::Keyboard::F1)
F1Menu.create(sf::VideoMode(200, 500), "SFML 2D - F1 Menu");
else if (Event.key.code == sf::Keyboard::Escape)
{
MainWin.close();
if (F1Menu.isOpen())
F1Menu.close();
}
break;
}
}
if (F1Menu.pollEvent(Event))
{
switch (Event.type)
{
case sf::Event::Closed:
F1Menu.close();
break;
case sf::Event::MouseButtonReleased:
if (Event.mouseButton.button == sf::Mouse::Left)
if (LMButton.mouseIn(F1Menu))
LoadMap("MapA.dat");
break;
case sf::Event::MouseMoved:
if (LMButton.mouseIn(F1Menu))
LMButton.setColor(sf::Color::Yellow);
else
LMButton.setColor(sf::Color::White);
break;
}
}
moveClock.restart();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
player.move(0, -4 * time);
player.setDirection(sfm::Direction::Up);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
player.move(0, 4 * time);
player.setDirection(sfm::Direction::Down);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
player.move(-4 * time, 0);
player.setDirection(sfm::Direction::Left);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
player.move(4 * time, 0);
player.setDirection(sfm::Direction::Right);
}
if (F1Menu.isOpen())
{
F1Menu.clear();
F1Menu.draw(LMButton);
F1Menu.display();
}
if (MainWin.isOpen())
{
MainWin.clear();
if (SplashScreen.didAnimate)
SplashScreen.Animate(MainWin, sfg::Animation::FadeIn);
if (inMenu)
{
}
if (isPlaying)
{
DrawMap(MainWin);
MainWin.draw(player);
}
MainWin.display();
}
}
In my knowledge, you aren't able to poll two separate windows with one sf::Event object. this is because when polling events, you are essentially popping off of the event stack and handling each one. The signature of pollEvent is
bool pollEvent(sf::Event &event);
note that there is no const qualifier here, because each processed event gets popped off the event stack. By the time you finish polling your main window there are no events left for your other window. This could be the cause of your window being unable to focus. Your second window should use it's own separate sf::Event
On a side note I would highly recommend encapsulating your data inside classes. You can find a great reference here on how to go about doing so. It's great coding practice and helps minimize confusion when bug hunting

Weird SFML error with window

I am learning the basics of SFML (enough to make a basic pong game), but I keep getting this strange error with the window. When the window launches sometimes it has a black background (as intented), but about 50% of the time it seems to look like what was behind the window when it launched. I get no errors at compile time.
Here is the bit of the code that I think is causing problems:
//Game loop
while(window.isOpen()){
sf::Event Event;
while(window.pollEvent(Event)){
//Getting input
switch(Event.type){
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch(Event.key.code){
case sf::Keyboard::Right:
std::cout << "Right Key Pressed" << std::endl;
break;
case sf::Keyboard::Left:
std::cout << "Left Key Pressed" << std::endl;
break;
case sf::Keyboard::Up:
std::cout << "Up key pressed" << std::endl;
break;
}
break;
}
}
window.display();
}
return 0;
}
This is how I am making my window:
sf::RenderWindow window(sf::VideoMode(screenWidth, screenHeight), "Pong!", sf::Style::Titlebar | sf::Style::Close);
Is there something extreemly obvious I am missing?
Also I am using Linux with xfce4 if that makes any difference.
I did not really understand your problem, but did you try to clear the window ?
add "window.clear();" just before "window.display();"