Game Programming Class6

esse quam videri
Revision as of 03:26, 4 March 2015 by Jeff (talk | contribs)
Jump to: navigation, search


Physics

http://box2d.org/

c# Box2D https://code.google.com/p/box2dx/

https://github.com/d-snp/Farseer-Physics

http://farseerphysics.codeplex.com/

http://www.mataliphysics.com/

Portability

Separation of Concerns

Single Responsibility Principle

PacMan Class Simplified and Generalized

<csharp> public enum PacManState { Spawning, Still, Chomping, SuperPacMan }

   public class PacMan 
   {
       protected PacManState _state;
       public PacManState State
       {
           get { return _state; }
           set
           {
               if (_state != value)
               {
                   this.Log(string.Format("{0} was: {1} now {2}", this.ToString(), _state, value));
                   
                   _state = value;
               }
           }
       }
       public PacMan()
       {
           
           //Set default state will call notify so make sure this.Ghosts is intitialized first
           this.State = PacManState.Still;
       }
       //Extra method for logging state change
       public virtual void Log(string s)
       {
           //nothing
           Console.WriteLine(s);
       }
   }

</csharp>

MovementController in Monogame

In MonogameDemos Project is IntroPacManMovementController

file is PacManController.cs

<csharp> sealed class PacManController

   {
       InputHandler input; //game service to handle input
       public Vector2 Direction {get; private set;}
       public float Rotate { get; private set;}
       //Checks to see if there is anymovement
       public bool hasInputForMoverment
       {
           get
           {
               
               if (Direction.Length() == 0) return false;
               return true;
           }
       }
       public PacManController(Game game)
       {
           //get input handler from game services
           input = (InputHandler)game.Services.GetService<IInputHandler>();
           if (input == null)
           {
               throw new Exception("PacMan controller depends on InputHandler service please add Input Handler as a service first");
           }
       }
       public void Update()
       {
           //Input for update from analog stick
           GamePadState gamePad1State = input.GamePads[0]; //HACK hard coded player index
           #region LeftStick
           Vector2 pacStickDir = Vector2.Zero;
           if (gamePad1State.ThumbSticks.Left.Length() > 0.0f)
           {
               pacStickDir = gamePad1State.ThumbSticks.Left;
               pacStickDir.Y *= -1;      //Invert Y Axis
               float RotationAngle = (float)Math.Atan2(
                   gamePad1State.ThumbSticks.Left.X,
                   gamePad1State.ThumbSticks.Left.Y);
               Rotate = (float)MathHelper.ToDegrees(RotationAngle - (float)(Math.PI / 2));
           }
           #endregion
           //Update for input from DPad
           #region DPad
           Vector2 PacManDPadDir = Vector2.Zero;
           if (gamePad1State.DPad.Left == ButtonState.Pressed)
           {
               //Orginal Position is Right so flip X
               PacManDPadDir += new Vector2(-1, 0);
           }
           if (gamePad1State.DPad.Right == ButtonState.Pressed)
           {
               //Original Position is Right
               PacManDPadDir += new Vector2(1, 0);
           }
           if (gamePad1State.DPad.Up == ButtonState.Pressed)
           {
               //Up
               PacManDPadDir += new Vector2(0, -1);
           }
           if (gamePad1State.DPad.Down == ButtonState.Pressed)
           {
               //Down
               PacManDPadDir += new Vector2(0, 1);
           }
           if (PacManDPadDir.Length() > 0)
           {
               //Angle in radians from vector
               float RotationAngleKey = (float)Math.Atan2(
                       PacManDPadDir.X,
                       PacManDPadDir.Y * -1);
               //Find angle in degrees
               Rotate = (float)MathHelper.ToDegrees(
                   RotationAngleKey - (float)(Math.PI / 2)); //rotated right already
               //Normalize NewDir to keep agled movement at same speed as horilontal/Vert
               PacManDPadDir = Vector2.Normalize(PacManDPadDir);
           }
           #endregion
           //Update for input from Keyboard
  1. if !XBOX360
           #region KeyBoard
           KeyboardState keyboardState = Keyboard.GetState();
           Vector2 PacManKeyDir = new Vector2(0, 0);
           if (keyboardState.IsKeyDown(Keys.Left))
           {
               //Flip Horizontal
               PacManKeyDir += new Vector2(-1, 0);
           }
           if (keyboardState.IsKeyDown(Keys.Right))
           {
               //No new sprite Effects
               PacManKeyDir += new Vector2(1, 0);
           }
           if (keyboardState.IsKeyDown(Keys.Up))
           {
               PacManKeyDir += new Vector2(0, -1);
           }
           if (keyboardState.IsKeyDown(Keys.Down))
           {
               PacManKeyDir += new Vector2(0, 1);
           }
           if (PacManKeyDir.Length() > 0)
           {
               float RotationAngleKey = (float)Math.Atan2(
                       PacManKeyDir.X,
                       PacManKeyDir.Y * -1);
               Rotate = (float)MathHelper.ToDegrees(
                   RotationAngleKey - (float)(Math.PI / 2));
               //Normalize NewDir to keep agled movement at same speed as horilontal/Vert
               PacManKeyDir = Vector2.Normalize(PacManKeyDir);
           }
           #endregion
  1. endif
           Direction= PacManKeyDir + PacManDPadDir + pacStickDir;
           if (Direction.Length() > 0)
           {
               Direction = Vector2.Normalize(Direction);
           }
       }
   }

</csharp>

GameConsolePacMan.cs //hadles logging <csharp> class GameConsolePacMan : PacMan

   {
       GameConsole console;
       public GameConsolePacMan()
       {
           this.console = null;
       }
       public GameConsolePacMan(GameConsole console)
       {
           this.console = console;
       }
       public override void Log(string s)
       {
           if (console != null)
           {
               console.GameConsoleWrite(s);
           }
           else
           {
               base.Log(s);
           }
       }
   }

</csharp>

MonoGamePacMan.cs <csharp> class MonoGamePacMan : IntroGameLibrary.Sprite2.DrawableSprite2

   {
       internal PacManController controller { get; private set; }
       internal GameConsolePacMan PacMan
       {
           get;
           private set;
       }
       protected PacManState pacState;
       public PacManState PacState
       {
           get { return this.pacState; }
           //Change pacman state also
           set { 
               if(this.pacState != value)
                   this.pacState = this.PacMan.State = value; 
           }
       }
               
       public MonoGamePacMan(Game game)
           : base(game)
       {
           this.controller = new PacManController(game);
           PacMan = new GameConsolePacMan((GameConsole)game.Services.GetService<IGameConsole>());
       }
       protected override void LoadContent()
       {
           base.LoadContent();
           this.SpriteTexture = content.Load<Texture2D>("PacManSingle");
           this.Orgin = new Vector2(this.SpriteTexture.Width / 2, this.SpriteTexture.Height / 2);
           this.Location = new Microsoft.Xna.Framework.Vector2(100, 100);
           this.Speed = 200;
       }
       public override void Update(GameTime gameTime)
       {
           //Elapsed time since last update
           float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
           
           this.controller.Update();
           this.Location += ((this.controller.Direction * (time / 1000)) * Speed);      //Simple Move 
           this.Rotate = this.controller.Rotate;
           //Change State based on movement
           if (this.controller.hasInputForMoverment)
           {
               if(pacState != PacManState.Spawning && pacState != PacManState.SuperPacMan)
                   this.PacState = PacManState.Chomping;
           }
           else
           {
               if (pacState != PacManState.Spawning && pacState != PacManState.SuperPacMan)
                   this.PacState = PacManState.Still;
           }
           //Keep PacMan On Screen
           if (this.Location.X > Game.GraphicsDevice.Viewport.Width - (this.spriteTexture.Width / 2))
           {
               this.Location.X = Game.GraphicsDevice.Viewport.Width - (this.spriteTexture.Width / 2);
           }
           if (this.Location.X < (this.spriteTexture.Width / 2))
               this.Location.X = (this.spriteTexture.Width / 2);
           if (this.Location.Y > Game.GraphicsDevice.Viewport.Height - (this.spriteTexture.Height / 2))
               this.Location.Y = Game.GraphicsDevice.Viewport.Height - (this.spriteTexture.Height / 2);
           if (this.Location.Y < (this.spriteTexture.Height / 2))
               this.Location.Y = (this.spriteTexture.Height / 2);
           base.Update(gameTime);
       }
   }

</csharp>

MovementController in Unity

Unity Project is GameProgrammingUnity

Package is PacManWithFood.unitypackage

script is PlayerController.cs <csharp>

   public class PlayerController : MonoBehaviour {

public Vector2 direction = new Vector2();

   private Vector2 keyDirection;
   private Vector2 padDirection;

public bool hasInputForMoverment { get {

           //Debug.Log(direction.sqrMagnitude);
           if (direction.magnitude == 0) return false;

return true;} }

   public PlayerController()
   {
       keyDirection = new Vector2();
   }

// Use this for initialization void Start () {

}

// Update is called once per frame void Update () {

       keyDirection.x = keyDirection.y = 0;
       //Keyboard
       if (Input.GetKey("right"))
       {
           keyDirection.x += 1;
       }

if (Input.GetKey ("left")) {

           keyDirection.x += -1;

}

       if (Input.GetKey("up"))
       {
           keyDirection.y += 1;
       }

if (Input.GetKey ("down")) {

           keyDirection.y += -1;

}

       direction = keyDirection;
       //Gamepad
       padDirection.x = Input.GetAxis("Horizontal");
       padDirection.y = Input.GetAxis("Vertical");
       if (padDirection.magnitude > 0)
       {
           //Debug.Log(padDirection + " " + padDirection.magnitude + " " + (padDirection.magnitude > 0));
           direction += padDirection;
       }
       //normalize
       direction.Normalize();

} } </csharp>

UnityPacMan.cs //Hadles logging <csharp> public class UnityPacMan : PacMan {

   private GameObject _gameObject;
   public UnityPacMan(GameObject g) : base()
   {
       _gameObject = g;
   }
   public override void Log(string s)
   {
       Debug.Log(s);
   }

} </csharp>


Simple Animation

what extra fields do we need for animation?

http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet

Platformer Example

Show platformer starter kit

http://msdn.microsoft.com/en-us/library/dd254918(v=xnagamestudio.31).aspx

simple and elegant but not that flexible

Animation Classes

Way too many classes for me to type here

  • PacMan States
  • PacMan Dying Animation
  • PacMan Eating

IntroAnimation Project IntroAnimation.zip

Complicated but flexible

  • DrawableAnimatableSprite.cs
  • CelAnimationManager.cs

Homework

Shooting Game

  • must use game components
  • must be multiplayer (both on keyboard or multiple game pads) don't use networking
  • must be able to shoot at each other or work together to shoot enemies
  • include shot manager and or shot manager

PadManShootCapture.PNG