Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (495)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Remove element while being used  (Read 4434 times)
0 Members and 1 Guest are viewing this topic.
Offline 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
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« 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 Cheesy

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #2 - Posted 2012-02-24 00:20:06 »

Easier yet, just change the ArrayList to a CopyOnWriteArrayList.

-Nathan

Check out my website!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« 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!!

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« 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

Check out my website!
Offline Cero
« Reply #5 - Posted 2012-02-24 00:35:05 »

just screw those iterators

Quote
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
   }
}

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« 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 Wink

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« 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. Tongue

See my work:
OTC Software
Online 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(); ) {
// do stuff
if(obectHasToBeRemoved) {
myArrayList.remove(i);
} else {
i++;
}
}


Works better than 'subtracting'.

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« 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 Tongue

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online 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.

Offline lhkbob

JGO Knight


Medals: 32



« 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--) {
   // do stuff

   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.

Offline 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?
Online 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.

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #14 - Posted 2012-02-24 06:05:30 »

OMG. What I said and lhkbob seconded - that's how you do it.

See my work:
OTC Software
Offline 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().

Offline R.D.

Senior Member


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« 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]).
Offline 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 Wink
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

Offline tom
« Reply #18 - Posted 2012-02-24 14:18:21 »

I vote for CopyOnWriteArrayList.

Offline 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
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« 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) {
    //game loop
   
    frames++;
    if(System.nanoTime() - lastTime >= 1e9) { //1e9 = 1 * 10 ^ 9 = 1,000,000,000 nanoseconds = 1 second :)
       System.out.println(frames);
        frames = 0;
        lastTime += 1e9;
    }
}

Offline BoBear2681

JGO Coder


Medals: 18



« 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.
Offline 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.

Offline R.D.

Senior Member


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« Reply #23 - Posted 2012-02-25 17:11:40 »

Oh sorry, I mean 1 microsecond not millisecond Cheesy One milisecond would be a lot for the few things I'm doing (Render BG, Render Map, Render Entites between Layer, Render foreground stuff).
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Dwinin (23 views)
2014-09-12 09:08:26

Norakomi (56 views)
2014-09-10 13:57:51

TehJavaDev (69 views)
2014-09-10 06:39:09

Tekkerue (34 views)
2014-09-09 02:24:56

mitcheeb (56 views)
2014-09-08 06:06:29

BurntPizza (40 views)
2014-09-07 01:13:42

Longarmx (25 views)
2014-09-07 01:12:14

Longarmx (31 views)
2014-09-07 01:11:22

Longarmx (31 views)
2014-09-07 01:10:19

mitcheeb (39 views)
2014-09-04 23:08:59
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!