0

I'm new at Java and I'm trying to develop a non-linear idle game for Android. I'm a bit stuck on how to manage the "time" in my game.

In linear idle game, I would have used System.currentTimeMillis() to update my model during game (application opened), and at game restart (as model is linear, simple formula to update model based on elapse time is sufficient).

But in non-linear idle game, my model must be time discrete, and a loop must be done at game restart. Then, at game restart, my models can't use System.currentTimeMillis(). My idea was to use a specific timer to calculate model when game is opened. But with my current knowledge, I don't know how to access a given timer from all my classes.

For example, in a class representing a Ship there is a method to travel. For this example, model is linear:

public class Ship {

    double travelStartTime, travelEndTime;
    double positionX, positionY;
    double maxSpeed = 10;

public Ship(double buildPostionX, double buildPositionY) {
        positionX = buildPositionY;
        positionY = buildPostionX;
        maxSpeed = 10;
        travelStartTime = 0; 
        travelEndTime = 0;
    }

public void startTravel(double destX, double destY){
        travelStartTime = System.currentTimeMillis();
        travelEndTime = System.currentTimeMillis() + travelTime(destX, destY);
    }


public double travelTime(double destinationX, double destinationY) {
        double currentX = this.getPositionX();
        double currentY = this.getPositionY();
        //calculate distance in km
        double distance = Math.pow(Math.pow(currentX-destinationX, 2) + Math.pow(currentY-destinationY, 2), 0.5);
        double time = distance/maxSpeed; //time in seconds
        return time;
    }

My questions are:

1. I would like to replace System.currentTimeMillis() by my own timer (started each time application starts), but how can I do that ? Knowing that any class of my model need to access the same timer ? Or is there any other to manage this issue ?

2. At the end of the travel, I would like to send a new "event", for example to display a new pop-up (or alertDialog) or to start a metho. How can I do that ?

Hope I was clear enough in my explanations.

Thank you in advance for any answer.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52

1 Answers1

0

You could add a currentTime field on your main game class and pass it down to entity instances on each update. You can also use a static long field, but this is discouraged. Example:

class MyGame {
    private long currentTime = 0;

    private Ship myShip = /* TODO */;

    // Called every x ms by an ExecutorService
    public void update() {
        // Update currentTime however you want
        // e.g. currentTime += 1000

        myShip.update(currentTime);
    }
}

class Ship {
    private int x;
    private int y;

    public void update(long currentTime) {
        // TODO e.g. perform lerp with previous position
    }
}

This is known as the Update Method pattern.

Hugo Manrique
  • 40
  • 3
  • 8
  • This method works well, I wanted to avoid it because you need to send currentTime to everyentity instances. Anyway it works, thank you. But for RecyclerView, I'm not able to send currentTime to it. Do you know how I could send currentTime to a RecyclerView ? – Anthony LEVILLAIN May 15 '20 at 17:21
  • In fact, I managed to pass the data "currentTime", but the data is not updated by adapter.notifydatasetchanged(); – Anthony LEVILLAIN May 15 '20 at 17:25