Monday, 30 December 2013

C# & XNA Game - Pong


Introduction & Description: Coming shortly...

Please check out the 10 video links where I go through the demo in full detail.


C# Experiments: Pong (Part 1)


C# Experiments: Pong (Part 2)



C# Experiments: Pong (Part 3)


C# Experiments: Pong (Part 4)


  C# Experiments: Pong (Part 5)


C# Experiments: Pong (Part 6)


C# Experiments: Pong (Part 7)



C# Experiments: Pong (Part 8)


C# Experiments: Pong (Part 9)



C# Experiments: Pong (Part 10)



The 2 Game assets present in the Content folder are:-

 The Paddle



The Ball




The code typed-in during the tutorial-session is as follows:-

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GameProject
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        //
        const int WINDOW_WIDTH = 600;
        const int WINDOW_HEIGHT = 400;

        Texture2D paddle;
        Rectangle paddleRect;

        Texture2D ball;
        Rectangle ballRect;

        int paddleShift = 8;

        const int START_SPEED = 5;
        Random rand = new Random();
        double randHolder;
        Vector2 velocity;
        double angle;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = WINDOW_WIDTH;
            graphics.PreferredBackBufferHeight = WINDOW_HEIGHT;
            IsMouseVisible = true;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
           
            paddle = Content.Load<Texture2D>("Paddle");
            paddleRect = new Rectangle(WINDOW_WIDTH/2 - paddle.Width/2, WINDOW_HEIGHT - paddle.Height, paddle.Width, paddle.Height);

            ball = Content.Load<Texture2D>("Ball");
            ballRect = new Rectangle(WINDOW_WIDTH/2 - ball.Width/2, WINDOW_HEIGHT/2 - ball.Width/2, ball.Width, ball.Height);

            //Start the Ball between 30 deg to 60 deg OR 120 deg to 150 deg.

            do
                randHolder = rand.NextDouble();
            while (randHolder < 30.0 / 360 || (randHolder > 60.0 / 360 && randHolder < 120.0 / 360) || randHolder > 150.0 / 360);

            // angle = 0 degrees [0]  => Right
            // angle = 90 degrees [0.25] => Up
            // angle = 180 degrees [0.5] => Left
            // angle = 270 degrees [0.75] => Down
            // angle = 360 degrees [1] => Right
           
            //1 radian = 180 deg divided by PI
            //=> 180 / 3.14 = 57.3 deg is 1 radian
            //30 degrees in radian = 30 deg / 57.3 deg
            //=> 30 / (180 /3.14) = 30 * 3.14 / 180
            //=> 30 * PI / 180 == 2 * 30 * PI / 360
            angle = 2 * Math.PI * randHolder;

            //[0-90] deg: Graph => {+ve, +ve}, Window => {+ve, -ve}
            //(90-180] deg: Graph => {-ve, +ve}, Window => {-ve, -ve}
            //(180-270] deg: Graph => {-ve, -ve}, Window => {-ve, +ve}
            //(270-360] deg: Graph => {+ve, -ve}, Window => {+ve, +ve}

            velocity.X = (float)(Math.Cos(angle) * START_SPEED);
            velocity.Y = (float)(-1 * Math.Sin(angle) * START_SPEED);


            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            if (Keyboard.GetState().IsKeyDown(Keys.Left))
                if (paddleRect.Left > 0)
                    paddleRect.X -= paddleShift;

            if (Keyboard.GetState().IsKeyDown(Keys.Right))
                if (paddleRect.Right < WINDOW_WIDTH)
                    paddleRect.X += paddleShift;

            ballRect.X += (int)velocity.X;
            ballRect.Y += (int)velocity.Y;

            if (ballRect.Y < 0)
            {
                ballRect.Y = 0;
                velocity.Y *= -1;
            }

            if (ballRect.X < 0)
            {
                ballRect.X = 0;
                velocity.X *= -1;
            }

            if (ballRect.Right > WINDOW_WIDTH)
            {
                ballRect.X = WINDOW_WIDTH - ballRect.Width;
                velocity.X *= -1;
            }

            if (paddleRect.Intersects(ballRect))
            {
                ballRect.Y = WINDOW_HEIGHT - ballRect.Height - paddleRect.Height;
                velocity.Y *= -1;

                velocity.X *= 1.15f;
                velocity.Y *= 1.15f;

                paddleShift = (int)(paddleShift * 1.15);
            }

            if(Keyboard.GetState().IsKeyDown(Keys.N))
                LoadContent();

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here


            spriteBatch.Begin();
            spriteBatch.Draw(paddle, paddleRect, Color.White);
            spriteBatch.Draw(ball, ballRect, Color.CornflowerBlue);
            spriteBatch.End();
           
            base.Draw(gameTime);
        }
    }
}
Thank you for reading this post and watching the videos. Please Subscribe, Comment, and Rate the channel if you liked the videos.

Goto C# Experiments to access more of such content! Thanks again!