sirlink99
Junior Newbie
|
 |
«
Posted
2012-02-24 00:16:13 » |
|
I have a player which can shoot bullets, and I have made it so that when the bullet is out of the frame the bullet gets removed. But when I run the program I get the ConcurrentModificationException error. I have all of my bullets stored in an ArrayList. Is there a simple way to remove the bullets?
Also my technique for game design is still quite basic. Could anyone link me to easy to understand tutorials(preferably video) for 2d game programming?
Thanks for the help
|
|
|
|
ra4king
|
 |
«
Reply #1 - Posted
2012-02-24 00:19:02 » |
|
You get a ConcurrentModificationException because you cannot remove an element while using the for-each loop. To bypass that, use the remove() method that is built in the Iterator: 1 2 3 4 5 6 7
| Iterator<MyType> i = myArrayList.iterator(); while(i.hasNext()) { MyType object = i.next(); if(objectHasToBeRemoved) i.remove(); } |
EDIT: Oh by the way if you didn't know, the for-each loop is only compiler magic, the bytecode is actually transformed to use that Iterator class 
|
|
|
|
StonePickaxes
|
 |
«
Reply #2 - Posted
2012-02-24 00:20:06 » |
|
Easier yet, just change the ArrayList to a CopyOnWriteArrayList.
-Nathan
|
|
|
|
Games published by our own members! Check 'em out!
|
|
ra4king
|
 |
«
Reply #3 - Posted
2012-02-24 00:22:54 » |
|
Easier yet, just change the ArrayList to a CopyOnWriteArrayList.
-Nathan
So you're trading speed and efficiency for ease of use? CopyOnWriteArrayList creates a new internal array for all the mutative methods!!
|
|
|
|
StonePickaxes
|
 |
«
Reply #4 - Posted
2012-02-24 00:28:34 » |
|
Well for the stuff I'm working with, speed and efficiency aren't exactly high on my priority list, as it can run upwards of 6k fps uncapped.
-Nathan
|
|
|
|
Cero
|
 |
«
Reply #5 - Posted
2012-02-24 00:35:05 » |
|
just screw those iterators for(int i=0;i<myArrayList.size();i++) { myArrayList.get(i); // <- element //do stuff if(objectHasToBeRemoved) { i.remove(); continue; // or break; depending on what you do } }
|
|
|
|
ra4king
|
 |
«
Reply #6 - Posted
2012-02-24 00:50:23 » |
|
<sarcasm>I never knew primitive ints had remove methods!</sarcasm> @Cero You need to subtract 1 from "i" after removing it from the list 
|
|
|
|
Eli Delventhal
|
 |
«
Reply #7 - Posted
2012-02-24 01:05:10 » |
|
If you're doing it index-based just count backwards to 0. But you almost always want to like set a boolean as in the first example and then after doing updates remove anything that is marked for removal. This is because theoretically every entity acts simultaneously, so you don't want someone to get deleted before someone else can be effected by him, just because the deleted guy happens to be at a lower index. Make sense? But I feel like I got this error for something not related to the loop. Let me try to remember what it was. Nope can't remember. That's from like 5 years ago. 
|
|
|
|
UprightPath
|
 |
«
Reply #8 - Posted
2012-02-24 01:10:07 » |
|
1 2 3 4 5 6 7 8
| for(int i = 0; i < myArrayList.size(); ) {
if(obectHasToBeRemoved) { myArrayList.remove(i); } else { i++; } } |
Works better than 'subtracting'.
|
|
|
|
ra4king
|
 |
«
Reply #9 - Posted
2012-02-24 01:21:19 » |
|
However, what if you remove in multiple places in the loop? Your method will become too clumsy. Adding an "i--" after every remove is the only sensible solution 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
UprightPath
|
 |
«
Reply #10 - Posted
2012-02-24 01:22:51 » |
|
Eck, if you're removing multiple things per iteration there's probably something wrong with your system.
|
|
|
|
lhkbob
|
 |
«
Reply #11 - Posted
2012-02-24 02:15:30 » |
|
Or just iterate backwards: 1 2 3 4 5 6 7
| for (int i = myArrayList.size() - 1; i >= 0; i--) {
if (needsRemoving) { myArrayList.remove(i); } } |
Everything else is clumsier and more error prone, except for the flag for removal and remove later scenario, which is valid if you need to process everything one stage at a time.
|
|
|
|
Z-Man
|
 |
«
Reply #12 - Posted
2012-02-24 03:16:01 » |
|
Eck, if you're removing multiple things per iteration there's probably something wrong with your system.
Um... what? What if your making an MMO and you have a area based attack that takes out multiple enemies at once? Or, what if your playing a simple space shooter and you fire three lasers at once, for a power-up or something, and the three lasers hit three entities at once?
|
|
|
|
UprightPath
|
 |
«
Reply #13 - Posted
2012-02-24 04:02:23 » |
|
Well, I'd think that the iteration through the list would take care of it, as opposed to having an iteration inside of the iteration.
I mean, I can probably think up a reason for doing it, but it feels like if you're doing it, then there's probably a better way to do it than that.
|
|
|
|
Eli Delventhal
|
 |
«
Reply #14 - Posted
2012-02-24 06:05:30 » |
|
OMG. What I said and lhkbob seconded - that's how you do it.
|
|
|
|
ReBirth
|
 |
«
Reply #15 - Posted
2012-02-24 06:48:26 » |
|
By not mentioning performance, add the will be removed object to 2nd arraylist and use first arraylist's removeAll().
|
|
|
|
R.D.
|
 |
«
Reply #16 - Posted
2012-02-24 10:18:14 » |
|
or list.clear();
Hell it's an ArrayList. Those are fast as hell, at least for my 2D game. I do this all the time I don't even get ONE millisecond for one frame (And this with no optimizations like don't draw objects out of view [only the map is rendered a bit optimized]).
|
|
|
|
Cero
|
 |
«
Reply #17 - Posted
2012-02-24 14:05:25 » |
|
or list.clear();
Hell it's an ArrayList. Those are fast as hell, at least for my 2D game. I do this all the time I don't even get ONE millisecond for one frame (And this with no optimizations like don't draw objects out of view [only the map is rendered a bit optimized]).
well 1ms would be A LOT. 60 fps games have only 16.6ms for everything, naturally you want to use way less, so you can breathe - and the pc your developing on is certainly not the slowest you want to support @Cero You need to subtract 1 from "i" after removing it from the list  well yeah, but it really depends on what you are doing alltogether I use pure arrays I have used ArrayLists too, with the remove later in a seperate loop approach
|
|
|
|
tom
|
 |
«
Reply #18 - Posted
2012-02-24 14:18:21 » |
|
I vote for CopyOnWriteArrayList.
|
|
|
|
sirlink99
Junior Newbie
|
 |
«
Reply #19 - Posted
2012-02-24 21:50:06 » |
|
Thanks for the help. I am using the Iterator method currently, but please keep posting because I find this very informative.
Also could anyone tell my how I can figure out what FPS my game is running at?
Thanks
|
|
|
|
ra4king
|
 |
«
Reply #20 - Posted
2012-02-24 22:27:38 » |
|
To find the FPS, you count the number of frames that occur in 1 second by having a frame counter and a time keeper: 1 2 3 4 5 6 7 8 9 10 11 12 13
| int frames = 0; long lastTime = System.nanoTime();
while(true) { frames++; if(System.nanoTime() - lastTime >= 1e9) { System.out.println(frames); frames = 0; lastTime += 1e9; } } |
|
|
|
|
BoBear2681
|
 |
«
Reply #21 - Posted
2012-02-25 03:54:20 » |
|
or list.clear();
Hell it's an ArrayList. Those are fast as hell, at least for my 2D game. I do this all the time I don't even get ONE millisecond for one frame (And this with no optimizations like don't draw objects out of view [only the map is rendered a bit optimized]).
well 1ms would be A LOT. I disagree... as you point out, if he can render a frame in 1 millisecond, his game is already running more than an order of magnitude faster than what is necessary for 60fps. There's no need for somebody in that situation to optimize anything.
|
|
|
|
ReBirth
|
 |
«
Reply #22 - Posted
2012-02-25 04:26:53 » |
|
He said he got 1ms for 1 frame, which means it should have done all logic and drawing. The time may be inaccurate, but if I see that result I'm quite happy. However if 1ms is time to do an operation to an AL, could be problem.
|
|
|
|
R.D.
|
 |
«
Reply #23 - Posted
2012-02-25 17:11:40 » |
|
Oh sorry, I mean 1 microsecond not millisecond  One milisecond would be a lot for the few things I'm doing (Render BG, Render Map, Render Entites between Layer, Render foreground stuff).
|
|
|
|
|