# Thread: I present to cprogramming.com: Prongject X

1. ## I present to cprogramming.com: Prongject X

http://i301.photobucket.com/albums/n.../Prongject.jpg

And the source code that makes it all work:
Code:
```#include "Paddle.h"
#include "Ball.h"
#include "Textures.h"
#include "Boundaries.h"
#include "vector2.h"

Ball ball;
Boundaries border;

class Mechanics
{
public:
void check_ball_collision(){
vector2 a_min, a_max, b_min, b_max;
if(ball.velocity.x > 0){
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;
if (collision2d(a_min, a_max, b_min, b_max))
{reverse_x_velocity(ball.velocity);}
else if(ball.location.x > 75)
{reverse_x_velocity(ball.velocity);}}
if(ball.velocity.x < 0){
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;
if (collision2d(a_min, a_max, b_min, b_max))
{reverse_x_velocity(ball.velocity);}
else if(ball.location.x < -75)
{reverse_x_velocity(ball.velocity);}}
if(ball.velocity.y > 0){
if (ball.location.y > 75)
{reverse_y_velocity(ball.velocity);}}
if(ball.velocity.y < 0){
if (ball.location.y < -75)
{reverse_y_velocity(ball.velocity);}}}
private:
bool collision2d(vector2 & a_min, vector2 & a_max, vector2 & b_min, vector2 & b_max) {
return (a_min.x <= b_max.x) && (a_min.y <= b_max.y) && (a_max.x >= b_min.x) && (a_max.y >= b_min.y);}
void reverse_y_velocity(vector2 & velocity)
{velocity.y *= -1;}
void reverse_x_velocity(vector2 & velocity)
{velocity.x *= -1;}
};

Mechanics game;```
Code:
```int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
game.check_ball_collision();
border.draw();
ball.draw(ball.location);
return TRUE;
}```

2. Congratulations

It's a beauty.

3. ty ty, now I'm working on getting freetype lib working so I can get some scoring and winning and stuff in.

4. The screenshot takes me back to the pre-Atari console we had in the very late 70's.

How would I compile it to see it in all it's glory, or do you have a lazy man's .exe you could attach. (I've not advanced to multiple file programming yet).

5. First of all, I think you have come a long way from your first attempt at a card-game!

Can I make some suggestions:
1. You have a tendency to squash braces and code into a single line. That's not good style, in my personal opinion. It gets much easier to read if you format the code over a few more lines (particularly, try to match up the end-brace with the start brace - it makes it much easier to see where each block starts and ends):
Code:
```    void check_ball_collision()
{
vector2 a_min, a_max, b_min, b_max;
if(ball.velocity.x > 0)
{
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;
if (collision2d(a_min, a_max, b_min, b_max))
{
reverse_x_velocity(ball.velocity);
}
else if(ball.location.x > 75)
{
reverse_x_velocity(ball.velocity);
}
}
if(ball.velocity.x < 0)
{
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;
if (collision2d(a_min, a_max, b_min, b_max))
{
reverse_x_velocity(ball.velocity);
}
else if(ball.location.x < -75)
{
reverse_x_velocity(ball.velocity);
}
}
if(ball.velocity.y > 0)
{
if (ball.location.y > 75)
{
reverse_y_velocity(ball.velocity);
}
}
if(ball.velocity.y < 0)
{
if (ball.location.y < -75)
{
reverse_y_velocity(ball.velocity);
}
}
}```
2. The constants 75 and -75 is repeated many times. Maybe you should use a (descriptively) named constant instead?

3. Large functions inline within the class declaration makes the header-file quite bulky and it gets hard to follow what member functions and member variables the class actually consists of. And it is unlikely that large functions with several dozen lines calling small functions will get inlined, since the compiler will first inline the small functions into the large function, at which point the large function gets too large to inline.

4. Try to avoid global variables. You have two paddle variables and a ball. It would probably be a good idea to have those as part of the mechanics or some other object, rather than as global variables. Is there any other class that uses paddle1, paddle2 and ball? If not, stick them in mechanics. If they are used by other classes, consider passing them in as parameters and use some overall class to bundle mechanics, the paddles and the ball together.

5. This segment of code is repeated twice:
Code:
```		a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;```
6. This
Code:
```    void reverse_y_velocity(vector2 & velocity)
{
velocity.y *= -1;
}```
could be written as:
Code:
```    void reverse_y_velocity(vector2 & velocity)
{
velocity.y = -velocity.y;
}```
and assuming the compiler does what you tell it to, you'd save a few clock-cycles by not using multiplication [ok, so chances are that the compiler does realize what you are doing and produces a negate instruction either way - but it doesn't seem to be any point to multiplying by -1].

--
Mats

6. Matsp thanks so much for your suggestion it's exactly what I needed to make the paddle loop go away!
Actually I did something a little different now that I look again, I did this:
Code:
```#include "Player.h"
#include "Ball.h"
#include "Boundaries.h"
#include "vector2.h"

Player player1;
Player player2;
Ball ball;
Boundaries border;

class Logic
{
public:
void check_ball_collision()
{
vector2 a_min, a_max, b_min, b_max;
if(ball.velocity.x > 0)
{
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;

if (collision2d(a_min, a_max, b_min, b_max))
{
reverse_x_velocity(ball.velocity);
}
else if(ball.location.x > 75)
{
reverse_x_velocity(ball.velocity);
player2.goal();
}
}
if(ball.velocity.x < 0)
{
a_min = ball.location + ball.d_min;
a_max = ball.location + ball.d_max;

if (collision2d(a_min, a_max, b_min, b_max))
{
reverse_x_velocity(ball.velocity);
}
else if(ball.location.x < -75)
{
reverse_x_velocity(ball.velocity);
player1.goal();
}
}
if(ball.velocity.y > 0)
{
if (ball.location.y > 75)
{
reverse_y_velocity(ball.velocity);
}
}
if(ball.velocity.y < 0)
{
if (ball.location.y < -75)
{
reverse_y_velocity(ball.velocity);
}
}
}
{
{
}
{
}
{
}
{
}
}
private:
bool collision2d(vector2 & a_min, vector2 & a_max, vector2 & b_min, vector2 & b_max)
{
return (a_min.x <= b_max.x) && (a_min.y <= b_max.y) && (a_max.x >= b_min.x) && (a_max.y >= b_min.y);
}
void reverse_y_velocity(vector2 & velocity){velocity.y = -velocity.y;}
void reverse_x_velocity(vector2 & velocity){velocity.x = -velocity.x;}
};

Logic logic;```

7. great game :] you should post it in the 'post your games thread', i've got one that looks like this in there

it uses glfont2 http://students.cs.byu.edu/~bfish/glfont2.php -- it works alright but it is many years old there might be better solutions now

8. The new code is better.

But you are still repeating the a_min and a_max calculation twice. The only time it's not going to be done is if ball.velocity.x == 0 [not sure if that's valid at all! - if it isn't, perhaps you should add a debug assert to ensure it doesn't happen].

Also, you still have the constants 75 and -75 in the code. It should be "field_size" or some such, I think.

Is the 70 in "paddle_collision" also related to the 75? If so, you probably should have that as a calculation from the named constant.

--
Mats