Introduction
This is the game we all know, the classic Ping pong game.
This is a simple version of the game, but very customizable and fun.
The Creation Process
I started the program with just making the ball bounce back and fourth against the walls, left to right.
- To do this, I first made what I call the
WorldFrame
. I added a Panel
in the right size and location. - In this panel, I then created a
picturebox
representing the ball called "pb_Ball
". - After this, I made a timer called "
timer_Movement
" and had its interval set to 1 ms.
- The tick event of this timer is what makes the ball move, I use a Boolean to check whether to go left or right. If the ball hits either of the walls, it changes the Boolean and makes the ball go in the other direction.
- Here's how I check if the ball hits the wall:
public Boolean Collision_Left(PictureBox obj)
{
if (obj.Location.X <= 0)
{
return true;
}
return false;
}
public Boolean Collision_Right(PictureBox obj)
{
if (obj.Location.X + obj.Width >= WorldFrame.Width)
{
return true;
}
return false;
}
Within the tick event, where the check for which direction the ball is going, I use this to check if the ball hits the outer wall. If it's true
, just change the Boolean value.
- After this, I added 2
Picturebox
es representing the player, and the enemy - Made the player able to go up and down with 2 events, KeyPress Up/Down
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.W:
case Keys.Up:
Player_Down = false;
Player_Up = true;
break;
case Keys.S:
case Keys.Down:
Player_Up = false;
Player_Down = true;
break;
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.W:
case Keys.Up:
Player_Up = false;
break;
case Keys.S:
case Keys.Down:
Player_Down = false;
break;
}
}
I use 2 Booleans to check if the player is going Up or Down, and then in the Movement timer, I check if any of the booleans is true
. Then the player moves.
if (Player_Up && !Collision_Up(pb_Player))
{
pb_Player.Top -= Speed_Player;
}
if (Player_Down && !Collision_Down(pb_Player))
{
pb_Player.Top += Speed_Player;
}
The extra functions like Collision_Up can be found in the well documented source code.
- When this was done, I made the same thing for the collision on the walls, but on the player instead.
- This was a bit tricky, at the same time I did this I made it so it checks where it lands on the player and from there changes the balls "force" how fast it goes up/down
- I did this by creating 5 small rectangles in front of the player, invisible and checks if the ball interacts with the player and these rectangles. If it does, then boom it goes away to the other direction.
- Sample code (See full source files for everything):
public Boolean Collision_Player(PictureBox tar)
{
if (tar.Bounds.IntersectsWith(pb_Player.Bounds))
{
PictureBox temp1 = new PictureBox();
temp1.Bounds = pb_Player.Bounds;
temp1.SetBounds(temp1.Location.X + temp1.Width, temp1.Location.Y, 1, 10);
if (tar.Bounds.IntersectsWith(temp1.Bounds))
{
BallForce = 3;
return true;
}
temp1.SetBounds(temp1.Location.X, temp1.Location.Y + 5, 1, 10);
if (tar.Bounds.IntersectsWith(temp1.Bounds))
{
BallForce = 2;
return true;
}
temp1.SetBounds(temp1.Location.X, temp1.Location.Y + 10, 1, 10);
if (tar.Bounds.IntersectsWith(temp1.Bounds))
{
BallForce = 1;
return true;
}
...
- With this, I created within the Movement timer event a check for if the Integer "
BallForce
" has any value below or above 0. If it's below 0, the ball goes down, above it goes up.
- At the same time, as the ball goes left-right, it also goes up/down depending on the
BallForce
value. - Example, if I hit the ball at the top of the player.
BallForce
goes to 3 - Then the ball goes 1 pixel to the side and 3 pixels up every ms.
if (BallForce > 0)
{
pb_Ball.Top -= BallForce;
}
if (BallForce < 0)
{
pb_Ball.Top -= BallForce;
}
- Along with this, I had to make sure that the ball didn't go flying up in space or down to hell. So with every movement up, it checks if the ball goes Above/Below the
WorldFrame
. And if it does, it reverses the BallForce
.
Inside timer_Movement tick event:
if (pb_Ball.Location.Y <= 1)
{
BallForce = ReverseInt(BallForce, true, true);
}
if (pb_Ball.Location.Y + pb_Ball.Height >= WorldFrame.Height - 1)
{
BallForce = ReverseInt(BallForce, true, false);
}
public int ReverseInt(int x, Boolean Force = false, Boolean Negative = false)
{
if (Force)
{
if (Negative)
{
if (x > 0)
{
x = ~x + 1;
}
}
else
{
x = x - (x * 2);
}
}
else
{
if (x > 0)
{
x = x - (x * 2);
}
else
{
x = ~x + 1;
}
}
return x;
}
- How the Enemy moves is very simple
- It checks whether the ball is above or below its central point. Then, it moves depending on its location.
if (pb_Enemy.Location.Y + 28 < pb_Ball.Location.Y)
{
pb_Enemy.Top += Speed_Enemy;
}
else
{
pb_Enemy.Top -= Speed_Enemy;
}
- I added this to a new timer called
timer_Enemy
, not sure why but it's there now. - I also added ex the same as the "if ball hits player on the top it bounces back" to the enemy with this.
- After this, I added every customizable option, like change of colors/timers/speeds with a new form called SettingsForm.cs.
- In this, I use a global setting in the file to change, and then in
Form1
, I just apply these every ms together with the movement. See source file for more information.
There are score images also, not visible on the image above but they're there.
- I made these by adding 5
picturebox
es on each side of the "Press space to start" label.
- Then, I changed the original code that the ball bounces when it hits each side by changing the
picturebox
es color to a black dot if the player/enemy messes up. - If 5 of these boxes turn black, the game is over.
public void AddScore(PictureBox[] Arr)
{
for (int i = 0; i < Arr.Length; i++)
{
if (Arr[i].BackColor == ScoreColor)
{
Arr[i].BackColor = Color.Black;
break;
}
}
if (Arr[4].BackColor == Color.Black)
{
GameOn = false;
label_Start.Visible = true;
RestoreScore();
pb_Ball.Location = new Point(208, rng.Next(10, 190));
pb_Player.Location = new Point(3, 67);
pb_Enemy.Location = new Point(409, 67);
Round = 0;
label_Time.Visible = false;
}
}
This is the basic idea, basis of the code.
Points of Interest
I learned a lot, had fun creating this. Making it while at work so had ~10 minutes of time each day so it took me a few days to complete.
I learned a lot from this, I have made games before so some of the code is what I reuse/improve from my other games.
I'm not a pro, I just like programming and I like to share my idéas and my code with others to play with.