Page 1 of 1

C# .NET 2.0 Pong

Posted: Sat Oct 07, 2006 7:08 pm
by AngusL
Well, the full code would be a little lengthy to post (not bad, ~500 lines or something, just a bit awkward). So the full VS.NET project can be downloaded at http://www.angusenterprises.co.uk/Pong.zip but I'll post the most interesting part below (the actual game part). I just got bored, and reckoned I'd give it a go. I've not done much in the way of C#, OOP (like none) or games (absolutely none). While code critique is very welcome, I'm particularly interested in the design since its really my first attempt at decent OOP.

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Pong
{
    public partial class frmGame : Form
    {
        int numberOfPlayers;

        private Timer timerGame = new Timer();
        private bool paused = false;

        private ball ballPlayer;
        private bat batRight = new bat();
        private bat batLeft = new bat();

        private Label labelscoreLeft = new Label();
        private Label labelscoreRight = new Label();

        private int scoreLeft = 0;
        private int scoreRight = 0;

        public frmGame(int players)
        {
            InitializeComponent();
            numberOfPlayers = players;
        }

        private void frmGame_Load(object sender, EventArgs e)
        {
            Random rng = new Random();
            int dx = rng.Next(-10, 10);
            if (dx == 0)
                dx = 1;
            int dy = rng.Next(-10, 10);
            if (dy == 0)
                dy = 1;
            ballPlayer = new ball(dx, dy);
            ballPlayer.setLocation(getHorizontalCenter(ballPlayer), getVerticalCenter(ballPlayer));
            ballPlayer.Name = "ballPlayer";
            Controls.Add(ballPlayer);

            batRight.Name = "batRight";
            batRight.setLocation(getRealWidth(batRight) - 5, getVerticalCenter(batRight));
            Controls.Add(batRight);

            batLeft.Name = "batLeft";
            batLeft.setLocation(5, getVerticalCenter(batRight));
            Controls.Add(batLeft);

            labelscoreLeft.AutoSize = true;
            labelscoreLeft.Left = 50;
            labelscoreLeft.Top = 50;
            labelscoreLeft.Text = scoreLeft.ToString();
            labelscoreLeft.Font = new Font("Console", 14);
            labelscoreLeft.ForeColor = Color.White;
            Controls.Add(labelscoreLeft);

            labelscoreRight.AutoSize = true;
            labelscoreRight.Left = ClientSize.Width - 50;
            labelscoreRight.Top = 50;
            labelscoreRight.Text = scoreRight.ToString();
            labelscoreRight.Font = new Font("Console", 14);
            labelscoreRight.ForeColor = Color.White;
            Controls.Add(labelscoreRight);

            timerGame.Interval = 1;
            timerGame.Tick +=new EventHandler(timerGame_Tick);

            this.FormClosing +=new FormClosingEventHandler(frmGame_FormClosing);
            this.LostFocus +=new EventHandler(frmGame_LostFocus);
            this.Activated +=new EventHandler(frmGame_Activated);
            this.KeyDown +=new KeyEventHandler(frmGame_KeyDown);

            timerGame.Start();
        }

        private void timerGame_Tick(object sender, EventArgs e)
        {
            if (paused)
                return;
            
            item.locationCollision location = ballPlayer.move(batLeft, batRight);
            switch (location)
            {
                case item.locationCollision.wallLeft:
                    ballPlayer.setLocation(getHorizontalCenter(ballPlayer), getVerticalCenter(ballPlayer));
                    scoreRight++;
                    labelscoreRight.Text = scoreRight.ToString();
                    break;
                case item.locationCollision.wallRight:
                    ballPlayer.setLocation(getHorizontalCenter(ballPlayer), getVerticalCenter(ballPlayer));
                    scoreLeft++;
                    labelscoreLeft.Text = scoreLeft.ToString();
                    break;
                case item.locationCollision.batLeftsideLeft:
                case item.locationCollision.batLeftsideRight:
                    ballPlayer.dy = (ballPlayer.dy + batLeft.dy) / 2;
                    break;
                case item.locationCollision.batRightsideLeft:
                case item.locationCollision.batRightsideRight:
                    ballPlayer.dy = (ballPlayer.dy + batRight.dy) / 2;
                    break;
            }

            if (numberOfPlayers == 1)
            {
                if (ballPlayer.Top < (batLeft.Top + (batLeft.Height / 2)))
                {
                    batLeft.dy += (-3 + batLeft.dy) / 2;
                }
                else
                {
                    batLeft.dy += (3 + batLeft.dy) / 2;
                }
            }

            batRight.move(10, -10, 0.5f);
            batLeft.move(10, -10, 0.5f);
        }

        private void frmGame_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    batLeft.setLocation(5, getVerticalCenter(batLeft));
                    batLeft.dy = 0;
                    batRight.setLocation(getRealWidth(batRight) - 5, getVerticalCenter(batRight));
                    batRight.dy = 0;
                    ballPlayer.setLocation(getHorizontalCenter(ballPlayer), getVerticalCenter(ballPlayer));
                    scoreLeft = 0;
                    labelscoreLeft.Text = scoreLeft.ToString();
                    scoreRight = 0;
                    labelscoreRight.Text = scoreRight.ToString();
                    break;
                case Keys.Pause:
                    paused = paused ? false : true;
                    break;
                case Keys.Enter:
                    batRight.dy = 0;
                    break;
                case Keys.Tab:
                    batLeft.dy = numberOfPlayers != 1 ? 0 : batLeft.dy;
                    break;
                case Keys.Down:
                    if (e.Shift)
                    {
                        batRight.dy += 10;
                    }
                    else
                    {
                        batRight.dy += 5;
                    }
                    break;
                case Keys.Up:
                    if (e.Shift)
                    {
                        batRight.dy += -10;
                    }
                    else
                    {
                        batRight.dy += -5;
                    }
                    break;
                case Keys.S:
                    if(numberOfPlayers == 1)
                        break;
                    if (e.Control)
                    {
                        batLeft.dy += 10;
                    }
                    else
                    {
                        batLeft.dy += 5;
                    }
                    break;
                case Keys.W:
                    if (numberOfPlayers == 1)
                        break;
                    if (e.Control)
                    {
                        batLeft.dy += -10;
                    }
                    else
                    {
                        batLeft.dy += -5;
                    }
                    break;
            }

            e.Handled = true;
        }

        private void frmGame_Activated(object sender, EventArgs e)
        {
            resume();
        }

        private void frmGame_LostFocus(object sender, EventArgs e)
        {
            pause();
        }

        private void frmGame_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Owner.Show();
        }

        private int getRealWidth(sprite sprItem)
        {
            return ClientSize.Width - sprItem.Width;
        }

        private int getRealHeight(sprite sprItem)
        {
            return ClientSize.Height - sprItem.Height;
        }

        private int getHorizontalCenter(sprite sprItem)
        {
            return getRealWidth(sprItem) / 2;
        }

        private int getVerticalCenter(sprite sprItem)
        {
            return getRealHeight(sprItem) / 2;
        }

        private void pause()
        {
            paused = true;
        }

        private void resume()
        {
           paused = false;
        }
    }

    public class sprite : PictureBox
    {
        public sprite()
        {
            this.Show();
        }

        public Point setLocation(int x, int y)
        {
            this.Location = new Point(x, y);
            return Location;
        }

        public bool setImage(string FilePath)
        {
            try
            {
                this.Image = Image.FromFile(FilePath);
                this.Size = new Size(this.Image.Width, this.Image.Height);
            }
            catch
            {
                return false;
            }

            return true;
        }

        public bool setImage(IntPtr hBitmap)
        {
            try
            {
                this.Image = Image.FromHbitmap(hBitmap);
                this.Size = new Size(this.Image.Width, this.Image.Height);
            }
            catch
            {
                return false;
            }

            return true;
        }
    }

    public class item : sprite
    {
        public enum locationCollision : int
        {
            batLeftsideLeft = 1, batLeftsideRight = 2,
            batRightsideLeft = 4, batRightsideRight = 8,
            wallTop = 16, wallBottom = 32,
            wallLeft = 64, wallRight = 128,
            none = 0
        }

        public int dx = 0;
        public int dy = 0;

        public item(int initdx, int initdy)
            : base()
        {
            dx = initdx;
            dy = initdy;
        }

        public virtual locationCollision move(int posLimit, int negLimit, float coefficientFriction)
        {
            int ldx;
            int ldy;
            ldy = dy > posLimit ? posLimit : dy;
            ldy = dy < negLimit ? negLimit : dy;
            ldx = dx > posLimit ? posLimit : dx;
            ldx = dx < negLimit ? negLimit : dx;

            this.Hide();
            Top += ldy;
            Left += ldx;
            this.Show();

            dx -= (int) (coefficientFriction * (float) ldx);
            dy -= (int) (coefficientFriction * (float) ldy);

            return checkCollisions();
        }

        public virtual locationCollision checkCollisions()
        {
            locationCollision location = locationCollision.none;

            // Check for collisions off top and bottom
            if (Top <= 0)
            {
                location |= locationCollision.wallTop;
                dy *= -1;
            }

            if (Top >= (frmGame.ActiveForm.ClientSize.Height - Image.Height))
            {
                location |= locationCollision.wallBottom;
                dy *= -1;
            }

            // Check for collisions off sides
            if (Left <= 0)
            {
                location |= locationCollision.wallLeft;
                dx *= -1;
            }

            if (Left >= (frmGame.ActiveForm.ClientSize.Width - Image.Width))
            {
                location |= locationCollision.wallRight;
                dx *= -1;
            }

            return location;
        }
    }

    public class ball : item
    {
        public ball(int initdx, int initdy)
            : base(initdx, initdy)
        {
            setImage(Pong.Properties.Resources.ball.GetHbitmap());
        }

        public locationCollision move(bat batLeft, bat batRight)
        {
            locationCollision location = move(10, -10, 0) | checkBatCollisions(batLeft, batRight);

            return location;
        }

        protected locationCollision checkBatCollisions(bat batLeft, bat batRight)
        {
            locationCollision location = locationCollision.none;

            // Check for collisions on facing side of left bat
            if (((Left <= (batLeft.Left + batLeft.Width) && (Left >= batLeft.Left))) && ((Top >= batLeft.Top) && (Top <= (batLeft.Top + batLeft.Height))))
            {
                location |= locationCollision.batLeftsideLeft;
                dx *= -1;
            }

            // Check for collisions on opposite side of left bat
            if ((((Left + Width) >= batLeft.Left) && (Left + Width < batLeft.Left + batLeft.Width)) && ((Top >= batLeft.Top) && (Top <= (batLeft.Top + batLeft.Height))))
            {
                location |= locationCollision.batLeftsideRight;
                dx *= -1;
            }

            // Check for collisions on facing side of right bat
            if ((((Left + Width) >= batRight.Left) && (Left <= (batRight.Left + batRight.Width))) && ((Top >= batRight.Top) && (Top <= (batRight.Top + batRight.Height))))
            {
                location |= locationCollision.batRightsideRight;
                dx *= -1;
            }

            // Check for collisions on opposite side of right bat
            if (((Left >= (batRight.Left + Width)) && (Left <= batLeft.Left)) && ((Top >= batRight.Top) && (Top <= (batRight.Top + batRight.Height))))
            {
                location |= locationCollision.batRightsideLeft;
                dx *= -1;
            }

            return location;
        }
    }

    public class bat : item
    {
        public bat()
            : base(0, 0)
        {
            setImage(Pong.Properties.Resources.bat.GetHbitmap());
        }

        public override item.locationCollision move(int posLimit, int negLimit, float coefficientFriction)
        {
            locationCollision location = base.move(posLimit, negLimit, coefficientFriction);
            if (location == locationCollision.wallTop)
            {
                dy = 0;
                Top = 0;
            }
            if (location == locationCollision.wallBottom)
            {
                dy = 0;
                Top = frmGame.ActiveForm.ClientSize.Height - Height;
            }

            return location;
        }
    }
}