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

Author Topic: sf::Event::Keypressed - Annoying delay while pressing keys  (Read 2865 times)

0 Members and 1 Guest are viewing this topic.

quemaster

  • Newbie
  • *
  • Posts: 1
    • View Profile
sf::Event::Keypressed - Annoying delay while pressing keys
« on: February 21, 2018, 12:57:38 pm »
When i began my journey with SFML, i wanted to create something simple. I chose 2D car game. For this moment it's quite simple: press up to accelerate, left+up or right+up to go in the other directions(i also added some more functions but it doesn't matter right now). The problem is, whenever i press any key, a small delay occurs. It's very annoying, for example, i press up for accelerate. The car moves for 1 pixel, stays for a while and then runs smoothly. Then i press left too to rotate. The car moves to left for one pixel, stays for a while and then turns left until i release left key. I made a video to show this more clearly. Could anybody tell me what should i change in my code to make this issue go away?

https://www.youtube.com/watch?v=5VURSQyqJwA&feature=youtu.be <- the video

#include <SFML/Graphics.hpp>
#include <iostream>
#include <random>
#include <string>
#include <sstream>

        // Converts an int into a string
static inline std::string int2Str(int x)
{
                std::stringstream type;
                type << x;
                return type.str();
}


struct Car
{
    sf::RectangleShape vehicleShape;
    double carPositionX = 10;
    double carPositionY = 10;
    int carSizeX = 20;
    int carSizeY = 10;
    int carRotation = 0.;
    int carVelocity = 1.;
};

int main()
{
    srand(time(0)); // used for random background color
    sf::RenderWindow window(sf::VideoMode(800, 600), "drive");
    sf::Event event;
    sf::Color color(sf::Color::Green);
    Car skoda;
    skoda.vehicleShape.setSize(sf::Vector2f(skoda.carSizeX,skoda.carSizeY));    //setting size of car
    skoda.vehicleShape.setOrigin((skoda.carSizeX/2),(skoda.carSizeY/2));    //setting origin(center point) of the car
    skoda.vehicleShape.setFillColor(sf::Color::Blue);   //setting color of the car

    sf::Font font;
    if(!font.loadFromFile("ComicSans.ttf"))
    {
        skoda.vehicleShape.setFillColor(sf::Color::Black);  //changes color of car when compilator can't find the font
    }

    sf::Text text;     //displays car rotation
    sf::Text debug;     //currently changes color to red whether up is pressed or not, doesn't work
    debug.setFont(font);
    debug.setCharacterSize(50);
    debug.setPosition(40,20);
    debug.setFillColor(sf::Color::Yellow);

    text.setFont(font);
    text.setString(int2Str(skoda.carRotation));
    text.setCharacterSize(10);
    text.setFillColor(sf::Color::Red);
    text.setStyle(sf::Text::Bold | sf::Text::Underlined);

    while(window.isOpen())
    {
        skoda.vehicleShape.setPosition(sf::Vector2f(skoda.carPositionX,skoda.carPositionY)); // sets position of car
        debug.setString("is up pressed");      //as mentioned, doesn't work
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
                window.close();
            if(event.type == sf::Event::KeyPressed)
            {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))     //random background while pressing space
                                                                        //it has the delay too
                {
                    color.g = rand();
                    color.r = rand();
                    color.b = rand();
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                        skoda.vehicleShape.setRotation(skoda.carRotation-=5);
                    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                        skoda.vehicleShape.setRotation(skoda.carRotation+=5);

                    debug.setFillColor(sf::Color::Red);
                    /*it should only be red when up is pressed, but instead it stays red until i
                    press other key*/


                    if(skoda.carRotation>=0 && skoda.carRotation<=90)
                    {
                        skoda.carPositionX += ((90. - skoda.carRotation)/(90./skoda.carVelocity));
                        skoda.carPositionY += (skoda.carRotation/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>90 && skoda.carRotation<=180)
                    {
                        skoda.carPositionX -= ((skoda.carRotation-90)/(90./skoda.carVelocity));
                        skoda.carPositionY += ((90. - (skoda.carRotation-90))/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>180 && skoda.carRotation<=270)
                    {
                        skoda.carPositionX -= ((90. - (skoda.carRotation - 180))/(90./skoda.carVelocity));
                        skoda.carPositionY -= ((skoda.carRotation-180)/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>270 && skoda.carRotation<360)
                    {
                        skoda.carPositionX += ((skoda.carRotation-270)/(90./skoda.carVelocity));
                        skoda.carPositionY -= ((90. - (skoda.carRotation-270))/(90./skoda.carVelocity));
                    }
                }
                else
                    debug.setFillColor(sf::Color::Yellow);

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                 {
                    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                        skoda.vehicleShape.setRotation(skoda.carRotation-=5);
                    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                        skoda.vehicleShape.setRotation(skoda.carRotation+=5);

                    if(skoda.carRotation>=0 && skoda.carRotation<=90)
                    {
                        skoda.carPositionX -= ((90. - skoda.carRotation)/(90./skoda.carVelocity));
                        skoda.carPositionY -= (skoda.carRotation/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>90 && skoda.carRotation<=180)
                    {
                        skoda.carPositionX += ((skoda.carRotation-90)/(90./skoda.carVelocity));
                        skoda.carPositionY -= ((90. - (skoda.carRotation-90))/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>180 && skoda.carRotation<=270)
                    {
                        skoda.carPositionX += ((90. - (skoda.carRotation - 180))/(90./skoda.carVelocity));
                        skoda.carPositionY += ((skoda.carRotation-180)/(90./skoda.carVelocity));
                    }
                    else if(skoda.carRotation>270 && skoda.carRotation<360)
                    {
                        skoda.carPositionX -= ((skoda.carRotation-270)/(90./skoda.carVelocity));
                        skoda.carPositionY += ((90. - (skoda.carRotation-270))/(90./skoda.carVelocity));
                    }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))     //temporary mechanism to set velocity of the car
                    skoda.carVelocity += 1;
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
                    skoda.carVelocity -= 1;
            }
            if(skoda.carRotation>=360)      //making sure that the rotation value won't go beyond 360
                skoda.carRotation = 0;
            if(skoda.carRotation<0)         //and under 0
                skoda.carRotation = 359;

        }
        text.setString(int2Str(skoda.carRotation));
        window.clear(color);
        window.draw(skoda.vehicleShape);
        window.draw(text);
        window.draw(debug);
        window.display();
    }

}

 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Event::Keypressed - Annoying delay while pressing keys
« Reply #1 on: February 21, 2018, 01:06:28 pm »
You're using events and they get trigger the same way like when you input into a text field. First one letter it printed, then a pause and then it starts repeating.

First of you're mixing events and real-time inputs which should not be done. Read the tutorial on events and how to handle them properly.

Since you actually want to do something as long as a key is pressed, you could also just forget about the events and just check the real-time input.
The in my opinion nicer (and more efficient) way is to change a direction variable when there is a key press and change it back when there's a key release and then move your update code outside of the event handling.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/