やっぱαブレンディングでしょ-その2
■αブレンディングはテクスチャにかけてもっと面白い事をしたい、という事でまずはテクスチャを用意してみました。
「ball.png」
今回は、このテクスチャを色加算を使用して、たくさん動かしたいと思います。
■ソース
ソースが2つあります
game1.cs | :メインのソース |
Particle.cs | :パーティクル部分 |
game1.cs
namespace WindowsGame { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; ContentManager content; VertexPositionTexture[] vertices = { new VertexPositionTexture( new Vector3( 0.0f, 0.0f, 0.0f ),new Vector2( 0.0f, 0.0f ) ), new VertexPositionTexture( new Vector3( 96.0f, 0.0f, 0.0f ),new Vector2( 1.0f, 0.0f ) ), new VertexPositionTexture( new Vector3( 0.0f, 96.0f, 0.0f ),new Vector2( 0.0f, 1.0f ) ), new VertexPositionTexture( new Vector3( 96.0f, 96.0f, 0.0f ),new Vector2( 1.0f, 1.0f ) ) }; Texture2D texture; VertexDeclaration vdecl; BasicEffect basicEffect; const int particleMax = 300; Particle[] particle = new Particle[particleMax]; public Game1() { graphics = new GraphicsDeviceManager(this); content = new ContentManager(Services); } protected override void Initialize() { vdecl = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionTexture.VertexElements); basicEffect = new BasicEffect(graphics.GraphicsDevice, null); basicEffect.TextureEnabled = true; basicEffect.World = Matrix.Identity; basicEffect.View = Matrix.Identity; //原点( 0, 0 )を画面右上に設定 basicEffect.Projection = Matrix.CreateOrthographicOffCenter( 0.0f, // 左座標 this.Window.ClientBounds.Width, // 右座標 Window幅 this.Window.ClientBounds.Height, // 下座標 Window高さ 0.0f, // 上座標 0.0f, // ニアクリップの距離 1.0f ); // ファークリップの距離 //パーティクルの生成 Random ran = new Random(); for (int i = 0; i < particleMax; i++) particle[i] = new Particle( (float)ran.Next(700), (float)ran.Next(500), (float)ran.Next(360) * 3.14159f / 180.0f); base.Initialize(); } protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { texture = content.Load<Texture2D>("ball"); } } protected override void Update(GameTime gameTime) { foreach (Particle p in particle) p.Move(); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.Black ); graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true; graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha; graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One; basicEffect.Begin(); graphics.GraphicsDevice.VertexDeclaration = vdecl; foreach (Particle p in particle) { basicEffect.CurrentTechnique.Passes[0].Begin(); graphics.GraphicsDevice.Textures[0] = texture; basicEffect.View = Matrix.CreateTranslation(p.Pos); graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>( PrimitiveType.TriangleStrip, vertices, 0, 2); basicEffect.CurrentTechnique.Passes[0].End(); } basicEffect.End(); base.Draw(gameTime); } } }
Particle.cs
using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; namespace WindowsGame { class Particle { public Vector3 Pos; public Vector3 Direction; public Particle( float x, float y, float ang ) { Pos = new Vector3( x, y, 0 ); Direction = new Vector3((float)Math.Sin(ang) * 2.0f, (float)Math.Cos(ang) * 2.0f, 0 ); } public void Move() { Pos += Direction; if ((Pos.X < 0) || (Pos.X > 700)) Direction.X = -Direction.X; if ((Pos.Y < 0) || (Pos.Y > 500)) Direction.Y = -Direction.Y; } } }
■ソース説明
foreach (Particle p in particle) p.Move();
「foreach」になれていない人用にC言語での表記を書いておきます。
for( int i = 0 ; i < particleMax ; i++ ) { p = particle[ i ]; p.Move(); }