Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Simple Problem With Sprites And Display  (Read 4634 times)

0 Members and 1 Guest are viewing this topic.

DarkNemesis

  • Newbie
  • *
  • Posts: 11
    • View Profile
Simple Problem With Sprites And Display
« on: April 03, 2013, 08:04:49 am »
Hello Guys!
I have recently started learning SFML, and I am still a beginner, so my question might be too lame for you, but please try to help me, as it really bugs me out.
I am using Win7 And SFML 1.6 and trying to make simple games (Minesweeper, Snake)
The Problem I want to ask is : I have created sprites, drawn them on the screen and displayed, and then started my main game loop. Everything runs fine here. But when I edit my code and try draw/change sprites according to the events in the game loop and display them again, why it happens that two screens are displayed alternatively, one having the old sprites, and one completely black screen with just the updates sprites? I read the whole tutorials and came to this simple conclusion that I have to redraw the old sprites again and again as well in the main loop, along with the changed sprites. But Why? And is there any other way to this?

For Instance this is my code for snake (It's not completed, I am just checking how to move the snake around)

#include<SFML/Graphics.hpp>
using namespace sf;
int main()
{
        RenderWindow Snake(VideoMode(800,600),"Snake");
        Image BackGround, SnakeBody;
        BackGround.LoadFromFile("C:/Users/Administrator/Desktop/BG.jpg");
        SnakeBody.LoadFromFile("C:/Users/Administrator/Desktop/SB.jpg");
        Sprite BG(BackGround), SB(SnakeBody);
        for(int i = 0; i < 800; i += 20)
                for(int j = 0; j < 600; j += 20)
                {
                        BG.SetPosition(i,j);
                        Snake.Draw(BG);
                }
        for(int j = 0; j < 61; j += 20)
        {
                SB.SetPosition(400,j);
                Snake.Draw(SB);
        }
        Snake.Display();
        while (Snake.IsOpened())
        {
                Event Event;
                while (Snake.GetEvent(Event))
                {
                        if (Event.Type == sf::Event::Closed)
                 Snake.Close();
                        if (Snake.GetInput().IsKeyDown(sf::Key::Down))
                        {
                                SB.Move(0, 20);
                                Snake.Draw(SB);
                        }
                        Snake.Display();
                }
        }
}
 
The Grid displayed is fine and the starting snake too. But when I press the down key, the snake moves in alternative black screen. Same was the case in my minesweeper game, I get the starting tiles displayed well, but when I click on a tile, it opens in another black screen, and then clicking again on the black screen will open corresponding tile in the old screen. Its like both the screen keeps switching after a Event.

I know the simple workout, but I am not satisfied with that, and I need to know why 2 screen appears, so that I can try to find another way.
I have attached the source code, as well as the images.
Please do tell me the reason, another way if possible, and then a simple but satisfying algo for moving a snake when key pressed (I searched the net, I just got complex algo for that).
Thank You

[attachment deleted by admin]
« Last Edit: April 03, 2013, 08:07:32 am by DarkNemesis »

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Simple Problem With Sprites And Display
« Reply #1 on: April 03, 2013, 02:21:34 pm »
Try with only one call to Display. And don't put it in your event loop. And Draw your background and your snake EVERY frame.

DarkNemesis

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Simple Problem With Sprites And Display
« Reply #2 on: April 03, 2013, 04:44:40 pm »
I did as you said, but I don't know why I have to redraw the background? Doing that works, but I want to know why just drawing only the updates don't work.
I did the following changes :
for(int i = 0; i < 800; i += 20)
        for(int j = 0; j < 600; j += 20)
        {
                BG.SetPosition(i,j);
                Snake.Draw(BG);
        }
for(int j = 0; j < 61; j += 20)
{
        SB.SetPosition(400,j);
        Snake.Draw(SB);
}
while (Snake.IsOpened())
{
        Event Event;
        while (Snake.GetEvent(Event))
        {
                if (Event.Type == sf::Event::Closed)
                Snake.Close();
                if (Snake.GetInput().IsKeyDown(sf::Key::Down))
                {
                        SB.Move(0, 20);
                        Snake.Draw(SB);
                }
        }
        Snake.Display();               
}
 
One thing I have known is calling Display function once works fine. Calling It again produces an empty black screen. On third call, the old screen reappears. And sprites drawn in the consecutive calls are shown on the respective screens. If on alternative calls, old screen reappears with the consecutive updates, then it means old sprites are still stored ad displayed. Then why does this second screen comes in between?  Is there any way to remove this??

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Simple Problem With Sprites And Display
« Reply #3 on: April 03, 2013, 05:07:52 pm »
You need to clear your target each time before you draw to it and display it again

http://www.sfml-dev.org/documentation/1.6/classsf_1_1RenderTarget.php#a125645088d7b2df07599ea36fbb8b87e

DarkNemesis

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Simple Problem With Sprites And Display
« Reply #4 on: April 05, 2013, 08:52:50 am »
Still getting no solution, this 2 Screens thing really bugs me...
And other than limiting frame rate, is there any way in which we can control the speed of our display, without producing imminent lag in events.
And also is there any command to pop all the events in a single go. Using
while(App.GetEvent(Event));
works, but becomes jammy if continously events are given and the control gets stuck in the while loop..
All Help would be appreciated..

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Simple Problem With Sprites And Display
« Reply #5 on: April 05, 2013, 11:20:10 am »
Rendering to the screen works on the principle of page flipping. You have 2 render destinations, one visible on screen, and one off screen. You first clear any existing data from your off screen target (RenderTarget::Clear()), then perform any draw calls (rt.draw(spr1); rt.draw(spr2) etc) before finally flipping or switching the two targets which is done with RenderTarget::Display(). The target you have just drawn to now becomes visible on screen, and the previously visible target is now ready to be cleared and drawn to. SFML / OpenGL handles this all internally so you only need (but are not restricted to) one RendwerWindow object to perform this.

For timing issues you need to look into game loop methods. This is a good starting point but I highly recommend doing some in-depth research via Google before you decide on what would best suit your project. Another version of the game loop could be based on delta time for example, which is often used in games with a lot of physics simulations.

You can also avoid event polling for player input as SFML2 lets you read the state of joysticks and keyboards directly (but you should still poll for window events such as minimize/maximize/close).

DarkNemesis

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Simple Problem With Sprites And Display
« Reply #6 on: April 06, 2013, 02:46:22 am »
Finally got the answer I was looking for!!
Thanks for your reply and the links which you gave. I never knew about screen switching, but guess now everything makes sense.
I appreciate your help in the speed loops too, although they were a bit complex, considering the fact I have just started, so I think I will have to Google more on that.
The problem with Events thing is, I want to reset all the events gathered immediately after the snake change its course, because otherwise if the user repeatedly gives inputs, the snake moves according to those events and gets stuck until those events end, which doesn't happen in normal cases. So I just wanted to end them in a swish after the snake change its course, and start gathering back after a few milli-seconds.

One more thing I need to ask, In SFML 1.6 we have the Shape::Circle command to draw circles. How do I store this Circle in a Sprite?

Thanks once again For all your help.. :)

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Simple Problem With Sprites And Display
« Reply #7 on: April 06, 2013, 08:43:54 am »
Is there a particular reason you are using 1.6? If you are starting out I highly recommend using SFML2. CircleShape and Sprite both inherit from sf::Drawable. Any classes which inherit from Drawable can be drawn the same way via RenderTarget::Draw(drawable).

DarkNemesis

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Simple Problem With Sprites And Display
« Reply #8 on: April 06, 2013, 04:12:46 pm »
The only reason is that when I started SFML, and when I searched about it, everywhere I read was that 1.6 is the current stable version, and that 2.0 is still in beta. So I decided to use 1.6. I didn't know much about this, so I decided to use 1.6 only. If you say, I will switch to 2.0. And if you could please, also provide me the link for tutorial on building SFML 2.0 on Visual Studio 2010. I tried goggling it, but I got some lengthy solutions with CMake/NMake, so if you could help me in that, I would be very pleased. :)

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Simple Problem With Sprites And Display
« Reply #9 on: April 06, 2013, 04:41:40 pm »
There are prebuilt binaries of the release candidate of SFML2 on the download page if you scroll down below the 1.6 downloads, and a guide to setting up VS here. If you want to build the latest version (which is more or less the finished version of SFML 2) you will have to use CMake, but it's actually pretty easy to use and worth learning. There is a CMake guide on the tutorials page, and CMake will output a VS project file which you can use to compile SFML in Visual Studio.