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

Author Topic: Change movement direction?  (Read 6564 times)

0 Members and 1 Guest are viewing this topic.

JulianOri

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Change movement direction?
« on: June 24, 2014, 05:17:46 pm »
Hi! =)

I´m programming a little game where a ball flies through the window and when it hits the end of the window it shall change its direction. Here´s the code I´m using for this:

void Ball::update(float frametime)
{
        if (pSpriteB->getPosition().y >= 9)
        {
                pSpriteB->move(-400 * frametime, -400 * frametime);
        }
        else if (pSpriteB->getPosition().y <= 9)
        {
                pSpriteB->move(400 * frametime, 400 * frametime);
        }
}

But when the ball hits the window´s end, it just stops and vibrates a bit. What I thought was that the previous movement is still active and I have to end up this previous movement so that the new movement direction can be done without errors, but I didn´t find anything to end up a movement.

What shall I do? Why isn´t it moving correctly? Please help!  :D


Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Change movement direction?
« Reply #1 on: June 24, 2014, 05:38:03 pm »
Simplest way to make something bounce off a wall is to just invert the x and y parts of the velocity/direction vector.

JulianOri

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Change movement direction?
« Reply #2 on: June 24, 2014, 05:44:40 pm »
Hi!  :)

This sounds logic, but unfortunately I don´t have any knowledge on vectors. In school we will have this topic  in about 1 year and on top of that I don´t really understand how SFML handles vectors.

Do you think it will help when I deal with vector mathematics? :)

Julian

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6276
  • Thor Developer
    • View Profile
    • Bromeon
Re: Change movement direction?
« Reply #3 on: June 24, 2014, 05:52:25 pm »
In game development, vector algebra is absolutely crucial. It's not a very difficult topic, yet it comes in extremely handy because you can essentially get rid of low-level math like component-wise operations or trigonometry. And for more complex operations like the cross-product, there is not even a straightforward way without knowing vector algebra.

If you're interested, I suggest you already have a look at vectors, it will certainly be of advantage in school :)

Having said that, you want to make the ball movement dependent on the velocity, not the position. Velocity is simply the change in position per time, or velocity = distance/time. On the other hand, this lets you infer the travelled distance as distance = velocity*time. With vectors, this extends to every component.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Change movement direction?
« Reply #4 on: June 24, 2014, 05:54:08 pm »
A basic knowledge of vector math makes many things like this a lot simpler, yes. Reading up on basic vector math would definitely be something I'd recommend.
If you want some easy to use classes to help you, take a look at the vector stuff in the Thor library: http://www.bromeon.ch/libraries/thor/index.html .

I don't have time today, but unless someone beats me to it I could make a simple bouncing ball example for you tomorrow evening.

JulianOri

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Change movement direction?
« Reply #5 on: June 24, 2014, 06:08:45 pm »
Hey guys!  :)

Thanks for all your expenditure! =)

I know that vectors are extremely important for game programming, so I think I´m going to deal with them. I hope I find a better way than this I used in my code example.

Making a little example a ball bouncing around would be really nice, but when there´s too much expenditure then of course you haven´t to do it for me.

Julian :D

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Change movement direction?
« Reply #6 on: June 24, 2014, 06:14:33 pm »
It won't take long to do. I'll try to find the time tomorrow - no problem.

In the mean time you could start reading here: http://mathinsight.org/vector_introduction and there are many other good introduction resources to be found online.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Change movement direction?
« Reply #7 on: June 25, 2014, 10:59:40 pm »
Ok, as promised, here's a simple example of a bouncing ball.

Stick it in a file called bounce.cc and then you can build it (on Linux) like this:
$ clang++ -std=c++11 -lsfml-window -lsfml-graphics -lsfml-system -o bounce bounce.cc
and then run it like so:
$ ./bounce

Each time you run the program the ball will get a random direction and speed, so run it a few times to see different bounces.

#include <SFML/Graphics.hpp>
#include <random>
#include <functional>
#include <cstdlib>
#include <cmath>

int main()
{
    const int window_width = 400;
    const int window_height = 300;
    const float ball_radius = 16.f;
    const int bpp = 32;

    sf::RenderWindow window(sf::VideoMode(window_width, window_height, bpp), "Bouncing ball");
    window.setVerticalSyncEnabled(true);

    std::random_device seed_device;
    std::default_random_engine engine(seed_device());
    std::uniform_int_distribution<int> distribution(-16, 16);
    auto random = std::bind(distribution, std::ref(engine));

    sf::Vector2f direction(random(), random());
    const float velocity = std::sqrt(direction.x * direction.x + direction.y * direction.y);

    sf::CircleShape ball(ball_radius - 4);
    ball.setOutlineThickness(4);
    ball.setOutlineColor(sf::Color::Black);
    ball.setFillColor(sf::Color::Yellow);
    ball.setOrigin(ball_radius / 2, ball_radius / 2);
    ball.setPosition(window_width / 2, window_height / 2);

    sf::Clock clock;
    sf::Time elapsed = clock.restart();
    const sf::Time update_ms = sf::seconds(1.f / 30.f);
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if ((event.type == sf::Event::Closed) ||
                ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))) {
                window.close();
                break;
            }
        }

        elapsed += clock.restart();
        while (elapsed >= update_ms) {
            const auto pos = ball.getPosition();
            const auto delta = update_ms.asSeconds() * velocity;
            sf::Vector2f new_pos(pos.x + direction.x * delta, pos.y + direction.y * delta);

            if (new_pos.x - ball_radius < 0) { // left window edge
                direction.x *= -1;
                new_pos.x = 0 + ball_radius;
            } else if (new_pos.x + ball_radius >= window_width) { // right window edge
                direction.x *= -1;
                new_pos.x = window_width - ball_radius;
            } else if (new_pos.y - ball_radius < 0) { // top of window
                direction.y *= -1;
                new_pos.y = 0 + ball_radius;
            } else if (new_pos.y + ball_radius >= window_height) { // bottom of window
                direction.y *= -1;
                new_pos.y = window_height - ball_radius;
            }
            ball.setPosition(new_pos);

            elapsed -= update_ms;
        }

        window.clear(sf::Color(30, 30, 120));
        window.draw(ball);
        window.display();
    }

    return EXIT_SUCCESS;
}
 
« Last Edit: June 25, 2014, 11:02:58 pm by Jesper Juhl »

JulianOri

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Change movement direction?
« Reply #8 on: June 28, 2014, 02:14:27 pm »
Thank you very much!

 ;D

Hapax

  • Hero Member
  • *****
  • Posts: 3058
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Change movement direction?
« Reply #9 on: June 28, 2014, 02:45:09 pm »
Just as an aside, I noticed that in your logic, you are testing to see if the values are equal (>=) in the first if, then - once you are certain that it is not (else) - testing to see if it is equal again (<=). This means that the only time that it runs the second part is when it is less than. As soon as it becomes equal again, it switches back to the first code.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

 

anything