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.
I'm working on a game, and I made all the building blocks. now I'm working on the game logic and rendering.
I have abstract Monster class and a class call GreenMonster that inherits from it.
Now the weird thing is, when I try to init a GreenMonster object.
when I do this:
private void initGreenMonsters()
{
for (int i = 0; i < greenMonsters.Length; i++)
{
greenMonsters[i] = new GreenMonster(new Point(0,40),new Size(40, 40));
}
}
every thing works like I planned and I can render the images on the form.
but when I try to init like that:
private void initGreenMonsters()
{
for (int i = 0; i < greenMonsters.Length; i++)
{
greenMonsters[i] = new GreenMonster();
greenMonsters[i].Position = new Point(0, 40);
greenMonsters[i].Size = new Size(40, 40);
}
}
I don't get any errors, and the app runs, but I can render the monsters.
This is the Monster class constructor and the Draw Method I use to draw a Monster:
public Monster(Point _startPosition,Size _size)
{
this.size = _size;
this.position = _startPosition;
}
public virtual void Draw(Graphics g)
{
Rectangle monsterRec = new Rectangle(position, size);
g.DrawImage(img, monsterRec);
}
and this is the GreenMonster class constructor:
public GreenMonster(Point _startPosition, Size _size)
: base(_startPosition, _size)
{
this.img = new Bitmap(SpaceInvadersGame.Properties.Resources.NormalMonster);
this.hp = 1;
this.speed = 1;
}
public GreenMonster()
{
this.img = new Bitmap(SpaceInvadersGame.Properties.Resources.NormalMonster);
this.hp = 1;
this.speed = 1;
}
the only thing that bothers me is, that when I'm looking at both ways I init the objects, it just looks the same..
I just can't find any different between in both of the ways.
someone have any idea how its different?
If you need more code so the question is more clear, I would be happy to add!
this is the Monster class and its properties
public abstract class Monster
{
protected Point position;
public Point Position { get { return position; } set { position = value; } }
protected Size size;
public Size Size { get { return size; } set { value = size; } }
public int speed;
protected Bitmap img;
protected int hp;
public int HP { get { return hp; } }
public void SetStartingPosition(int x, int y)
{
this.position = new Point(x, y);
}
public virtual void Draw(Graphics g)
{
Rectangle monsterRec = new Rectangle(position, size);
g.DrawImage(img, monsterRec);
}
}
You are setting your incoming value to the current size, rather than setting the current size to the incoming value, in the method below:
public Size Size { get { return size; } set { value = size; } }
should be
public Size Size { get { return size; } set { size = value; } }
Your code for Position looks OK though:
public Point Position { get { return position; } set { position = value; } }
This question already has answers here:
Can't access public class properties
(4 answers)
Closed 8 years ago.
I'm trying to set a new List variable to the result of a class' methods return value a bit like this:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
public static SpriteBatch spriteBatch;
// ...stuff...
// Class initialization
private Map map = new Map() { Width = 10, Height = 10, TileWidth = 16, TileHeight = 16 };
// Variable declaration
List<Vector2> blockPos = new List<Vector2>();
blockPos = map.generateMap(); // Doesn't work
Texture2D dirtTex;
// ...more stuff...
}
I figure it doesn't work because it's not inside a method and that I could put it in my Update() method but that runs each frame and I only want to do this once.
Attempting the above code results in 3 errors:
'Deep.Game1.blockPos' is a 'field' but is used like a 'type'
Invalid token '=' in a class, struct, or interface member declaration
'Deep.Game1.map' is a 'field' but is used like a 'type'
Map class:
class Map
{
// Variable declaration
public int Width { get; set; } // Width of map in tiles
public int Height { get; set; } // Height of map in tiles
public int TileWidth { get; set; }
public int TileHeight { get; set; }
Random rnd = new Random();
// Generate a list of Vector2 positions for blocks
public List<Vector2> generateMap()
{
List<Vector2> blockLocations = new List<Vector2>();
// For each tile in the map...
for (int w = 0; w < Width; w++)
{
for (int h = 0; h < Height; h++)
{
// ...decide whether or not to place a tile...
if (rnd.Next(0, 1) == 1)
{
// ...and if so, add a tile at that location.
blockLocations.Add(new Vector2(w * TileWidth, h * TileHeight));
}
}
}
return blockLocations;
}
}
I tried using constructors, but the code inside it didn't appear to run despite no errors:
public void getPos()
{
blockPos = map.generateMap();
}
Fixed by declaring the variable, then setting it to map.generateMap() in the LoadContent() method:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
public static SpriteBatch spriteBatch;
// ...
// Class initialization
private Map map = new Map() { Width = 10, Height = 10, TileWidth = 16, TileHeight = 16 };
// Variable declaration
List<Vector2> blockPos = new List<Vector2>();
Texture2D dirtTex;
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
dirtTex = Content.Load<Texture2D>("dirt");
blockPos = map.generateMap();
}
// ...
}
I'm Having a problem with an experiment of mine. I'm trying to make a method that fuses one Texture2D into another Texture2D, then reloads the Texture2D, this time moving the pasted texture in a new spot. I plan to perfect upon this method in later projects where I paste in a spotlight onto a dark background to "illuminate" the scenery behind it. While I managed to make the paste-to method work perfectly, I am having some major problems with the second part of my plan. I have the pasted texture set to a Vector2, where the X member increases by 1 every frame, thus dragging the pasted texture along the background. However, the background doesn't reset after each frame, leaving a drag mark on the background where the previous image was. For the last half hour I've been working to cure this problem by resetting the background texture to make it clean again for when it has the other image pasted onto it.
Here is my code.
namespace CopyTest
{
public class Image
{
public Texture2D Bitmap;
public Vector2 Position;
public String BitmapName;
public Rectangle Viewport;
public Color Tint = Color.White;
public void ResetViewportDimensions()
{
this.Viewport = new Rectangle(this.Viewport.X, this.Viewport.Y, Bitmap.Width, Bitmap.Height);
}
public void Draw(SpriteBatch Target)
{
}
public void FinalizeBitmap(ContentManager Target)
{
this.Bitmap = null;
this.Bitmap = Target.Load<Texture2D>(this.BitmapName);
}
public Image(Vector2 Position, String BitmapName)
{
this.BitmapName = BitmapName;
this.Position = Position;
}
}
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Image Rainbow = new Image(new Vector2(0, 0), "Rainbow");
public Image Eye = new Image(new Vector2(0, 0), "Glow");
public Image PrintOut = new Image(new Vector2(0, 0), "Rainbow");
public Vector2 Destination = new Vector2(100, 50);
public void PrintTo(Image Source, Image Target, Vector2 Location)
{
Color[] A = new Color[Source.Bitmap.Width * Source.Bitmap.Width];
Color[] B = new Color[Target.Bitmap.Width * Target.Bitmap.Width];
int Y = 0;
int X = 0;
Source.Bitmap.GetData(A);
Target.Bitmap.GetData(B);
for (int i = 0; i < A.Length; i++)
{
B[(int)Location.X + X + (((int)Location.Y + Y) * Target.Bitmap.Width)] = A[i];
X++;
if (X == Source.Bitmap.Width)
{
X = 0;
Y++;
}
}
Target.Bitmap.SetData<Color>(B);
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Eye.FinalizeBitmap(Content);
Rainbow.FinalizeBitmap(Content);
PrintOut.FinalizeBitmap(Content);
Eye.ResetViewportDimensions();
Rainbow.ResetViewportDimensions();
PrintOut.ResetViewportDimensions();
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
GraphicsDevice.Textures[0] = null;
PrintOut.FinalizeBitmap(Content);
PrintTo(Eye, PrintOut, Destination);
Destination.Y++;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(PrintOut.Bitmap, PrintOut.Position, PrintOut.Viewport, PrintOut.Tint);
spriteBatch.End();
base.Draw(gameTime);
}
}
Any help at all would be greatly appreciated.
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.