Clock in a HUD

Hey

Does anyone know how to make a clock in an existing HUD??  :?

I would prefer a clock that counts down to 0. :slight_smile:

Are you wanting to do a countdown with graphics representing a number or plain text display?



There is a fairly big difference in implementation.



it's a little easier with text, but either way works well.



Let me get a class from Dradis that I wrote and post it.

oh… thx  XD I was thinking about a digital clock - numbers  :slight_smile:

I stripped out a ton of stuff from my timer event that I didn't need for this example.



Basically, when this starts up it sets an event at one minute out… then in the simpleUpdate it checks to see if the starting second is the same as the current second, if not it updates the display and increments the starting second by one.



This is the simple nitty gritty version.



lemmie know if you have any other questions.



import java.util.Calendar;
import java.text.NumberFormat;

import com.jme.app.SimpleGame;
import com.jme.scene.Text;

public class CountdownTest extends SimpleGame {
    private Calendar event;

    private int second;
    private int hour;
    private int minute;

    private int startSecond = 10;
    private int startMinute;
    private int startHour;
    private static final NumberFormat twoDecimals = NumberFormat.getInstance();
    private static Text completionText;
    private boolean continueUpdating = true;

    protected void simpleInitGame() {
        twoDecimals.setMinimumIntegerDigits(2);

        event = Calendar.getInstance();
        second = event.get(Calendar.SECOND);
        minute = event.get(Calendar.MINUTE);
        hour = event.get(Calendar.HOUR);
        event.set(Calendar.MINUTE, startMinute);
        event.set(Calendar.HOUR, startHour);
        event.set(Calendar.SECOND, startSecond);

        //sorry Go Diego Go reference:)
        completionText = new Text("textNode", "Mission Completa");
        completionText.setLocalTranslation(100, 100, 0);

        drawTimer();
    }

    protected void simpleUpdate() {
        super.simpleUpdate();
        if (continueUpdating) {
            Calendar current = Calendar.getInstance();
            int tmpSec = current.get(Calendar.SECOND);
            int tmpMinute = current.get(Calendar.MINUTE);
            int tmpHour = current.get(Calendar.HOUR);
            boolean reDrawTimer = false;

            if (tmpSec == second + 1) {
                second++;
                startSecond--;
                event.add(Calendar.SECOND, -1);
                reDrawTimer = true;
            }

            if (tmpMinute == minute + 1) {
                minute++;
                startMinute--;
                event.add(Calendar.MINUTE, -1);
                reDrawTimer = true;
            }

            if (tmpHour == hour + 1) {
                hour++;
                startHour--;
                event.add(Calendar.HOUR, -1);
                reDrawTimer = true;
            }

            if (startSecond <= 0 && startMinute <= 0 && startHour <= 0) {
                reDrawTimer = false;
                rootNode.detachChildNamed("textNode");
                rootNode.attachChild(completionText);
                continueUpdating = false;
            }

            if (reDrawTimer) {
                drawTimer();
            }
        }
    }



    private void drawTimer() {
        StringBuilder sb = new StringBuilder();

        sb.append(twoDecimals.format(event.get(Calendar.HOUR))).append(":");
        sb.append(twoDecimals.format(event.get(Calendar.MINUTE))).append(":");
        sb.append(twoDecimals.format(event.get(Calendar.SECOND)));

        final Text timerText = new Text("textNode", sb.toString());
        timerText.setLocalTranslation(100, 100, 0);
        rootNode.detachChildNamed("textNode");
        rootNode.attachChild(timerText);
    }

    public static void main(String[] args) {
        new CountdownTest().start();
    }
}



edit -- the number format thing was bothering me.

jup  :wink: thx  :slight_smile: that was nice!!

Is that what you were looking for?



edit – removed unnecessary comment :slight_smile:

je, think so :wink:

Do you know how i can get the clock and the hud to run at the same time (in the same window)??

the example provided is based on SimpleGame.  If you are wanting to use it in another game, simply pull the info out of the example I provided and place it in it's own bean calling the same methods from your game.



eg. in your game, call update(tpf) in the TimerCountdown bean or whatever you name it.



In your game, add your hud as normal, and add a getText() to the "TimerCountdown" bean that returns the Text node.



If you need anymore help, let me know.


Here's a change in the code for a singleton class.

the example provided for running the source shows that you can "re" init the singleton to restart the timer if you wish.

You'll have to do the work to change the message at the end or add listeners or whatever you want to do with it.

Also remember, that this is a singleton, so if you're wanting multiple timer countdowns to display you'll have to change it so it's a non-singleton class.


import com.jme.app.SimpleGame;

public class CountdownTest extends SimpleGame {
    protected void simpleInitGame() {
        TimerCountdown.getInstance().init(rootNode, 0, 0, 10);
        startTimeMillis = System.currentTimeMillis();
    }

    private static long startTimeMillis;

    protected void simpleUpdate() {
        super.simpleUpdate();
        TimerCountdown.getInstance().update(tpf);
        //this code is just to demonstrate that after the first five seconds it will reset the timer countdown to 15 then continue down to zero
        if (System.currentTimeMillis() - startTimeMillis == 5000) {
            TimerCountdown.getInstance().init(rootNode, 0, 0, 15);
        }
    }


    public static void main(String[] args) {
        new CountdownTest().start();
    }
}




import java.util.Calendar;
import java.text.NumberFormat;

import com.jme.scene.Text;
import com.jme.scene.Node;

public class TimerCountdown {
    private static final TimerCountdown _INSTANCE = new TimerCountdown();

    private TimerCountdown() {}

    public static TimerCountdown getInstance() {
        return _INSTANCE;
    }

    private Calendar event;

    private int second;
    private int hour;
    private int minute;

    private int startSecond;
    private int startMinute;
    private int startHour;
    private static final NumberFormat twoDecimals = NumberFormat.getInstance();
    private static Text completionText;
    private boolean continueUpdating;

    private Node rootNode;

    static {
        twoDecimals.setMinimumIntegerDigits(2);
    }

    public void init(Node _rootNode, int _startHour, int _startMinute, int _startSecond) {
        startSecond = _startSecond;
        startMinute = _startMinute;
        startHour = _startHour;

        continueUpdating = true;

        rootNode = _rootNode;
        event = Calendar.getInstance();

        second = event.get(Calendar.SECOND);
        minute = event.get(Calendar.MINUTE);
        hour = event.get(Calendar.HOUR);

        event.set(Calendar.MINUTE, startMinute);
        event.set(Calendar.HOUR, startHour);
        event.set(Calendar.SECOND, startSecond);

        //sorry Go Diego Go reference:)
        completionText = new Text("textNode", "Mission Completa");
        completionText.setLocalTranslation(100, 100, 0);

        drawTimer();
    }

    public void update(float tpf) {
        if (continueUpdating) {
            Calendar current = Calendar.getInstance();
            int tmpSec = current.get(Calendar.SECOND);
            int tmpMinute = current.get(Calendar.MINUTE);
            int tmpHour = current.get(Calendar.HOUR);
            boolean reDrawTimer = false;

            if (tmpSec == second + 1) {
                second++;
                startSecond--;
                event.add(Calendar.SECOND, -1);
                reDrawTimer = true;
            }

            if (tmpMinute == minute + 1) {
                minute++;
                startMinute--;
                event.add(Calendar.MINUTE, -1);
                reDrawTimer = true;
            }

            if (tmpHour == hour + 1) {
                hour++;
                startHour--;
                event.add(Calendar.HOUR, -1);
                reDrawTimer = true;
            }

            if (startSecond <= 0 && startMinute <= 0 && startHour <= 0) {
                reDrawTimer = false;
                rootNode.detachChildNamed("textNode");
                rootNode.attachChild(completionText);
                continueUpdating = false;
            }

            if (reDrawTimer) {
                drawTimer();
            }
        }
    }

    private void drawTimer() {
        StringBuilder sb = new StringBuilder();

        sb.append(twoDecimals.format(event.get(Calendar.HOUR))).append(":");
        sb.append(twoDecimals.format(event.get(Calendar.MINUTE))).append(":");
        sb.append(twoDecimals.format(event.get(Calendar.SECOND)));

        final Text timerText = new Text("textNode", sb.toString());
        timerText.setLocalTranslation(100, 100, 0);
        rootNode.detachChildNamed("textNode");
        rootNode.attachChild(timerText);
    }
}