Sign in to follow this  

XNA Detecting out of Screen

This topic is 3118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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[i].Pos.X < rGameScreen.X || bullet[i].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[i].Pos.X < -2 || bullet[i].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]

Share this post


Link to post
Share on other sites
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 bullets
foreach(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]

Share this post


Link to post
Share on other sites
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[i].Pos.X < rGameScreen.X || bullet[i].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

Share this post


Link to post
Share on other sites
if i put

for(int i = 0; i < Bulletlist.Count; i++)
{
//check visibility here
if (bullet[i].Pos.X < 0 || bullet[i].Pos.Y < 0)
offscreenBullets.Add(bullet[i]); //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

Share this post


Link to post
Share on other sites
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>();

Share this post


Link to post
Share on other sites

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[i].Pos.X < rGameScreen.X || bullet[i].Pos.Y < rGameScreen.Y)
offscreenBullets.Add(bullet[i]);
}
foreach(Bullet bullet in offscreenBullets)
{
Bulletlist.Remove(bullet);
}
}




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

regards,
Kevin

Share this post


Link to post
Share on other sites

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;

Share this post


Link to post
Share on other sites
yea :P noticed but i still get an error here

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

Error 2 The best overloaded method match for 'System.Collections.Generic.List<FortressGameV1.Game1.Bullet[]>.Remove(FortressGameV1.Game1.Bullet[])' has some invalid arguments
Error 3 Argument '1': cannot convert from 'FortressGameV1.Game1.Bullet' to 'FortressGameV1.Game1.Bullet[]'

is this becuase this is declared wrong?
List<Bullet[]> Bulletlist = new List<Bullet[]>();



Share this post


Link to post
Share on other sites
OK thanks. i think the lists are now working now i just need to Fix the Creation of my Bullet struct

struct Bullet
{
public Vector2 Pos;
public Vector2 Dir;
public void Update()
{
Pos = new Vector2(Pos.X - Dir.X, Pos.Y - Dir.Y);
}
}


but I am not sure exactly how adding items to a list works.

Bullet[] bullet = new Bullet[50];
if (Bulletlist.Count < MaxNumBullets)
{
Vector2 FireFrom = new Vector2(myTurret.PosVect.X - 88, myTurret.PosVect.Y);
// * Create a new Bullet
bullet[Bulletlist.Count + 1].Pos = FireFrom;
bullet[Bulletlist.Count + 1].Dir = new Vector2(2, 0);
Bulletlist.Add(bullet[Bulletlist.Count + 1]);
timeScinceFire = 0;
}


if(number of bullets draw < Max number of bullets allowed)
{
Get the Vector to Draw the Sprite
Create the new Bullet - Assign its position
Assign its velocity
Add it to the List of bullets
Reset the timer;
}

However I believe that there is something wrong here and this is why all the Bullets are being deleted when they hit the boundary. can anyone see anything here that would cause this. or if Ii am doing something I shouldn't :P

(anything else you need I can give)

Share this post


Link to post
Share on other sites
Why are you using arrays, with your code you can get not more than 50 bullets.
With Lists there is no (real) limit. And you can convert lists to arrays if you need to: BulletList.ToArray
You can Add Objects to you list: BulletList.Add(obj)
Lists are easier to use and very powerfull

reagards,
Kevin

Share this post


Link to post
Share on other sites
i was using arrays because there are multiple bullets draw at a time, do i not need an array to handle these?

as I have a turret firing bullets there are 'n' Number of them on the screen at anyone time. if I don't use an array to hold the data I think I need a hell of a lot of variables to hold the position, direction and velocity of each bullet

[Edited by - Andy474 on June 5, 2009 7:43:46 AM]

Share this post


Link to post
Share on other sites
Instead of having an array of bullets, you have a list of bullets.

Read up on using lists in C#. In very, very, very simple terms, they are C#'s version of a dynamicly sized array.

Share this post


Link to post
Share on other sites
Quote:
Original post by Andy474
i was using arrays because there are multiple bullets draw at a time, do i not need an array to handle these?

as I have a turret firing bullets there are 'n' Number of them on the screen at anyone time. if I don't use an array to hold the data I think I need a hell of a lot of variables to hold the position, direction and velocity of each bullet

Nope, no array necessary.

By the looks of things in your other thread, you've got it sorted out now.

Share this post


Link to post
Share on other sites

This topic is 3118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this