2d pong

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
catman13
Posts: 8
Joined: Fri Jan 15, 2010 11:18 pm

2d pong

Post by catman13 »

Hello,

I was just wondering how you would make the pong ball move correctly when it bounces off the walls or paddles.

It would help if you could tell me the formula to calculate the angle and show me how do make it move in the direction.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

I don't know if you are referring to a specific program, but in general...
(without considering elasticity or friction or anything else)

if you are bouncing off a horizontal or vertical wall, it makes the calculations simple.

Horizontal Wall (or collision object):

Code: Select all

objectVelocity.X = - objectVelocity.X
Vertical Wall (or collision object):

Code: Select all

objectVelocity.Y = - objectVelocity.Y
That is how to make it move in the correct direction. You don't need the angle, the x and y velocities produce the angle.

If you want to know the angle, the rebound angle is exactly the same as the approach angle but in the opposite (x or y) direction depending if it hit the horizontal or vertical wall.

if the wall (or collision object) is non-perpendicular then you need to consider the angle of the wall.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

I actually saved some code that rogerborg posted for reflection, I don't know why :lol: but here it is:

Code: Select all

// Include the Irrlicht header
#include "irrlicht.h"
#include <assert.h>

#pragma comment(lib, "Irrlicht.lib")

// Irrlicht Namespaces
using namespace irr;
using namespace core;

vector3df reflectVectorFromSurface(const vector3df & incident,
                                   const vector3df & surfaceNormal)
{
    vector3df reflection(incident);

    const f32 dot = vector3df(reflection).normalize().dotProduct(vector3df(surfaceNormal).normalize());

    // I'm assuming that the surface is double sided, and that rays coming from inside it
    // are reflected internally.  If you want to make it single sided, perform this check.
    //if(dot > 0.f)
    //    return incident;

    // Otherwise, we have to reject parallel vectors or we get NaN results.
    if(equals(dot, 1.f))
        return incident;

    // Pretend that it's being emitted from the surface.
    reflection.invert();

    quaternion MrQuaternion;

    // Calculate the quaternion that will rotate the (inverted) incident to match the normal.
    (void)MrQuaternion.rotationFromTo(reflection, surfaceNormal);

    // Make it a matrix
    matrix4 rotationMatrix;
    MrQuaternion.getMatrix(rotationMatrix);

    // And apply it twice to the inverted incident vector.
    rotationMatrix.rotateVect(reflection);
    rotationMatrix.rotateVect(reflection);

    return reflection;
}

void testReflection(const vector3df & incident,
                    const vector3df & surfaceNormal,
                    const vector3df & expectedReflection)
{
    vector3df reflection = reflectVectorFromSurface(incident, surfaceNormal);
    (void)printf("Result %f %f %f\n", reflection.X, reflection.Y, reflection.Z);
    assert(reflection == expectedReflection);
}

int main()
{
    testReflection(vector3df(5, 0, 0), vector3df(-1, 0, 1), vector3df(0, 0, 5));

    // This is coming from inside the surface.  We'll reflect it, but it could
    // also be emitted; see the comments in reflectVectorFromSurface()
    testReflection(vector3df(-5, 0, 0), vector3df(-1, 0, 1), vector3df(0, 0, -5));

    // This is coming in orthogonally, so should be reflected directly back.
    testReflection(vector3df(5, 0, -5), vector3df(-1, 0, 1), vector3df(-5, 0, 5));

    // This is perpendicular, so should be emitted unchanged.
    testReflection(vector3df(5, 0, 0), vector3df(1, 0, 0), vector3df(5, 0, 0));
}
Post Reply