Original Post
Hey guys,
I've been playing around with several projects to better understand the Matrix transforms but have been running into issues.
I created a simple program to bounce a primitive rectangle around the screen using simple collision detection.
I modified the code from our colored primitive lesson to create a ball class as a DrawableGameComponent:
----------------------------------------------------------------
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Sample
{
public class Ball : Microsoft.Xna.Framework.DrawableGameComponent
{
VertexPositionColor[] ballData;
Vector2 ballPosition;
Vector2 ballVelocity;
float ballSize;
float ballWidth;
float ballHeight;
public Ball(Game game)
: base(game)
{
}
public override void Initialize()
{
ballPosition = new Vector2(0.1f, 0.4f);
ballVelocity = new Vector2(0.5f, 0.5f);
ballSize = 0.1f;
base.Initialize();
}
protected override void LoadContent()
{
// Initialize ball vertices
ballData = new VertexPositionColor[4];
ballData[0] = new VertexPositionColor();
ballData[0].Position = new Vector3(-0.5f, -0.5f, 0);
ballData[0].Color = Color.Red;
ballData[1] = new VertexPositionColor();
ballData[1].Position = new Vector3(-0.5f, 0.5f, 0);
ballData[1].Color = Color.Red;
ballData[2] = new VertexPositionColor();
ballData[2].Position = new Vector3(0.5f, -0.5f, 0);
ballData[2].Color = Color.Red;
ballData[3] = new VertexPositionColor();
ballData[3].Position = new Vector3(0.5f, 0.5f, 0);
ballData[3].Color = Color.Red;
ballWidth = ballData[3].Position.X - ballData[0].Position.X;
ballHeight = ballData[3].Position.Y - ballData[0].Position.Y;
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
ballPosition += ballVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
// Check for collision
CheckCollision();
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
GraphicsDeviceManager graphics = Game.Services.GetService(
typeof(GraphicsDeviceManager)) as GraphicsDeviceManager;
BasicEffect effect = Game.Services.GetService(
typeof(BasicEffect)) as BasicEffect;
effect.World = Matrix.CreateScale(ballSize) * Matrix.CreateTranslation(ballPosition.X, ballPosition.Y, 0);
effect.CurrentTechnique.Passes[0].Apply();
graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip,
ballData, 0, 2);
base.Draw(gameTime);
}
private void CheckCollision()
{
// Check for X collision
if (ballPosition.X < -2.0f)
{
ballPosition.X = -2.0f;
ballVelocity.X *= -1;
}
else if (ballPosition.X > 2.0f)
{
ballPosition.X = 2.0f;
ballVelocity.X *= -1;
}
// Check for Y collision
else if (ballPosition.Y < -1.2f)
{
ballPosition.Y = -1.2f;
ballVelocity.Y *= -1;
}
else if (ballPosition.Y > 1.2f)
{
ballPosition.Y = 1.2f;
ballVelocity.Y *= -1;
}
}
}
}
----------------------------------------------------------------
This code works just fine. The "ball" bounces around the screen but I had to hard code the collision detection boundaries from -2.0 to 2.0 and -1.2 to 1.2 instead of using the Viewport width and height properties.
Most of the various XNA sources talk about using unit values because it keeps the math simpler. This makes sense, but the piece I'm missing is how do I then transform the primitive position to regular screen coordinates? I could iterate through the VertexPositionColor array and multiply each Position vertex, but using that approach, I might as well just hard code the final screen coordinates to begin with.
I know there's something painfully obvious I'm overlooking but I'm just not catching it. Thanks in advance for any suggestions.
I've been playing around with several projects to better understand the Matrix transforms but have been running into issues.
I created a simple program to bounce a primitive rectangle around the screen using simple collision detection.
I modified the code from our colored primitive lesson to create a ball class as a DrawableGameComponent:
----------------------------------------------------------------
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Sample
{
public class Ball : Microsoft.Xna.Framework.DrawableGameComponent
{
VertexPositionColor[] ballData;
Vector2 ballPosition;
Vector2 ballVelocity;
float ballSize;
float ballWidth;
float ballHeight;
public Ball(Game game)
: base(game)
{
}
public override void Initialize()
{
ballPosition = new Vector2(0.1f, 0.4f);
ballVelocity = new Vector2(0.5f, 0.5f);
ballSize = 0.1f;
base.Initialize();
}
protected override void LoadContent()
{
// Initialize ball vertices
ballData = new VertexPositionColor[4];
ballData[0] = new VertexPositionColor();
ballData[0].Position = new Vector3(-0.5f, -0.5f, 0);
ballData[0].Color = Color.Red;
ballData[1] = new VertexPositionColor();
ballData[1].Position = new Vector3(-0.5f, 0.5f, 0);
ballData[1].Color = Color.Red;
ballData[2] = new VertexPositionColor();
ballData[2].Position = new Vector3(0.5f, -0.5f, 0);
ballData[2].Color = Color.Red;
ballData[3] = new VertexPositionColor();
ballData[3].Position = new Vector3(0.5f, 0.5f, 0);
ballData[3].Color = Color.Red;
ballWidth = ballData[3].Position.X - ballData[0].Position.X;
ballHeight = ballData[3].Position.Y - ballData[0].Position.Y;
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
ballPosition += ballVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
// Check for collision
CheckCollision();
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
GraphicsDeviceManager graphics = Game.Services.GetService(
typeof(GraphicsDeviceManager)) as GraphicsDeviceManager;
BasicEffect effect = Game.Services.GetService(
typeof(BasicEffect)) as BasicEffect;
effect.World = Matrix.CreateScale(ballSize) * Matrix.CreateTranslation(ballPosition.X, ballPosition.Y, 0);
effect.CurrentTechnique.Passes[0].Apply();
graphics.GraphicsDevice.DrawUserPrimitives
ballData, 0, 2);
base.Draw(gameTime);
}
private void CheckCollision()
{
// Check for X collision
if (ballPosition.X < -2.0f)
{
ballPosition.X = -2.0f;
ballVelocity.X *= -1;
}
else if (ballPosition.X > 2.0f)
{
ballPosition.X = 2.0f;
ballVelocity.X *= -1;
}
// Check for Y collision
else if (ballPosition.Y < -1.2f)
{
ballPosition.Y = -1.2f;
ballVelocity.Y *= -1;
}
else if (ballPosition.Y > 1.2f)
{
ballPosition.Y = 1.2f;
ballVelocity.Y *= -1;
}
}
}
}
----------------------------------------------------------------
This code works just fine. The "ball" bounces around the screen but I had to hard code the collision detection boundaries from -2.0 to 2.0 and -1.2 to 1.2 instead of using the Viewport width and height properties.
Most of the various XNA sources talk about using unit values because it keeps the math simpler. This makes sense, but the piece I'm missing is how do I then transform the primitive position to regular screen coordinates? I could iterate through the VertexPositionColor array and multiply each Position vertex, but using that approach, I might as well just hard code the final screen coordinates to begin with.
I know there's something painfully obvious I'm overlooking but I'm just not catching it. Thanks in advance for any suggestions.