Getting Acces to Other Classes Variables - c#

I'm working on a pong game, since i'm new at programming, i don't know how to get acess to another class variable. I have seperate classes, green and blue paddles, a ball, and game1.cs.
I control the ball movement with bool movingUp, movingLeft;
It bounces off the borders of the screen, but i don't know how to make it work with the paddles. Basically, how do i check the position of the paddle, and make so when the ball touches the paddle, it bounces off? I mean, how to detect the collision?
public class Ball
{
ParticleEngine particleEngine;
GraphicsDeviceManager graphics;
Texture2D texture;
Vector2 position;
Boolean movingUp, movingLeft;
Vector2 origin;
public Ball()
{
position = new Vector2(800 / 2, 330);
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("ball");
movingLeft = true;
//Particle Engine
List<Texture2D> textures = new List<Texture2D>();
textures.Add(Content.Load<Texture2D>("pixel"));
particleEngine = new ParticleEngine(textures, new Vector2(400, 240));
}
public void Update(GameTime gameTime)
{
float speed = 2.5f;
//Physics
if (movingUp)
{
position.Y -= 3;
}
if (movingLeft)
{
position.X -= 3;
}
if (!movingUp)
{
position.Y += 3;
}
if (!movingLeft)
{
position.X += 3;
}
if (position.X <= 0 && movingLeft) movingLeft = false;
if (position.Y <= 85 && movingUp) movingUp = false;
if (position.X >= 800 - texture.Width && !movingLeft) movingLeft = true;
if (position.Y >= 500 - texture.Height && !movingUp) movingUp = true;
origin = new Vector2(position.X + texture.Width / 2, position.Y + texture.Height / 2);
//Particles
particleEngine.EmitterLocation = new Vector2(origin.X, origin.Y);
particleEngine.Update();
}
public void Draw(SpriteBatch spriteBatch)
{
particleEngine.Draw(spriteBatch);
spriteBatch.Draw(texture, position, Color.White);
}
}
One of the paddle classes (they look the same exept the name and movement keys):
public class GreenPaddle
{
Texture2D texture;
Vector2 position;
float speed = 2f;
public GreenPaddle()
{
position = new Vector2(10, 230);
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("greenpaddle");
}
public void Update(GameTime gameTime)
{
KeyboardState keyState = Keyboard.GetState();
//Check If Keys Are Pressed // Movement
if (keyState.IsKeyDown(Keys.W))
position.Y -= speed;
if (keyState.IsKeyDown(Keys.S))
position.Y += speed;
//Check Border
if (position.Y < 87)
{
position.Y = 87;
}
if (position.Y > 396)
{
position.Y = 396;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
}
Thanks in advance, i really wish to learn things like this :D

Declare the variables you want to access as public, or create get methods.
For public variables you would do:
public Vector2 Position;
And to access it, you would call:
Ball ball;
ball.Position
For get method implement:
public Vector2 getPosition()
{
return Position;
}
And you would call that method to get the position.

Related

trying to define location on paddle for breakout game to create better ball collision physics

So I'm trying to figure out how to split the rectangle of my paddle up so i can define different points on the paddle at which the ball can be hit. I want to make it so that if the ball is hit on either the left or right side of the paddle, then the ball direction will change slightly rather than following the exact same path every time.
Here is my paddle class (I started writing the code I would need in the isboxcolliding method but got stuck and confused):
class Ball
{
Texture2D texture;
Vector2 position;
Vector2 speed;
Rectangle bounds;
Rectangle screenBounds;
Random rnd = new Random();
bool collisionWithBrick; // Prevents rapid brick removal.
public Ball(Texture2D texture, Rectangle screenbounds) // Constructor
{
this.texture = texture;
this.screenBounds = screenbounds;
}
public int Width
{
get { return texture.Width; }
}
public int Height
{
get { return texture.Height; }
}
public Rectangle Bounds
{
get
{
bounds = new Rectangle((int)position.X, (int)position.Y,
Width, Height);
return bounds;
}
}
public void SetStartBallPosition(Rectangle paddle)
{
position.X = paddle.X + (paddle.Width - Width) / 2;
position.Y = paddle.Y = paddle.Y - Height;
bounds = Bounds;
if (rnd.Next(0, 2) < 1)
speed = new Vector2(-200.0f, 200.0f); // Move ball left.
else
speed = new Vector2(200.0f, -200.0f); // Move Ball Right.
}
internal void Deflection(MultiBallBrick multiBallBrick)
{
if (!collisionWithBrick)
{
speed.Y *= -1;
collisionWithBrick = true;
}
}
internal void Deflection(ReinforcedBrick reinforcedBrick)
{
if (!collisionWithBrick)
{
speed.Y *= -1;
collisionWithBrick = true;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.Silver);
}
// Check if our ball collides with the right paddle.
public void IsBoxColliding(Rectangle paddle)
{
if (bounds.Intersects(paddle))
{
int center = paddle.Center.X - bounds.Center.X;
if (center > )
{
speed.Y *= -1;
speed.X = speed.X * 1.5f;
}
}
/*if (paddle.Intersects(bounds)) // Bounds = our ball
{
position.Y = paddle.Y - Height;
speed.Y *= - 1; // Reverse the direction of the ball.
}*/
}
public void Update(GameTime gameTime)
{
collisionWithBrick = false;
position += speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
// Check to see if the ball goes of the screen.
if (position.X + Width > screenBounds.Width) // Right side
{
speed.X *= -1;
position.X = screenBounds.Width - Width;
}
if (position.X < 0) // Left side
{
speed.X *= -1;
position.X = 0;
}
if (position.Y < 0) // Top
{
speed.Y *= -1;
position.Y = 0;
}
}
public bool OffBottom()
{
if (position.Y > screenBounds.Height)
return true;
return false;
}
public void Deflection(Brick brick)
{
if (!collisionWithBrick)
{
speed.Y *= -1;
collisionWithBrick = true;
}
}
}
}
any help would be greatly apreciated!
You do not necessarily need to split the collision rectangle up. You can check if the collision is on the left or right side by having the following information.
The collision point or the centre position of the ball when the collision occurs, lets call it Vector2 collisionPoint
Centre position of the paddle, lets call it Vector2 paddleCentrePosition
This only works if the paddle does not rotate.
Vector2 difference = collisionPoint - paddleCentrePosition;
if(difference.x > 0) {
/*Right side of the paddle*/
}
else if(difference.x < 0) {
/*Left side of the paddle*/
}
else{
/*The exact same position*/
}

How do I fix my platformer collision detection?

I'm working on a game that allows my 2D sprite to jump on a platform but when it lands on the platform, my 2D sprite is not exactly on top of the platform, sometimes its exceeding or the same as the position of the platform.
//here is my code:
Texture2D jumper;
Texture2D tile;
Vector2 position, velocity;
Rectangle top;
Rectangle tile_rectangle;
Rectangle jumper_rectangle;
KeyboardState ks;
bool jump;
//here is my Load Content:
protected override void LoadContent()
{
jump = true;
position.X = 10;
position.Y = 10;
jumper = Content.Load<Texture2D>("character");
tile = Content.Load<Texture2D>("tile");
tile_rectangle = new Rectangle(300, 350, tile.Width, tile.Height);
top = new Rectangle(tile_rectangle.X, tile_rectangle.Y - 16, tile_rectangle.Width, 10);
}
//Here is my update:
protected override void Update(GameTime gameTime)
{
ks = Keyboard.GetState();
position += velocity;
float i = 1;
if (ks.IsKeyDown(Keys.Up) && jump == false)
{
position.Y -= 10f;
velocity.Y = -25f;
jump = true;
}
if (jump == true)
{
velocity.Y += 2f * i;
}
if (position.Y > 400)
{
jump = false;
}
if (jump == false)
{
velocity.Y = 0f;
}
BoundingBox();
if (ks.IsKeyDown(Keys.Right))
{
position.X += 5f;
velocity.X = +0.05f;
if (jumper_rectangle.Left > tile_rectangle.Right)
{
jump = true;
}
}
if (ks.IsKeyDown(Keys.Left))
{
position.X -= 5f;
velocity.X = -0.05f;
if (jumper_rectangle.Right < tile_rectangle.Left)
{
jump = true;
}
}
jumper_rectangle = new Rectangle((int)position.X, (int)position.Y, jumper.Width, jumper.Height);
BoundingBox();
base.Update(gameTime);
}
//here is my draw:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(jumper, jumper_rectangle, Color.White);
spriteBatch.Draw(tile, tile_rectangle, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
//here is my method on landing:
public void BoundingBox()
{
if (jumper_rectangle.Intersects(top))
{
if (jumper_rectangle.Bottom > top.Top)
{
position.Y--;
jump = false;
}
}
}
Where did i go wrong or is there some other way?

Draw a never-ending line in XNA

I am drawing a line in XNA which I want to never end. I also have a tool that moves forward in X-direction and a camera which is centered at this tool. However, when I reach the end of the viewport the lines are not drawn anymore. Here are some pictures to illustrate my problem:
At the start the line goes across the whole screen, but as my tool moves forward, we reach the end of the line.
Here are the method which draws the lines:
private void DrawEvenlySpacedSprites (Texture2D texture, Vector2 point1, Vector2 point2, float increment)
{
var distance = Vector2.Distance (point1, point2); // the distance between two points
var iterations = (int)(distance / increment); // how many sprites with be drawn
var normalizedIncrement = 1.0f / iterations; // the Lerp method needs values between 0.0 and 1.0
var amount = 0.0f;
if (iterations == 0)
iterations = 1;
for (int i = 0; i < iterations; i++) {
var drawPoint = Vector2.Lerp (point1, point2, amount);
spriteBatch.Draw (texture, drawPoint, Color.White);
amount += normalizedIncrement;
}
}
Here are the draw method in Game. The dots are my lines:
protected override void Draw (GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black);
nyVector = nextVector (gammelVector);
GraphicsDevice.SetRenderTarget (renderTarget);
spriteBatch.Begin ();
DrawEvenlySpacedSprites (dot, gammelVector, nyVector, 0.9F);
spriteBatch.End ();
GraphicsDevice.SetRenderTarget (null);
spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, camera.transform);
spriteBatch.Draw (renderTarget, new Vector2 (), Color.White);
spriteBatch.Draw (tool, new Vector2(toolPos.X - (tool.Width/2), toolPos.Y - (tool.Height/2)), Color.White);
spriteBatch.End ();
gammelVector = new Vector2 (nyVector.X, nyVector.Y);
base.Draw (gameTime);
}
Can anyone point me in the right direction here? I'm guessing it has to do with the viewport.width, but I'm not quite sure how to solve it. Thank you for reading!
I read this and thought it would be a fun exercise this morning, so I decided to write this for fun.
The implementation is pretty simple, keep adding lines at the end of each other until the last line is outside of the viewable area.
The following code will draw a line infinitely going right. As an added optimization, the lines on the left side of the screen are deleted as you pass them. You could easily make it retain the lines that were there previously, or also create lines going left as well. I will leave these exercises to you.
Take a look at the following Line class, which will define a single line on screen:
public class Line
{
Texture2D Texture;
Color Color;
public Vector2 PointA;
public Vector2 PointB;
float Width;
public Line(Vector2 pointA, Vector2 pointB, float width, Color color, Texture2D texture)
{
Texture = texture;
PointA = pointA;
PointB = pointB;
Width = width;
Color = color;
}
public void Draw(SpriteBatch spritebatch)
{
float angle = (float)Math.Atan2(PointB.Y - PointA.Y, PointB.X - PointA.X);
float length = Vector2.Distance(PointA, PointB);
spritebatch.Draw(Texture, PointA, null, Color, angle, Vector2.Zero, new Vector2(length, Width), SpriteEffects.None, 0);
}
}
I wrote the implementation inside of a game class, since I was speedcoding. You can see the Game class below:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Camera Camera;
Texture2D LineTexture;
List<Line> Lines;
Random Random;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Camera = new Camera(GraphicsDevice.Viewport, 1f);
LineTexture = new Texture2D(GraphicsDevice, 1, 1);
LineTexture.SetData<Color>(new Color[] { Color.White });
Random = new Random();
Lines = new List<Line>();
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
//handle input
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Escape))
this.Exit();
if (kbState.IsKeyDown(Keys.OemMinus))
Camera.Zoom -= 0.015f;
else if (kbState.IsKeyDown(Keys.OemPlus))
Camera.Zoom += 0.015f;
if (kbState.IsKeyDown(Keys.Up))
Camera.Move(new Vector2(0, -30));
else if (kbState.IsKeyDown(Keys.Down))
Camera.Move(new Vector2(0, 30));
if (kbState.IsKeyDown(Keys.Left))
Camera.Move(new Vector2(-30, 0));
else if (kbState.IsKeyDown(Keys.Right))
Camera.Move(new Vector2(30, 0));
//check if line is still in viewport - if not remove it
for (int i = 0; i < Lines.Count; i++)
{
if (Lines[i].PointB.X < Camera.Viewport.X)
{
Lines.RemoveAt(i);
i--;
}
}
//if there are no lines, create one to get started
if (Lines.Count == 0)
{
Vector2 p1 = new Vector2(Camera.Viewport.X, Random.Next(Camera.Viewport.Y + 50, Camera.Viewport.Height - 100));
Vector2 p2 = new Vector2(p1.X + Random.Next(5, 20), p1.Y + Random.Next(-5, 5));
Line line = new Line(p1, p2, 1, Color.Black, LineTexture);
Lines.Add(line);
}
//Check if we need to add some lines to the right of our last list item
while (Lines[Lines.Count - 1].PointB.X < Camera.Viewport.X + Camera.Viewport.Width)
{
Vector2 p1 = new Vector2(Lines[Lines.Count - 1].PointB.X, Lines[Lines.Count - 1].PointB.Y); ;
Vector2 p2 = new Vector2(p1.X + Random.Next(5, 20), p1.Y + Random.Next(-5, 5));
Line line = new Line(p1, p2, 1, Color.Black, LineTexture);
Lines.Add(line);
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(new Color(30, 90, 150));
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, Camera.View);
foreach (Line line in Lines)
line.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
I've also included the Camera class for your convenience:
public class Camera
{
private const float zoomUpperLimit = 1.5f;
private const float zoomLowerLimit = 0.1f;
private float _zoom;
private Vector2 _pos;
private int ViewportWidth, ViewportHeight;
#region Properties
public float Zoom
{
get { return _zoom; }
set
{
_zoom = value;
if (_zoom < zoomLowerLimit)
_zoom = zoomLowerLimit;
if (_zoom > zoomUpperLimit)
_zoom = zoomUpperLimit;
}
}
public Rectangle Viewport
{
get
{
int width = (int)((ViewportWidth / _zoom));
int height = (int)((ViewportHeight / _zoom));
return new Rectangle((int)(_pos.X - width / 2), (int)(_pos.Y - height / 2), width, height);
}
}
public void Move(Vector2 amount)
{
_pos += amount;
}
public Vector2 Position
{
get { return _pos; }
set { _pos = value; }
}
public Matrix View
{
get
{
return Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
}
}
#endregion
public Camera(Viewport viewport, float initialZoom)
{
_zoom = initialZoom;
_pos = Vector2.Zero;
ViewportWidth = viewport.Width;
ViewportHeight = viewport.Height;
}
}

Issue with matrix transformations and sprite direction

I have a sprite called Tool that moves with a speed represented as a float and in a direction represented as a Vector2. When I click the mouse on the screen the sprite change its direction and starts to move towards the mouseclick. In addition to that I rotate the sprite so that it is facing in the direction it is heading. However, when I add a camera that is suppose to follow the sprite so that the sprite is always centered on the screen, the sprite won't move in the given direction and the rotation isn't accurate anymore. This only happens when I add the Camera.View in the spriteBatch.Begin(). I was hoping anyone could maybe shed a light on what I am missing in my code, that would be highly appreciated.
Here is the camera class i use:
public class Camera
{
private const float zoomUpperLimit = 1.5f;
private const float zoomLowerLimit = 0.1f;
private float _zoom;
private Vector2 _pos;
private int ViewportWidth, ViewportHeight;
#region Properties
public float Zoom
{
get { return _zoom; }
set
{
_zoom = value;
if (_zoom < zoomLowerLimit)
_zoom = zoomLowerLimit;
if (_zoom > zoomUpperLimit)
_zoom = zoomUpperLimit;
}
}
public Rectangle Viewport
{
get
{
int width = (int)((ViewportWidth / _zoom));
int height = (int)((ViewportHeight / _zoom));
return new Rectangle((int)(_pos.X - width / 2), (int)(_pos.Y - height / 2), width, height);
}
}
public void Move(Vector2 amount)
{
_pos += amount;
}
public Vector2 Position
{
get { return _pos; }
set { _pos = value; }
}
public Matrix View
{
get
{
return Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
}
}
#endregion
public Camera(Viewport viewport, float initialZoom)
{
_zoom = initialZoom;
_pos = Vector2.Zero;
ViewportWidth = viewport.Width;
ViewportHeight = viewport.Height;
}
}
And here is my Update and Draw-method:
protected override void Update (GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
TouchCollection touchCollection = TouchPanel.GetState ();
foreach (TouchLocation tl in touchCollection) {
if (tl.State == TouchLocationState.Pressed || tl.State == TouchLocationState.Moved) {
//direction the tool shall move towards
direction = touchCollection [0].Position - toolPos;
if (direction != Vector2.Zero) {
direction.Normalize ();
}
//change the direction the tool is moving and find the rotationangle the texture must rotate to point in given direction
toolPos += (direction * speed * elapsed);
RotationAngle = (float)Math.Atan2 (direction.Y, direction.X);
}
}
if (direction != Vector2.Zero) {
direction.Normalize ();
}
//move tool in given direction
toolPos += (direction * speed * elapsed);
//change cameracentre to the tools position
Camera.Position = toolPos;
base.Update (gameTime);
}
protected override void Draw (GameTime gameTime)
{
graphics.GraphicsDevice.Clear (Color.Blue);
spriteBatch.Begin (SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, Camera.View);
spriteBatch.Draw (tool, new Vector2 (toolPos.X, toolPos.Y), null, Color.White, RotationAngle, originOfToolTexture, 1, SpriteEffects.None, 1);
spriteBatch.End ();
base.Draw (gameTime);
}
You need to convert your cursor position into world position:
Vector2 adjustedPosition = Vector2.Transform(touchCollection[0].Position, Matrix.Invert(camera.View));
Then your direction would be:
direction = adjustedPosition - toolPos;

Field is never assigned and will always have default value null

So I just finished up doing a class for my wandering & pursuing enemies yet once I've gone through and declared the class and done the necessary coding when I run the game I get a NullReferenceException pop up which then tells me that the field Virtual_Alien is never assigned and will always have the default value of null.
What am I doing wrong here?
main game code:
private Roaming_Aliens roamingAlien;
private Virtual_Aliens virtualAlien;
public Vector2 playerPosition;
public Player mainPlayer = new Player();
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mainPlayer.position = playerPostion;
// now assign that image to each of the characters we have
roamingAlien.LoadContent(Content);
virtualAlien.LoadContent(Content);
mainPlayer.LoadContent(Content);
score.LoadContent(Content);
// mainBackground.LoadContent(Content);
}
protected override void Update(GameTime gameTime)
{
currentKey = Keyboard.GetState();
if (currentKey.IsKeyDown(Keys.Escape))
{
this.Exit();
}
mainPlayer.Update(gameTime);
score.Update(gameTime);
virtualAlien.Update(gameTime);
roamingAlien.Wander();
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//mainBackground.Draw(spriteBatch);
mainPlayer.Draw(spriteBatch);
virtualAlien.Draw(spriteBatch);
roamingAlien.Draw(spriteBatch);
spriteBatch.End();
}
Virtual alien code:
public class Virtual_Aliens
{
private enum TankAiState
{
Chasing,
Wander
}
private float maxSpeed;
private float maxRotation;
private float chaseDistance;
private float hysteresis;
private Texture2D texture;
private Vector2 drawingOrigin;
private Vector2 position;
private TankAiState tankState = TankAiState.Wander;
private float orientation;
private Random random = new Random();
private Rectangle viewportbounds;
public Rectangle boundingBox;
public Vector2 playerPosition;
private Vector2 heading;
public Virtual_Aliens(Rectangle pos, Rectangle b)
{
position = new Vector2 (100, 100);
boundingBox = new Rectangle(pos.X, pos.Y, pos.Width, pos.Height);
viewportbounds = new Rectangle(b.X, b.Y, b.Width, b.Height);
orientation = 0.0f;
heading = new Vector2(0, 0);
maxSpeed = 2.0f;
maxRotation = 0.20f;
random = new Random();
hysteresis = 15.0f;
chaseDistance = 250.0f;
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("images/asteroid");
}
private Vector2 OrientationAsVector(float orien)
{
Vector2 orienAsVect;
orienAsVect.X = (float)Math.Cos(orien);
orienAsVect.Y = (float)Math.Sin(orien);
return orienAsVect;
}
Vector2 wanderPosition = new Vector2();
public void Wander()
{
// The wander effect is accomplished by having the character aim in a random
// direction. Every frame, this random direction is slightly modified.
// the max +/- the agent will wander from its current position
float wanderLimits = 0.5f;
// this defines what proportion of its maxRotation speed the agent will turn
float turnFactor = 0.15f;
// randomly define a new position
wanderPosition.X += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
wanderPosition.Y += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
// normalize the wander position, ...
if (wanderPosition != Vector2.Zero)
wanderPosition.Normalize();
// now find the new orientation based on the wanderPosition
orientation = TurnToFace(wanderPosition, orientation, turnFactor * maxRotation);
// determine the heading vector based on orientation
heading = OrientationAsVector(orientation);
// finally update the agents position based upon the new heading and its speed
// assume a wandering agent only moves at 0.5 of maxSpeed
position += heading * 0.5f * maxSpeed;
WrapForViewport();
}
private void WrapForViewport()
{
if (position.X < 0)
{
position.X = viewportbounds.Width;
}
else if (position.X > viewportbounds.Width)
{
position.X = 0;
}
if (position.Y < 0)
{
position.Y = viewportbounds.Height;
}
else if (position.Y > viewportbounds.Height)
{
position.Y = 0;
}
}
private float WrapAngle(float radian)
{
while (radian < -MathHelper.Pi)
{
radian += MathHelper.TwoPi;
}
while (radian > MathHelper.Pi)
{
radian -= MathHelper.TwoPi;
}
return radian;
}
private float TurnToFace(Vector2 steering, float currentOrientation, float turnSpeed)
{
float newOrientation;
float desiredOrientation;
float orientationDifference;
float x = steering.X;
float y = steering.Y;
// the desiredOrientation is given by the steering vector
desiredOrientation = (float)Math.Atan2(y, x);
// find the difference between the orientation we need to be
// and our current Orientation
orientationDifference = desiredOrientation - currentOrientation;
// now using WrapAngle to get result from -Pi to Pi
// ( -180 degrees to 180 degrees )
orientationDifference = WrapAngle(orientationDifference);
// clamp that between -turnSpeed and turnSpeed.
orientationDifference = MathHelper.Clamp(orientationDifference, -turnSpeed, turnSpeed);
// the closest we can get to our target is currentAngle + orientationDifference.
// return that, using WrapAngle again.
newOrientation = WrapAngle(currentOrientation + orientationDifference);
return newOrientation;
}
public void Update(GameTime gameTime)
{
if (tankState == TankAiState.Wander)
{
chaseDistance -= hysteresis / 2;
}
else if (tankState == TankAiState.Chasing)
{
chaseDistance += hysteresis / 2;
}
// Second, now that we know what the thresholds are, we compare the tank's
// distance from the cat against the thresholds to decide what the tank's
// current state is.
float distanceFromPlayer = Vector2.Distance(position, playerPosition);
if (distanceFromPlayer > chaseDistance)
{
// just like the mouse, if the tank is far away from the cat, it should
// idle.
tankState = TankAiState.Wander;
}
else
{
tankState = TankAiState.Chasing;
}
// Third, once we know what state we're in, act on that state.
float currentTankSpeed;
if (tankState == TankAiState.Chasing)
{
// the tank wants to chase the cat, so it will just use the TurnToFace
// function to turn towards the cat's position. Then, when the tank
// moves forward, he will chase the cat.
orientation = TurnToFace(playerPosition, orientation, maxRotation);
currentTankSpeed = maxSpeed;
}
else if (tankState == TankAiState.Wander)
{
Wander();
}
}
public void Draw(SpriteBatch spriteBatch)
{
drawingOrigin = new Vector2(texture.Width / 2, texture.Height / 2);
spriteBatch.Draw(texture, position, null, Color.White, orientation, drawingOrigin, 1.0f, SpriteEffects.None, 0.0f);
}
public Vector2 PlayerPosition
{
set
{
playerPosition = value;
}
get
{
return playerPosition;
}
}
}
You declare (twice actually) a variable called virtualAlien (of type Virtual_Aliens). However, you never assign it anything (while using it all over the place.
You declaration needs to look like:
Virtual_Alien virtualAlien = new Virtual_Alien();
This is assigns it to a new instance of the Virtual_Alien class, allowing you to use it later on. If you need parameters that aren't available until later, put the instantiation at the point when all needed information is available, and add null checks around any use of the variable that could happen before the instantiating code is called.
The romaingAlien member appears to have a similar problem.

Categories

Resources