Erail
Erail

Reputation: 169

Accessing an object inside Timer : Java

I need some help with the program that I'm currently working on. It is a plants vs zombies game and I Timer to keep adding the zombies.

  Timer ZombieTimer = new Timer (); 

    TimerTask task = new TimerTask() { //for continuous arrival of zombies
      public void run()
      {
        Random rand = new Random(); //puts a zombie in a random lane
        int a = rand.nextInt(4);
        int b=9; 

        Zombie z = new Zombie(); 
        gardenField[a][b] = z;
        System.out.println("New zombie in " + a + " tile " + b);
      }
    };

    ZombieTimer.scheduleAtFixedRate(task, 1000, 8000); //new zombie every 8 seconds

Now after creating one Zombie object I would like to allow the zombie to move in the horizontal array that it belongs(moving closer to the plant). I am thinking of using Timer as well but I dont know if I should pass the entire array in the Zombie class. Any help? Thanks.

Upvotes: 1

Views: 326

Answers (4)

Jose Zevallos
Jose Zevallos

Reputation: 725

I would use a ScheduledExecutorService instead of a Timer. Also, I would use a ExecutorService to have one thread in charge of moving the zombies.

for example like this:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class ZombiesVsPlantsExample {

private static volatile Zombie[][] map = new Zombie[100][100]; // volatile not needed if you synchronize all access to the map. not only writes

    public static void main(String[] args) {
        ZombiesVsPlantsExample zombiesVsPlantsExample = new ZombiesVsPlantsExample();
        zombiesVsPlantsExample.doTheWork();
    }

    private void doTheWork() {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);  // this thread pool will be used to create zombies

        ExecutorService executorService = Executors.newFixedThreadPool(1);  // this thread pool will be used to move zombies



        ZombieCreator zombieCreator = new ZombieCreator(map);
        scheduler.scheduleAtFixedRate(zombieCreator, 2, 8, TimeUnit.SECONDS); // one new zombie every 8 seconds

        executorService.submit(new ZombiesPositionProcessor(map));

    }
}

class Zombie {

}

class ZombieCreator implements Runnable {

    Zombie[][] map;

    public ZombieCreator(Zombie[][] map) {
        this.map = map;
    }

    @Override
    public void run() {
        Zombie zombie = new Zombie();
        synchronized(map){
            map[1][2] = zombie;  // put new zombie in some random location in map
        }
        System.out.println("new zombie was created");
    }
}

class ZombiesPositionProcessor implements Runnable {

    Zombie[][] map;

    public ZombiesPositionProcessor(Zombie[][] map) {
        this.map = map;
    }

    @Override
    public void run() {
        while (true) {
            // iterate map and move zombies one by one
            System.out.println("moving one zombie");
        }
    }
}

Upvotes: 1

Leonardo Pina
Leonardo Pina

Reputation: 468

It is a matter of design. Should something manage the game entirely? Should the objects manage themselves?

Personally, I think your idea is a good approach self-managed objects can help reduce complexity as your game grows.

Upvotes: 0

Arno C
Arno C

Reputation: 490

You don't need to pass the array gardenField to the Zombie class.

If you have access to the gardenField somewhere it's just a matter of updating them all every x-time interval by looping over all zombies in the array and shifting their position right. Make a separate timer for this and it should work.

Upvotes: 2

EsotericVoid
EsotericVoid

Reputation: 2576

I think you are on the right path, but you have no need to pass the list to the timer. Inside the run() method of the task you should simply call a method updatePositions() (that moves the zombies 1 step forward) that is defined in the outer class.

Upvotes: 2

Related Questions