How to create a single thread cooldown - java

I'm finding the way to make a Single thread cooldown but get stuck.
In the class who manages the cooldown I created a:
private HashMap<UUID,Integer> players = new HashMap<>();
//UUID = Player UUID
//Integer = Time in cooldown (Seconds)
public void run(){
for(UUID player : players){
//WHAT I NEED TO DO HERE?
if(//Time == 0){
players.remove(player);
}
}
}
Didn't use an IDE hopefully I didn't miss an error that eclipse would have picked up.
But how I can get the integer and save it with a second less?

TimeUnit is used for delaying a process, as it could be used as followed:
TimeUnit.SECONDS.sleep(1);
This will delay the current thread by one second.
I won't suggest using it, because your situation sounds more like a thread is working in the background and you want to wait till it has finished! Therefore use the new feature isAlive, which could be used in a (while) loop.
Edit
If you do want to delay a thread from another thread over the instance, then I'd suggest using the sleep method.
Example:
myThread.sleep(1000);
This will delay myThread by one second.
Edit #2
To change a value for a certain key of a HashMap, use the put and get method.
Example:
// Get the time of a player and subtract it by one
Integer value = players.get(player) - 1;
// Update the value
players.put(player, value);
// If the time runs out, than delete the player
if (value == 0){
players.remove(player);
}

Related

How to delay a method's repeated execution?

I'm new to java and I'm trying to constantly add "zombie" entity to my game after a delay, and then shortening the delay as time goes on.
In my PlayState class I've got the code to spawn the entities in a position when my update(); method is run (which houses getInput(); and such. Not shown for clarity.)
public void update(long elapsed) {
this.entities.add(new Zombie(-535));
}
How would i make a delay that shortens? I'm guessing I would make the delay and then use a multiplier which i have getting smaller every 10 seconds or so, but how would I do this?
Now, I don't know much about the finer workings of your class, but this might give you a general idea of what I mean:
int counter = 50;
for(int i = 100; i >= 0; i--)
{
if(i == counter)
{
counter = counter / 2;
this.entities.add(new Zombie(-535));
}
}
Suppose i is the the total run-time of the game, and counter represents a percent of the game when you want to add a zombie.
If you want to add a zombie after 50% of the run-time (here, 100 seconds), then as the time reduces, you check if the time has come to add a zombie (Here, 50 seconds).
What I've done here is reduce the delay to half, and continue checking if the time has come to add a zombie.
Maybe you could call sleep on your thread of execution:
int sleepInMs = 5000
Thread.sleep(sleepInMs);
sleepInMs+=1000; //Then of course handle the case when sleepInMs == 0
Really need more information about your implementation.
For a simple delay, use "delay ms;"
Edit ms for the number of milliseconds you want. 1000 milliseconds is one second

Java - add time delay to a cycle flow

I need to add time delay between cycle flow like this:
public boolean timeDelay(int seconds) {
// 1000000000 ns = 1 s
if (/* some system method to start calculate time in seconds*/ == seconds) {
return true;
} else {
return false;
}
}
public void renderEnemies() {
for (int w = 0; w < wave.size(); w++) {
while(timeDelay(2)){
(wave.get(w)).render();
}
}
}
Maybe my thinking isn't good, but I need to do like this...
wave --> ArrayList of enemies in my game
Render enemies is in game loop after pressing button "NextWave" and I need to spawn them with delay between them like a --> 2s * 2s * 2s * 2s * 2s *
where * is enemy...
Can you help me?
Try:
Thread.sleep(1000);
and use a try-catch.
You should probably thread it and use sleep as #curiosu mentions.
However, if you don't want to use sleeps/multiple threads but do want it to be pseudo real time (not turn based) you'll need a driving loop at the top of your game like so:
boolean keepPlaying = true;
while(keepPlaying) {
doNpcStep()
doPlayerStep()
keepPlaying = !isGameOver()
}
Each of these steps needs to run in a very small time slice, then in the doNpcStep function you get the current time, find the offset from a start time and run any action that should happen by now.
You could, for example, do this by keeping a min priority queue where priority is equal to the time they should execute by (in ms since start of java epoch). Then take all elements off the queue that are less than or equal to current time and run them, placing new occurrences onto the queue as necessary.
In essence this is a simulation of running a player and npc thread, where you are in charge of how much time each gets to run for.
try putting an infinite while loop
while(1)
{
if(/*method to calc time*/ == seconds)
return true;
}
return false;
I'm assuming that you want to start spawning enemies after 'seconds' time, so always a 'true' should be returned after 'seconds' time has passed. Your method should keep track from what time it has to start counting the seconds. You can call that function when 'NextWave' button is pressed where a variable can increment itself in multiples of 'seconds' so that you can keep track of elapsed time.
Hope this helps.

Making just one part of the class wait for execution, with or without threads?

I am coding a space invaders clone, I need the invaders to do their usual movement but pause for one second before moving again.
EG. Move 5 pixels, then wait, then move another 5 pixels.
The method called moveInvaders() is the method I want to make wait for 1000ms. Below is that such method.
private void moveInvaders() {
if(direction == "right") {
if(invaderGreenEight.getX() == 455 || invaderRedEight.getX() == 455 || invaderBlueEight.getX() == 455) {
direction = "left"; // Change direction to left
}
} else {
if(invaderGreenOne.getX() == 15 || invaderRedOne.getX() == 15 || invaderBlueOne.getX() == 15) {
direction = "right"; // Change direction to right
}
}
if(direction == "right") {
// Move Green Invaders Right
invaderGreenOne.moveX(1);
invaderGreenTwo.moveX(1);
invaderGreenThree.moveX(1);
invaderGreenFour.moveX(1);
invaderGreenFive.moveX(1);
invaderGreenSix.moveX(1);
invaderGreenSeven.moveX(1);
invaderGreenEight.moveX(1);
// Move Red Invaders Right
invaderRedOne.moveX(1);
invaderRedTwo.moveX(1);
invaderRedThree.moveX(1);
invaderRedFour.moveX(1);
invaderRedFive.moveX(1);
invaderRedSix.moveX(1);
invaderRedSeven.moveX(1);
invaderRedEight.moveX(1);
// Move Blue Invaders Right
invaderBlueOne.moveX(1);
invaderBlueTwo.moveX(1);
invaderBlueThree.moveX(1);
invaderBlueFour.moveX(1);
invaderBlueFive.moveX(1);
invaderBlueSix.moveX(1);
invaderBlueSeven.moveX(1);
invaderBlueEight.moveX(1);
}
if(direction == "left") {
// Move Green Invaders Left
invaderGreenOne.moveX(-1);
invaderGreenTwo.moveX(-1);
invaderGreenThree.moveX(-1);
invaderGreenFour.moveX(-1);
invaderGreenFive.moveX(-1);
invaderGreenSix.moveX(-1);
invaderGreenSeven.moveX(-1);
invaderGreenEight.moveX(-1);
// Move Red Invaders Right
invaderRedOne.moveX(-1);
invaderRedTwo.moveX(-1);
invaderRedThree.moveX(-1);
invaderRedFour.moveX(-1);
invaderRedFive.moveX(-1);
invaderRedSix.moveX(-1);
invaderRedSeven.moveX(-1);
invaderRedEight.moveX(-1);
// Move Blue Invaders Right
invaderBlueOne.moveX(-1);
invaderBlueTwo.moveX(-1);
invaderBlueThree.moveX(-1);
invaderBlueFour.moveX(-1);
invaderBlueFive.moveX(-1);
invaderBlueSix.moveX(-1);
invaderBlueSeven.moveX(-1);
invaderBlueEight.moveX(-1);
}
}
The game is already a thread and the method in question is in the same class so issuing Thread.sleep(1000); just pauses the entire game for 1 second, but I just want the execution of one method to pause.
If you want more information I am more than happy to provide it.
GeissT
The moveInvaders() method should keep track of a member variable which stores the time the invaders were last moved (e.g. as a long number of milliseconds), this way, any time it is called it can check the value of that variable - if enough time has elapsed then the invaders can move, if not, then the method will simply return without doing anything. For example:
protected long invadersLastMovedMillis;
protected void moveInvaders() {
long currentTime = System.currentTimeMillis();
if ((invadersLastMovedMillis != 0)
&& ((currentTime - invadersLastMovedMillis) < 1000L)) {
return; // No need to move them yet.
}
// March on, space invaders!
invadersLastMovedMillis = currentTime;
}
You don't want to actually cause the thread to sleep because the game will then become unresponsive!
I'm guessing that you would use a Timer of some sort, but what sort will depend on many issues not yet known to us. What GUI library are you using?
For example, if this were a Swing GUI, I'd suggest using a Swing Timer for this delay -- but again, we've no idea what libraries your using.
Bottom line: Please provide more information and code.
Edit:
First suggestion: Get rid of all if (myString == "Foo"). You shouldn't compare Strings that way since this checks if one String object is one and the same as another, and you don't care about this. You want to know if they have the same content. Instead use the String#equals(...) or String#equalsIgnoreCase(...) methods.
Next: use arrays to reduce the severe code redundancy present.
Finally for a Swing app, consider using a Swing Timer to drive your game loop, and in the timer notify items listening to it of time ticks. Then have the items only respond after a certain amount of time has elapsed since their last action.
Create another thread (say T1) at the same level where you create game thread.
Start it after game thread is fully created OR when moveInvaders() method can be called without any crash.
ASA game thread ends, stop T1 also.
The game is already a thread and the method in question is in the same class so issuing Thread.sleep(1000);just pauses the entire game for 1 second, but I just want the execution of one method to pause.
The problem is there is one class, one object and only one thread to execute. It should be one class, one object and two thread. (Game Thread and T1)

Android Thread stop randomly in the middle of process

As the question says, here's the code.
What I want to do basically is I have a list of array, says "myArray". This array contains stored time points in millisecond. Next thing is I want to call a method based on those time points. So, I need to run a time counter from 0 while the music is playing, compare the time counter with the time points in the array progressively (from first array index until finished).
The first method "timeCounter" is a method to start a time counter while a music is playing through MediaPlayer.
public void timeCounter(){
Runnable myRunnable = new Runnable(){
#Override
public void run(){
while(musicPlaying){
startCounter(arrayPos);
}
}
};
Thread musicPlayer = new Thread(myRunnable);
musicPlayer.start();
}
This is where the comparison of time counter and time in the array takes place.
public void startCounter(List<Long> array){
elapsedTime = System.currentTimeMillis() - timeStart;
if(elapsedTime == array.get(arrayPos)){
arrayPos += 1; //Continue comparing with the next number in the array
Log.v("DEBUG", "TIME MATCHES!");
if(arrayPos>= array.size()){
arrayPos= 0; //Prevent out of array index
}
}
}
I have the code running correctly and the result from the LogCat is correct.
Now the problem is sometimes the Thread is not running until the music finished playing (I have set onCompletionListener and set "musicPlaying" to false when music finished). The stopping point is totally random, sometimes when it's just started, or around 50%, or even when it's near to completion. Sometimes it doesn't even start!
I've been trying to figure out why but I couldn't find any info about Thread stopping halfway or such in anywhere. Thanks in advance! =)
If musicPlaying is modified and read between threads, make sure it is declared volatile.
I suspect your if(elapsedTime == array.get(arrayPos)) should be if(elapsedTime >= array.get(arrayPos)).
You need to remember that the millisecond timer does not necessarily have a one millisecond tick. On Windows, for example, the returned value will only change every 15 ms or so. You may therefore completely miss a particular time and therefore never get past that entry in your list.

Problem related to variable persistence between threads in java

all. A thread in a Java program I am working on animates a random walk in space (or at least, it will once this problem is resolved). It contains the following two methods:
public void run() {
while(gw.checkBoundingBox()) {
if(!gw.pause) step();
}
}
public void step() {
Point3d p1, p2;
//get the last point, step, get the new point
p1 = new Point3d(gw.position);
gw.randomStep();
p2 = new Point3d(gw.position);
//create the Alpha that will do the animation, and wrap it in an AlphaControl,
//which will set this object's pause flag until the Alpha finishes
Alpha alpha = new Alpha();
alpha.setLoopCount(1);
if(alpha.finished()) System.out.println("DEBUG: I'm already dead.");
AlphaControl ac = new AlphaControl(alpha,gw);
ac.start();
//create a piece of the path, attach an interpolator to do the animation
PathCyl cyl = new PathCyl(p1,p2);
StretchInterpolator si = new StretchInterpolator(alpha, cyl.anchor);
si.setSchedulingBounds(new BoundingSphere(new Point3d(0,0,0),50));
cyl.anchor.addChild(si);
//put it all together
BranchGroup b = new BranchGroup();
b.addChild(cyl.tg);
trans.addChild(b);
}
So if the pause flag is not set, it runs step(). The only part of step() that you need to look at is the few lines about the Alpha object. (Alpha is an API class that produces a time-dependent function used for animating). So step() creates an Alpha object, which it then feeds to another thread called AlphaControl. AlphaControl tells the program to stop calculating points until this step is done animating. It does this by setting the pause flag that is checked in the run() method.
So what's the problem? Note that I added a debug line that immediately checks if the Alpha is finished after it is created. It seems like this line of code should never execute. Is the Alpha finished? Of course not, we just created it. But this line executes every time that the function is called AFTER the first time. Somehow it is hanging onto the same Alpha instance and using it over and over. I assume that this is because of the reference to the Alpha that is still alive in the AlphaControl thread.
So how do I fix this? I have tried several things. I created a huge array of Alphas, initialized them all before the walk even started, and tried to tell it to use a different alpha from the array at every step, but this had the same result. I also tried using the AlphaControl to set alpha to null before it closes, but this didn't work either. Is it possible to destroy this object? By the time the step() code gets back to running again, the AlphaControl that was created the first time around should be done and waiting for garbage collection.
Also, just in case it would be helpful to see it, here is the AlphaControl class.
public class AlphaControl extends Thread {
public Alpha alpha;
public GraphicalWalker gw;
public AlphaControl(GraphicalWalker gw, Alpha alpha) {
this.gw = gw;
this.alpha = alpha;
}
public void run() {
boolean stop = false;
boolean finished;
while(!stop) {
finished = alpha.finished();
if( !finished && !gw.pause ) gw.pause = true;
if( finished && gw.pause ) gw.pause = false;
if(finished) stop = true;
}
}
}
Thanks in advance for any help.
Jeff
I think key to understanding why your code fails is understanding what the Alpha class of the Java3D library does.
From your question it seems to me you do not understand it correctly. It does not loop. If you check the source code (http://www.java2s.com/Open-Source/Java/6.0-JDK-Modules/java-3d/javax/media/j3d/Alpha.java.htm) you will see it does not contain a single loop structure. What it does do, is define a function that maps a time value to a value in the range [0,1].
If you look at the source of the finished() method :
/**
* Query to test if this alpha object is past its activity window,
* that is, if it has finished looping.
* #return true if no longer looping, false otherwise
*/
public boolean finished() {
long currentTime = paused ? pauseTime : J3dClock.currentTimeMillis();
return ((loopCount != -1) &&
((float)(currentTime - startTime) * .001f > stopTime));
}
you notice that its value depends on when it is called.
And since you basically defined your alpha to have 1 loop of 1 millisecond, starting from the time of creation it will not be finished for 1 millisecond after you create that alpha, and finished ever after.
I hope this helps.
I'm not sure if I completely follow the intent of the program, but it seems like you have a race condition. When you call ac.start() on your AlphaControl object, there is no guarantee that gw.pause will be set prior to the next round of your loop executing. In fact, there's a fair chance that the loop will execute many times prior to gw.pause getting set.
Just for kicks, I suggest calling ac.run() instead of ac.start() on a run-through, as a shortcut to take threading out of the picture. If the intended behavior occurs, then I would look hard at your reason for doing this in multiple threads instead of a single one.
I think the problem is one of two issues:
Alpha's state is kept as a static variable, meaning that it's the same for all instances of Alpha, and you're likely not resetting it in the constructor (rightfully so).
Some part of your state isn't marked volatile, which breaks the semantics the compiler relies on to know that a marked field will always require a fresh value lookup (otherwise the compiler is free to cache the value)

Categories