3
\$\begingroup\$

Im new to the game-dev world and I have a tendancy to over-simplify my code, and sometimes this costs me alot fo memory.

Im using a custom TimerTask that looks like this:

    public class Task extends TimerTask {

    private MainGamePanel panel;
    public Task(MainGamePanel panel) {
    this.panel=panel;
    }

    /**
    * When the timer executes, this code is run.
    */
    public void run() {
    panel.createEnemies();
    }
    }

this task calls this method from my view:

    public void createEnemies() {
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.female);
    if(enemyCounter < 24){
        enemies.add(new Enemy(bmp, this));
    }
    enemyCounter++;
      }

Since I call this in the onCreate-method instead of in my views contructor (because My enemies need to get width and height of view). Im wondering if this will work when I have multiple levels in game (start a new intent). And if this kind of timer really is the best way to add a delay between the spawning-time of my enemies performance-wise.

adding code for my timer if any1 came here cus they dont understand timers:

    private Timer timer1 = new Timer();
    private long delay1 = 5*1000; // 5 sec delay

    public void surfaceCreated(SurfaceHolder holder) {
    timer1.schedule(new Task(this), 0, delay1); //I call my timer and add the delay
    thread.setRunning(true);
    thread.start();
}
\$\endgroup\$
6
  • \$\begingroup\$ How are your other entities keeping track of time? You should just have a timer class you pass the deltaTime to every frame, and it switches a boolean once the total time reaches your amount (5 secs). Then you query the class each frame and ask it, "are you ready?" and it returns its boolean. \$\endgroup\$ Sep 6, 2012 at 23:25
  • \$\begingroup\$ dont really have any other timers in my game, just a ordinary main-thread.. I do add delay between bullets using ordnary counters and system.currenttime. so nothing else big \$\endgroup\$
    – Green_qaue
    Sep 7, 2012 at 0:21
  • \$\begingroup\$ You could just add the timer into the class that's the level you're spawning. Do you have anything that's keeping track of elapsed time in the game, maybe an enemy controller? \$\endgroup\$ Sep 7, 2012 at 1:23
  • \$\begingroup\$ I dont, and I dont rly plan to tbh. Can see the use of it obviously but Im almost done and no point putting it in now. \$\endgroup\$
    – Green_qaue
    Sep 7, 2012 at 12:29
  • \$\begingroup\$ Ofc now I need a variable like that.. I have a timerTask that spawns enemies with delay. And obv that timer dosnt respond well to onPaus so It just keeps going, so when I start it up again after a paus there are like 20 enemies spawned right away \$\endgroup\$
    – Green_qaue
    Sep 7, 2012 at 14:44

1 Answer 1

3
\$\begingroup\$

TimerTask is not really the best or "right" way to do this. You need to update your game each frame as the execution proceeds. That way you can:

  1. Account for pausing the game.
  2. Adjust the gameplay if the framerate slows down.

(Though the second one is certainly not an issue for your mini-game.)


First, you want to figure out deltaTime, which is the amount of time that's passed since you last checked the system clock. I'm calling your main program loop run():

volatile boolean running = true;

public void run() {
    long startTime = System.nanoTime();

    while (running) {
        float deltaTime = (System.nanoTime() - startTime) / 1000000000.0f;        // Makes deltaTime into fractions of seconds
        startTime = System.nanoTime();

        // Rest of game code, including your "onDraw" code.
        ...
    }
}

Now you want to keep a value or class, your timer, that you add the deltaTime to once per "frame" of your game (i.e. each time your game draws itself). Once the accumulated time reaches 5 seconds, you can call your enemy spawner.

volatile boolean running = true;

public void run() {
    long startTime = System.nanoTime();

    while (running) {
        float deltaTime = (System.nanoTime() - startTime) / 1000000000.0f;        // Makes deltaTime a more reasonable-looking size of time
        startTime = System.nanoTime();

        spawnEnemyTimer += deltaTime;
        if (spawnEnemyTimer >= 5.0f) {        // 5.0f == 5 seconds
            createEnemies();                  // The method you listed in your question
            spawnEnemyTimer -= 5.0f;
        }

        // Rest of game code, including your "onDraw" code.
        ...
    }
}

Now, to pause, you simply stop running, and start running when you 'resume':

public void onPause() {
    running = false;
    ...
}

...

public void onResume() {
    running = true;
    ...
}

When the system enters your run() code again, your startTime is reset, so any system time spent while your app was paused is automatically accounted for.


You should make as many other elements rely on the deltaTime value as possible. This means, however, you can no longer assume frames of your game as a "fixed" time. Your enemies and bullets should have like a "speedPerSecond" value and each frame they move deltaTime's percentage of that distance.

distanceMoved = speedPerSecond * deltaTime;

If your game was just incrementing everything each frame before (like enemies moved X amount every time you drew), you should have a timer that's counting frames, instead of counting real time.

\$\endgroup\$
6
  • \$\begingroup\$ I am already using delta for speeds etc. But didnt think of using it to add a delay that way. Very helpfull. Thank you good sir! \$\endgroup\$
    – Green_qaue
    Sep 7, 2012 at 20:30
  • \$\begingroup\$ Great! Since you're already using it, you should try and make every component of your game use deltaTime, and safely ignore the absolute system time from now on. \$\endgroup\$ Sep 7, 2012 at 22:54
  • \$\begingroup\$ @iQue Just made an edit; the way I had the timer set up it would only trigger once. I believe your code example was set up to trigger every 5 seconds, so I added spawnEnemyTimer -= 5.0f; to reflect that. \$\endgroup\$ Sep 7, 2012 at 22:56
  • \$\begingroup\$ yeah I alrdy added that :) but thanks! works like charm \$\endgroup\$
    – Green_qaue
    Sep 8, 2012 at 11:33
  • \$\begingroup\$ Ran into a weird problem all of a sudden, in some of my classes its like my Thread-class isnt being imported the right way, Im not getting any errors but delta is always = 0. And in some classes it works the way it should. really weird \$\endgroup\$
    – Green_qaue
    Sep 8, 2012 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .