Naro
Naro

Reputation: 11

Java Game: ArrayList and Iterator vs. Thread

Sup guys.

I'm writing a simple zombie game for my Java classes and I'm struck with a little problem: the Zombies are a class I made and I'm treating them on an ArrayList, like this:

horda.add(new Zumbi( (int)(Math.random()* 750), 0));

Where the arguments represent the zombie spawn position on the screen. To kill them you have to click them, pretty simple, checking the collision with an Iterator, here:

java.util.Iterator<Zumbi> itr = horda.iterator();
        while (itr.hasNext()){
            Zumbi z = itr.next();
            if (tiroPos.x > z.zumbiPos.x && 
                tiroPos.x < z.sprite.getWidth() + z.zumbiPos.x &&
                tiroPos.y > z.zumbiPos.y &&
                tiroPos.y < z.sprite.getHeight() + z.zumbiPos.y){

                //things to do when it hits    
            }

tiroPos is a pointer that holds the coordinates where the player shoot. Thing is: sometimes those things that should happen when you hit a zombie aren't happening. I don't know if it is because the Iterator isn't running fast enough or some other thing.

Maybe making a different Thread for each zombie works, but that would change the code is some fundamental ways and I didn't want to risk losing all that time if it don't help.

So, any thoughts?

//EDIT: Forgot to say: I'm checking for collisions in a Overrided paint method, because I don't know how to draw things on other methods and when I tried to access the ArrayList (it is a Sync'd ArrayList) on another thread it threw me a co-modification exception.

//EDIT2: Problem solved(that never were).

The MouseEvent object passed by the MouseListener passes the cordinate of the lower-end of the mouse pointer. So it wasn't really a collision problem, more of a math problem. I had to compare the clickPoint.y - 25 to get it right.

Thanks to everyone that tried to help!

Upvotes: 1

Views: 987

Answers (4)

Caspar
Caspar

Reputation: 7759

I'm assuming that a player "shoots" by clicking in the window, and hence tiroPos is the x,y coordinates of the click.

If that is the case, and your problem is that some zombies don't appear to get shot when they are clicked when the user is clicking a lot, it might be that only the last "shot" is getting saved in tiroPos.

You can test this by adding appropriate System.out.println() calls around your for loop and another one where you set tiroPos. If tiroPos is getting changed in the middle of your for loop, that would be why some zombies aren't getting shot.

If that is the case, you need to start storing a list of clicks instead of just the latest click.

Edit: this wouldn't fix your concurrent modification exceptions though.

Upvotes: 0

ataylor
ataylor

Reputation: 66089

Two things to keep in mind:

  1. If you need to remove items from the ArrayList while iterating through it, you must do it through the remove() method on the iterator. If you modify the list itself, it will fail.

  2. If two threads are accessing the list, you should wrap it with Collections.synchronizedList, or choose a different data structure.

Edit: it sounds like you're modifying the list on one thread while iterating through it on another. That will cause a ConcurrentModificationException. The easiest way to avoid it is to wrap the usage of the list with a synchronized block on both threads. Example:

synchronized(horda) {
    iterator = horda.iterator();
    while (iterator.hasNext()) {
        z = iterator.next();
        ...
    }
}

Another alternative is to clone the list before iterating or use one of the special list implementations from java.util.concurrent such as CopyOnWriteArrayList.

Upvotes: 2

adamjmarkham
adamjmarkham

Reputation: 2164

You would be best off using a for-each loop to iterate over the zombies in my opinion. It was introduced for performing such a task, so you may as well use it.

Upvotes: 0

Steve Wang
Steve Wang

Reputation: 1824

Multithreading can only help you so much, and it's really dependent on how much processing power you have.

Quadtrees are generally used for collision detection, so those might be worth looking into, as an alternative.

Upvotes: 0

Related Questions