XNA - adding items to a list and draw them - c#

So I'm making a Space Invaders clone in XNA. I created the invaders array and added their movement logic. I want to make them shoot bullets. So I've been following a tutorial about it and used only the code I need. But still no bullets are drawn on the screen. Here's my invader class, I removed what is not related to the question from it:
class botInvaders
{
public botInvaders(Texture2D newBulletTex)
{
bulletsList = new List<blasterLasers>();
bulletTex = newBulletTex;
botInvadersHealth = 5;
currentDificultyLevel = 1;
bulletDelay = 40;
isVisible = true;
}
public static Texture2D botInvaderTex, bulletTex;
public static Rectangle botInvaderHitBox;
public static Vector2 botInvaderOrigin;
public int botInvaderCurrentFrame = 1, botInvaderFrameWidth = 52, botInvaderFrameHeight = 90, bulletDelay, botInvadersHealth, currentDificultyLevel, invaderRows = 3, invaderCollumns = 10; // invaderRows = 5 // For 50 invaders
public static Rectangle[,] botInvadersRect;
public bool isVisible;
public List<blasterLasers> bulletsList;
public void LoadContent(ContentManager Content)
{
botInvaderTex = Content.Load<Texture2D>(".\\gameGraphics\\gameSprites\\botInvaders\\normalInvaders\\invaderShip1");
bulletTex = Content.Load<Texture2D>(".\\gameGraphics\\gameSprites\\botInvaders\\normalInvaders\\botInvaderLaser");
botInvadersRect = new Rectangle[invaderRows, invaderCollumns];
}
public void Update(GameTime gameTime)
{
for (int r = 0; r < invaderRows; r++)
{
for (int c = 0; c < invaderCollumns; c++)
{
EnemyShoot();
UpdateBullets();
}
}
}
public void Draw(Texture2D invadersTex, Rectangle[,] invadersDestinationRect, Nullable<Rectangle> invadersSourceRect, Color invadersColor, float invadersRotation, Vector2 invadersOrigin, SpriteEffects invadersEffects, float invadersScale, SpriteBatch spriteBatch)
{
for (int r = 0; r < invaderRows; r++)
{
for (int c = 0; c < invaderCollumns; c++)
{
spriteBatch.Draw(botInvaderTex, botInvadersRect[r, c], botInvaderHitBox, Color.White);
foreach (blasterLasers bulletSpawn in bulletsList)
{
bulletSpawn.Draw(spriteBatch);
}
}
}
}
public void UpdateBullets()
{
foreach (blasterLasers bulletsSpawn in bulletsList)
{
bulletsSpawn.bulletPos.Y = bulletsSpawn.bulletPos.Y + bulletsSpawn.bulletSpeed;
if (bulletsSpawn.bulletPos.Y >= -632)
{
bulletsSpawn.isVisible = false;
}
}
for (int i = 0; i < bulletsList.Count(); i++)
{
if (!bulletsList[i].isVisible)
{
bulletsList.RemoveAt(i);
i--;
}
}
}
public void EnemyShoot()
{
if (bulletDelay >= 0)
{
bulletDelay--;
}
if (bulletDelay <= 0)
{
blasterLasers newBullet = new blasterLasers(bulletTex);
newBullet.bulletPos = new Vector2(botInvaderHitBox.X + botInvaderFrameWidth / 2 - newBullet.bulletTex.Width / 2, botInvaderHitBox.Y + 90);
newBullet.isVisible = true;
if (bulletsList.Count() < 20)
{
bulletsList.Add(newBullet);
}
}
if (bulletDelay == 0)
{
bulletDelay = 40;
}
}
}
I initialize the class in Game1:
// Create a var
botInvaders botInvader;
// Init it
botInvader = new botInvaders(botInvaders.bulletTex);
// Load Content
botInvader.LoadContent(Content);
// Update
botInvader.Update(gameTime);
// Draw Invaders
botInvader.Draw(botInvaders.botInvaderTex, botInvaders.botInvadersRect, botInvaders.botInvaderHitBox, Color.White, 0f, botInvaders.botInvaderOrigin, SpriteEffects.None, 1.0f, spriteBatch);
Could the problem be that I'm not actually drawing the bullets?
Or I'm not adding any bullets to the list?
If I debug I can see:
bulletsList Count = 0
_size 0
_items [0] null [1] null [2] null [3] null
EDIT:
blasterLasers class:
public class blasterLasers
{
public Texture2D bulletTex;
public Vector2 bulletOrigin, bulletPos;
public bool isVisible;
public float bulletSpeed;
public Rectangle boundingBox;
public blasterLasers(Texture2D newBulletTex)
{
bulletSpeed = 10f;
bulletTex = newBulletTex;
isVisible = false;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(bulletTex, bulletPos, Color.White);
}
}

It looks like you are removing the bullets from bulletslist when you call UpdateBullets, so when you go call Draw, it loops through bulletList, which is empty, hence nothing is drawn.

Related

GUI text created during runtime is not visible

I am using the DebugConsole script to show the debug output on screen.It works perfectly but appears at the top left corner. I want it to appear inside a panel where I have created a window and a GUI text element and the script gives this option as well. I see the gui text formed as an element in the project console, but is not visible.
I do have a GUI layer
My gui text element is the direct child of a canvas
Camera is set to screen space overlay. I tried worldspace , still not visible.
My code:
namespace OctopartApi
{
using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
using System.Net;
using UnityEngine.UI;
public class KeywordSearch1 : MonoBehaviour
{
public InputField mainInputField;
public Canvas can;
public Text infoText;
public float x, y;
void Start () {
mainInputField.onEndEdit.AddListener(delegate {LockInput(mainInputField); });
}
void LockInput(InputField input)
{
ExecuteSearch (input.text);
}
public void ExecuteSearch(string inp)
{
// -- your search query --
string query = inp;
string octopartUrlBase = "http://octopart.com/api/v3";
string octopartUrlEndpoint = "parts/search";
string apiKey = "57af648b";
// Create the search request
var client = new RestClient(octopartUrlBase);
var req = new RestRequest(octopartUrlEndpoint, Method.GET)
.AddParameter("apikey", apiKey)
.AddParameter("q", query)
.AddParameter("start", "0")
.AddParameter("limit", "10");
var resp = client.Execute(req);
string octojson = resp.Content;
RootOb rr = JsonUtility.FromJson<RootOb> (octojson);
string hhts = (rr.hits).ToString();
hhts = hhts + rr.user_currency;
infoText.horizontalOverflow = HorizontalWrapMode.Overflow;
infoText.verticalOverflow = VerticalWrapMode.Overflow;
infoText.text = hhts;
// sendR (inp);
// Perform the search and obtain results
/* var resp = client.Execute(req);
var search_response = JsonConvert.DeserializeObject<dynamic>(resp.Content);
Console.WriteLine (search_response);
// Print the number of hits and results
Console.WriteLine("Number of hits: " + search_response["hits"]);
Debug.Log(search_response ["hits"]+"OCTO");
foreach (var result in search_response["results"])
{
var part = result["item"];
Debug.Log(part["brand"]["name"] + "OCTO" + part["mpn"]+part["octopart_url"]);
DebugConsole.Log (part ["brand"] ["name"] + "-- " + part ["mpn"]+" " +part["octopart_url"]);
}*/
}
// -- your API key -- (https://octopart.com/api/register)
private const string APIKEY = "57af648b";
}
}
DebugConsole script :
using UnityEngine;
using System.Collections;
public class DebugConsole : MonoBehaviour
{
public GameObject DebugGui = null; // The GUI that will be duplicated
public Vector3 defaultGuiPosition = new Vector3(0.01F, 0.98F, 0F);
public Vector3 defaultGuiScale = new Vector3(0.5F, 0.5F, 1F);
public Color normal = Color.green;
public Color warning = Color.yellow;
public Color error = Color.red;
public int maxMessages = 30; // The max number of messages displayed
public float lineSpacing = 0.02F; // The amount of space between lines
public ArrayList messages = new ArrayList();
public ArrayList guis = new ArrayList();
public ArrayList colors = new ArrayList();
public bool draggable = true; // Can the output be dragged around at runtime by default?
public bool visible = true; // Does output show on screen by default or do we have to enable it with code?
public bool pixelCorrect = false; // set to be pixel Correct linespacing
public static bool isVisible
{
get
{
return DebugConsole.instance.visible;
}
set
{
DebugConsole.instance.visible = value;
if (value == true)
{
DebugConsole.instance.Display();
}
else if (value == false)
{
DebugConsole.instance.ClearScreen();
}
}
}
public static bool isDraggable
{
get
{
return DebugConsole.instance.draggable;
}
set
{
DebugConsole.instance.draggable = value;
}
}
private static DebugConsole s_Instance = null; // Our instance to allow this script to be called without a direct connection.
public static DebugConsole instance
{
get
{
if (s_Instance == null)
{
s_Instance = FindObjectOfType(typeof(DebugConsole)) as DebugConsole;
if (s_Instance == null)
{
GameObject console = new GameObject();
console.AddComponent<DebugConsole>();
console.name = "DebugConsoleController";
s_Instance = FindObjectOfType(typeof(DebugConsole)) as DebugConsole;
DebugConsole.instance.InitGuis();
}
}
return s_Instance;
}
}
void Awake()
{
s_Instance = this;
InitGuis();
}
protected bool guisCreated = false;
protected float screenHeight =-1;
public void InitGuis()
{
float usedLineSpacing = lineSpacing;
screenHeight = Screen.height;
if(pixelCorrect)
usedLineSpacing = 1.0F / screenHeight * usedLineSpacing;
if (guisCreated == false)
{
if (DebugGui == null) // If an external GUIText is not set, provide the default GUIText
{
DebugGui = new GameObject();
DebugGui.AddComponent<GUIText>();
DebugGui.name = "DebugGUI(0)";
DebugGui.transform.position = defaultGuiPosition;
DebugGui.transform.localScale = defaultGuiScale;
}
// Create our GUI objects to our maxMessages count
Vector3 position = DebugGui.transform.position;
guis.Add(DebugGui);
int x = 1;
while (x < maxMessages)
{
position.y -= usedLineSpacing;
GameObject clone = null;
clone = (GameObject)Instantiate(DebugGui, position, transform.rotation);
clone.name = string.Format("DebugGUI({0})", x);
guis.Add(clone);
position = clone.transform.position;
x += 1;
}
x = 0;
while (x < guis.Count)
{
GameObject temp = (GameObject)guis[x];
temp.transform.parent = DebugGui.transform;
x++;
}
guisCreated = true;
} else {
// we're called on a screensize change, so fiddle with sizes
Vector3 position = DebugGui.transform.position;
for(int x=0;x < guis.Count; x++)
{
position.y -= usedLineSpacing;
GameObject temp = (GameObject)guis[x];
temp.transform.position= position;
}
}
}
bool connectedToMouse = false;
void Update()
{
// If we are visible and the screenHeight has changed, reset linespacing
if (visible == true && screenHeight != Screen.height)
{
InitGuis();
}
if (draggable == true)
{
if (Input.GetMouseButtonDown(0))
{
if (connectedToMouse == false && DebugGui.GetComponent<GUIText>().HitTest((Vector3)Input.mousePosition) == true)
{
connectedToMouse = true;
}
else if (connectedToMouse == true)
{
connectedToMouse = false;
}
}
if (connectedToMouse == true)
{
float posX = DebugGui.transform.position.x;
float posY = DebugGui.transform.position.y;
posX = Input.mousePosition.x / Screen.width;
posY = Input.mousePosition.y / Screen.height;
DebugGui.transform.position = new Vector3(posX, posY, 0F);
}
}
}
//+++++++++ INTERFACE FUNCTIONS ++++++++++++++++++++++++++++++++
public static void Log(string message, string color)
{
DebugConsole.instance.AddMessage(message, color);
}
//++++ OVERLOAD ++++
public static void Log(string message)
{
DebugConsole.instance.AddMessage(message);
}
public static void Clear()
{
DebugConsole.instance.ClearMessages();
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//---------- void AddMesage(string message, string color) ------
//Adds a mesage to the list
//--------------------------------------------------------------
public void AddMessage(string message, string color)
{
messages.Add(message);
colors.Add(color);
Display();
}
//++++++++++ OVERLOAD for AddMessage ++++++++++++++++++++++++++++
// Overloads AddMessage to only require one argument(message)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void AddMessage(string message)
{
messages.Add(message);
colors.Add("normal");
Display();
}
//----------- void ClearMessages() ------------------------------
// Clears the messages from the screen and the lists
//---------------------------------------------------------------
public void ClearMessages()
{
messages.Clear();
colors.Clear();
ClearScreen();
}
//-------- void ClearScreen() ----------------------------------
// Clears all output from all GUI objects
//--------------------------------------------------------------
void ClearScreen()
{
if (guis.Count < maxMessages)
{
//do nothing as we haven't created our guis yet
}
else
{
int x = 0;
while (x < guis.Count)
{
GameObject gui = (GameObject)guis[x];
gui.GetComponent<GUIText>().text = "";
//increment and loop
x += 1;
}
}
}
//---------- void Prune() ---------------------------------------
// Prunes the array to fit within the maxMessages limit
//---------------------------------------------------------------
void Prune()
{
int diff;
if (messages.Count > maxMessages)
{
if (messages.Count <= 0)
{
diff = 0;
}
else
{
diff = messages.Count - maxMessages;
}
messages.RemoveRange(0, (int)diff);
colors.RemoveRange(0, (int)diff);
}
}
//---------- void Display() -------------------------------------
// Displays the list and handles coloring
//---------------------------------------------------------------
void Display()
{
//check if we are set to display
if (visible == false)
{
ClearScreen();
}
else if (visible == true)
{
if (messages.Count > maxMessages)
{
Prune();
}
// Carry on with display
int x = 0;
if (guis.Count < maxMessages)
{
//do nothing as we havent created our guis yet
}
else
{
while (x < messages.Count)
{
GameObject gui = (GameObject)guis[x];
//set our color
switch ((string)colors[x])
{
case "normal": gui.GetComponent<GUIText>().material.color = normal;
break;
case "warning": gui.GetComponent<GUIText>().material.color = warning;
break;
case "error": gui.GetComponent<GUIText>().material.color = error;
break;
}
//now set the text for this element
gui.GetComponent<GUIText>().text = (string)messages[x];
//increment and loop
x += 1;
}
}
}
}
}// End DebugConsole Class

XNA game not launching under very strange conditions

First thing to get out of the way, sorry if I'm missing something (very) obvious, I'm still kinda new at this.
Anyway, I've been working on an asteroids clone in XNA, and for some reason it would occasionally not start if I hit the Start Debugging button. I tracked the problem to my AsteroidsManager class, which takes an int of initial asteroids to generate, minimum and maximum velocities and rotational velocites, and two texture lists for asteroids and particles. Now the weirdness:
temp = new AsteroidManager(1, 20, 50, 1, 2, asteroids, particles, true); //With this constructor, the game always starts fine...
But if I crank up the number of initial asteroids:
temp = new AsteroidManager(10, 20, 50, 1, 2, asteroids, particles, true); //This seems to start about 1/3 times in the Visual Studio debugger, but if I launch it without debugging or from the bin folder, it works fine.
And lastly, if I set the asteroids to more than ~20, it never starts in the debugger, and if I try to start it from the folder, the process appears in the task manager, but nothing ever happens. Or it just crashes on launch. I honestly have no idea what's causing this, and will gladly provide any code if needed, but here's what I think is relevant:
Full AsteroidManager:
public class AsteroidManager
{
#region Declarations
public List<GameObject> Asteroids { get; set; }
public bool RegenerateAsteroids { get; set; }
public readonly int InitialAsteroids;
public readonly float MinVelocity;
public readonly float MaxVelocity;
public readonly float MinRotationalVelocity; //in degrees
public readonly float MaxRotationalVelocity; //in degrees
public readonly List<Texture2D> Textures;
public readonly List<Texture2D> ExplosionParticleTextures;
List<ParticleEmitter> emitters;
Random rnd;
const int MINPARTICLES = 50;
const int MAXPARTICLES = 200;
const int PARTICLEFTL = 40;
#endregion
public AsteroidManager(
int initialAsteroids,
float minVel,
float maxVel,
float minRotVel,
float maxRotVel,
List<Texture2D> textures,
List<Texture2D> explosionParticleTextures,
bool regenAsteroids)
{
rnd = new Random();
InitialAsteroids = initialAsteroids;
MinVelocity = minVel;
MaxVelocity = maxVel;
MinRotationalVelocity = minRotVel;
MaxRotationalVelocity = maxRotVel;
Textures = textures;
ExplosionParticleTextures = explosionParticleTextures;
RegenerateAsteroids = regenAsteroids;
Asteroids = new List<GameObject>();
emitters = new List<ParticleEmitter>();
for (int i = 0; i < InitialAsteroids; i++)
addAsteroid();
}
public void Update(GameTime gameTime)
{
for (int i = 0; i < Asteroids.Count; i++)
Asteroids[i].Update(gameTime);
for (int i = 0; i < emitters.Count; i++)
emitters[i].Update(gameTime);
if (Asteroids.Count < InitialAsteroids && RegenerateAsteroids)
addAsteroid();
}
public void Draw(SpriteBatch spriteBatch)
{
for (int i = 0; i < Asteroids.Count; i++)
Asteroids[i].Draw(spriteBatch);
for (int i = 0; i < emitters.Count; i++)
emitters[i].Draw(spriteBatch);
}
public void DestroyAsteroid(GameObject asteroid)
{
int x = rnd.Next(MINPARTICLES, MAXPARTICLES);
List<Color> colors = new List<Color>();
colors.Add(Color.White);
emitters.Add(new ParticleEmitter( //TODO: Test
x,
asteroid.WorldCenter,
ExplosionParticleTextures,
colors,
PARTICLEFTL,
true,
1,
x,
1f,
0.3f,
0f,
180f));
Asteroids.Remove(asteroid);
}
protected void addAsteroid()
{
GameObject tempAsteroid;
bool isOverlap = false;
do //Do-While to ensure that the asteroid gets generated at least once
{
Texture2D text = Textures.PickRandom<Texture2D>();
float rot = MathHelper.ToRadians((float)rnd.NextDouble(0f, 359f));
float rotVel = MathHelper.ToRadians((float)rnd.NextDouble(MinRotationalVelocity, MaxRotationalVelocity));
int colRadius = (((text.Width / 2) + (text.Height / 2)) / 2); //Get the mean of text's height & width
Vector2 vel = Vector2.Multiply( //calculate a random velocity
rot.RotationToVectorFloat(),
(float)rnd.NextDouble(MinVelocity, MaxVelocity));
Vector2 worldPos = new Vector2(
rnd.Next(Camera.WorldRectangle.X, Camera.WorldRectangle.Width),
rnd.Next(Camera.WorldRectangle.Y, Camera.WorldRectangle.Height));
tempAsteroid = new GameObject( //init a temporary asteroid to check for overlaps
text, worldPos, vel, Color.White, false, rot, rotVel, 1f, 0f, colRadius);
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap); //if overlapping, loop
Asteroids.Add(tempAsteroid); //add the temp asteroid
}
}
Full GameObject:
public class GameObject
{
#region Declarations
public Texture2D Texture { get; set; }
public Vector2 Origin { get; set; }
public Color TintColor { get; set; }
public float Rotation { get; set; } //radians
public float RotationalVelocity { get; set; }
public float Scale { get; set; }
public float Depth { get; set; }
public bool Active { get; set; }
public SpriteEffects Effects { get; set; }
public Vector2 WorldLocation { get; set; }
public Vector2 Velocity { get; set; }
public int CollisionRadius { get; set; } //Radius for bounding circle collision
public int BoundingXPadding { get; set; }
public int BoundingYPadding { get; set; } //Padding for bounding box collision
public int TotalFrames
{
get //simple get
{ return totalFrames; }
set //check if given totalFrames is in possible range
{
if (value <= (Rows * Columns))
totalFrames = value;
else
throw new ArgumentOutOfRangeException();
}
} //Used in spritesheet animation
private int totalFrames;
public int CurrentFrame
{
get { return currentFrame; }
set
{
currentFrame = (int)MathHelper.Clamp(value, 0, totalFrames);
}
}
private int currentFrame;
public int Rows { get; set; }
public int Columns { get; set; }
public bool Animating { get; set; }
public float RotationDegrees
{
get { return MathHelper.ToDegrees(Rotation); }
set { Rotation = MathHelper.ToRadians(value); }
}
public float RotationVelocityDegrees
{
get { return MathHelper.ToDegrees(RotationalVelocity); }
set { RotationalVelocity = MathHelper.ToRadians(value); }
}
public const float VELOCITYSCALAR = 1.0f / 60.0f; //Default to 60fps standard movement
#endregion
#region Properties
public int GetWidth { get { return Texture.Width / Columns; } } //Width of a frame
public int GetHeight { get { return Texture.Height / Rows; } } //Height of a frame
public int GetRow { get { return (int)((float)CurrentFrame / (float)Columns); } } //Current row
public int GetColumn { get { return CurrentFrame % Columns; } } //Current column
public Vector2 SpriteCenter
{ get { return new Vector2(GetWidth / 2, GetHeight / 2); } } //Get this Sprite's center
public Rectangle WorldRectangle //get rectangle in world coords with width of sprite
{
get
{
return new Rectangle(
(int)WorldLocation.X,
(int)WorldLocation.Y,
GetWidth,
GetHeight);
}
}
public Rectangle BoundingBox //get bounding box for use in collision detection
{
get
{
return new Rectangle( //Get bounding box with respect to padding values
(int)WorldLocation.X + BoundingXPadding,
(int)WorldLocation.Y + BoundingYPadding,
GetWidth - (BoundingXPadding * 2),
GetHeight - (BoundingYPadding * 2));
}
}
public Vector2 ScreenLocation
{ get { return Camera.GetLocalCoords(WorldLocation); } } //get screen coordinates
public Rectangle ScreenRectangle
{ get { return Camera.GetLocalCoords(WorldRectangle); } } //get screen rectangle
public Vector2 WorldCenter
{
get { return WorldLocation + SpriteCenter; }
set { WorldLocation = value - SpriteCenter; }
} //gets/sets the center of the sprite in world coords
public Vector2 ScreenCenter
{ get { return Camera.GetLocalCoords(WorldLocation + SpriteCenter); } } //returns the center in screen coords
#endregion
public GameObject( //main constructor, /w added optional parameters and call to SpriteBase init
Texture2D texture,
Vector2 worldLocation,
Vector2 velocity,
Color tintColor,
bool animating = false,
float rotation = 0f, //default to no rotation
float rotationalVelocity = 0f,
float scale = 1f, //default to 1:1 scale
float depth = 0f, //default to 0 layerDepth
int collisionRadius = 0, //collision radius used in bounding circle collision, default to 0 or no bounding circle
int xPadding = 0, //amount of x padding, used in bounding box collision, default to 0, or no bounding box
int yPadding = 0, //amount of y padding, used in bounding box collision, default to 0, or no bounding box
SpriteEffects effects = SpriteEffects.None,
int totalFrames = 0,
int rows = 1,
int columns = 1)
{
if (texture == null) { throw new NullReferenceException("Null texture reference."); }
Texture = texture; //assign parameters
WorldLocation = worldLocation;
TintColor = tintColor;
Rotation = rotation;
RotationalVelocity = rotationalVelocity;
Scale = scale;
Depth = depth;
Effects = effects;
Velocity = velocity;
Animating = animating;
Active = true;
BoundingXPadding = xPadding; BoundingYPadding = yPadding; CollisionRadius = collisionRadius; //assign collision data
Rows = rows; Columns = columns; this.TotalFrames = totalFrames; //assign animation data
Origin = SpriteCenter; //assign origin to the center of a frame
}
#region Methods
public virtual void Update(GameTime gameTime)
{
if (Active) //if object is active
{
WorldLocation += Velocity * (1f / 60f);
Rotation += RotationalVelocity; //Rotate according to the velocity
//Move by Velocity times a roughly 60FPS scalar
if (TotalFrames > 1 && Animating)
{
CurrentFrame++;
if (CurrentFrame >= TotalFrames)
CurrentFrame = 0; //Loop animation
}
if (Camera.IsObjectInWorld(this.WorldRectangle) == false)
{
if (Camera.LOOPWORLD) //if world is looping and the object is out of bounds
{
Vector2 temp = WorldCenter; //temporary Vector2 used for updated position
//X-Axis Component
if (WorldCenter.X > Camera.WorldRectangle.Width)
temp.X = Camera.WorldRectangle.X - (GetWidth / 2); //If X is out of bounds to the right, move X to the left side
if (WorldCenter.X < Camera.WorldRectangle.X)
temp.X = Camera.WorldRectangle.Width + (GetWidth / 2); //If X is out of bound to the left, move X to the right side
//Y-Axis Component
if (WorldCenter.Y > Camera.WorldRectangle.Height)
temp.Y = Camera.WorldRectangle.Y - (GetHeight / 2); //If Y is out of bounds to the bottom, move Y to the top
if (WorldCenter.Y < Camera.WorldRectangle.Y)
temp.Y = Camera.WorldRectangle.Height + (GetHeight / 2); //If Y is out of bounds to the top, move Y to the bottom
WorldCenter = temp; //Assign updated position
}
if (Camera.LOOPWORLD == false)
{
Active = false; //if the object is outside the world but the LOOPWORLD constant is false, set inactive
}
}
}
}
public virtual void Draw(SpriteBatch spriteBatch)
{
if (Active)
{
if (TotalFrames > 1 && Camera.IsObjectVisible(WorldRectangle)) //if multi-frame animation & object is visible
{
Rectangle sourceRectangle = new Rectangle(GetWidth * GetColumn,
GetHeight * GetRow, GetWidth, GetHeight); //get source rectangle to use
spriteBatch.Draw(
Texture,
ScreenCenter,
sourceRectangle, //use generated source rectangle
TintColor,
Rotation,
Origin,
Scale,
Effects,
Depth);
}
else //if single frame sprite
{
if (Camera.IsObjectVisible(WorldRectangle)) //check if sprite is visible to camera
{
spriteBatch.Draw(
Texture,
ScreenCenter, //center of the sprite in local coords
null, //full sprite
TintColor,
Rotation,
Origin,
Scale,
Effects, //spriteeffects
Depth); //layerdepth
}
}
}
}
public bool IsBoxColliding(Rectangle obj) //bounding box collision test
{
return BoundingBox.Intersects(obj);
}
public bool IsBoxColliding(GameObject obj) //overload of previous which takes a GameObject instead of a rectangle
{
if (BoundingBox.Intersects(obj.BoundingBox))
return true;
else
return false;
}
public bool IsCircleColliding(Vector2 objCenter, float objRadius)
{
if (Vector2.Distance(WorldCenter, objCenter) <
(CollisionRadius + objRadius)) //if the distance between centers is greater than the sum
return true; //of the radii, collision has occurred
else
return false; //if not, return false
}
public bool IsCircleColliding(GameObject obj) //overload of previous which takes a GameObject instead of loose values
{
if (Vector2.Distance(this.WorldCenter, obj.WorldCenter) <
(CollisionRadius + obj.CollisionRadius))
return true;
else
return false;
}
public void RotateTo(Vector2 point) //rotates the GameObject to a point
{
Rotation = (float)Math.Atan2(point.Y, point.X);
}
protected Vector2 rotationToVector()
{
return Rotation.RotationToVectorFloat();
} //local version of extension method
#endregion
}
Game1 Draw:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(); //BEGIN SPRITE DRAW
fpsDisplay.Draw(spriteBatch);
temp.Draw(spriteBatch);
spriteBatch.End(); //END SPRITE DRAW
base.Draw(gameTime);
}
Game1 Update:
protected override void Update(GameTime gameTime)
{
InputHandler.Update(); //update InputHandler
if (InputHandler.IsKeyDown(Keys.Left))
Camera.Position += new Vector2(-3f, 0f);
if (InputHandler.IsKeyDown(Keys.Right))
Camera.Position += new Vector2(3f, 0f);
if (InputHandler.IsKeyDown(Keys.Up))
Camera.Position += new Vector2(0f, -3f);
if (InputHandler.IsKeyDown(Keys.Down))
Camera.Position += new Vector2(0f, 3f);
fpsDisplay.Value = (int)Math.Round(1 / gameTime.ElapsedGameTime.TotalSeconds, 0);
//calculate framerate to the nearest int
temp.Update(gameTime);
base.Update(gameTime);
}
I would guess that your overlapping code is never finding a spot to place the asteroid. It enters a near-infinite (or possibly infinite if space is covered properly) loop that never exits. You could use a counter that given a number of attempts, it just "gives up". Or you can increase the max size of the playing area they can spawn in, or decrease their size; this would reduce the likelyhood of such an infinite loop from occurring, but not make it impossible given enough asteroids.
int attempts = 0;
do //Do-While to ensure that the asteroid gets generated at least once
{
attempts++;
...
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap && attempts < 20); //if overlapping, loop, give up after 20 tries
if (attempts == 20)
{
//log it! Or fix it, or something!
}
Even if you "fix" this by increasing the game size or reducing the asteroid size, I still suggest you make it run a maximum number of times to avoid infinite loops.

Unity3D: How to show GUI.box if condition is true?

I'm making a game in Unity3D with C#. I am using GUI.box to show a healthbar for the mobs, but I only want to show the GUI.box if there is a target.
This is my code at the moment.
public GameObject target;
public bool existsTarget;
// Use this for initialization
void Start()
{
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;
existsTarget = false;
}
// Update is called once per frame
void Update()
{
if(target != null)
existsTarget = true;
else
existsTarget = false;
}
void OnGUI()
{
if(existsTarget)
GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
else {
GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
}
Unfortunately this doesn't show any healthbars at all. Any ideas as to why?
Posting the scripts here after popular demand.
public class Targetting : MonoBehaviour {
public List<Transform> targets;
public List<Transform> items;
public GameObject TheSelectedTarget {get; set;}
private Transform selectedTarget;
private Transform selectedItem;
private Transform myTransform;
// Use this for initialization
void Start () {
targets = new List<Transform>();
items = new List<Transform>();
selectedTarget = null;
selectedItem = null;
myTransform = transform;
TheSelectedTarget = null;
addAllEnemies();
addAllItems();
}
//adds all targets to a list
private void addAllEnemies() {
GameObject[] go = GameObject.FindGameObjectsWithTag("Enemy");
foreach(GameObject enemy in go){
addTarget(enemy.transform);
}
}
//adds a target
private void addTarget(Transform enemy) {
targets.Add(enemy);
}
//sorts target by distance
private void sortTargets() {
targets.Sort(delegate(Transform t1, Transform t2) {
return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
});
}
//targets an enemy
private void targetEnemy() {
addAllEnemies();
if(selectedTarget == null) {
sortTargets();
selectedTarget = targets[0];
} else {
int index = targets.IndexOf(selectedTarget);
if(index < targets.Count -1) {
index++;
} else {
index = 0;
}
deselectTarget();
selectedTarget = targets[index];
}
selectTarget();
targets.Clear();
}
//selects a specific target, and colors it red
public void selectTarget() {
selectedTarget.renderer.material.color = Color.red;
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
pa.target = selectedTarget.gameObject;
TheSelectedTarget = pa.target;
}
//deselects the current selected target, and colors i grey
private void deselectTarget() {
selectedTarget.renderer.material.color = Color.gray;
selectedTarget = null;
}
//adds all items to a list
void addAllItems() {
GameObject[] go = GameObject.FindGameObjectsWithTag("Book");
foreach(GameObject book in go){
addItem(book.transform);
}
}
'
.... And then the script continues but without any relevance to this...
' public class EnemyHealth : MonoBehaviour
{
public string enemyName;
public int maxHealth = 100;
public int curHealth = 100;
public float healthBarLength;
public GameObject target;
public bool existsTarget;
public AudioSource dying;
// Use this for initialization
void Start()
{
//enemyName = this.enemyName;
healthBarLength = Screen.width / 3;
existsTarget = false;
}
// Update is called once per frame
void Update()
{
adjustCurHealth(0);
Targetting ta = (Targetting)GetComponent("Targetting");
target = ta.TheSelectedTarget;
Debug.Log (target);
if(target != null)
existsTarget = true;
else {
existsTarget = false;
}
}
void OnGUI()
{
if(existsTarget)
GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
else {
GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
}
}
public void adjustCurHealth(int adj)
{
curHealth += adj;
if (curHealth < 0)
curHealth = 0;
if (curHealth > 100)
curHealth = 100;
if (maxHealth < 0)
maxHealth = 1;
if(curHealth == 0)
{
//dying.Play ();
GameObject.Destroy(gameObject);
}
healthBarLength = (Screen.width / 3) * (curHealth / (float)maxHealth);
}
}
Are you ever setting the target anywhere other than the Start() method? The code you show will only ever show a GUI.box if the PlayerAttack.Target is not null at the start. Try moving this code to the Update() method.
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;
Edit:
Check to see if the target is null, that could be the issue.
target = pa.target;
Debug.Log(target);
This will either print to the log as whatever GameObject it is, or null. If it's null, then there is no target.

Loading an X position between classes gives a "field is never assigned to" warning

So I created a small game in XNA and I am at the stage of coding AI. The problem I have currently is that I can't load the X position of the redNinja (player's character) and have the blueNinja (AI) read it and walk towards it.
Every time I try to reference it via redNinja.Position.X, it gives me the field is never assigned to, and will always have it's default value null. warning.
namespace Ninja_DM
{
class AI
{
Texture2D blueNinja;
Ninjas redNinja;
float timer = 0f;
float interval = 130f;
int currentFrame = 0;
int spriteSpeed = 2;
int spriteWidth = 32;
int spriteHeight = 28;
public Rectangle sourceRect;
Vector2 position_b;
Vector2 origin;
public Vector2 Position
{
get { return position_b; }
set { position_b = value; }
}
public Vector2 Origin
{
get { return origin; }
set { origin = value; }
}
public Texture2D Texture
{
get { return blueNinja; }
set { blueNinja = value; }
}
public Rectangle SourceRect
{
get { return sourceRect; }
set { sourceRect = value; }
}
public AI(Texture2D texture, int currentFrame, int spriteWidth, int spriteHeight)
{
this.blueNinja = texture;
this.currentFrame = currentFrame;
this.spriteWidth = spriteWidth;
this.spriteHeight = spriteHeight;
}
public void AIMovement(GameTime gameTime)
{
sourceRect = new Rectangle(30 * currentFrame, 0, 30, 37);
if (position_b.X > redNinja.Position.X)
{
AnimateLeftAI(gameTime);
if (position_b.X < 20)
{
position_b.X += spriteSpeed;
}
}
if (position_b.X < redNinja.Position.X)
{
AnimateRightAI(gameTime);
if (position_b.X < 1100)
{
position_b.X += spriteSpeed;
}
}
}
public void AnimateLeftAI(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
if (currentFrame > 4)
{
currentFrame = 3;
}
timer = 0f;
}
}
public void AnimateRightAI(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
if (currentFrame > 4)
{
currentFrame = 3;
}
timer = 0f;
}
}
}
}
you would need to bring the player's ninja as an argument when calling AIMovement(), something like this:
public void AIMovement(GameTime gameTime, Ninjas playerNinja)
{
sourceRect = new Rectangle(30 * currentFrame, 0, 30, 37);
if (position_b.X > playerNinja.Position.X)
{
AnimateLeftAI(gameTime);
if (position_b.X < 20)
{
position_b.X += spriteSpeed;
}
}
if (position_b.X < playerNinja.Position.X)
{
AnimateRightAI(gameTime);
if (position_b.X < 1100)
{
position_b.X += spriteSpeed;
}
}
}
Notice you really don't need to declare a field variable called redNinja anymore because you bring the Ninjas in that you are testing against as arguments/parameters of the method.

Sprites and Spawning

I've got a ship that's spawning sprites. There are two types: railgun rounds and missiles. The missiles fire off properly, but the railgun rounds always spawn about one hundred pixels in front of the ship (or at least, it seems to). I'm not sure why this is happening. Also, there are two turrets, when it fires out of one, it's supposed to set a boolean value to true to make it fire out of the other one; when it fires out of that one, it sets the boolean back to false and so on. It always fires out of the first one. Again, no idea why. I've been banging my head against this all day. Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using ShipBattle.Classes.Ships;
using ShipBattle.Classes.Ships.Fighters;
using ShipBattle.Classes.Ships.Projectiles;
using ShipBattle.Classes.Ships.Projectiles.Tauri;
namespace ShipBattle.Classes.Ships.Fighters
{
public class F302 : Ship
{
const double missileMinimumFiringArc = Utilities.NINETY_DEGREES / 2;
const double missileMaximumFiringArc = Utilities.NINETY_DEGREES + (Utilities.NINETY_DEGREES / 2);
const double railgunMinimumFiringArc = 1.5;
const double railgunMaximumFiringArc = 1.6;
const double MISSILES_ROF = 30.0;
protected List<double> CooldownLeft = new List<double>();
private ContentManager content;
public event ShipFired WeaponFired;
public List<NaquadahEnhancedMissile> missiles;
public List<RailgunRound> railgunRounds;
public int[] MissileAmmo { get; set; }
public int[] RailgunAmmo { get; set; }
//Determines which missile/railgun to fire
bool leftMissile = true;
bool leftRailgun = true;
public F302(Vector2 position, ContentManager Content)
{
content = Content;
Texture = content.Load<Texture2D>(#"Textures\Ships\Tauri\Fighters\F302");
Position = position;
Rotation = 0;
#region Physics Stuff
mass = 19200;
force = 76.3f;
acceleration = (force * 1000) / mass;
maxSpeed = Utilities.GetVelocity(acceleration);
#endregion
#region Hull & Shielding
HullIntegrity = 10;
ShieldStrength = 0;
#endregion
#region Weapons!!!
/*
* [0] = Port Missile
* [1] = Starboard Missile
* [2] = Port Railgun
* [3] = Starboard Railgun
*/
//Setup
missiles = new List<NaquadahEnhancedMissile>();
railgunRounds = new List<RailgunRound>();
MissileAmmo = new int[2];
RailgunAmmo = new int[2];
//Port Missile
WeaponRatesOfFire.Add(MISSILES_ROF);
CooldownLeft.Add(0);
WeaponsEnplacements.Add(new Vector2(14, 5));
WeaponEmplacementOffsets.Add(new Vector2(14, 5));
MissileAmmo[0] = 2;
//Starboard Missile
WeaponRatesOfFire.Add(MISSILES_ROF);
CooldownLeft.Add(0);
WeaponsEnplacements.Add(new Vector2(35, 5));
WeaponEmplacementOffsets.Add(new Vector2(35, 5));
MissileAmmo[1] = 2;
//Port Railgun
WeaponRatesOfFire.Add(7.2);
CooldownLeft.Add(0);
WeaponsEnplacements.Add(new Vector2(24, 0));
WeaponEmplacementOffsets.Add(new Vector2(24, 0));
RailgunAmmo[0] = 10000;
//Starboard Railgun
WeaponRatesOfFire.Add(7.2);
CooldownLeft.Add(0);
WeaponsEnplacements.Add(new Vector2(26, 0));
WeaponEmplacementOffsets.Add(new Vector2(26, 0));
RailgunAmmo[1] = 10000;
#endregion
}
protected override void UpdateProjectiles(Vector2 pos)
{
for (int i = 0; i < missiles.Count; i++)
if (missiles[i].Remove)
missiles.RemoveAt(i);
for (int i = 0; i < railgunRounds.Count; i++)
if (railgunRounds[i].Remove)
railgunRounds.RemoveAt(i);
foreach (NaquadahEnhancedMissile nem in missiles)
nem.Update(enemyPos);
foreach (RailgunRound rr in railgunRounds)
rr.Update(enemyPos);
}
protected override void DrawProjectiles(SpriteBatch spriteBatch)
{
foreach (NaquadahEnhancedMissile nem in missiles)
nem.Draw(spriteBatch);
foreach (RailgunRound rr in railgunRounds)
rr.Draw(spriteBatch);
}
protected override void CheckTarget(Ship target)
{
enemyPos = target.Position;
double distance = Vector2.Distance(Position, target.Position);
Vector2 vector1 = Vector2.Normalize(Position - target.Position);
Vector2 vector2 = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation));
double angle = Math.Acos(Vector2.Dot(vector1, vector2));
if (angle > missileMinimumFiringArc && angle < missileMaximumFiringArc)
if (distance < 500)
if (((target.HullIntegrity + target.ShieldStrength) - 10) <= 0)
FireMissiles();
if (angle > railgunMinimumFiringArc && angle < railgunMaximumFiringArc)
FireRailguns();
}
protected void FireMissiles()
{
if (leftMissile)
{
if (CooldownLeft[0] <= 0)
{
if (MissileAmmo[0] > 0)
{
NaquadahEnhancedMissile nem = new NaquadahEnhancedMissile(WeaponsEnplacements[0], Rotation, content);
nem.hit += new ProjectileHit(nem_hit);
missiles.Add(nem);
CooldownLeft[0] = WeaponRatesOfFire[0];
CooldownLeft[1] = WeaponRatesOfFire[1];
MissileAmmo[0]--;
leftMissile = false;
}
}
}
else
if (CooldownLeft[1] <= 0)
{
if (MissileAmmo[1] > 0)
{
NaquadahEnhancedMissile nem = new NaquadahEnhancedMissile(WeaponsEnplacements[1], Rotation, content);
nem.hit += new ProjectileHit(nem_hit);
missiles.Add(nem);
CooldownLeft[0] = WeaponRatesOfFire[0];
CooldownLeft[1] = WeaponRatesOfFire[1];
MissileAmmo[1]--;
leftMissile = true;
}
}
}
private void FireRailguns()
{
if (leftRailgun)
{
if (CooldownLeft[2] <= 0)
{
if (RailgunAmmo[0] > 0)
{
RailgunRound rgr = new RailgunRound(WeaponsEnplacements[2], Rotation, content);
rgr.hit += new ProjectileHit(nem_hit);
railgunRounds.Add(rgr);
CooldownLeft[2] = WeaponRatesOfFire[2];
CooldownLeft[3] = WeaponRatesOfFire[3];
RailgunAmmo[0]--;
leftRailgun = false;
}
}
}
else
if (CooldownLeft[3] <= 0)
{
if (RailgunAmmo[1] > 0)
{
RailgunRound rgr = new RailgunRound(WeaponsEnplacements[3], Rotation, content);
rgr.hit += new ProjectileHit(nem_hit);
railgunRounds.Add(rgr);
CooldownLeft[2] = WeaponRatesOfFire[2];
CooldownLeft[3] = WeaponRatesOfFire[3];
MissileAmmo[1]--;
leftRailgun = true;
}
}
}
protected override void Cooldown()
{
for (int f = 0; f < CooldownLeft.Count; f++)
CooldownLeft[f]--;
}
private void nem_hit(Projectile p, EventArgs e)
{
if (p is NaquadahEnhancedMissile)
{
p.Remove = true;
if (targetShip.ShieldStrength > 0)
targetShip.ShieldStrength -= p.Damage;
else
targetShip.HullIntegrity -= p.Damage;
}
else if (p is RailgunRound)
{
p.Remove = true;
if (targetShip.ShieldStrength > 0)
targetShip.ShieldStrength -= p.Damage / 4;
else
targetShip.HullIntegrity -= p.Damage;
}
}
protected override void CleanupProjectiles()
{
missiles.Clear();
railgunRounds.Clear();
}
}
}
And here's the code for the ship class this all inherits from:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShipBattle.Classes.Ships.Projectiles;
using ShipBattle.Classes.Ships.Projectiles.Tauri;
namespace ShipBattle.Classes.Ships
{
public abstract class Ship
{
public Texture2D Texture { get; set; }
public Vector2 Position
{
get
{
return _position;
}
set
{
_position = value;
}
}
public float Rotation { get; set; }
private Vector2 _position;
protected Ship targetShip;
protected Vector2 enemyPos;
#region Health & Shielding
public float HullIntegrity { get; set; }
public float ShieldStrength { get; set; }
public bool Remove { get; set; }
#endregion
#region Guns
protected List<Vector2> WeaponsEnplacements = new List<Vector2>();
protected List<Vector2> WeaponEmplacementOffsets = new List<Vector2>();
protected List<double> WeaponRatesOfFire = new List<double>();
/// <summary>
/// The rates of fire for all weapons, represented in terms of the delay between frames
/// </summary>
#endregion
#region Targeting Logic
bool hasTarget = false;
protected int targetHashCode;
Vector2 targetShipPosition;
Ship target;
bool evasive = false;
bool hasRandomTrajectory = false;
bool reachedBounds = false;
bool followingRandom = false;
int timeToFaffAbout = 360;
double randomRotation;
#endregion
#region Physics Stuff
float angleA, b, a, speed = 0;
double turningRadius = 10 * (Math.PI / 180);
//Acceleration
protected int mass; // kg
protected float force; // kN, thruster power
protected float acceleration; // m/s^2
//Velocity
protected float maxSpeed; // m/s, calculated using 30-second burn
protected float initialSpeed = 0;
protected float finalSpeed = 0;
protected float time = 0.016666f;
#endregion
public void Update(List<Ship> ships)
{
if (timeToFaffAbout >= 0)
{
timeToFaffAbout = 360;
followingRandom = false;
}
if (!hasTarget)
{
targetShip = GetTarget(ships);
hasTarget = true;
}
else
{
if (targetShip != null)
{
if (Vector2.Distance(Position, targetShip.Position) < 75)
evasive = true;
else
evasive = false;
if (evasive)
{
if (!hasRandomTrajectory)
{
Random random = new Random();
randomRotation = random.Next((int)(Math.PI * 100));
double negative = random.Next(2);
if (negative == 1)
randomRotation *= -1;
Rotation = (float)randomRotation;
hasRandomTrajectory = true;
}
}
else
{
if (!followingRandom)
{
//Rotate the sprite using the turning radius
Rotation = Utilities.TurnToFace(Position, new Vector2(targetShip.Position.X, targetShip.Position.Y), (float)Rotation, (float)turningRadius);
}
}
KeepOnTheScreen();
//Move the sprite, using KINEMATIC PHYSICS, ***!!! -->goes in the direction set by the rotation algorithm
Move();
CheckTarget(targetShip);
UpdateProjectiles(targetShip.Position);
//Stop targeting a dead enemy
if (targetShip.HullIntegrity <= 0)
hasTarget = false;
}
}
//Recalculate the List<Vector2> weapons enplacements based on the current rotation angle
RecalculateWeaponsPositions();
//Cooldown the guns
Cooldown();
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, new Vector2(Texture.Width / 2, Texture.Height / 2), 0.5f,
SpriteEffects.None, 0.0f);
if (hasTarget)
DrawProjectiles(spriteBatch);
}
/// <summary>
/// Uses trig and the thruster power to move the ship. b is the y distance to move, a is the x distance to move
/// </summary>
private void Move()
{
if (finalSpeed < maxSpeed)
finalSpeed = speed + (acceleration * time);
angleA = Rotation;
b = (float)Math.Cos(angleA) * finalSpeed;
a = (float)Math.Sin(angleA) * finalSpeed;
_position.Y -= b;
_position.X += a;
speed = finalSpeed;
}
/// <summary>
/// Acquires the closes enemy ship
/// </summary>
/// <param name="ships">The ships to search through</param>
/// <returns></returns>
private Ship GetTarget(List<Ship> ships)
{
CleanupProjectiles();
Ship rVal = null;
int distance = int.MaxValue;
float c;
foreach (Ship ship in ships)
{
c = Vector2.Distance(Position, ship.Position);
if (c < distance)
rVal = ship;
}
return rVal;
}
/// <summary>
/// Reorients the positions of all the weapon positions on this ship
/// </summary>
private void RecalculateWeaponsPositions()
{
for (int i = 0; i < WeaponsEnplacements.Count; i++)
{
WeaponsEnplacements[i] = RotateWeapons(WeaponEmplacementOffsets[i]);
}
}
/// <summary>
/// Recalculates the positions of the weapons on this ship based off their default offset and the current angle
/// </summary>
/// <param name="weapon">The weapon position to recalculate</param>
/// <param name="offset">The default offset of that weapon</param>
private Vector2 RotateWeapons(Vector2 offset)
{
Quaternion rotation = Quaternion.CreateFromAxisAngle(Vector3.Backward, (float)Rotation);
return Vector2.Transform(offset, rotation) + Position;
}
/// <summary>
/// Keeps the ship on the screen
/// </summary>
private void KeepOnTheScreen()
{
if (Position.X > 1019 || Position.X < 5 || Position.Y > 761 || Position.Y < 5)
reachedBounds = true;
else
reachedBounds = false;
if (reachedBounds)
{
followingRandom = true;
if (!followingRandom)
Rotation = Utilities.TurnToFace(Position, new Vector2(1024 / 2, 768 / 2), Rotation, (float)turningRadius);
else
timeToFaffAbout--;
}
}
/// <summary>
/// Checks to see if the target ship is within weapons range
/// </summary>
/// <param name="target"></param>
protected abstract void CheckTarget(Ship target);
/// <summary>
/// Decrements the cooldown of all weapons
/// </summary>
protected abstract void Cooldown();
protected abstract void UpdateProjectiles(Vector2 pos);
protected abstract void DrawProjectiles(SpriteBatch spriteBatch);
protected abstract void CleanupProjectiles();
}
}
If anyone can help me with this, I'd be really appreciative. Thank you!
Why does FireRailguns() execute MissileAmmo[1]--; ?

Categories