XNA Detecting out of Screen

Started by
15 comments, last by Moe 14 years, 10 months ago
Hi there :) i am having a little trouble Detecting wether my Sprites are out of the Screen or not (2D game) here is my Function Prototype (using XNA V3)

rGameScreen = new Rectangle(0, 0, iscreenWidth, 385);

private void CheckCollisions()
        {            
            for (int i = 0; i < Bulletlist.Count; i++)
            {
                //if the bullet hits the edge of the screen   
                if(bullet.Pos.X < rGameScreen.X || bullet.Pos.Y < rGameScreen.Y)
                {
                    inumBullets--;
                    Bulletlist.Remove(bullet);
                }
            }
        }
Basically I look through my List(Bulletlist) which contains all the Bullets i have fired. I the check to see if the bullets are out of bound of my gamescreen(rGameScreen) However this results in the bullet being removed as it is draw for some reason. the Number of bullets iNumBullets gets reduced every time I trigger the even (N.B This is the same if i use negative values to delete)

if(bullet.Pos.X < -2 || bullet.Pos.Y < -2)
                {
                    inumBullets--;
                    Bulletlist.Remove(bullet);
                }
            
is there any reason this wont work as it should? [Edited by - Andy474 on June 4, 2009 3:13:38 PM]
Advertisement
I haven't fully looked through your code, but why bother having a separate variable tracking the number of bullets? Why not use List<>.Count()?

I think what might be happening is that you are checking the .Count in your for loop, then because you are altering that by removing bullets as you loop through, it's going to mess things up.

EDIT: One way around this is to add a property to your bullets so that you can mark them as being being drawn or not. Then, when you are looping through to draw your bullets you check the property. Another way to do this is to make a list of the bullets that need to be removed, and remove them from the list. Something like:

List<Bullet> offscreenBullets = new List();foreach(Bullet bullet in BulletList){   //check visibility here   if(bullet.Pos.X < rGameScreen.X || bullet.Pos.Y < rGameScreen.Y)       offscreenBullets.Add(bullet);}//remove the off screen bulletsforeach(Bullet bullet in offscreenBullets){    BulletList.Remove(bullet);}

Perhaps not the most efficient way of doing things, but whatever.

EDIT 2: My personal preference would lean toward having a class that represents a bullet, and have a property on it that says if it is visible or not. Then, in your update function you set if it is visible or not and in your Draw() function you only draw visible bullets.

[Edited by - Moe on June 4, 2009 3:36:10 PM]
thanks a lot, That's absolutely Perfect :)
I Am Using
struct Bullet        {            public Vector2 Pos;            public Vector2 Dir;            public bool onScreen;            public void Update()            {                Pos = new Vector2(Pos.X - Dir.X, Pos.Y - Dir.Y);            }        }

to store bullet values
private void CheckCollisions(){      //Bullet is Offscreen      List<Bullet[]> offscreenBullets = new List<Bullet[]>();      for(int i = 0; i < Bulletlist.Count; i++)      {            //check visibility here            if (bullet.Pos.X < rGameScreen.X || bullet.Pos.Y < rGameScreen.Y)                    offscreenBullets.Add(bullet);      }      foreach(Bullet[] bullet in offscreenBullets)      {             Bulletlist.Remove(bullet);      }}

one problem with this : as soon as the first bullet hits the boundary ALL bullets are removed from the game regardless of there position and no more can be fired
Hi,
I'm not sure: you wrote offscreenBullets.Add(bullet);
but it has to be offscreenBullets.Add(bullet);

regards,
Kevin
if i put
for(int i = 0; i < Bulletlist.Count; i++)            {                //check visibility here                if (bullet.Pos.X < 0 || bullet.Pos.Y < 0)                    offscreenBullets.Add(bullet); //Error            }

Error 3 The best overloaded method match for 'System.Collections.Generic.List<FortressGameV1.Game1.Bullet[]>.Add(FortressGameV1.Game1.Bullet[])' has some invalid arguments I:\R_ENGINE\R_ENGINE\FortressGameV1\FortressGameV1\Game1.cs 165 21 FortressGameV1
Your problem is here:
List<Bullet[]> offscreenBullets = new List<Bullet[]>();

You want a list of bullets, not a list of bullet arrays.

This should work:
List<Bullet> offscreenBullets = new List<Bullet>();
private void CheckCollisions(){      //Bullet is Offscreen      List<Bullet> offscreenBullets = new List<Bullet>();      for(int i = 0; i < Bulletlist.Count; i++)      {            //check visibility here            if (bullet.Pos.X < rGameScreen.X || bullet.Pos.Y < rGameScreen.Y)                    offscreenBullets.Add(bullet);      }      foreach(Bullet bullet in offscreenBullets)      {             Bulletlist.Remove(bullet);      }}


Why did you use a list of arrays??
Try this code.

regards,
Kevin
foreach(Bullet bullet in offscreenBullets){       Bulletlist.Remove(bullet);}


this returns an error(s)
Error 2 The best overloaded method match for 'System.Collections.Generic.List<FortressGameV1.Game1.Bullet[]>.Remove(FortressGameV1.Game1.Bullet[])'
Error 3 Argument '1': cannot convert from 'FortressGameV1.Game1.Bullet' to 'FortressGameV1.Game1.Bullet[]'

Bullet[] bullet;
BulletList have to be List<Bullet>.

This topic is closed to new replies.

Advertisement