xna l09–2d graphics and particle engines

Post on 14-May-2015

340 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Mohammad Shakermohammadshaker.com

@ZGTRShaker2011, 2012, 2013, 2014

XNA Game DevelopmentL09 – 2D Graphics and Particle Engines

2D Graphics

2D Graphics Topics

• Introduction to 2D Graphics

• SpriteBatches

• Drawing Text with SpriteFonts

• Texure Atlases

• Rotating Sprites

• Additive Blending with Sprites

• 2D Particle Engines

2D World - Intro

SpriteBatch

SpriteBatch

• Create a Place to Store the Images In Game

private Texture2D background;

private Texture2D shuttle;

private Texture2D earth;

SpriteBatch

• Create a Place to Store the Images In Game

• LoadContent() method

private Texture2D background;

private Texture2D shuttle;

private Texture2D earth;

background = Content.Load<Texture2D>("stars");

shuttle = Content.Load<Texture2D>("shuttle");

earth = Content.Load<Texture2D>("earth");

Textures, Content

Textures, Content

SpriteBatch

• SpriteBatches Declaration

SpriteBatch spriteBatch;

SpriteBatch

• SpriteBatches Declaration

• Initializing in LoadContent()

SpriteBatch spriteBatch;

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

}

SpriteBatch

• Drawing with SpriteBatches

spriteBatch.Begin();

spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);

spriteBatch.End();

SpriteBatch

• Drawing with SpriteBatches

spriteBatch.Begin();

spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);

spriteBatch.End();

SpriteBatch

• A Few More Sprites

spriteBatch.Begin();

spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);

spriteBatch.Draw(earth, new Vector2(400, 250), Color.White);

spriteBatch.Draw(shuttle, new Vector2(450, 250), Color.White);

spriteBatch.End();

SpriteBatch

• A Few More Sprites

spriteBatch.Begin();

spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);

spriteBatch.Draw(earth, new Vector2(400, 250), Color.White);

spriteBatch.Draw(shuttle, new Vector2(450, 250), Color.White);

spriteBatch.End();

SpriteBatch

• A Few More Sprites

spriteBatch.Begin();

spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);

spriteBatch.Draw(earth, new Vector2(400, 250), Color.White);

spriteBatch.Draw(shuttle, new Vector2(450, 250), Color.White);

spriteBatch.End();

You can find this in “App1-SimpleTextures”

Going on with 2D!

Acquiring Fonts

• Making a SpriteFont

Acquiring Fonts

• Down at about line 14 in the new created file you will see the following:

• You can use any font you want that’s installed in your system

• Fonts can be installed by dragging the font file to your Fonts folder, which is

located in C:/Windows/Fonts

<FontName>Segoe UI Mono</FontName>

Acquiring Fonts

• Down at about line 14 in the new created file you will see the following:

<FontName>Segoe UI Mono</FontName>

Acquiring Fonts

• Down at about line 14 in the new created file you will see the following:

• Also look down at line 20, where it says:

<FontName>Segoe UI Mono</FontName>

<Size>14</Size>

Acquiring Fonts – the using of

• Global Scope

private SpriteFont font;

private int score = 0;

Acquiring Fonts – the using of

• Global Scope

• LoadContent()

private SpriteFont font;

private int score = 0;

font = Content.Load<SpriteFont>("Score"); // Use the name of your font here instead of 'Score'.

Acquiring Fonts – the using of

• Global Scope

• LoadContent()

• Draw()

private SpriteFont font;

private int score = 0;

font = Content.Load<SpriteFont>("Score"); // Use the name of your font here instead of 'Score'.

spriteBatch.Begin();

spriteBatch.DrawString(font, "Score", new Vector2(100, 100), Color.Black);

spriteBatch.End();

Acquiring Fonts – the using of

Acquiring Fonts – the using of

• Enhancing visual with Update() method

Acquiring Fonts – the using of

• Enhancing visual with Update() method

score++;

Acquiring Fonts – the using of

• Enhancing visual with Update() method

• Now let's replace our original spriteBatch.DrawString() line with the following:

score++;

spriteBatch.DrawString(font, "Score: " + score, new Vector2(100, 100), Color.Black);

Acquiring Fonts – the using of

• “App2-ShowingText”

Texture Atlases

Texture Atlases

Texture Atlases

Texture Atlases

• Creating an AnimatedSprite Class

• Class scope members

public class AnimatedSprite

public Texture2D Texture { get; set; }

public int Rows { get; set; }

public int Columns { get; set; }

private int currentFrame;

private int totalFrames;

Texture Atlases

• Update() method

public void Update()

{

currentFrame++;

if (currentFrame == totalFrames)

currentFrame = 0;

}

Texture Atlases

• Draw() method

public void Draw(SpriteBatch spriteBatch, Vector2 location)

{

int width = Texture.Width / Rows;

int height = Texture.Height / Columns;

int row = (int)((float)currentFrame / (float)Columns);

int column = currentFrame % Columns;

Rectangle sourceRectangle = new Rectangle(width * column, height * row, width, height);

Rectangle destinationRectangle = new Rectangle((int)location.X, (int)location.Y, width, height);

spriteBatch.Begin();

spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White);

spriteBatch.End();

}

Texture Atlases

• Draw() method

public void Draw(SpriteBatch spriteBatch, Vector2 location)

{

int width = Texture.Width / Rows;

int height = Texture.Height / Columns;

int row = (int)((float)currentFrame / (float)Columns);

int column = currentFrame % Columns;

Rectangle sourceRectangle = new Rectangle(width * column, height * row, width, height);

Rectangle destinationRectangle = new Rectangle((int)location.X, (int)location.Y, width, height);

spriteBatch.Begin();

spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White);

spriteBatch.End();

}

Texture Atlases

• Draw() method

public void Draw(SpriteBatch spriteBatch, Vector2 location)

{

int width = Texture.Width / Rows;

int height = Texture.Height / Columns;

int row = (int)((float)currentFrame / (float)Columns);

int column = currentFrame % Columns;

Rectangle sourceRectangle = new Rectangle(width * column, height * row, width, height);

Rectangle destinationRectangle = new Rectangle((int)location.X, (int)location.Y, width, height);

spriteBatch.Begin();

spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White);

spriteBatch.End();

}

Texture Atlases

• Now, in Game1 Class there’s just two calls!

Texture Atlases

• Now, in Game1 Class there’s just two calls!

Texture Atlases

• Now, in Game1 Class there’s just two calls!

Texture Atlases

protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

animatedSprite.Update();

base.Update(gameTime);

}

Texture Atlases

protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

animatedSprite.Update();

base.Update(gameTime);

}

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

animatedSprite.Draw(spriteBatch, new Vector2(400, 200));

base.Draw(gameTime);

}

Texture Atlases

protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

animatedSprite.Update();

base.Update(gameTime);

}

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

animatedSprite.Draw(spriteBatch, new Vector2(400, 200));

base.Draw(gameTime);

}

Texture Atlases

• “App3-AnimatedSprite”

Rotating Sprites

Rotating Sprites

• Preparing the Content

private Texture2D arrow;

private float angle = 0;

Rotating Sprites

• Preparing the Content

private Texture2D arrow;

private float angle = 0;

Rotating Sprites

• Preparing the Content

• In LoadContent() method

• In Update() method

private Texture2D arrow;

private float angle = 0;

// use the name of your texture here, if you are using your own

arrow = Content.Load<Texture2D>("arrow");

angle += 0.01f;

Rotating Sprites

• Draw() Method

spriteBatch.Begin();

Vector2 location = new Vector2(400, 240);

Rectangle sourceRectangle = new Rectangle(0, 0, arrow.Width,

arrow.Height);

Vector2 origin = new Vector2(0, 0);

spriteBatch.Draw(arrow, location, sourceRectangle, Color.White,

angle, origin, 1.0f, SpriteEffects.None, 1);

spriteBatch.End();

Rotating Sprites

• Draw() Method

Rotating Sprites

• Compile and run and c it!

• “App3-RotatingSpriteV0.1”

Rotating Sprites

• It’s not what we need!

Rotating Sprites

• It’s not what we need!

• We need a“Center Point Rotation”!

Using a Center Point for Rotation

• In Draw(), change

Vector2 origin = new Vector2(0, 0);

Vector2 origin = new Vector2(arrow.Width / 2, arrow.Height);

• To

Using a Center Point for Rotation

• Compile and run

Using a Center Point for Rotation

• Compile and run

Particle EnginesThe Concept

2D Particle Engine

2D Particle Engine

• Introduction

2D Particle Engine

2D Particle Engine

• images

2D Particle Engine

• Anatomy of a Particle Engine

2D Particle Engine

• Anatomy of a Particle Engine

– particles,

2D Particle Engine

• Anatomy of a Particle Engine

– particles,

– particle emitter,

2D Particle Engine

• Anatomy of a Particle Engine

– particles,

– particle emitter,

– the engine itself

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity

– particle emitter,

– the engine itself

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter,

– the engine itself

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter

• Location that the particles are coming from

– the engine itself

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter

• Location that the particles are coming from

• Responsible for determining how many particles will be created at any given time

– the engine itself

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter

• Location that the particles are coming from

• Responsible for determining how many particles will be created at any given time

– the engine itself

• Manages the state of the previous two components

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter

• Location that the particles are coming from

• Responsible for determining how many particles will be created at any given time

– the engine itself

• Manages the state of the previous two components

• Responsible for removing dead particles from the system

2D Particle Engine

• Anatomy of a Particle Engine

– particles

• Velocity, Angles

– particle emitter

• Location that the particles are coming from

• Responsible for determining how many particles will be created at any given time

– the engine itself

• Manages the state of the previous two components

• Responsible for removing dead particles from the system.

2D Particle Engine

• Particle

Public class Particle

2D Particle Engine

• Particle

• ParticleEngine2D

Public class Particle

Public class ParticleEngine2D

2D Particle Engine

• Particle

Public class Particle

2D Particle Engine

• Particle

• The Particle's Properties

Public class Particle

2D Particle Engine

Public class Particle

public Texture2D Texture { get; set; }

public Vector2 Position { get; set; }

public Vector2 Velocity { get; set; }

public float Angle { get; set; }

public float AngularVelocity { get; set; }

public Color Color { get; set; }

public float Size { get; set; }

public int TTL { get; set; }

• Particle

• The Particle's Properties

2D Particle Engine

• Particle

• The Particle's Properties

Public class Particle

public Texture2D Texture { get; set; }

public Vector2 Position { get; set; }

public Vector2 Velocity { get; set; }

public float Angle { get; set; }

public float AngularVelocity { get; set; }

public Color Color { get; set; }

public float Size { get; set; }

public int TTL { get; set; }

2D Particle Engine

• Particle

• The Particle's Properties

Public class Particle

public Texture2D Texture { get; set; }

public Vector2 Position { get; set; }

public Vector2 Velocity { get; set; }

public float Angle { get; set; }

public float AngularVelocity { get; set; }

public Color Color { get; set; }

public float Size { get; set; }

public int TTL { get; set; }

2D Particle Engine

• Update()

2D Particle Engine

• Update()

public void Update()

{

TTL--;

Position += Velocity;

Angle += AngularVelocity;

}

2D Particle Engine

• Update()

public void Update()

{

TTL--;

Position += Velocity;

Angle += AngularVelocity;

}

2D Particle Engine

• Draw()

public void Draw(SpriteBatch spriteBatch)

{

Rectangle sourceRectangle = new Rectangle(0, 0, Texture.Width, Texture.Height);

Vector2 origin = new Vector2(Texture.Width / 2, Texture.Height / 2);

spriteBatch.Draw(Texture, Position, sourceRectangle, Color,

Angle, origin, Size, SpriteEffects.None, 0f);

}

2D Particle Engine

• Particle

• ParticleEngine2D

Public class Particle

Public class ParticleEngine2D

2D Particle Engine

Public class ParticleEngine2D

2D Particle Engine

Public class ParticleEngine2D

• Propertiesprivate Random random;

public Vector2 EmitterLocation { get; set; }

private List<Particle> particles;

private List<Texture2D> textures;

2D Particle Engine

public void Update()

{

int total = 10;

for (int i = 0; i < total; i++)

{

particles.Add(GenerateNewParticle());

}

for (int particle = 0; particle < particles.Count; particle++)

{

particles[particle].Update();

if (particles[particle].TTL <= 0)

{

particles.RemoveAt(particle);

particle--;

}

}

}

2D Particle Engine

public void Update()

{

int total = 10;

for (int i = 0; i < total; i++)

{

particles.Add(GenerateNewParticle());

}

for (int particle = 0; particle < particles.Count; particle++)

{

particles[particle].Update();

if (particles[particle].TTL <= 0)

{

particles.RemoveAt(particle);

particle--;

}

}

}

2D Particle Engine

public void Draw(SpriteBatch spriteBatch)

{

spriteBatch.Begin();

for (int index = 0; index < particles.Count; index++)

{

particles[index].Draw(spriteBatch);

}

spriteBatch.End();

}

2D Particle Engine

public void Draw(SpriteBatch spriteBatch)

{

spriteBatch.Begin();

for (int index = 0; index < particles.Count; index++)

{

particles[index].Draw(spriteBatch);

}

spriteBatch.End();

}

2D Particle Engine

• Game1 calling

2D Particle Engine

• In Update()

• In Draw()

2D Particle Engine

• In Update()

• In Draw()

particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

particleEngine.Update();

2D Particle Engine

• In Update()

• In Draw()

particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

particleEngine.Update();

particleEngine.Draw(spriteBatch);

2D Particle Engine

• In Update()

• In Draw()

particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

particleEngine.Update();

particleEngine.Draw(spriteBatch);

2D Particle Engine

• Test it, Very nice!

• Can easily be ported to windows phone!

– Visit my mobile crash course on slideshare / Windows Phone slide:http://www.slideshare.net/ZGTRZGTR/mobile-software-engineering-crash-course-c06-windowsphone/

• App-2DParticleEngines

• You can test it on Windows Mobile!

top related