looking for a quick code example (im a visual guy) and this is getting a little confusing/frustrating.
Because im a very "modular" kind of guy, I like to split my code up into logical files as often as possible, and all examples in the XNA tutorials led me into a small funk as all I ever did seemingly happened in the main .cs file save for my typical classes but all rendering takes in (example) Game1.cs so far.
I then heard about GameComponents and see they have the exact same structure as "Game1.cs", So I immediately set out to migrate my player code (it's not much) over to it, and it compiles correctly, but I honestly have NO idea how to implement the new component into my game.
So I made a new GameComponentCollection
but when I try to add my new GameComponent class (extends DrawableGameComponent
btw as you will see) with components.Add
it simply tells me that I cannot.
Im not sure where to go from here to be honest, MSDN is useless with this topic (theres no documentation nor examples) and thread after thread has lead to very elaborate and very strange places that I would rather not get into. This seems like it should be a very simple concept, please correct me if im wrong here:
- You create a new GameComponentCollection manager
- You add your GameComponents and DrawableGameComponents to the manager
- You do something with the manager (I'm not sure at this point, iterate through and call their updates?)
Need some help, heres my source code to this
Game1.cs
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;
using System.Diagnostics;
namespace TestGame1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GameComponentCollection components;
DrawableGameComponent player;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
player = new GC_Player( this );
components.Add(player); // DOESN'T WORK. NullReferenceException
}
/// <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);
// 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
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);
spriteBatch.Begin();
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
GC_Player.cs
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 TestGame1
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class GC_Player : Microsoft.Xna.Framework.DrawableGameComponent
{
King theKing;
SpriteBatch spriteBatch;
public GC_Player(Game game)
: base(game)
{
// TODO: Construct any child components here
// Make THE KING.
theKing = new King();
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
protected override void LoadContent()
{
base.LoadContent();
spriteBatch = new SpriteBatch(Game.GraphicsDevice);
theKing.Sprite = Game.Content.Load<Texture2D>("King");
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
UpdateSprite(gameTime);
base.Update(gameTime);
}
void UpdateSprite(GameTime gameTime)
{
//spritePosition += spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
//theKing.Position = theKing.Position += theKing.Speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
//int MaxX = Game.graphics.GraphicsDevice.Viewport.Width - theKing.SpriteWidth;
int MinX = 0;
//int MaxY = Game.graphics.GraphicsDevice.Viewport.Height - theKing.SpriteHeight;
int MinY = 0;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
theKing.SpeedVertical += theKing.AccelerationVertical;
}
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
theKing.SpeedVertical -= theKing.AccelerationVertical;
}
if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
theKing.SpeedHorizontal += theKing.AccelerationHorizontal;
}
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
theKing.SpeedHorizontal -= theKing.AccelerationHorizontal;
}
if (Keyboard.GetState().IsKeyUp(Keys.Down) && Keyboard.GetState().IsKeyUp(Keys.Up))
{
if (theKing.SpeedVertical > 0)
{
theKing.SpeedVertical -= theKing.AccelerationVertical;
}
else if (theKing.SpeedVertical < 0)
{
theKing.SpeedVertical += theKing.AccelerationVertical;
}
}
if (Keyboard.GetState().IsKeyUp(Keys.Left) && Keyboard.GetState().IsKeyUp(Keys.Right))
{
if (theKing.SpeedHorizontal > 0)
{
theKing.SpeedHorizontal -= theKing.AccelerationHorizontal;
}
else if (theKing.SpeedHorizontal < 0)
{
theKing.SpeedHorizontal += theKing.AccelerationHorizontal;
}
}
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
spriteBatch.Begin();
if (theKing.FlipSprite)
{
spriteBatch.Draw(theKing.Sprite, theKing.CalculatePosition, null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0);
}
else
{
spriteBatch.Draw(theKing.Sprite, theKing.Position, Color.White);
}
spriteBatch.End();
}
}
}
King.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
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 TestGame1
{
class King
{
private String spriteRef;
private Texture2D sprite;
private Vector2 position;
private Vector2 speed;
private Vector2 maxSpeed;
private Boolean flipSprite;
private Vector2 accel;
public String SpriteReference
{
get { return spriteRef; }
set { spriteRef = value; }
}
public Texture2D Sprite
{
get { return sprite; }
set { sprite = value; }
}
public int SpriteWidth
{
get { return sprite.Width; }
}
public int SpriteHeight
{
get { return sprite.Height; }
}
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public float PositonHorizontal
{
get { return position.X; }
set { position.X = value; }
}
public float PositionVertical
{
get { return position.Y; }
set { position.Y = value; }
}
public Vector2 CalculatePosition
{
get
{
//Trace.WriteLine("Hor: " + SpeedHorizontal);
//Trace.WriteLine("Ver: " + SpeedVertical);
if (SpeedHorizontal != 0 || SpeedVertical != 0)
{
if (SpeedHorizontal != 0)
{
if (SpeedHorizontal > 0 || SpeedHorizontal < 0)
{
position.X += SpeedHorizontal / 2;
}
}
if (SpeedVertical != 0)
{
if (SpeedVertical > 0 || SpeedVertical < 0)
{
position.Y += SpeedVertical / 2;
}
}
}
return Position;
}
}
public Vector2 Speed
{
get { return speed; }
set { speed = value; }
}
public float SpeedHorizontal
{
get { return speed.X; }
set { speed.X = value; }
}
public float SpeedVertical
{
get { return speed.Y; }
set { speed.Y = value; }
}
public Vector2 MaxSpeed
{
get { return maxSpeed; }
set { maxSpeed = value; }
}
public float MaxSpeedHorizontal
{
get { return maxSpeed.X; }
set { maxSpeed.X = value; }
}
public float MaxSpeedVertical
{
get { return maxSpeed.Y; }
set { maxSpeed.Y = value; }
}
public Vector2 Acceleration
{
get { return accel; }
set { accel = value; }
}
public float AccelerationHorizontal
{
get { return accel.X; }
set { accel.X = value; }
}
public float AccelerationVertical
{
get { return accel.Y; }
set { accel.Y = value; }
}
public Boolean FlipSprite
{
get { return flipSprite; }
set { flipSprite = value; }
}
public King()
{
SpriteReference = "King";
Position = new Vector2(10.0f, 100.0f);
Speed = new Vector2(0.0f, 0.0f);
Acceleration = new Vector2(0.01f, 0.02f);
FlipSprite = true;
}
public void FlipSpriteHorizontal()
{
if (FlipSprite)
FlipSprite = false;
else
FlipSprite = true;
}
}
}