This site requires JavaScript, please enable it in your browser!
Greenfoot back
ortizme93
ortizme93 wrote ...

2013/4/3

Timer/Clock for a game

ortizme93 ortizme93

2013/4/3

#
I want am writing a program for a zombie killing game and want to have a clock that keeps track of how long the player has lasted before dying and then shows them when they do die how long they lasted. I can't seem to figure out how to do so though, any help is much appreciated!
I know there is a specific Timer object in the Java language, but I haven't looked much into it and don't know how it works. Another thing you can do is count every frame and do the math to see how many frames equals one second. However, that would take up a lot of space counting each frame and probably wouldn't be useful. One of the more experience programmers should give you a better answer.
danpost danpost

2013/4/3

#
Actually, counting every frame is the way to go; and it would be more useful than it would appear. The reason is because you would be using game-time, which is usually more preferable than real-time (more consistant as far as judging the 'time' the player survives). In the world class code:
// add (if you do not already have) these instance fields
private Player player; // sub 'Player' with name of player-controlled actor class
private int gameTime; // number of game-time units elapsed
private int gameTimer; // frame counter
// in the world constructor
player = new Player();
addObject(player, /* x, y */);
// in world act method or method it calls
if (player.getWorld() != null)
{
    gameTimer = (gameTimer + 1) % 60; // adjust 6 to suit
    if (gameTimer == 0) gameTime++;
}
else
{
    // show value of 'gameTime'; in normal speed scenario, this will be approximate seconds
    // code to end game, reset level or start another life
}
This will take care of the timing of the player internally. To show tenths of seconds, change '60' to '6' and show double value of 'gameTime/10'. Another way is, since you will be showing the value eventually, to create a Counter object from the start as follows:
// world instance fields
private Player player;
private Counter gameTime;
private int gameTimer;
// in world constructor
player = new Player();
addObject(player, /* x, y */);
gameTime = new Counter(); // the counter is created; but not added to the world
// in the act method or a method it calls
if (player.getWorld() != null)
{
    gameTimer = (gameTimer + 1) % 60;
    if (gameTimer == 0) gameTime.add(1);
}
else
{
    // if game is over
    addObject(gameTimer, /* x, y */); // now add it to the world
    Greenfoot.stop();[u]
}
Of course, this is just the basics and you will need to create the Counter class code with a int 'gameTime' field and a method that can be called to change its value ('add' in my example).
Hmm, I wasn't thinking of having multiple timer ints, where one is for seconds, minutes, etc. That definitely won't take up as much space.
danpost danpost

2013/4/4

#
Line 18 of my second code post above should read
addObject(gameTime, /* x, y */); // now add it to the world
Anne2403 Anne2403

2014/11/23

#
here I am again @danpost :D I have a question? If I am going to apply your example code above in my game,. which one is the better? The first or the second or both?? and also, am I going to put a clock object in the world or the program or Greenfoot will automatically put the timer??
danpost danpost

2014/11/23

#
@Anne2403, if you are not using the system clock (which you will not as it is less consistent with respect to game-time) then the first way will work if you are not using a running display of the elapsed time. The code you see was written 18 months ago and I am always trying to find easier ways to do things. Of late, I have been using a very simple subclass of Actor for multiple purposes, using something like the following for the entire class code:
public class BasicActor extends greenfoot.Actor {}
It is possible to use this class for (1) basic text image (2) clickable buttons (3) displayable counters and timers ... to name a few things. For each of the ones mentioned, you would have an instance field to hold a reference to the actors (I am showing one of each kind in order):
// instance fields to reference the actors
private Actor titleText, infoButton, scoreCounter;
For displayed text (set image and add to world)
titleText = new BasicActor();
titleText.setImage(new GreenfootImage("GAME NAME", 48, null, null));
addObject(titleText, 300, 50);
For button (set image, add to world, and check for clicks)
GreenfootImage image = new GreenfootImage(80, 28);
image.fill();
image.setColor(Color.lightGray);
image.fillRect(2, 2, 24, 24);
GreenfootImage caption = new GreenfootImage("Info", 24, null, null);
image.drawImage(caption, 40-caption.getWidth()/2, 14-caption.getHeight()/2);
infoButton = new BasicActor();
infoButton.setImage(image);
addObject(infoButton, 300, getHeight()-20);
// in act method
if (Greenfoot.mouseClicked(infoButton)) Greenfoot.setWorld(new InfoWorld());
For counters and timers (set initial image and use an int field and update method)
// add instance field
private int score;
// in constructor
scoreCounter = new BasicActor();
updateScoreCounter();
addObject(scoreCounter, 50, 20);
// this method is called first from the constructor
// it should also be called anytime the value of 'score' changes
private void updateScoreCounter()
{
    scoreCounter.setImage(new GreenfootImage("Score: "+score, 28, null, null));
}
With the first coding that you mentioned in the previous post above, you would call the 'update' method when 'gameTime' is changed to show game time elapsed ('gameTime' being the int field instead of 'score'). The button code seems extensive, but the first 7 lines all deal with the image. If you had an image saved in a file it would only take one line to set the image of the actor.
Anne2403 Anne2403

2014/11/23

#
@danpost I will understand this, Thank You. My game doesn't have Scores but that will be a big help. I will just have to find a way how to shoot a fire(for enemies) and Lightning(for my actor which is the cat.) Thank u po.
danpost danpost

2014/11/23

#
I found a couple of mistakes in my previous post. (1) line 4 for the button example should be:
image.fillRect(2, 2, 76, 24);
(2) at the end, I had referred to the first 7 lines of the button class -- well that would more correctly be 7 of the first 8 lines (all but line 7).
You need to login to post a reply.