computer pong paddle

Started by
20 comments, last by phil67rpg 10 years, 4 months ago

well I am making a simple pong game using dx9 and c++. I want to do the AI for the computer pong paddle. All I want the paddle to do is move up and down and up again on the edge of the screen.

Advertisement

Have a Paddle object. The Paddle object can have a vertical position field (m_VerticalPos or something), which you can increase or decrease to change the Paddle's position on the screen. When you render the Paddle object, use its vertical position field to create the model transform matrix. You can use a function like D3DXMatrixTranslation to create the translation matrix (pass m_VerticalPos into the y argument).

Kinda vague, but if you want a more specific answer you'll have to ask a more specific question.

The simplest approach is to make the paddle move up or down by having the same Y position as the ball. In the update loop you would have something like this:


cpuPaddle.y = ball.y

There is a problem here, though. The computer paddle never misses. You need do add a delay of some sort. You could add a skip frame every n-th frame so the computer paddle will miss from time to time. Another method that I like more is to add some sort of easing to the coputer paddle's movement. This will add a small delay every time the computer paddle starts moving.


cpuPaddle.y += (ball.y - cpuPaddle.y) * 0.15;

Well, something like this in the update loop could work:


const int reactionRange = 600;

// IF the ball is near the paddle and moving towards the paddle
	if ((ballY - getPosition().y <= reactionRange) && (ballDir >= 90 && ballDir <= 270)) 
	{
                // If the ball is a little to the left of the paddle, move left
		if (ballX <= getPosition().x+30) 
		{
			movement.ChangeSpeed(8);
			movement.ChangeDirection(90);
		}
                // If the ball is a little to the right of the paddle, move right
		else if (ballX >= getPosition().x + getLocalBounds().width - 30)
		{
			movement.ChangeDirection(270);
			movement.ChangeSpeed(8);
		}
                // Else the ball is between the paddle ends, and there is no need to move
		else movement.ChangeSpeed(0);
	}

With this approach there are a few things that you can do to change the difficulty of the AI. You can change the reactionRange so that the paddle begins moving earlier. Or change the speed of the paddle. This is still extremely basic but it should serve as a base for more extensive decisions.

EDIT: Damn, I just realized that I created code for a paddle moving left to right.. But just convert it to up/down. Sorry.

cpuPaddle.y = ball.y

That would mean the AI player can move the paddle at an infinite speed, which I believe can make it flawless victory for him biggrin.png

I think the trick is to have some limit as to what speed you can move the paddle with - so if the ball bounces of a wall and is near enough the AI player he cannot move in time to stop it. Basically, let's say for an easy game mode - the AI player would predict where the ball will be, based on it's movement vector - the ball would collide with the "goal wall" of the AI player at some y value - so the AI player would aim to get to that y value (x is fixed as you only move up and down). Basically look for the intersection point of the parametric equation for the ball movement and the wall.

Example:


Define the wall:
x=w0, for every y.
Line definition for the movement of the ball(assuming the ball is moving with constant speed):
x = x0 + bx*s
y = y0 + by*s
Direction vector for the ball b(bx,by).
Starting point of the ball B0(x0,y0).

So now you solve the equations for s:
w0 = x = x0 + bx*s
=>
s = (w0-x0)/bx (the ball should be moving on the x axis or you have a division by 0)
y = y0 + by*(w0-x0)/bx

That's how you get at what y value the ball will hit the wall of the AI player.
So each movement update the AI player should try to move towards that y with his max speed until he can reach it. Now, when will he miss? The trivial case: if the AI player's max speed is too low and the ball is too fast, so you should at least make the AI player be able to catch any ball that didn't change direction since you shot it. And here's the other thing - when will the ball change direction - when it bounces off a wall. The nearer the ball bounces of a wall to the AI player, the more likely it is that the AI player won't be able to catch it in time.
Here's an example of that case - you shoot the ball so that it will bounce off right before reaching the AI player let's say from the upper wall. So when the AI paddle reaches the upper wall it will just stay there waiting, and when the ball bounces off it won't be able to move fast enough to catch it. For higher difficulty you can give the AI player the possibility to calculate one or 2 bounces or at least approximate them to some extent, give a higher limit to the speed for the AI player paddle, nd make the ball faster(which will actually make the AI player miss more to be honest, but you will start missing more too). So by playing with that max_speed, ball_speed, the predictive possibilities for the AI, maybe even make the ball lose speed when it bounces off(basically non constant ball speed) etc. you can tweak the "difficulty level".

That example got kinda bigtongue.png . if anything is not clear feel free to ask. Maybe there's a better method but I can't think of such a method now(probably a method that will rather approximate things a little so the AI player would do more mistakes - kinda like a human, probably use an approximation of where the ball will be, get some randomness in the whole thing etc.).

here is my code

RECT rect;

rect.left=0;

rect.top=0;

rect.right=35;

rect.bottom=100;

RECT rect_two;

rect_two.left=989;

rect_two.top=y;

rect_two.right=1024;

rect_two.bottom=y+100;

RECT rect_three;

rect_three.left=m+506;

rect_three.top=n+380;

rect_three.right=m+516;

rect_three.bottom=n+390;

m+=5;

n+=5;

if(m>=108 && n>=278)

{

m+=5;

n-=5;

}

//draw surface to the backbuffer

d3ddev->StretchRect(surface_two, NULL, backbuffer, NULL, D3DTEXF_NONE);

//draw surface to the backbuffer

d3ddev->StretchRect(surface, NULL, backbuffer, &rect, D3DTEXF_NONE);

//draw surface to the backbuffer

d3ddev->StretchRect(surface_three, NULL, backbuffer, &rect_two, D3DTEXF_NONE);

//draw surface to the backbuffer

d3ddev->StretchRect(surface_four, NULL, backbuffer, &rect_three, D3DTEXF_NONE);

//stop rendering

d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);

}

?

Do you have a question?

If not, good luck onwards.

Hello to all my stalkers.

how do I get the ball to bounce off the edges of the screen.

well I have tried the following code

(vel_y >= 0 && vel_y <= 664) ? vel_y+=5 : vel_y-=5;

this code moves the paddle down to the edge of the screen but I want it to move up the screen and down again.

In pseudo-code, because I believe in learning by doing, instead of learning by copying:


Somewhere, you need to know and keep track of the position of the ball, and the speed of the ball.

if the ball is moving up, and the ball is too high up on the screen...
    change/inverse the speed so the ball moves up.
if the ball is moving down, and the ball is too low on the screen...
   change/inverse the speed so the ball moves up.
Move the ball according to its speed.

Similar logic applies if you want it to bounce on the left & right walls.

Hello to all my stalkers.

This topic is closed to new replies.

Advertisement