XNA Level 2 Lesson 4
Object Oriented Programming
- Create a new class called CSprite
- Create an Instance of that class
- Update the initialise function
- Update the update function
- Update the draw function
|
|
|
What are Objects?
Object Oriented Programming (OOP) can be a little tricky to head around, but once you start coding in this style you won’t go back.
Using Objects allows us to wrap up (encapsulate) variables and functions together. I shall explain more as we go along.
At the moment if wanted to create another tank we would have to duplicate all the variables
So instead of this
(what we currently doing)
protected Vector2 position;
protected float rotation;
protected Vector2 shellPos;
protected float shellRot;
protected int fireState;
we would now have this (DO NOT COPY)
protected Vector2 position1;
protected Vector2 position2;
protected float rotation1;
protected float rotation2;
protected Vector2 shellPos1;
protected Vector2 shellPos2;
protected float shellRot1;
protected float shellRot2;
protected int fireState1;
protected int fireState2;
What if we needed 3 tanks, 4 tanks or even 10 tanks? a hundred tanks???
It would soon get out of hand.
We are going to create a class to hold all the variables together
Create a new class called CSprite
CSprite will hold information about where a texture should be drawn on screen, later we will create a tank class
Click on the Project menu and select 'Add Class'
Call it CSprite press 'Add'
You should now have a nice new class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Level2_Lesson04
{
class CSprite
{
}
}
We are now going to create the variables within our class.
class CSprite
{
//all variable currently public, we will change this later!
public Vector2 position = new Vector2();
public float rotation;
public Rectangle sourceRect; //which part of the image are we drawing
public Vector2 handlePosition; //which part of the image does it rotate around
}
Now switch back to your Game1.cs file (your main code)
Delete the following 2 lines from your global variable, warning this will create a lot of errors, but do not worry.
protected Vector2 position;
protected float rotation;
Now in its place we create and 'instance' of our new class
We now need to edit the initialise function
protected override void Initialize()
{
// TODO: Add your initialization logic here
tank1 = new CSprite();
tank1.rotation= 0;
tank1.position.X = 200;
tank1.position.Y = 200;
tank1.sourceRect = new Rectangle(128, 0, 128, 128);
tank1.handlePosition = new Vector2(64, 64);
Now the not to easy bit, you need to go through your code where ever it is underlined in red change it from position or rotation to tank1.position and tank1.rotation
Finally we need to change the draw command to
spriteBatch.Begin();
spriteBatch.Draw(SpriteSheet, tank1.position, tank1.sourceRect,
Color.White, tank1.rotation, tank1.handlePosition, 1.0f, SpriteEffects.None, 1);
Congratulations you have created and used your first object.
Your next challenge is to covert the shell to an object instead
<<Complete Listings>>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//Global Variables
protected Texture2D SpriteSheet;
CSprite tank1;
protected Vector2 shellPos;
protected float shellRot;
protected int fireState;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
tank1 = new CSprite();
tank1.rotation= 0;
tank1.position.X = 200;
tank1.position.Y = 200;
tank1.sourceRect = new Rectangle(128, 0, 128, 128);
tank1.handlePosition = new Vector2(64, 64);
shellPos = new Vector2();
shellRot = 0;
fireState = 0;
base.Initialize();
}
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
SpriteSheet = Content.Load<Texture2D>("TankSpriteSheet");
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
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
KeyboardState key = Keyboard.GetState();
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (key.IsKeyDown(Keys.Left))
{
tank1.rotation -= 1.0f * elapsed;
}
if (key.IsKeyDown(Keys.Right))
{
tank1.rotation += 1.0f * elapsed;
}
if (key.IsKeyDown(Keys.Up))
{
float x, y;
x = (100 * elapsed) * (float)Math.Cos(tank1.rotation);
y = (100 * elapsed) * (float)Math.Sin(tank1.rotation);
tank1.position.X += x;
tank1.position.Y += y;
}
if (key.IsKeyDown(Keys.Down))
{
float x, y;
x = (-100 * elapsed) * (float)Math.Cos(tank1.rotation);
y = (-100 * elapsed) * (float)Math.Sin(tank1.rotation);
tank1.position.X += x;
tank1.position.Y += y;
}
if (key.IsKeyDown(Keys.Space) && fireState == 0)
{
//fire
//position shell to barrel
float sx, sy;
//start 70 pixels from centre of the tank (horizontal not vertical)
sx = (70 * (float)Math.Cos(tank1.rotation)) - (0 * (float)Math.Sin(tank1.rotation));
sy = (70 * (float)Math.Sin(tank1.rotation)) + (0 * (float)Math.Cos(tank1.rotation));
//set shell position
shellPos.X = tank1.position.X + sx;
shellPos.Y = tank1.position.Y + sy;
//set rotation of shell to angle of tank
shellRot = tank1.rotation;
//FIRE!!!
fireState = 1;
}
if (fireState == 1) //IF Firing
{
//move shell position
float x, y;
x = (500 * elapsed) * (float)Math.Cos(shellRot); //500 is speed of shell
y = (500 * elapsed) * (float)Math.Sin(shellRot);
shellPos.X += x;
shellPos.Y += y;
//if out of screen bounds
if (shellPos.X < 0 || shellPos.X > 1280 || shellPos.Y < 0 || shellPos.Y > 720)
{
fireState = 0;//reset shell
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.SeaGreen);
spriteBatch.Begin();
spriteBatch.Draw(SpriteSheet, tank1.position, tank1.sourceRect,
Color.White, tank1.rotation, tank1.handlePosition, 1.0f, SpriteEffects.None, 1);
if (fireState == 1)
{
spriteBatch.Draw(SpriteSheet, shellPos, new Rectangle(512, 0, 128, 128),
Color.White, shellRot, new Vector2(64, 64), 1.0f, SpriteEffects.None, 1);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
|