I'm working on a final project for school with a Java applet that counts down from a given interval to zero. When a Rectangle on screen experiences a mouse down event, it is supposed to execute the timer; however this does not occur; the program ends up crashing. I've seen a lot of examples of timers online, but many are using Java's built in timer class, which I am not using. I figured there must be a more basic way to do a simple timer. All variables have been declared at the top of the class.
public boolean mouseDown(Event e, int x, int y)
{
if(start.inside(x,y))
{
timerAct = true;
startTime = System.currentTimeMillis() / 1000;
endTime = startTime + interval;
while (System.currentTimeMillis() / 1000 < endTime) {
while (startTime != System.currentTimeMillis() / 1000) {
startTime += 1;
timeLeft = (endTime - startTime);
}
}
timerAct = false;
}
repaint();
return true;
}
The logic seems to workout okay because this began as System.out.println(), and it worked just fine. Then, it was converted to store the variable timeLeft. In the paint method, I have
g.drawString("Time: " + timeLeft, 420, 180);
to print the the time remaining. I also have the update method; but it doesn't seem to make a difference. And I know the issue isn't because I'm changing a variable. My mouse down method has an if statement with a different rectangle that tracks clicks (not shown), and it updates a counter of clicks on screen in the applet window without any issue. Any help is greatly appreciated.
Check this. It's pretty self explanatory.
Here's how you would code a simple countdown timer. This code needs to be run in a separate thread and not the Event Dispatch thread.
private void countdownTimer(int intervalSecs) {
long endTime = System.currentTimeMillis() + (intervalSecs * 1000L);
while (System.currentTimeMillis() < endTime) {
sleep();
repaint();
}
}
private void sleep() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void repaint() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
panel.repaint();
}
});
}
Related
I know that this question has been asked many times in a similar way on this platform. I've already spent a few hours trying the answers on my code (Threats and much more), but nothing has worked for me so far. So I'll ask the question here again specifically for my situation. I am currently programming a card game and would like to flip a coin before a card is played. I have already animated this as a gif and the coin toss logic works too. Now I want to get the animation into my program. For this I wrote a while loop which runs for 2 seconds. In this I would like to repaint, but the paint method (like many others had the problem before) is not called. This is my code in my public boolean cointoss() method for it:
cointossed = true;
long startTime = System.currentTimeMillis();
long elapsedTime = 0L;
while (elapsedTime < 2*1000) {
//Used this beacuse I thought my PC isnt fast enough
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
paintImmediately();
elapsedTime = (new Date()).getTime() - startTime;
}
cointossed = false;
In my paint() method there is the following Code, to draw the gif:
if(cointossed) {
g.drawImage(gif, 20, 20,100 , 100, null);
}
Somebody has an idea for my specific case?
Thx to MadProgrammer for helping me out with this.
I dont know if you mean it like that, but this worked for me:
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("Timer abgeschlossen");
cointossed = false;
repainter.setRepeats(false);
}
};
ActionListener rep = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
repaint();
}
};
Timer timer = new Timer(2000 ,taskPerformer);
Timer repainter = new Timer(20 ,rep);
With this I created my own while loop where I can call repaint();
Just started both timers and my gif plays :D
I have this interesting problem with some code I wrote in Java. I am executing this code in in the latest version of eclipse with jdk-17.0.1. The purpose of the code is to take a screenshot of my screen every couple of milliseconds, but only if running is true. At the start, running is false. I can set running to be true by hitting a certain key. Here is the code
double timePerTick = 1_000_000_000/fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
while (true) {
now = System.nanoTime();
delta+= (now-lastTime)/timePerTick;
lastTime = now;
if (delta >= 1) {
//for some reason code only works if this print statement here
//System.out.println("WOWEE");
if (running) {
//Create rectangle screen-capture around cursor
BufferedImage image = robot.createScreenCapture(new Rectangle(0,0, width, height));
try {
output.write(("Capture taken \n").getBytes());
System.out.println("WRITTEN!");
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.println("BRUH!");
e1.printStackTrace();
}
}
delta--;
}
}
The problem is that the if (running) statement never runs, even when running is true. However, when I uncomment the System.out.println statement after the if(delta) code, it works perfectly well. Like this:
double timePerTick = 1_000_000_000/fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
while (true) {
now = System.nanoTime();
delta+= (now-lastTime)/timePerTick;
lastTime = now;
if (delta >= 1) {
//for some reason code only works if this print statement here
System.out.println("WOWEE");
if (running) {
//Create rectangle screen-capture around cursor
BufferedImage image = robot.createScreenCapture(new Rectangle(0,0, width, height));
try {
output.write(("Capture taken \n").getBytes());
System.out.println("WRITTEN!");
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.println("BRUH!");
e1.printStackTrace();
}
}
delta--;
}
}
In the first code, nothing gets printed, but in the second code, WOWEE gets printed over and over again. By the way, if running is true at the start, then both codes work fine. However, if you switch from running = false to running = true, the first code never prints anything, but the second code goes from printing nothing to printing WOWEE. Is there any reason for this?
By the way, output is a FileOutputStream instance if that is necessary info.
user16320675 found the answer to my problem in the comments, but for some reason they deleted their comments. I waited to see if they'd come back, but they didn't. So, I will post the information they gave me. The reason my program didn't work is because the variable "running" was being accessed by multiple threads, one thread being the main thread, and the other thread being the one that monitors keyboard input. When a piece of memory is being accessed by multiple threads, you must declare it as "volatile" to make sure synchronization issues don't happen. Like this
public static volatile boolean running;
More information here https://www.baeldung.com/java-volatile
So basically I have a timer method in my program which uses the integer z as it's parameter as well as the delay for the timer itself. But every time I run this method, it creates a new timer not deleting the old one. So I decided to add an if else block that made it so that it only created a timer on the first time but now it's saying that it might not have been initialized because it was initialized in the if else block. Can someone help me?
public void timer(int z) {
int count = 0;
Timer tester;
z = (60000 / z);
decide = true;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {noteDecider();}
};
if(count == 0) {
tester = new Timer(z, taskPerformer);
tester.start();
}
else {
tester.setDelay(z);
tester.start();
}
count++;
}
I would say that if you are concern about optimizing your code you should look into optimizing your Timer class. Like moving the ActionListener object inside Timer itself and more. All your timer(int z) method is doing is trying to use an object to keep track time not managing the lifecycle of Timer objects.
I wanted to know how can I add time to my events in libgdx. I have a button and when you press it a sprite will appear. I want the sprite to appear for only a short period of time. How can I do this? I used Scene2D to make the sprites as an actor.
I will show you an example in pseudo code.
wait time = 5 second;
current time = get time;
if (current time > wait time) {
// do the following
}
There's two ways to do this. You can either use something similar to your your pseudo code or you can use a timer.
Manual calculation:
private Long lifeTime;
private Long delay = 2000L; //1000 milliseconds per second, so 2 seconds.
public void create () {
lifeTime = System.currentTimeMillis();
}
public void render () {
lifeTime += Gdx.graphics.getDeltaTime();
if (lifetime > delay) {
//Do something
}
}
Using a timer:
private float delay = 2; //In seconds this time
//At some point you set the timer
Timer.schedule(new Task(){
#Override
public void run() {
// Do something
}
}, delay);
Read more here: https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Timer.html
This question already has answers here:
Calculating frames per second in a game
(21 answers)
Closed 9 years ago.
Yesterday I wrote a Thread addressing how my game loop ran (in java) and how it works.
My game loop works completely, and I know why, but now I just wan't to know how to calculate FPS (Frames Per Second) and print it out every second.
I got a response yesterday about this, but he/she explained it in words and I couldn't understand it.
If anyone could help me (with a code example? :D) that would be great.
Here is my game loop:
while (running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if (wait < 0) {
wait = 5;
}
try {
Thread.sleep(wait);
} catch (Exception e) {
Game.logger.log("ERROR! Printing Stacktrace...");
e.printStackTrace();
}
}
ALSO:
In my JFrame when ever I call setName(string) it never works/updates on the Frame - Link me to a thread?
The easiest way to do this is to keep a variable whatTheLastTimeWas stored and doing this where you want to check your frame rate:
double fps = 1000000.0 / (lastTime - (lastTime = System.nanoTime())); //This way, lastTime is assigned and used at the same time.
Alternatively, you can make a FPS counter like so:
class FPSCounter extends Thread{
private long lastTime;
private double fps; //could be int or long for integer values
public void run(){
while (true){//lazy me, add a condition for an finishable thread
lastTime = System.nanoTime();
try{
Thread.sleep(1000); // longer than one frame
}
catch (InterruptedException e){
}
fps = 1000000000.0 / (System.nanoTime() - lastTime); //one second(nano) divided by amount of time it takes for one frame to finish
lastTime = System.nanoTime();
}
}
public double fps(){
return fps;
}
}
Then in your game, have an instance of FPSCounter and call nameOfInstance.interrupt(); when one frame is finished.
You can combine a simple counter and Timer.scheduleAtFixedRate for this.
Disclaimer: I don't know if this is the best method; it's just easy.
int totalFrameCount = 0;
TimerTask updateFPS = new TimerTask() {
public void run() {
// display current totalFrameCount - previous,
// OR
// display current totalFrameCount, then set
totalFrameCount = 0;
}
}
Timer t = new Timer();
t.scheduleAtFixedRate(updateFPS, 1000, 1000);
while (running) {
// your code
totalFrameCount++;
}