C# .NET 2.0 Pong

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
AngusL
Forum Contributor
Posts: 155
Joined: Fri Aug 20, 2004 4:28 am
Location: Falkirk, Scotland

C# .NET 2.0 Pong

Post 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;
        }
    }
}
Post Reply