Ping Pong (Ball Movement)
#1 Members - Reputation: 430
Posted 12 February 2012 - 07:50 PM
I am looking for advice on ball movement for my game. So far, I have the paddles functioning (Smooth movement). I have drawn the ball on the screen, but I need to start the actual movement.
Here are some of my own ideas as to getting the ball moving...
Use the random number function, such as srand and so on.
Use a linear equation for a linear direction(Advice from a friend).
Declaring a function called..... int ballmovement() or void ballmovement.
*I am not familiar with objects and classes yet, so don't recommend anything that has to do with this topic.
#2 Members - Reputation: 308
Posted 13 February 2012 - 05:52 PM
ballPosition += ballVelocity * frameTime; // ballPosition is the position the ball is // ballVelocity is how fast the ball is moving // frametime is the amount of time that passed since last frame
I prefer using vectors, which are basically just x, y and z coordinates, to represent my positions and velocities. You could use single variables aswell...
ballX += velocityX * frameTimer; ballY += velocityY * frameTimer;
Think about how you implemented the paddle movement, just this time instead of waiting for player input, it moves automatically.
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
#4 Members - Reputation: 308
Posted 14 February 2012 - 02:28 PM
Would placing this in a while loop work?
Can never decide on which loop to use when.
Sure a while loop would work just fine... what does your main game loop look like?
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
#5 Members - Reputation: 159
Posted 15 February 2012 - 03:50 PM
_VelocityX = int ( cos( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * ( _CurrentMovementSpeed * _FrameDeltaTime ) ) ); _VelocityY = int ( sin( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * (_CurrentMovementSpeed * _FrameDeltaTime ) ) );p.s _FrameDeltaTime = time it took to complete one cycle or the gameloop. This means the ball travels the same distance no matter the frame rate
then we can use
_Ball->x += _VelocityX; _Ball->y += _VelocityY;
#6 Members - Reputation: 430
Posted 15 February 2012 - 05:30 PM
my main game loop is a while loop..
[/left]
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_LEFT:
keys
[left]= true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_A:
keys[A] = true;
break;
case ALLEGRO_KEY_D:
keys[D] = true;
break;
}
}
else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_A:
keys[A] = false;
break;
case ALLEGRO_KEY_D:
keys[D] = false;
break;
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
}
}
else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) // Close the display
{
done = true; // Shutdown
}
else if(ev.type == ALLEGRO_EVENT_TIMER)
{
player1_y -= keys[LEFT] * 20;
player1_y += keys[RIGHT] * 20;
player2_y -= keys[A] * 20;
player2_y += keys[D] * 20;
redraw = true;
}
if(redraw && al_is_event_queue_empty(event_queue))
{
redraw = false;
al_draw_filled_rectangle(player1_x , player1_y, player1_x + 10, player1_y - 100, al_map_rgb(99,99,100)); // Paddle number 1
al_draw_filled_rectangle(player2_x, player2_y, player2_x + 10, player2_y - 100,al_map_rgb(99,99,100)); // Paddle number 2
// Ball
al_flip_display(); // Helps what has been drawn visible on screen. Switches from blank screen to the actually image
al_clear_to_color(al_map_rgb(0,0,0));
}
}
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][size=3][/size][/font][/color]@MaxFire
Hope I am not bothering you, but can you give me an explanation as to why you recommended sin and cos. I am familiar with the functions, but I am really interested in know how they relate to game programming. An in depth explanation on what sin and cos will be doing in my game, and or maybe other games you might have examples for, in terms of application. The only reason I am asking is because I am a student and I am trying to soak in as much information as I can, to make myself a better programmer.
Thank you both for you suggestions and advice, keep them coming.
Edited by Czar05, 18 July 2012 - 11:21 PM.
#8 Members - Reputation: 208
Posted 16 February 2012 - 02:56 PM
At least for two dimensions, you can represent vectors like velocity in two ways: an angle and a length, or an x-component length and a y-component length. Sine and cosine convert from the angle-length way to the component way. More precisely, given an angle, sine tells you what fraction of the length sticks out in the y direction and cosine tells you what fraction sticks out in the x direction. There are other uses, but that's the one that MaxFire is talking about, and it's one of the most important....can you give me an explanation as to why you recommended sin and cos. I am familiar with the functions, but I am really interested in know how they relate to game programming. An in depth explanation on what sin and cos will be doing in my game, and or maybe other games you might have examples for, in terms of application.
It's useful to use the angle-length form when you want to modify the angle directly - say, by adding five degrees. When you want to do other calculations with the vector, like adding it to another vector, it's usually easiest to convert it into components so that you can deal with each component separately; that's when you need to use sine and cosine. For example, in a top-down racing game you might store the angle so you can rotate the car's velocity clockwise and counterclockwise when the player presses left and right. When the player starts to move forward, then, you would want to get the x- and y-components of the car's velocity so you could add it to the car's position every frame.
In this case I assume MaxFire is recommending you store the angle because you need to ensure that the ball bounces off the paddle at the correct angle. This is not actually necessary if all your walls and paddles are all at right angles; when the ball hits a vertical wall, you can just flip the sign of the x-component of the velocity, and similarly with the y-component for a horizontal wall collision. This will always produce the correct bounce angle.
Later you'll probably want to add a little randomness to the bounces; otherwise, they'll always occur at exactly the same angles, which gets boring. Having the angle to play with does make that easier because you can use it to change the direction easily without changing the speed, but if you're trying to keep things simpler for the moment the sign-flip might be better.
#9 Members - Reputation: 159
Posted 17 February 2012 - 02:52 AM
but may I add that if you simply add speed to X and Y when you want to move at an angle ( NE, SE, SW, NW ) then you will probably be adding or subtracting speed to both X and Y this gives the unwanted effect of doubling the speed of the ball ( you are the full amount to both X and Y ). You could of course compensate for this by keeping track of the latest direction you want to travel in and halving the appropriate velocity ( hard coding all directions ) but then we may as use an angle in the first place
If you need help implementing cos and sin give us a howler il plot out some example code for ya
#12 Members - Reputation: 159
Posted 21 February 2012 - 04:25 PM
im not sure how you code your controls work but I will use arrow keys for player 1 and WS for player 2
finally not knowing your framwework means that i will made logical substitutions on how events may be handled
ok well I scratched this together using notepad on my laptop as my computer has died on me so sorry for any syntax errors
main(int)
{
Player player1;
player player2;
While(!end)
{
//events
if(event)
{
string button = event.getButton(); //this is totally made up for this example many frameworks handle this differantly I know SDL has its own event lableing system ( yes string is very bad way of doing this but makes it clearer as an example)
bool upordown = event.upordown(); // again I dont know your framework so making this up to make scence if( button == up || button == down )
{
player1.HandleEvent( button );// each object should know how to handle its own even in my oppinion
}
else if( button == W || button == S )
{
player2.HandleEvent( button, upordown ):
}
else
{
//anything elts like program close/exit for example
}
}
//updates
player1.Update();
player2.Update();
//drawing
player1.Draw();
player2.Draw();
}
return 0;
}
//player class
class Player
{
public:
//contructor and deconstructor
void Update();
void Draw();
void HandleEvent( string button, bool upordown );
private:
int direction;
int speed;
int _VelocityX;
int _VelocityY;
int X;
int Y;
}
void Player::HandleEvent( string button, bool upordown )
{
//w and up handed in the same way for this example, you can create some sort of id system where w and up return the same id
if( button == w || button == up )
{
if( upordown == true )
{
speed = BALL_SPEED; //probably a const or passed in the constructor
}
else
{
speed = 0;
}
direction = 180;//assumes mathamatic cos and sign where 0 is east direction
}
//elts do the same for down with direction as 90//update velocities if speed is 0 ball will stop
_VelocityX = int ( cos( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * ( _CurrentMovementSpeed * _FrameDeltaTime ) ) );
_VelocityY = int ( sin( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * (_CurrentMovementSpeed * _FrameDeltaTime ) ) );
}
void Player::Update()
{
x += _VelocityX;
y += _VelocityY;
}
void Player::Draw()
{
draw however your frameworks draws
}This is my take on doing something like this, might be some people that disagree but hope it helps. Note the ball movement can be done in exactly the same way but using collision detection to change direction rather than some event from the keyboard
#13 Members - Reputation: 430
Posted 21 February 2012 - 05:41 PM
#15 Members - Reputation: 430
Posted 21 February 2012 - 07:22 PM
int ball_x = 454;
int ball_y = 350;
int ball_rad = 10;
int fx = (ball_y/ball_x) + 1;
int fx1 = (-(ball_y)/ball_x) - 1;
int fx2 = (ball_y/ -(ball_x)) + 1;
int fx3 = (-(ball_y) / -(ball_x)) + 1;
if(!run)
{
if(fx)
{
ball_x = ball_x + 10;
ball_y = ball_y - 10;
}
else if(fx1)
{
ball_x = ball_x + 10;
ball_y = ball_y + 10;
}
else if(fx2)
{
ball_x = ball_x - 10;
ball_y = ball_y - 10;
}
else if(fx3)
{
ball_x = ball_x - 10;
ball_y = ball_y + 10;
}
else
{
rand() * fx * fx1 * fx2 * fx3;
}
al_draw_filled_circle(ball_x, ball_y, ball_rad,al_map_rgb(250,0,0)); // Ball
al_flip_display(); // Helps what has been drawn visible on screen. Switches from blank screen to the actually image
al_clear_to_color(al_map_rgb(0,0,0));int ball_x = 454;
int ball_y = 350;
int ball_rad = 10;
int fx = (ball_y/ball_x) + 1;
int fx1 = (-(ball_y)/ball_x) - 1;
int fx2 = (ball_y/ -(ball_x)) + 1;
int fx3 = (-(ball_y) / -(ball_x)) + 1;
if(!run)
{
if(fx)
{
ball_x = ball_x + 10;
ball_y = ball_y - 10;
}
else if(fx1)
{
ball_x = ball_x + 10;
ball_y = ball_y + 10;
}
else if(fx2)
{
ball_x = ball_x - 10;
ball_y = ball_y - 10;
}
else if(fx3)
{
ball_x = ball_x - 10;
ball_y = ball_y + 10;
}
else
{
rand() * fx * fx1 * fx2 * fx3;
}
al_draw_filled_circle(ball_x, ball_y, ball_rad,al_map_rgb(250,0,0)); // Ball
al_flip_display(); // Helps what has been drawn visible on screen. Switches from blank screen to the actually image
al_clear_to_color(al_map_rgb(0,0,0));
***Sorry if the source code doesn't appear in the proper format****
#16 Members - Reputation: 159
Posted 22 February 2012 - 02:59 AM
With your linear equations are you trying to achieve a random direction? it might be slightly over complicating it but if it works then should be fine
Another suggestion for you would be to define a static const for your speed makes it neater and clearer
static const int BALL_SPEED = 10; Velocity += BALL_SPEED;






