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

Author Topic: How to add speed  (Read 4547 times)

0 Members and 1 Guest are viewing this topic.

MitjaHD

  • Newbie
  • *
  • Posts: 6
    • View Profile
How to add speed
« on: August 25, 2018, 05:51:25 pm »
I'm a beginner and have never programmed games, now I'm trying to create PONG game, but I'm stuck at ball movement. I don't really care about angles yet, I would just like to move a ball at constant speed in some direction. I know that veolcity is distance / time, but I don't really know how to apply it in SFML. I read the documents regarding drawing stuff, handling time... I created Tic Tac Toe game but now I'm stuck.
I would appriciate help and maybe an example and I also know this might be a stupidily easy problem but I could't find the answer yet.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How to add speed
« Reply #1 on: August 26, 2018, 10:06:06 am »
Movement isn't covered by SFML; you need to calculate positions from movement manually. However, it's not so difficult :D

sf::Vector2f Velocity(10.f, 0.f);

position += velocity; // assuming that position is also an sf::Vector2f

This will change the position towards the right at 10 (pixels if the view matches the window) per frame.
To change the speed, change the value of 10.
To change the direction to left, use a negative number and to use a vertical direction use the other element:
(0.f, 10.f) to go upwards.
Of course, you can use both to go in a diagonal direction.

For exact values for velocity you can use sine and cosine to calculate for any possible direction.



* Slightly more advanced *
Once you have the velocity, you should be aware that the frames may not take the same amount of time so multiplying the velocity by the difference in time (commonly called delta time or dt) allows you solidify the exact speed over time regardless of how long the frame takes. In fact, the value for velocity then becomes 'per second'.
So:
sf::RenderWindow window;
window.setFrameRateLimit(120u);
sf::Vector2f position;
sf::Clock clock;

while (window.isOpen()
{
    // event handling (while window.pollEvent)

    float dt = clock.restart().asSeconds(); // restart gives the amount of time passed and also restarts the clock allowing a constant looping
    sf::Vector2f velocity(100.f, 0.f); // 100 to the right per second
    position += velocity * dt;

    // render (clear, draw, display)
}
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

MitjaHD

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to add speed
« Reply #2 on: August 26, 2018, 05:31:55 pm »
#include <SFML/Graphics.hpp>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <conio.h>

sf::Vector2i mousePos;
bool startPlaying = false;

sf::Vector2f position(510.f, 310.f);

using namespace std;

int main()
{
    //Window, position, origin... stuff
    sf::RenderWindow window(sf::VideoMode(1600, 800), "Tic Tac Toe");
    sf::RectangleShape board(sf::Vector2f(1020,620));
    sf::RectangleShape line(sf::Vector2f(10,610));
    sf::RectangleShape left_paddle(sf::Vector2f(15,80));
    sf::CircleShape ball;
    board.setFillColor(sf::Color::Blue);
    board.setOutlineThickness(-10);
    line.setOrigin(5,0);
    line.setPosition(1020/2,0);
    window.setFramerateLimit(120u);

    left_paddle.setPosition(25,300);
    left_paddle.setOrigin(15/2,80/2);
    left_paddle.setFillColor(sf::Color::Yellow);
    ball.setRadius(10);
    ball.setFillColor(sf::Color::Red);
    ball.setPosition(position.x, position.y);
    ball.setOrigin(ball.getRadius(), ball.getRadius());

    sf::Clock clock;


    while (window.isOpen())
    {
        float dt = clock.restart().asSeconds();

        sf::Vector2f Velocity(2.f, 0.f);
        position += Velocity * dt;
        cout<<"pos x:" << position.x <<endl;


        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            if(event.type == sf::Event::MouseButtonPressed)
            {
                if(event.mouseButton.button == sf::Mouse::Left)
                {
                    mousePos = sf::Mouse::getPosition(window);
                    printf("x: %i, y: %i\n",mousePos.x,mousePos.y);
                }
            }

            //Left paddle movement
            if(event.type == sf::Event::MouseMoved)
            {
                mousePos = sf::Mouse::getPosition(window);
                left_paddle.setPosition(25,mousePos.y);
                if(mousePos.y < 50)
                {
                    left_paddle.setPosition(25,50);
                }
                if(mousePos.y > 570)
                {
                    left_paddle.setPosition(25,570);
                }
            }

        }
       
        //Other functions
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
            {
                startPlaying = true;
            }

        while(ball.getPosition().x > 10 && ball.getPosition().x < 1010 &&   //inside game board
              ball.getPosition().y > 10 && ball.getPosition().x < 610  )
        {
            ball.move(position.x, 0);
        }

        //Drawing stuff
        window.clear();
        window.draw(board);
        window.draw(line);
        window.draw(left_paddle);
        window.draw(ball);
        window.display();
    }

}
 

This is my code currently and now my problem is that the ball moves to the edge immediately, but in console it shows that position.x  is chaing slowly from 510 onwards as it should.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How to add speed
« Reply #3 on: August 27, 2018, 03:22:22 pm »
You don't want to be "moving" the ball by the target position. You move the ball by the difference in positions. Better still, you could just set its position:
ball.setPosition(position);
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

MitjaHD

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to add speed
« Reply #4 on: August 31, 2018, 05:53:39 pm »
Alright thanks, it is working now, but I have a question about clock/time. Delta time (dt) is constantly restarting, but if it doesn't start as soon as the program opens it's value is equal to seconds passed, for example if I want 5 seconds before I press SPACE to start the game (start moving ball), dt is already 5 and the ball moves very quick.

if(startPlaying==true)
{
    float dt = clock.restart().asSeconds();
    position += Velocity * dt;
}
 

Clock is created outside while function.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How to add speed
« Reply #5 on: August 31, 2018, 09:47:31 pm »
Try creating the clock immediately before the "window.isOpen" while loop as the very last thing to do.
Otherwise, just restart the clock immediately before that while loop.

This way you are avoiding the amount of time it takes to initialise everything, including the creation of your window and loading resources if you are doing those after creating the clock.

Another option (not that you need one now) is to use a so-called pausable clock that you can start and stop whenever you need to, including stopping it when doing something "outside of the game bit".

Kairos has a few different types of pausable clocks (Stopwatch is the simple one, Continuum is the advanced one; in fact, Timestep uses Continuum, which uses Stopwatch!).
Thor also has a pausable clock.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*