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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - glenjoker

Pages: [1]
1
General / Re: why pollEvent is always used with a while loop?
« on: February 27, 2015, 01:50:46 pm »
Did some tests just now, and found out the update() did make changes every time a frame was rendered, which was why the circle moved faster.

Thanks for all your helps. I really appreciate it.

2
General / Re: why pollEvent is always used with a while loop?
« on: February 27, 2015, 11:59:18 am »
Quote
As you already noticed yourself a lot more frames get rendered compared to the amount of events that get process. If your update function is inside the event loop, your circle will only update when there's an event and not every frame.

Yes, the circle will only be updated when there is an event happened, but is it the same when update() is out of the event loop? I mean even though in this case, the circle would be updated in every frame, but if this is no event, the update makes no change.

In both cases, if I press a key, say 'w', without releasing, then approximately the same number of events will be processed in a unit time, and since I mentioned earlier, the values of deltaTime roughly the same as well for both cases, I would expect that the circle moves by roughly the same distance in both cases, but it turned out to be very different. Why exactly did this happen?

3
General / Re: why pollEvent is always used with a while loop?
« on: February 27, 2015, 08:43:44 am »
I tested it out by using two static ints which were used to count the number of frames and events respectively, and printing out the number frames that had been produced whenever the while loop in the function run() was iterated and the number of events that had been processed whenever the while loop in the function processEvents() was iterated.
And indeed a KeyPressed event was always tens of frames apart from the following KeyReleased event. One other thing that interested me during the testing was that there was always an event whose type I did not know being processed immediately after every KeyPressed event in the same frame as the KeyPressed event. Could you tell me what the event was and why it was processed?

Moreover, in order to deal with case where there were one KeyPressed event and one KeyReleased event in the same queue and thus no update would be made (though it's very unlikely as you said), I shifted the function update() to inside the while loop in the function processEvents(), and run the program again, but this time the motion of the circle became extremely slow and unsteady as compared to before. I tested the number of frames produced per second as well as the value of deltaTime, and they were generally around the same amount before the change and after the change, so I was expecting it run as well as before it's changed, but it didn't. Why is it so?

The code used to print the number frames and loops as well as the changed code are below:

Before change:
#include<SFML/Graphics.hpp>
#include <iostream>
class Game;

class Game
{
public:
    Game();
    void run();
private:
    void processEvents();
    void update(sf::Time deltaTime);
    void render();
    void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);

    sf::RenderWindow mWindow;
    sf::CircleShape mPlayer;
    bool mIsMovingUp = false;
    bool mIsMovingDown = false;
    bool mIsMovingRight = false;
    bool mIsMovingLeft = false;
    static int counter, frame;
};
int Game::counter = 1, Game::frame = 1;
int main()
{
    Game game;
    game.run();
}
Game::Game():mWindow(sf::VideoMode(640,480),"SFML Application"),mPlayer()
{
    mPlayer.setRadius(40.f);
    mPlayer.setPosition(100.f,100.f);
    mPlayer.setFillColor(sf::Color::Cyan);
}
void Game::run()
{
    sf::Clock clock;
    while (mWindow.isOpen())
    {
        sf::Time deltaTime = clock.restart();
        processEvents();
        update(deltaTime);
        render();
        ++frame;
    }
}
void Game::processEvents()
{
    sf::Event event;
    while(mWindow.pollEvent(event))
    {
        std::cout << "loop NO" << counter << std::endl;
        ++counter;
        std::cout << "frame NO" << frame << std::endl;
        switch(event.type)
        {
            case sf::Event::KeyPressed:
                handlePlayerInput(event.key.code, true);
                std::cout << "subloopPressed" << std::endl;
                break;
            case sf::Event::KeyReleased:
                handlePlayerInput(event.key.code, false);
                std::cout << "subloopReleased" << std::endl;
                break;
            case sf::Event::Closed:
                mWindow.close();
                break;
        }
    }
}
void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
    if(key == sf::Keyboard::W)
        mIsMovingUp = isPressed;
    else if(key == sf::Keyboard::S)
        mIsMovingDown = isPressed;
    else if(key == sf::Keyboard::A)
        mIsMovingLeft = isPressed;
    else if(key == sf::Keyboard::D)
        mIsMovingRight = isPressed;
}
void Game::update(sf::Time deltaTime)
{
    sf::Vector2f movement(0.f, 0.f);
    if (mIsMovingUp)
        movement.y -= 100.f;
    if (mIsMovingDown)
        movement.y += 100.f;
    if (mIsMovingLeft)
        movement.x -= 100.f;
    if (mIsMovingRight)
        movement.x += 100.f;

    mPlayer.move(movement * deltaTime.asSeconds());
}
void Game::render()
{
    mWindow.clear();
    mWindow.draw(mPlayer);
    mWindow.display();
}
 



After change:
#include<SFML/Graphics.hpp>
#include <iostream>
class Game;

class Game
{
public:
    Game();
    void run();
private:
    void processEvents(sf::Time deltaTime);
    void update(sf::Time deltaTime);
    void render();
    void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);

    sf::RenderWindow mWindow;
    sf::CircleShape mPlayer;
    bool mIsMovingUp = false;
    bool mIsMovingDown = false;
    bool mIsMovingRight = false;
    bool mIsMovingLeft = false;
    static int counter, frame;
};
int Game::counter = 1, Game::frame = 1;
int main()
{
    Game game;
    game.run();
}
Game::Game():mWindow(sf::VideoMode(640,480),"SFML Application"),mPlayer()
{
    mPlayer.setRadius(40.f);
    mPlayer.setPosition(100.f,100.f);
    mPlayer.setFillColor(sf::Color::Cyan);
}
void Game::run()
{
    sf::Clock clock;
    while (mWindow.isOpen())
    {
        sf::Time deltaTime = clock.restart();
        processEvents(deltaTime);
        render();
        ++frame;
    }
}
void Game::processEvents(sf::Time deltaTime)
{
    sf::Event event;
    while(mWindow.pollEvent(event))
    {
        std::cout << "loop NO" << counter << std::endl;
        ++counter;
        std::cout << "frame NO" << frame << std::endl;
        switch(event.type)
        {
            case sf::Event::KeyPressed:
                handlePlayerInput(event.key.code, true);
                std::cout << "subloopPressed" << std::endl;
                break;
            case sf::Event::KeyReleased:
                handlePlayerInput(event.key.code, false);
                std::cout << "subloopReleased" << std::endl;
                break;
            case sf::Event::Closed:
                mWindow.close();
                break;
        }
        update(deltaTime);
    }
}
void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
    if(key == sf::Keyboard::W)
        mIsMovingUp = isPressed;
    else if(key == sf::Keyboard::S)
        mIsMovingDown = isPressed;
    else if(key == sf::Keyboard::A)
        mIsMovingLeft = isPressed;
    else if(key == sf::Keyboard::D)
        mIsMovingRight = isPressed;
}
void Game::update(sf::Time deltaTime)
{
    sf::Vector2f movement(0.f, 0.f);
    if (mIsMovingUp)
        movement.y -= 100.f;
    if (mIsMovingDown)
        movement.y += 100.f;
    if (mIsMovingLeft)
        movement.x -= 100.f;
    if (mIsMovingRight)
        movement.x += 100.f;

    mPlayer.move(movement * deltaTime.asSeconds());
}
void Game::render()
{
    mWindow.clear();
    mWindow.draw(mPlayer);
    mWindow.display();
}
 

4
General / Re: why pollEvent is always used with a while loop?
« on: February 27, 2015, 03:44:42 am »
What you described totally makes sense, but the problem is that the while loop that processes event is in the function processEvents(), and the function update(st::Time) is not inside this loop, which indicates that as long as the program begins to update simulation (it's when update() is called), it's out of this while loop in processEvents() already. Then, after function call update() terminates, it will go on to call render() to plot one frame.

Although I tested it myself with update() inside the while loop of processEvents(), the speed of the circle became non-constant. But why?

5
General / Re: why pollEvent is always used with a while loop?
« on: February 26, 2015, 06:00:41 pm »
Thanks for the heads-up, and apologies for not using the tag. I'm new here, so I do not know the rule.  It actually took me quite a while to find if there is a icon for code font, but I didn't see one.

If the events indeed get queued up, and there are several events being processed per frame, then what if , as I said earlier in my post, there are two events being processed in one frame (I'm not sure if I understand it right. Is one frame equivalent to the main loop in run() being executed once?). One is KeyPressed (assume 'w' is the key that was pressed), and the other one is KeyReleased. These two events should be processes during function call of processEvents(), and when the call ends, the value of 'mIsMovingUp' would still be false ( during the function call, the while loop in processEvents() would be executed twice. In the first time, mIsMovingUp would be changed to be true, and in the twice time, it would be changed to be false). As a result, update(deltaTime) would not make any changes, and the circle would not move as well.

6
General / why pollEvent is always used with a while loop?
« on: February 26, 2015, 04:02:42 pm »
Why pollEvent is always used with a while loop like
while (window.pollEvent(event))
{
    //doing something accordingly to the type of events happened...
}
?

why can it be
if (window.pollEvent(event))
{
    //doing something accordingly to the type of events happened...
}
?

Is it solely because event could be not only just one event but a queue of events, and therefore it need to use while loop to process every event in the queue? If this is indeed the case, the rise another problem. I was just reading this book SFML game development, and in the first chapter, it teaches you to write a program that allows you to move a circle by press 'w', 'a', 's' and 'd', whose code is shown below:

#include<SFML/Graphics.hpp>
class Game;
int main()
{
    Game game;
    game.run();
}
class Game
{
public:
    Game();
    void run();
private:
    void processEvents();
    void update(sf::Time deltaTime);
    void render();
    void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);

    sf::RenderWindow mWindow;
    sf::CircleShape mPlayer;
    bool mIsMovingUp = false;
    bool mIsMovingDown = false;
    bool mIsMovingRight = false;
    bool mIsMovingLeft = false;
};
Game::Game():mWindow(sf::VideoMode(640,480),"SFML Application"),mPlayer()
{
    mPlayer.setRadius(40.f);
    mPlayer.setPosition(100.f,100.f);
    mPlayer.setFillColor(sf::Color::Cyan);
}
void Game::run()
{
    sf::Clock clock;
    while (mWindow.isOpen())
    {
        sf::Time deltaTime = clock.restart();
        processEvents();
        update(deltaTime);
        render();
    }
}
void Game::processEvents()
{
    sf::Event event;
    while(mWindow.pollEvent(event))
    {
        switch(event.type)
        {
            case sf::Event::KeyPressed:
                handlePlayerInput(event.key.code, true);
                break;
            case sf::Event::KeyReleased:
                handlePlayerInput(event.key.code, false);
                break;
            case sf::Event::Closed:
                mWindow.close();
                break;
        }
    }
}
void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
    if(key == sf::Keyboard::W)
        mIsMovingUp = isPressed;
    else if(key == sf::Keyboard::S)
        mIsMovingDown = isPressed;
    else if(key == sf::Keyboard::A)
        mIsMovingLeft = isPressed;
    else if(key == sf::Keyboard::D)
        mIsMovingRight = isPressed;
}
void Game::update(sf::Time deltaTime)
{
    sf::Vector2f movement(0.f, 0.f);
    if (mIsMovingUp)
        movement.y -= 100.f;
    if (mIsMovingDown)
        movement.y += 100.f;
    if (mIsMovingLeft)
        movement.x -= 100.f;
    if (mIsMovingRight)
        movement.x += 100.f;

    mPlayer.move(movement * deltaTime.asSeconds());
}
void Game::render()
{
    mWindow.clear();
    mWindow.draw(mPlayer);
    mWindow.display();
}

In this code, if the object 'event' contained two events at a time while processEvents() was run, say a Event::KeyPressed and a Event::KeyReleased, then after the while loop terminated after finishing processing the two events, the values of four bool type object, 'mIsMovingUp' and the other three, would be set to be false, which would not result in a movement of the circle, but the user indeed had pressed one of the four keys,  and was expecting to see the circle moving.
Therefore, I personally think that using while here with pollEvent would only jeopardize this program, and if would be a much better choice. Am I right?

Pages: [1]