I'm trying to loop trough an array of Points with a delay, but nothing happens and I don't get errors.
Here's an example of what my code looks like:
public class Class {
private Point[] points;
private int start, delay;
public Class() {
points = new Point[] {
new Point(1, 1),
new Point(2, 1),
new Point(1, 2)
};
start = System.nanoTime();
delay = 500;
}
public void update() {
for(int i = 0; i < points.length; i++) {
long elapsed = (System.nanoTime() - startT) / 1000000;
if(elapsed > delay) {
System.out.println("x: " + points[i].x);
System.out.println("y: " + points[i].y);
start = System.nanoTime();
}
}
}
}
Everything inside the update function is working except for that for loop.
edit:
It's a java Swing application with only 1 thread.
One of your problems is that you're using an if block and not a while loop. An if block just checks once, sees that the condition is false, and skips over it. A while loop will loop until the condition is false.
For most delays you could use a general purpose Timer object such as a java.util.Timer together with a java.util.TimerTask object.
for delays in a Swing GUI you would use a javax.swing.Timer
Other options for general non-Swing computing including using a while loop that contains a Thread.sleep(...) call.
Also look into using a ScheduledThreadPoolExecutor for non-Swing delays.
Edit
Regarding your edit:
edit: It's a java Swing application with only 1 thread.
Then use a javax.swing.Timer. You can find the tutorial here: Swing Timer Tutorial
And here's the Swing Concurrency Tutorial
Also have a look at the Swing Tutorial for more on Swing development.
If you need more help, then as we've already mentioned, provide more detail in your question.
To sleep for an aproximate amount of time use Thread.sleep(millis);
Do not expect accuracy to be more than 30ms.
Related
I'm working on a game where I move a car image based on keyboard input. Currently I'm using this game loop:
private void runGameLoop() {
window.setVisible();
isRunning = true;
final double FRAMES_PER_SECOND = 60;
double timePerUpdate = 1000000000 / FRAMES_PER_SECOND;
double timeFromLastUpdate = 0;
long now;
long last = System.nanoTime();
while (isRunning) {
now = System.nanoTime();
timeFromLastUpdate += (now - last) / timePerUpdate;
last = now;
if(timeFromLastUpdate >= 1) {
tick();
render();
timeFromLastUpdate--;
}
}
}
The tick method updates the car image location, and the render method will render the image(with the new location) on screen.
I want to have the calculations for the new image location on a separate thread, because at the moment the calculations are taking to long and causing a rendering lag. Is there a way to use multi threading while still implementing a game loop?
Thanks in advance.
Perhpas you can do something similar to what Android does. In Android there is the mainthread which would be like your game loop. It has a Handler for runnables that are posted from background/concurrent threads to the mainthread.
So at every loop cycle the mainthread executes any runnables posted feom background threads.
Note, that the calculations should not be done in the runnables (which are executed in mainthread), only passing the results/updating stuff should be done in the runnables.
I'm coding this in JavaFX using a FXMLController and the scene builder.
I'm currently creating an Instagram "liker" mostly just for practice as I'm a Computer Science major, and I just like coding.
My issue is, I have a for loop that "likes" 20 photos for each hashtag, I obviously need a delay or I'd get banned rather quickly. The user can choose the delay, then I randomize this delay so it's not too robotic.
The only way I've been able to use this delay is through the thread.sleep method, but since I'm coding on the FXMLController, it freezes the whole UI, and somehow stops other textareas from being updated. This is obviously not ideal.
I've looked everywhere trying to find an alternative to this, but I can't find anything that works in my program.
I'll give the whole method:
private void start() {
sleepWhen();
tagNumber++;
int delays = Integer.valueOf(delay.getText());
delays = delays * 1000;
if (loaded) {
runTime.clear();
runTime.appendText("Liking...");
for (int i = 0; i < 20; i++) {
webEngine.executeScript("document.getElementsByClassName('btn btn-default btn-xs likeButton')[" + i + "].click()");
try {
double random = Math.random() * 1000;
random = random + delays;
delays = (int) random;
System.out.println(delays);
likes++;
likesNumber.clear();
likesNumber.appendText(String.valueOf(likes));
System.out.println(String.valueOf(likes));
Thread.sleep(delays);
delays = Integer.valueOf(delay.getText());
delays = delays * 1000;
} catch (InterruptedException ex) {
//do nothing
}
System.out.println("tag number" + tagNumber + "numbertags" + numberTags);
if (!sleep) {
if (tagNumber < numberTags) {
System.out.println("Loading tag:" + tagNumber);
loadTag(tagNumber);
}
}
}
}
}
This likes 20 photos, then loads another hashtag, and repeats.
Any help with this would be great, thanks.
The freeze is because you are trying to do everything on the same thread, when you are using Thread.sleep(delays), you are actually putting your UI thread to sleep and hence the lag !
Try using different thread for your work, you can either use a worker thread, if whatever you are doing will not affect the UI
or you can use Platform.runLater(), if you want the changes to shown on the UI !
For more details :
concurrency in javafx !
Platform.runLater and Task in JavaFX
I'm attempting to get an animation working in a game I'm developing. The animation works by setting a button size to very small, then gradually growing it to its normal size again. I have it working, except I'm having timing issues.
Sometimes the button will grow almost instantly, sometimes it goes VERY slow. I'm looking for something inbetween, and I need it to ALWAYS grow at that size, not some times fast sometimes slow.
I've looked into it and I found this pseudocode:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
Unfortunately I don't understand what's being said, and I don't know how to apply this to my code. Can anyone help with that or explain what's being said in the above pseudocode?
Here's my timer code, timer is already defined above as a Timer, and z[] is just a pair of coordinates:
timer = new Timer(18, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension dim = button[z[0]][z[1]].getSize();
if (dim.getHeight() < 79.9) {
button[z[0]][z[1]].setSize((int) (dim.getWidth() + 6), (int) (dim.getHeight() + 6));
} else {
button[z[0]][z[1]].setSize(80, 80);
timer.stop();
}
}
});
timer.start();
Depending on how many updates you're calling on your Swing application, it may be getting "backed up" and slowing down. For instance, if you wanted to accomplish the animation without a Timer, you could just do something like this:
// example method to do animation
public void animateButton(final int wait){
Thread thread = new Thread(){
public void run(){
// some loop structure to define how long to run animation
Dimension dim = button[z[0]][z[1]].getSize();
while (dim.getHeight() < 79.9){
SwingUtilities.invokeLater(new Runnable(){
//update Swing components here
});
try{ Thread.Sleep(wait); }
catch(Exception e){}
}
}
}
}
thread.start();
}
I think this may be similar to how a Timer updates the GUI, as Timers run on a separate thread. I would look into whether or not you need to use invokeLater(new Runnable) inside a timer to properly schedule the task. I had to do this to allow a project I was working on to keep responsive during long tasks. If you really needed to ensure the speed and maybe DROP updates to adjust for system lag, then you'll need to be calculating how complete the animation is vs how much time has passed, using a method call such as System.currentTimeMillis() or System.nanoTime(). Then, adjust accordingly for each step of the animation.
I'm working on a simple Java 2D game.
I wrote a certain game-loop for the game. Using this game-loop, the game sometimes runs in moderate (constant, I think) speed, and sometimes when I start it, it runs in slow (constant) speed.
I learned to implement this game-loop from the following article: Here
It's code:
(I changed it's code to Java. You can find this loop in the article under the title "FPS dependent on Constant Game Speed").
public void run(){
next_game_tick = System.currentTimeMillis();
while(true){
updateGame(); // This is actually a bunch of methods.
repaint();
next_game_tick = next_game_tick + skip_ticks;
sleep_time = next_game_tick - System.currentTimeMillis();
if(sleep_time<0)sleep_time=2;
try {
Thread.sleep(sleep_time);
} catch (InterruptedException e) {}
next_game_tick = System.currentTimeMillis();
}
}
As I said, this loop wasn't always running the game at an appropriate speed, so I looked at the other game-loop implementations suggested in the above article.
The following implementation, only based on it's description, seemed like the most suitable for my game:
int TICKS_PER_SECOND = 50;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;
long next_game_tick = System.currentTimeMillis();
int loops;
bool game_is_running = true;
while( game_is_running ) {
loops = 0;
while( System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
repaint();
}
(I changed it's code to Java. You can find this loop in the article under the title "Constant Game Speed with Maximum FPS").
My problem is, I don't fully understand it. I read it's description in the article, and understood that this game-loop might be the best for my game, but didn't understand fully how it works.
I would appreciate if someone explained this game-loop to me, so I would fully understand it before trying to implement it in my game.
(EDIT: I understand the concept of a game-loop and how it works, but not this game loop specifically and everything it does).
Thank you for your help
The game loop you found is actually way outdated. You might want to search for a more up-to-date tutorial. For your game try the following:
First define the game loop:
class GameLoop extends Runnable {
public void run() {
updateGame();
repaint();
}
}
And call it like this:
static final long TARGET_FPS = 60;
static final long TICK_RATE = 1000 / TARGET_FPS;
// ... in main:
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new GameLoop(), TICK_RATE, TimeUnit.MILLISECONDS);
Your GameLoop will now be called about as often as requested, while not wasting CPU time on waiting, you can find more information why in the documentation of scheduleAtFixedRate.
If you use the proper Java classes, coding usually becomes much easier.
As a side note: there is no need to update the game if the update is not then drawn to the screen. You should try to code your calculations to not require intermediate steps, because that's just a waste of CPU time.
next_game_tick stores the moment at which the next game tick is suppose to happen.
You have two different times. The real time that you can get with System.currentTimeMillis(), and the game time which is equal to SKIP_TICKS times the number of iterations of your loop plus the time at which the game started.
In the loop the update method is called until the game time has caught up with the real time. Each call of update_game advances the "clock" of the game by SKIP_TICKS ms.
Right now I've programmed a method for use in a swing program that is supposed to slow down the speed the method it's called in is run (via thread.sleep(x) ) and instead of slowing down the speed of refresh it's just causing the whole program to hang and the screen to refresh at the end of the methods execution.
Here's my code:
public final void doBubbleSort(String numbers[], JButton numButton[]){
for (int k = 0; k < numbers.length - 1; k++){
String str1 = "";
boolean isSorted = true;
for (int i = 1; i < numbers.length - k; i++){
if (Integer.parseInt(numbers[i]) < Integer.parseInt(numbers[i - 1]) ){
try{
String tempVariable = numbers[i];
numbers[i] = numbers[i - 1];
numbers[i - 1] = tempVariable;
isSorted = false;
str1 = numButton[i].getText();
numButton[i].setText(numButton[i-1].getText());
Thread.sleep(100);
}catch(Exception e){ System.err.println("Error: " +e.getMessage()); }
numButton[i-1].setText(str1);
}
}
if (isSorted)
break;
}
}
If anyone can tell me where I should be putting thread.sleep() to make it delay the display of items being swapped I would be greatly appreciate it.
Thanks!
You should never sleep in the event dispatch thread.
Create a model, (in your case a list)
Create a view (your swing gui)
Make sure the view gets updated once the model changes (by adding a listener for instance)
Create a separate thread that updates the model regularly (using Thread.sleep if you so like)
When changing "speed" change the sleep times for the updater-thread
You may want to have a look at the Timer class (which provides a nicer interface for doing things at a regular interval) or the Swing Workers.
You cannot do animation by putting a loop in an event handler like this. You must do it by using a separate thread, either explicitly or by using the javax.swing.Timer class. If you loop and sleep on the event thread, as you're doing, then during the entire time the loop is running, the event thread is unavailable to perform its other duties, like painting the screen.
See this article for information about using the Swing timer class.