• Create Account

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.

21 replies to this topic

### #1phil67rpg  Members

215
Like
0Likes
Like

Posted 30 November 2013 - 06:51 PM

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.

### #2Samith  Members

2450
Like
1Likes
Like

Posted 30 November 2013 - 07:15 PM

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.

### #3ram64  Members

862
Like
1Likes
Like

Posted 01 December 2013 - 02:14 AM

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;


Edited by ram64, 01 December 2013 - 02:14 AM.

### #4PragmaOnce  Members

755
Like
0Likes
Like

Posted 01 December 2013 - 05:51 AM

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.

Edited by PragmaOnce, 01 December 2013 - 05:56 AM.

### #5lightxbulb  Members

1164
Like
0Likes
Like

Posted 01 December 2013 - 07:04 AM

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

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

Edited by lightxbulb, 01 December 2013 - 07:32 AM.

### #6phil67rpg  Members

215
Like
-2Likes
Like

Posted 01 December 2013 - 08:04 PM

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);

}

### #7Lactose  GDNet+

9652
Like
1Likes
Like

Posted 01 December 2013 - 08:05 PM

Do you have a question?

If not, good luck onwards.

Hello to all my stalkers.

### #8phil67rpg  Members

215
Like
0Likes
Like

Posted 04 December 2013 - 10:50 PM

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

### #9phil67rpg  Members

215
Like
0Likes
Like

Posted 05 December 2013 - 12:09 AM

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.

### #10Lactose  GDNet+

9652
Like
2Likes
Like

Posted 05 December 2013 - 03:27 AM

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.

### #11lightxbulb  Members

1164
Like
1Likes
Like

Posted 08 December 2013 - 02:18 AM

You gotta check for collision with the upper and lower walls. So let's say the upper wall is at y=upperY and the lower wall is at y = lowerY.

You got some radius of the ball, so you would check for collisions kinda like this:

//ball.position.y is the y coord of your ball
{
//Collision at (ball.position.x, upperY)
//calculate the bounce-off - we want to "reflect the ball from the wall
//To calculate reflection of a vector we need the normal of the wall
// However since the wall is parallel with the Ox basis vector, the normal of the wall
//is perpendicular to it, so for the upper wall we'll have upperNormal(0,-1)
//where ball.direction is the directional vector of the ball:
kFi = dot(ball.direction,upperNormal);
ball.direction.x = ball.direction.x - 2*kFi*upperNormal.x;
ball.direction.y = ball.direction.y - 2*kFi*upperNormal.y
}

//ball.position.y is the y coord of your ball
{
//Collision at (ball.position.x, lowerY)
//calculate the bounce-off - we want to "reflect the ball from the wall
//To calculate reflection of a vector we need the normal of the wall
//However since the wall is parallel with the Ox basis vector, the normal of the wall
//is perpendicular to it, so for the lower wall we'll have lowerNormal(0,1)
//where ball.direction is the directional vector of the ball:
kFi = dot(ball.direction,lowerNormal);
ball.direction.x = ball.direction.x - 2*kFi*lowerNormal.x;
ball.direction.y = ball.direction.y - 2*kFi*lowerNormal.y
}

//And you use the new ball direction vector to move your ball once again


It's better if your ball.direction vector is normlized - then you can do this for movement:

//Each frame(if you got a game clock it's better)
ball.position = ball.position + ball.direction*ball.speed*deltaTime;
//Where you can calculate deltaTime each frame like so(not really a great way though):
deltaTime = fps*100/6;
//fps is frames per second


P.S. If something is not clear enough, tell me what it is and I'll elaborate more on it

Edited by lightxbulb, 08 December 2013 - 04:03 AM.

### #12phil67rpg  Members

215
Like
0Likes
Like

Posted 09 December 2013 - 07:53 PM

thanks lightxbulb could you help me with the paddle movement only.

### #13phil67rpg  Members

215
Like
0Likes
Like

Posted 18 December 2013 - 04:38 PM

well I can get the paddle to move up or down the screen but I cant get it to move up and down and up and down again. here is the code that moves the paddle up the screen.

RECT rect;
rect.left=0;
rect.top=vel_y+664;
rect.right=35;
rect.bottom=vel_y+764;

if (vel_y <= 0 && vel_y >= -659)
{
vel_y-=5;
}


### #14Lactose  GDNet+

9652
Like
2Likes
Like

Posted 18 December 2013 - 04:42 PM

You can have more than 1 if in the same block of code.

You can, for example, have 1 if statement that controls moving up, and 1 if statement that controls moving down.

Hello to all my stalkers.

### #15phil67rpg  Members

215
Like
0Likes
Like

Posted 18 December 2013 - 04:51 PM

You can, for example, have 1 if statement that controls moving up, and 1 if statement that controls moving down.

ok I have implemented 2 if statements but it only moves the paddle up and stays at the top of the screen.



if (vel_y <= 0 && vel_y >= -659)
{
vel_y-=5;
}

if (vel_y >= 0 && vel_y <= 659)
{
vel_y+=5;
}


### #16Lactose  GDNet+

9652
Like
2Likes
Like

Posted 18 December 2013 - 05:00 PM

If the first if is triggered, vel_y is never above 0, and it gets decremented. This means vel_y never becomes higher than 0. This means if the first if happens, it will never swap to using the second if.

The same logic applies for the second if.

You need to re-think your if logic and try again.

I don't want to outright tell you how to solve this, because this stuff you need to be able to figure out on your own.

As a tip, try drawing the top and bottom borders on a piece of paper, and label the y coordinates. Then, using the paper, figure out when you want the paddle to move up and down.

Hint: You might have to change something to keep track of which direction the paddle is currently moving. I would suggest storing the paddle's speed and using that.

Hello to all my stalkers.

### #17phil67rpg  Members

215
Like
0Likes
Like

Posted 18 December 2013 - 05:30 PM

As a tip, try drawing the top and bottom borders on a piece of paper, and label the y coordinates. Then, using the paper, figure out when you want the paddle to move up and down.

### #18lightxbulb  Members

1164
Like
1Likes
Like

Posted 20 December 2013 - 10:13 AM

well I can get the paddle to move up or down the screen but I cant get it to move up and down and up and down again. here is the code that moves the paddle up the screen.

RECT rect;
rect.left=0;
rect.top=vel_y+664;
rect.right=35;
rect.bottom=vel_y+764;

if (vel_y <= 0 && vel_y >= -659)
{
vel_y-=5;
}


I'll just give you the way I'd do it, and not fix your code, as CoreLactose mentioned it's more useful if you figure it out yourself(though I believe that sometimes a person needs to have seen how it works numerous times to make it work).

Here's what I would do:

1)I will give my paddle some constant speed for movement (we don't need acceleration just yet I think )

2)I will check when the player pressed up/down and resolve these cases

3)I will check for collisions with the walls

Incoming pseudo-code:

//At init:
int upperWallY = 10;
int lowerWallY = screenHeight-10;

//In the main loop:
//where keyPressed is a function that checks if that key was pressed
//And the other statement checks if a collision would occur
{
}

{
}


### #19Lactose  GDNet+

9652
Like
1Likes
Like

Posted 20 December 2013 - 10:32 AM

I believe the question refers to making the AI paddle move up and down, based on the initial post.

While I would do this based on the ball's current position or something, the question seems to be related to just moving the paddle up to the ball, and then back down again.

Hello to all my stalkers.

### #20lightxbulb  Members

1164
Like
0Likes
Like

Posted 20 December 2013 - 11:06 AM

Lolz seems like I went full retard  I thought he was talking about his paddle.

Here's a revised version then:

1)You calculate where the ball will collide with the wall behind the AI paddle:

k = (wallBehindAIPaddleX - ballX)/ ballVelocityX; //care not to have ballVelocityX == 0
pointOfCollisionAtY = ballY + ballVelocityY*k;

2)If the y component of that point is < upperWallY or >lowerWallY the AI paddle should aim for either upperWallY+paddleSizeY/2 or lowerWallY-paddleSizeY/2, otherwise it should aim just for that point ( basically if the ball is assumed to go beyond the upper or lower wall, the paddle should just wait at the upper or lower walls, because it can't go beyond them).

Basically something like this:

//Check this once each time the ball bounces off something or the game starts
{
}

{
}

//In the main loop:
//If the distance between the paddle and the point where it wants to be can be
//taken in one go - go there
{
}
//If it can't, do it by steps each frame until you can get to where you want
else
{