Each of the boundaries in your world is a line. One side of the line is solid and the other is not. The usual one you are trying to calculate is part of the equation for this line. It indicates the non-continuous side of the line. Another part of the linear equation is the distance from the line to the origin. The equation for a line can be found from two points on this line. You can define these two points based on the coordinates in the playing space where you need the wall.
The rate is calculated by rotating the line segment, defined by two points of 90 degrees, and then normalizing.
public static Vector2 ComputeNormal(Vector2 point1, Vector2 point2) { Vector2 normal = new Vector2(); normal.X = point2.Y - point1.Y; normal.Y = point1.X - point2.X; normal.Normalize(); return normal; }
You use the preferred width and height of the buffer to determine your space in the world, to use them to determine the points used to calculate the normals.
float left = 0.0f; float right = graphics.PreferredBackBufferWidth; float top = 0.0f; float bottom = graphics.PreferredBackBufferHeight; Vector2 topNormal = ComputeNormal(new Vector2(left, top), new Vector2(right, top)); Vector2 bottomNormal = ComputeNormal(new Vector2(right, bottom), new Vector2(left, bottom));
Please note that points must be indicated in clockwise order so that normal points are in the right direction.
The following XNA 4.0 program demonstrates the use of these concepts:
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace WindowsGame { public class Ball { const int DIAMETER = 40; const float RADIUS = DIAMETER * 0.5f; const float MASS = 0.25f; const int PIXELS = DIAMETER * DIAMETER; static readonly uint WHITE = Color.White.PackedValue; static readonly uint BLACK = new Color(0, 0, 0, 0).PackedValue; Texture2D m_texture; Vector2 m_position; Vector2 m_velocity; public Ball(GraphicsDevice graphicsDevice) { m_texture = new Texture2D(graphicsDevice, DIAMETER, DIAMETER); uint[] data = new uint[PIXELS]; for (int i = 0; i < DIAMETER; i++) { float iPosition = i - RADIUS; for (int j = 0; j < DIAMETER; j++) { data[i * DIAMETER + j] = new Vector2(iPosition, j - RADIUS).Length() <= RADIUS ? WHITE : BLACK; } } m_texture.SetData<uint>(data); } public float Radius { get { return RADIUS; } } public Vector2 Position { get { return m_position; } } public Vector2 Velocity { get { return m_velocity; } set { m_velocity = value; } } public void ApplyImpulse(Vector2 impulse) { Vector2 acceleration = impulse / MASS; m_velocity += acceleration; } public void Update(float dt) { m_position += m_velocity;
source share