Jump to content

  • Log In with Google      Sign In   
  • Create Account

Ping Pong (Ball Movement)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

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.


Sponsor:

#2 freeworld   Members   -  Reputation: 308

Like
2Likes
Like

Posted 13 February 2012 - 05:52 PM

how bout doing this each frame...

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.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.

#3 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

Posted 13 February 2012 - 07:25 PM

Would placing this in a while loop work?

Can never decide on which loop to use when.

#4 freeworld   Members   -  Reputation: 308

Like
0Likes
Like

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?
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.

#5 MaxFire   Members   -  Reputation: 159

Like
1Likes
Like

Posted 15 February 2012 - 03:50 PM

Simply adding velocity to X and Y is fine but what about when you need to calculate the bounce? surly we need to be a little more accurate using cos sin and bounce angle/ facing direction is better no?

_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 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

Posted 15 February 2012 - 05:30 PM

@freeworld

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.


#7 SeiryuEnder   Members   -  Reputation: 198

Like
0Likes
Like

Posted 16 February 2012 - 01:38 AM

Just a note, it's generally a good idea to put large amounts of code between [.CODE][./CODE] tags.
Makes things easier to read and doesn't bloat the thread as much. :)

#8 before-it-was-popular   Members   -  Reputation: 208

Like
2Likes
Like

Posted 16 February 2012 - 02:56 PM

...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.

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.

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 MaxFire   Members   -  Reputation: 159

Like
1Likes
Like

Posted 17 February 2012 - 02:52 AM

Well I guess before-it-was-popular took the words right out of my mouth nice explanation m8

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 Posted Image

If you need help implementing cos and sin give us a howler il plot out some example code for ya

#10 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

Posted 18 February 2012 - 09:20 PM

I would appreciate some sample code, thanks.

I am using allegro 5 as my library and I am curious if I need an event queue for the ball.

#11 MaxFire   Members   -  Reputation: 159

Like
1Likes
Like

Posted 21 February 2012 - 06:04 AM

I have never used allegro 5 but I will create some sudo code that you will be able to convert to your needs, il post this tonight for you :). And if you are using a game loop rather than event driven you will probably need a queue.

#12 MaxFire   Members   -  Reputation: 159

Like
1Likes
Like

Posted 21 February 2012 - 04:25 PM

ok so you have you game loop, I will just lay out how I would do the basic movement. If I was to do the whole thing you wouldnt be learning anythign Posted Image

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 Posted Image.

#13 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

Posted 21 February 2012 - 05:41 PM

Thank you MaxFire, this is very generous of you. You went above and beyond, and I greatly appreciate it. This is the most help I have ever received from the site...(no offense to the people that answered, I appreciate your help as well). I totally understand that you didn't do the all thing, it is all about the learning experience on my part. Thanks again.

#14 MaxFire   Members   -  Reputation: 159

Like
0Likes
Like

Posted 21 February 2012 - 05:50 PM

Nps dude happy to help, give us A howler with anything elts

#15 Czar05   Members   -  Reputation: 430

Like
0Likes
Like

Posted 21 February 2012 - 07:22 PM

I have a question, was it or is it possible to have ball movement with out classes. Reason I ask is because I haven't started to dive in that area as of yet, soon will. Before you helped me, I used linear equations for ball movement. I want to know if what I did was the right way to go, here is some source code:




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 MaxFire   Members   -  Reputation: 159

Like
1Likes
Like

Posted 22 February 2012 - 02:59 AM

yea you can do it without classes, but if your using c++ then you may as use them. If you are not conformal with classes I suggest reading up on them now because they are one of the core foundation principles of nearly every program :).

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;





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS