Pong
From SDL.NET
This article will guide you through the creation of a simple pong clone. Pong is a simple game in which there are two paddles, one controled by the player, and a ball that bounces between them. If you have never played Pong before, you can try it out this online version (http://www.addictinggames.com/pingpong.html). Of course, our version will be much more primitive than this. We'll be using C#, although you can use VB.NET or any other .NET compatible language that you're familiar with.
| Table of contents |
Getting Started
The first thing we have to do is setup our project for using SDL.NET.
Project Creation
You can use any IDE that you're familiar with, but this tutorial's scope is Visual Studio 2005.
- Start up your IDE of choice and create a new Windows Application project named Pong.
- Delete the windows form that was created by the project by right clicking on
Form1.cs. - Add a new class to the project named Pong.cs by right clicking on it and choosing Add -> Add New Item...
- We'll now have to make reference to SDL.NET. Right click on the References folder in the project and choose Add Reference...
- Click on Browse and find SdlDotNet...
- Once it's in the Selected Components panel, click on OK.
Pong Class
Now that we have reference to SDL.NET in our new project, we can use it in our Pong class. Change Pong.cs so that it looks like the following:
using System;
using System.IO;
using System.Drawing;
using SdlDotNet;
using SdlDotNet.Graphics;
using SdlDotNet.Graphics.Sprites;
using SdlDotNet.Core;
using SdlDotNet.Input;
namespace SdlDotNetExamples.SmallDemos
{
public class PongExample
{
public PongExample()
{
Video.SetVideoMode(300, 200);
}
public void Go()
{
Events.Run();
}
[STAThread]
public static void Main()
{
PongExample pong = new PongExample();
pong.Go();
}
}
}
If you run your application, it may complain that it can't find some DLLs (namely the SDL.dll). You can find these in the SdlDotNet/lib/win32deps folder. Copy all the required DLLs to the bin/Debug directory in your project and it should now pop up a blank window when you run it. You also could copy the DLLs to the common folder such as the C:\winnt\system32 folder.
Graphics
The next thing that we'll need to do is find some interesting graphics for use in our Pong game. I've provided some basic graphics that you can find below that were taken from SpriteLib (http://www.flyingyogi.com/fun/spritelib.html):
Missing image
Paddle1.PNG
Image:Paddle1.PNG
Missing image
Paddle2.PNG
Image:Paddle2.PNG
Missing image
Ball.PNG
Image:Ball.PNG
Put the graphics into your bin/Debug directory so they are in the same folder as the exe. All we'll be needing for this tutorial are the paddles and the ball. Once you've done that, we're ready to use them in our Pong game.
To The Code-Mobile
We'll be using sprites to display the ball and paddles as it's probably the easiest and fastest way to get graphics on the screen with minimal amount of work and code. So add the following using directive to the top of Pong.cs:
using SdlDotNet.Graphics.Sprites;
Now that we have easy access to the Sprites namespace, we can create our sprite objects. We'll start with making the ball:
Sprite ball = new Sprite(new Surface("ball.png"));
This will define a new sprite that we can use named ball. You can see that we provide it a surface for it to use, loaded from ball.png. If your ball image is named different, change it accordingly. Once we have our ball sprite loaded, it's now ready for use. We'll have to create a tick event that will trigger every once in a while so that we can draw the ball on the screen:
public Pong()
{
Video.SetVideoMode(300, 200);
Events.Tick += new EventHandler<TickEventArgs>(Events_Tick);
}
private void Events_Tick(object sender, TickEventArgs e)
{
// Draw the ball
Video.Screen.Blit(ball);
// Update the screen
Video.Screen.Update();
}
Now if we run our pong game, you'll see the ball rendered in the upper left corner. One problem though, there is purple around it. This is because we haven't set the transparent color, or color key of the ball. We can set it by using:
ball.TransparentColor = Color.Magenta; ball.Transparent = true;
Movement
Yes it's nice to have a ball on the screen, but it's not fun if it doesn't do anything. Lets make it bounce! Look back at the Events_Tick function. You'll see that it calls this method every tick of the game. Right now it renders the ball, and then updates the screen. We'll change it so that it changes the location of the ball before it renders it. Put the following into your Tick method and run it:
ball.X++; ball.Y++;
Oh no, looks like we ran into some problems. We forgot to clear the screen before rendering. To fix it, all we have to do it fill the screen with black before rendering the ball:
private void Events_Tick(object sender, TickEventArgs e)
{
// Update location of the ball
ball.X++;
ball.Y++;
// Clear the screen
Video.Screen.Fill(Color.Black);
// Draw the ball
Video.Screen.Blit(ball);
// Update the screen
Video.Screen.Update();
}
Run it now, we're getting somewhere! We're going to have to implement a way of having the ball go in any direction. We can do this by recording its x and y speeds. Add these two lines below the declaration of ball:
Sprite ball = new Sprite(new Surface("ball.png"));
int ballSpeedX = 1;
int ballSpeedY = 1;
And change the ball.X++ and ball.Y++ to the following:
// Update location of the ball ball.X += ballSpeedX; ball.Y += ballSpeedY;
If we run it again, you'll notice that the ball goes down at a different angle and then eventually goes off the screen. We need it to bounce. All we have to do is set a boundry for the sprite when it's moving.
// Bounce the ball
if (ball.Right > Video.Screen.Width)
{
ballSpeedX *= -1;
}
if (ball.Left < 0)
{
ballSpeedX *= -1;
}
if (ball.Top < 0)
{
ballSpeedY *= -1;
}
if (ball.Bottom > Video.Screen.Height)
{
ballSpeedY *= -1;
}
PongExample.png
The ball now successfully bounces around the screen endlessly. After adding some code to allow for more flexible ball.png file placement and implementing IDisposable, you should have something like this:
using System;
using System.IO;
using System.Drawing;
using SdlDotNet;
using SdlDotNet.Graphics;
using SdlDotNet.Graphics.Sprites;
using SdlDotNet.Core;
using SdlDotNet.Input;
namespace SdlDotNetExamples.SmallDemos
{
public class PongExample : IDisposable
{
Sprite ball;
int ballSpeedX = 1;
int ballSpeedY = 1;
public PongExample()
{
string filePath = Path.Combine("..", "..");
string fileDirectory = "Data";
string ballFileName = "ball.png";
//string paddle1FileName = "paddle1.png";
//string paddle2FileName = "paddle2.png";
if (File.Exists(ballFileName))
{
filePath = "";
fileDirectory = "";
}
else if (File.Exists(Path.Combine(fileDirectory, ballFileName)))
{
filePath = "";
}
//string file = Path.Combine(Path.Combine(filePath, fileDirectory), fileName);
ball = new Sprite(new Surface(Path.Combine(Path.Combine(filePath, fileDirectory), ballFileName)));
Video.WindowIcon();
Video.WindowCaption = "SDL.NET - Pong Example";
Video.SetVideoMode(300, 200);
ball.TransparentColor = Color.Magenta;
ball.Transparent = true;
}
private void Events_Quit(object sender, QuitEventArgs e)
{
Events.QuitApplication();
}
private void KeyboardDown(object sender, KeyboardEventArgs e)
{
// Check if the key pressed was a Q or Escape
if (e.Key == Key.Escape || e.Key == Key.Q)
{
Events.QuitApplication();
}
}
private void Events_Tick(object sender, TickEventArgs e)
{
// Update location of the ball
ball.X += ballSpeedX;
ball.Y += ballSpeedY;
// Bounce the ball
if (ball.Right > Video.Screen.Width)
{
ballSpeedX *= -1;
}
if (ball.Left < 0)
{
ballSpeedX *= -1;
}
if (ball.Top < 0)
{
ballSpeedY *= -1;
}
if (ball.Bottom > Video.Screen.Height)
{
ballSpeedY *= -1;
}
// Clear the screen
Video.Screen.Fill(Color.Black);
// Draw the ball
Video.Screen.Blit(ball);
// Update the screen
Video.Screen.Update();
}
public void Go()
{
Events.KeyboardDown += new EventHandler<KeyboardEventArgs>(this.KeyboardDown);
Events.Tick += new EventHandler<TickEventArgs>(Events_Tick);
Events.Quit += new EventHandler<QuitEventArgs>(Events_Quit);
Events.Run();
}
[STAThread]
public static void Run()
{
PongExample pong = new PongExample();
pong.Go();
}
/// <summary>
/// Lesson Title
/// </summary>
public static string Title
{
get
{
return "PongExample: Simple game of Pong";
}
}
#region IDisposable Members
private bool disposed;
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (this.ball != null)
{
this.ball.Dispose();
this.ball = null;
}
}
this.disposed = true;
}
}
/// <summary>
///
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
///
/// </summary>
public void Close()
{
Dispose();
}
/// <summary>
///
/// </summary>
~PongExample()
{
Dispose(false);
}
#endregion
}
}
See Also
- SpriteLib (http://www.flyingyogi.com/fun/spritelib.html)
- Online Ping Pong (http://www.addictinggames.com/pingpong.html)
Categories: Stubs | Examples | Tutorials

