GlennBrann
|
 |
«
Posted
2013-02-03 20:36:54 » |
|
Hello Everyone, Recently i have been making a game and i have encountered a problem. I have an IndexOutOfBounds Exception but i cant seem to fix it. I am basically trying to remove a bullet once it hits the enemy. It works for one enemy but not for the rest. here is the code i used could you please help me thanks 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| package com.glennbrann.Controllers;
import java.awt.Graphics; import java.util.ArrayList;
import com.glennbrann.Game.Game; import com.glennbrann.Screen.Sprites; import com.glennbrann.Stuff.Bullet; import com.glennbrann.Stuff.Enemy;
public class BulletController { ArrayList<Enemy> e = new ArrayList<Enemy>(); ArrayList<Bullet> b = new ArrayList<Bullet>();
Bullet bullet; Bullet bullets; Game game; Sprites sprites; Enemy enemy; public BulletController(Game game, Sprites sprites){ this.game = game; this.sprites = sprites; } public void update(ArrayList<Enemy> e, EnemyController ec, Game game){ for(int i = 0; i < b.size() ; i++){ bullet = b.get(i);
for(int ii = 0; ii < e.size(); ii++){ if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){ removeBullet(b.get(i)); game.enemyHealth--; if(game.enemyHealth <= 0){ ec.removeEnemy(e.get(ii)); game.score ++; } } } bullet.update(e); } } public void render(Graphics g){ for(int i = 0; i < b.size(); i++){ bullet = b.get(i); bullet.render(g); } } public ArrayList<Bullet> getBulletBounds(){ return b; } public void addBullet(Bullet bullet){ b.add(bullet); } public void removeBullet(Bullet bullet){ b.remove(bullet); } } |
Here is the Error i'm getting: 1 2 3 4 5 6 7
| Exception in thread "Thread-2" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5 at java.util.ArrayList.rangeCheck(Unknown Source) at java.util.ArrayList.get(Unknown Source) at com.glennbrann.Controllers.BulletController.update(BulletController.java:35) at com.glennbrann.Game.Game.update(Game.java:181) at com.glennbrann.Game.Game.run(Game.java:129) at java.lang.Thread.run(Unknown Source) |
Please help thanks
|
|
|
|
Mads
|
 |
«
Reply #1 - Posted
2013-02-03 20:45:06 » |
|
Didn't read most of it, but I know as per experience that this might help you. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| for(int i = 0; i <= b.size()-1; i++){ bullet = b.get(i);
for(int ii = 0; ii <= e.size()-1; ii++){ if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){ removeBullet(b.get(i)); game.enemyHealth--; if(game.enemyHealth <= 0){ ec.removeEnemy(e.get(ii)); game.score ++; } } } bullet.update(e); } |
Everything is so much more fun, if you're counting the zero.
|
|
|
|
GlennBrann
|
 |
«
Reply #2 - Posted
2013-02-03 20:50:42 » |
|
That Kind of works. it doesn't work if is use 1
| for(int ii = 0; ii <= e.size()-1; ii++) |
. but it does work when i do this 1
| (int i = 0; i <= b.size()-1; i++) |
. But i have one problem. When i shoot the bullet just spawns and doesn't move. but when i shoot again the previous bullet moves and the next one stays. this happens again and again. Any ideas?
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Jimmt
|
 |
«
Reply #3 - Posted
2013-02-03 20:51:49 » |
|
I don't see any movement code, you might want to post that...
|
|
|
|
GlennBrann
|
 |
«
Reply #4 - Posted
2013-02-03 20:53:14 » |
|
Here is my movement bullet code : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| package com.glennbrann.Stuff;
import java.awt.Graphics; import java.awt.Rectangle; import java.util.ArrayList;
import com.glennbrann.Controllers.BulletController; import com.glennbrann.Controllers.EnemyController; import com.glennbrann.Player.Entity; import com.glennbrann.Screen.Sprites;
public class Bullet extends Entity{
Sprites sprites; Bullet bullet; Enemy enemy; EnemyController ec; BulletController b; ArrayList<Enemy> e; ArrayList<Bullet> bul; public Bullet(int x, int y, Sprites sprites) { super(x, y); this.sprites = sprites; } public void update(){ y -= 8; if(getX() < 10){ b.removeBullet(this); } } public void render(Graphics g){ g.drawImage(sprites.bullet, x, y, 16, 16, null); } public Rectangle getBounds(){ return new Rectangle(x,y,16,16); } public void removeBullet(Bullet bullet){ b.removeBullet(bullet); } public int getX(){ return x; } public int getY(){ return y; }
} |
|
|
|
|
GabrielBailey74
|
 |
«
Reply #5 - Posted
2013-02-03 21:02:53 » |
|
lolz, we need to see the line @: 1
| com.glennbrann.Controllers.BulletController.update(BulletController.java:35) |
Line #35 in BulletController.Java is where the issue is coming from.
|
|
|
|
GlennBrann
|
 |
«
Reply #6 - Posted
2013-02-03 21:04:33 » |
|
i posted it above. but here it is again: public void update(ArrayList<Enemy> e, EnemyController ec, Game game){ for(int i = 0; i < b.size() ; i++){ bullet = b.get(i);
for(int ii = 0; ii < e.size(); ii++){ if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){ //line 35 removeBullet(b.get(i)); game.enemyHealth--; if(game.enemyHealth <= 0){ ec.removeEnemy(e.get(ii)); game.score ++; } } } bullet.update(e); } }
|
|
|
|
GabrielBailey74
|
 |
«
Reply #7 - Posted
2013-02-03 21:05:30 » |
|
I'm sorry, I just woke up mate. Didn't realize you already posted it on OP. >...< thanks.
|
|
|
|
GlennBrann
|
 |
«
Reply #8 - Posted
2013-02-03 21:12:01 » |
|
do you have any idea?
|
|
|
|
GabrielBailey74
|
 |
«
Reply #9 - Posted
2013-02-03 21:14:33 » |
|
Well, I'm in the process of re-writing it so I can run it in my IDE. What I have at the moment: (feel free to replace your method with this one, see if it changes anything  ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public void update(ArrayList<Enemy> e, EnemyController ec, Game game) { for (Bullet bullet : b) { if (b != null) { for (Enemy enemy : e) { if (enemy != null) { if (bullet.getBounds().intersects(enemy.getBounds())) { removeBullet(bullet); game.enemyHealth--; if (game.enemyHealth <= 0) { ec.removeEnemy(enemy); game.score++; } } } } bullet.update(e); } } } |
|
|
|
|
Games published by our own members! Check 'em out!
|
|
GlennBrann
|
 |
«
Reply #10 - Posted
2013-02-03 21:17:28 » |
|
i got this error. PS sorry if i'm annoying you with this: 1 2 3 4 5 6 7
| Exception in thread "Thread-2" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.glennbrann.Controllers.BulletController.update(BulletController.java:31) at com.glennbrann.Game.Game.update(Game.java:181) at com.glennbrann.Game.Game.run(Game.java:129) at java.lang.Thread.run(Unknown Source) |
|
|
|
|
Danny02
|
 |
«
Reply #11 - Posted
2013-02-03 21:22:59 » |
|
Didn't read most of it, but I know as per experience that this might help you.
Everything is so much more fun, if you're counting the zero.
dafuq? pls explain why you think there is a difference between the two lines 1 2
| for(int i=0; i<10; i++) for(int i=0; i<=9; i++) |
The problem you are having Glenn is that you are removing bullets while you are iterating over it. i.e. you are deleting the last bullet from your collection at the first enemy, but want to access it again for the next enemy. You should have written it like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public void update(ArrayList<Enemy> e, EnemyController ec, Game game) { for (int i = b.size() - 1; i >= 0; i--) { Bullet toTest = b.get(i); for (Enemy enemy : e) { if (toTest .getBounds().intersects(enemy.getBounds())) { removeBullet(bullet); game.enemyHealth--; if (game.enemyHealth <= 0) { ec.removeEnemy(enemy); game.score++; } continue; } } } bullet.update(e); } } } |
ps: I don't now where this enemy collection is comming from and if it is the same which is in the enemycontroller, because if this would be another bug. @GabrielBailey74 pls try your code first befor posting, your code will produce an exception
|
|
|
|
GabrielBailey74
|
 |
«
Reply #12 - Posted
2013-02-03 21:23:37 » |
|
@Danny I'm more than aware of that lolz. This will fix the exception, and most likely fix his error at the same time  i got this error. PS sorry if i'm annoying you with this: 1 2 3 4 5 6 7
| Exception in thread "Thread-2" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.glennbrann.Controllers.BulletController.update(BulletController.java:31) at com.glennbrann.Game.Game.update(Game.java:181) at com.glennbrann.Game.Game.run(Game.java:129) at java.lang.Thread.run(Unknown Source) |
No worries mate, I'm one of the people here on JGO who like helping people / will take the time  Now.. The ConcurrentModificationException is happening due to me changing the 'for (int i = 0)' to the 'for (Bullet bullet : b). I have found a work around for this, but you'll have to modify your code a little bit.. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| ArrayList<Bullet> nulledBullets = new ArrayList<Bullet>(); public void update(ArrayList<Enemy> e, EnemyController ec, Game game) { if (nulledBullets.size() > 0) { for (Bullet nulledBullet : nulledBullets) { if (b.contains(nulledBullet)) { b.remove(nulledBullet); } } nulledBullets.clear(); } for (Bullet bullet : b) { if (b != null) { for (Enemy enemy : e) { if (enemy != null) { if (bullet.getBounds().intersects(enemy.getBounds())) { if (!nulledBullets.contains(bullet)) { nulledBullets.add(bullet); } game.enemyHealth--; if (game.enemyHealth <= 0) { ec.removeEnemy(enemy); game.score++; } } } } bullet.update(e); } } } |
|
|
|
|
Danny02
|
 |
«
Reply #13 - Posted
2013-02-03 21:26:40 » |
|
the easiest thing is, as I did in the snipped posted by me, to just iterate from the last to the first. Also Glenn you have a lot of useless fields in your classes, something like the following is just dangerous: 1 2 3 4 5 6 7 8 9 10 11
| class Foo { Bar coolTempVar;
void stuff() { for(int i=0; i<10; ++i) { coolTempVar = somethingNice(); } } |
just do: 1 2 3 4 5 6
| ... for(int i=0; i<10; ++i) { Bar coolTempVar = somethingNice(); } ... |
|
|
|
|
GlennBrann
|
 |
«
Reply #14 - Posted
2013-02-03 21:31:52 » |
|
When i shoot the bullet it progressively get faster and faster each time i shoot it. Also some of the time time the bullets get stuck and i get an error some times 1 2 3 4 5 6 7
| Exception in thread "Thread-2" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.glennbrann.Controllers.BulletController.update(BulletController.java:31) at com.glennbrann.Game.Game.update(Game.java:181) at com.glennbrann.Game.Game.run(Game.java:129) at java.lang.Thread.run(Unknown Source) |
line 31 is 1
| for (Enemy enemy : e) { |
Thanks again
|
|
|
|
GlennBrann
|
 |
«
Reply #15 - Posted
2013-02-03 21:33:17 » |
|
Yes i get what you mean. Good tip. i'm still learning though
|
|
|
|
GabrielBailey74
|
 |
«
Reply #16 - Posted
2013-02-03 21:36:13 » |
|
Well, we just fixed the exception for the Bullet being removed. NOTE: The enemy's below are being removed from the ArrayList that's passed through as a parameter in the method. Now we have to fix for the Enemy being removed: (NO MORE EXCEPTIONS  ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| ArrayList<Bullet> nulledBullets = new ArrayList<Bullet>(); ArrayList<Enemy> nulledEnemys = new ArrayList<Enemy>(); public void update(ArrayList<Enemy> e, EnemyController ec, Game game) { if (nulledEnemys.size() > 0) { for (Enemy nulledEnemy : nulledEnemys) { if (e.contains(nulledEnemy)) { e.remove(nulledEnemy); } } nulledEnemys.clear(); } if (nulledBullets.size() > 0) { for (Bullet nulledBullet : nulledBullets) { if (b.contains(nulledBullet)) { b.remove(nulledBullet); } } nulledBullets.clear(); } for (Bullet bullet : b) { if (b != null) { for (Enemy enemy : e) { if (enemy != null) { if (bullet.getBounds().intersects(enemy.getBounds())) { if (!nulledBullets.contains(bullet)) { nulledBullets.add(bullet); } game.enemyHealth--; if (game.enemyHealth <= 0) { if (!nulledEnemys.contains(enemy)) { nulledEnemys.add(enemy); } game.score++; } } } } bullet.update(e); } } } |
|
|
|
|
GlennBrann
|
 |
«
Reply #17 - Posted
2013-02-03 21:38:51 » |
|
i am getting yet another ConcurrentModificationException
|
|
|
|
jonjava
|
 |
«
Reply #18 - Posted
2013-02-03 21:40:24 » |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public void update(ArrayList<Enemy> e, EnemyController ec, Game game){ List<Bullet> tempAList = new ArrayList<Bullet>( b.size() ); for ( Bullet bullet : b ) {
for (Enemy enemy : e) {
if ( bullet.getBounds().intersects( enemy.getBounds() ) ) {
game.enemyHealth--;
if ( game.enemyHealth <= 0 ) {
ec.removeEnemy( enemy ); game.score ++;
} } else { tempAList.add( bullet ); } } bullet.update(e); }
b.clear(); b = tempAList; tempAList = null; } |
A shot in the dark.
|
|
|
|
GlennBrann
|
 |
«
Reply #19 - Posted
2013-02-03 21:45:10 » |
|
Thank you so much. its working now  [Just not sure how that works though.] would you mind maybe explain it. if not its fine
|
|
|
|
jonjava
|
 |
«
Reply #20 - Posted
2013-02-03 21:45:54 » |
|
Thank you so much. its working now  [Just not sure how that works though.] would you mind maybe explain it. if not its fine Which one works?
|
|
|
|
GlennBrann
|
 |
«
Reply #21 - Posted
2013-02-03 21:47:33 » |
|
This one works: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| ArrayList<Bullet> nulledBullets = new ArrayList<Bullet>(); ArrayList<Enemy> nulledEnemys = new ArrayList<Enemy>(); public void update(ArrayList<Enemy> e, EnemyController ec, Game game) { if (nulledEnemys.size() > 0) { for (Enemy nulledEnemy : nulledEnemys) { if (e.contains(nulledEnemy)) { e.remove(nulledEnemy); } } nulledEnemys.clear(); } if (nulledBullets.size() > 0) { for (Bullet nulledBullet : nulledBullets) { if (b.contains(nulledBullet)) { b.remove(nulledBullet); } } nulledBullets.clear(); } for (Bullet bullet : b) { if (b != null) { for (Enemy enemy : e) { if (enemy != null) { if (bullet.getBounds().intersects(enemy.getBounds())) { if (!nulledBullets.contains(bullet)) { nulledBullets.add(bullet); } game.enemyHealth--; if (game.enemyHealth <= 0) { if (!nulledEnemys.contains(enemy)) { nulledEnemys.add(enemy); } game.score++; } } } } bullet.update(e); } } } |
|
|
|
|
GlennBrann
|
 |
«
Reply #22 - Posted
2013-02-03 21:48:44 » |
|
no your one worked. Thanks
|
|
|
|
jonjava
|
 |
«
Reply #23 - Posted
2013-02-03 21:51:54 » |
|
Well they both sort of use the same idea. "ConcurrentModificationException" is getting thrown since you are removing stuff from the list at the same time as you are iterating over it.
What we do here is we create a temporary list to hold the object that are not removed (my method) or in Gabriel's method he stores the faulty enemies in an array and checks them before looping through the thingy.
In any case, my code still doesn't deal with the enemies being removed.
If it works -- great!
|
|
|
|
GabrielBailey74
|
 |
«
Reply #24 - Posted
2013-02-03 21:53:27 » |
|
*gasp*  Well, this was something that I came up with a while ago when dealing with Bullets and Collision myself  . What's going on is since we switched to: 1 2 3 4 5 6 7 8 9 10
| for (Bullet b : bullets) {
}
for (int i = 0; i < bullets.size(); i++) {
}
|
It will throw a Exception (Due to the fact that we're currently looping through the data in the ArrayList, so we can't remove it). So, I needed a way to remove those bullets from the list after the collision without getting the Exception. We created a List of NulledBullets, everytime we want to remove a bullet we add it to that list. And the next time the method restarts it will check if the NulledBullets contains any bullets, if it does it will treat them as un-wanted and remove them from the list. (The fix was removing them at the beginning of the method vs. removing them while we're looping through them). Once again, just woke up so I hope everything's readable. Glad I could help mate  EDIT: Where the hell.... did that horned smiley face come from??? It's not even on the smiley face list LOL
|
|
|
|
GlennBrann
|
 |
«
Reply #25 - Posted
2013-02-03 21:55:20 » |
|
Haha, Thanks for explaining it. really helped
|
|
|
|
sproingie
|
 |
«
Reply #26 - Posted
2013-02-03 21:55:48 » |
|
Another popular alternative is to maintain two lists. Copy the items you want to keep into the new list as you go through it and leave out the ones you don't, then alternate lists every time. Basically a home-grown semispace collector. It does take double the amount of space for references, but those are usually pretty small.
|
|
|
|
Danny02
|
 |
«
Reply #27 - Posted
2013-02-03 22:03:11 » |
|
I give up
|
|
|
|
jonjava
|
 |
«
Reply #28 - Posted
2013-02-03 22:03:38 » |
|
Another popular alternative is to maintain two lists. Copy the items you want to keep into the new list as you go through it and leave out the ones you don't, then alternate lists every time. Basically a home-grown semispace collector. It does take double the amount of space for references, but those are usually pretty small.
Yeah something like this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public void update(ArrayList<Enemy> e, EnemyController ec, Game game){ List<Enemy> tempEnemy = new ArrayList<Enemy>( e.size() ); List<Bullet> tempBullet = new ArrayList<Bullet>( b.size() ); for ( Bullet bullet : b ) {
for (Enemy enemy : e) {
if ( bullet.getBounds().intersects( enemy.getBounds() ) ) {
game.enemyHealth--;
if ( game.enemyHealth <= 0 ) {
game.score ++;
} else { tempEnemy.add( enemy ); } } else { tempBullet.add( bullet ); } } e.clear(); e = tempEnemy; tempEnemy.clear();
bullet.update(e); }
b.clear(); b = tempBullet; tempBullet.clear(); } |
|
|
|
|
|