#region File Description
//-----------------------------------------------------------------------------
// Particles.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Spacewar
{
///
/// A class that represents a group of particles
///
public class Particles : SceneItem
{
private static string particleTexture = @"textures\circle";
private static Random random = new Random();
private static SpriteBatch batch;
public Particles(Game game)
: base(game)
{
if (game != null)
{
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)game.Services.GetService(typeof(IGraphicsDeviceService));
batch = new SpriteBatch(graphicsService.GraphicsDevice);
}
}
///
/// Draws the particles in a batch
///
public override void Render()
{
if (Count != 0)
{
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
GraphicsDevice device = graphicsService.GraphicsDevice;
batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp,
DepthStencilState.None, RasterizerState.CullCounterClockwise);
int particleCount = 0;
foreach (SceneItem particle in this)
{
if (particle is Particle)
{
batch.Draw(SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + particleTexture),
new Vector2(particle.Position.X, particle.Position.Y),
null, new Color(((Particle)particle).Color), 0,
new Vector2(16, 16), .2f,
SpriteEffects.None, particle.Position.Z);
particleCount++;
}
}
batch.End();
//We DON'T need to call base class here. We are handling batching all the children ourselves
//base.Render();
}
}
///
/// Adds particles to represent vapour trail
///
/// Start position of the particle
/// Direction the ship is heading. Particles will be lined up along this vec
public void AddShipTrail(Matrix world, Vector2 direction)
{
//Move source point into screen space
Vector4 source = Vector4.Transform(new Vector4(0, 0, 130000, 1), world * SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
//and into pixels
Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
direction = Vector2.Normalize(direction);
for (int i = 0; i < 70; i++)
{
float trailDistance = random.Next(50);
float trailOffset = random.Next(21) - 10;
Add(new Particle(this.GameInstance,
new Vector2(source2D.X + trailDistance * direction.X + trailOffset * direction.Y, source2D.Y + trailDistance * direction.Y + trailOffset * direction.X),
new Vector2(trailDistance * trailOffset * direction.Y / 5, trailDistance * trailOffset * direction.X / 5),
new Vector4(1f, 1f, .5f, .5f),
new Vector4(.2f, .2f, 0f, .2f),
new TimeSpan(0, 0, 2)));
}
}
///
/// Adds particles to represent vapour trail
///
/// Start position of the particle
/// Direction the rocket is heading. Particles will be lined up along this vec
public void AddRocketTrail(Matrix world, Vector2 direction)
{
//Move source point into screen space
Vector4 source = Vector4.Transform(new Vector4(0, 0, 291, 1), world * SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
//and into pixels
Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
direction = Vector2.Normalize(direction);
for (int i = 0; i < 20; i++)
{
float trailDistance = random.Next(50);
Add(new Particle(this.GameInstance,
new Vector2(source2D.X, source2D.Y) + trailDistance * -direction,
-direction,
new Vector4(1f, 1f, .5f, .5f),
new Vector4(.2f, .2f, 0f, .2f),
new TimeSpan(0, 0, 1)));
}
}
///
/// Adds particles that look like an explosion
///
///
public void AddExplosion(Vector3 position)
{
//Move source point into screen space
Vector4 source = Vector4.Transform(position, SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
//and into pixels
Vector2 source2D = new Vector2((int)((source.X / source.W + 1f) / 2f * 1280), (int)((-source.Y / source.W + 1f) / 2f * 720));
for (int i = 0; i < 300; i++)
{
Vector2 velocity = (float)random.Next(100) * Vector2.Normalize(new Vector2((float)(random.NextDouble() - .5), (float)(random.NextDouble() - .5)));
Add(new Particle(this.GameInstance,
new Vector2(source2D.X, source2D.Y),
velocity,
(i > 70) ? new Vector4(1.0f, 0f, 0f, 1) : new Vector4(.941f, .845f, 0f, 1),
new Vector4(.2f, .2f, .2f, 0f),
new TimeSpan(0, 0, 0, 0, random.Next(1000) + 500)));
}
}
public override void OnCreateDevice()
{
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
batch = new SpriteBatch(graphicsService.GraphicsDevice);
}
}
}