Java Timing A Trigger - java

I want to trigger an action after a certain time, I've been googling how I would do this but I have had no luck I guess it's just the way my game is coded.
Anyways I need to make it to where 30 minutes after the code a1 is triggered, the code a2 is triggered.
a1:
if (itemId == 608) {
c.sendMessage("The scroll has brought you to the Revenants.");
c.sendMessage("They are very ghastly, powerful, undead creatures.");
c.sendMessage("If you defeat them, you may receive astounding treasures.");
c.sendMessage("If you donate you may visit the Revenants anytime without a scroll.");
c.getPA().movePlayer(3668, 3497, 0);
c.gfx0(398);
c.getItems().deleteItem(608, 1);
}
a2:
c.getPA().movePlayer(x, y, 0);

There are plenty of ways to do timers in Java but to introduce yourself to a nice framework check out http://quartz-scheduler.org/. Also Spring has quartz integration if you use it.
But more importantly if you are creating a game you will need a core technique of game programming called the event loop
This seems like a decent discussion of how to create a game architecture

Since this code uses Project Insanity, you should use the built-in scheduled event facility provided by server.event.EventManager.
Below is example code:
if (itemId == 608) {
c.sendMessage("The scroll has brought you to the Revenants.");
c.sendMessage("They are very ghastly, powerful, undead creatures.");
c.sendMessage("If you defeat them, you may receive astounding treasures.");
c.sendMessage("If you donate you may visit the Revenants anytime without a scroll.");
c.getPA().movePlayer(3668, 3497, 0);
c.gfx0(398);
c.getItems().deleteItem(608, 1);
/* only if the parameter Client c isn't declared final */
final Client client = c;
/* set these to the location you'd like to teleport to */
final int x = ...;
final int y = ...;
EventManager.getSingleton().addEvent(new Event() {
public void execute(final EventContainer container) {
client.getPA().movePlayer(x, y, 0);
}
}, 1800000); /* 30 min * 60 s/min * 1000 ms/s = 1800000 ms */
}

You can use Thread.sleep(), but it will freeze your application if you call it in your main thread, so, create another thread and put your code in it. Doing this you will not stop the main application.
Here is a simple example.
public class MyThread implements Runnable {
#Override
public void run() {
try {
System.out.println( "executing first part..." );
System.out.println( "Going to sleep ...zzzZZZ" );
// will sleep for at least 5 seconds (5000 miliseconds)
// 30 minutes are 1,800,000 miliseconds
Thread.sleep( 5000L );
System.out.println( "Waking up!" );
System.out.println( "executing second part..." );
} catch ( InterruptedException exc ) {
exc.printStackTrace();
}
}
public static void main( String[] args ) {
new Thread( new MyThread() ).start();
}
}
This will run just one time. To run several times, you will need an infinite loop that encloses the run method body (or a loop controled by a flag).
You have some other options like:
java.util.Timer
javax.swing.Timer

Related

(Spigot) How to await in java

I am making a minecraft mini game plugin, i need to make a loop that do the minigame, if the game is ended, stop it, but else continue, for making that i just created a boolean that is false and i put a :
while(isEnded) {
//my code
}
But in my code, there is async fuction, so it's repeat, but the async function don't have the time to finish before an other loop start, so all my game is glitched.
Any solution to await the async function ? ( i am using Bukkit.getServer().getScheduler().runTaskTimer(Main.plugin, new Runnable() { )
thanks for the help ;)
I don't really understand where you are stuck, but I will give you some way to do what you are looking for.
Run method from the end of mini-games.
For example, when the game when, you are running a method:
public void endGame() {
// do something
callMethod();
}
Use for another variable.
You can just set a variable, then run a task like that :
public static boolean isEnd = false;
public void runTask() {
Bukkit.getScheduler().runTaskTimer(myPlugin, () -> {
if(isEnd) {
// do something
}
}, 20, 20);
}
Finally, set the variable when it's fine with just MyClass.isEnd = true;
It will run each 20 ticks (so each second, because 20 ticks = 1 second).
If you know the time to wait, you can use the same scheduler as you are using and as I explain in #2 option.

Java do something in X minutes

I'm looking for a way to do something every X minutes.
For example in a game you will be playing then every 3 minutes activate
foo();
but I'm not sure how to do this given that other actions will be going on. Ie, we cannot just wait 3 minutes then do foo() instead the rest of the program must be running and the user can invoke other methods but in the background we have to be counting and getting ready to do foo() when the time is ready.
If anyone can give me a starting point I'd much appreciate it!
You want some manner of separate thread that has a timer in it. A built in structure is the ScheduledExecutorService.
A tutorial on how to use one can be found here
The tutorial is kind of confusing and ugly, so here it is summarized in three steps:
1) Define a thread executor (something that manages your threads)
int x = 1; // However many threads you want
ScheduledExecutorService someScheduler = Executors.newScheduledThreadPool(x);
2) Create a Runnable class, which contains whatever it is you want to do on a schedule.
public class RunnableClass implements Runnable {
public void run() {
// Do some logic here
}
}
3) Use the executor to run the Runnable class on whatever level of your program you want
Runnable someTask = new RunnableClass(); // From step 2 above
long timeDelay = 3; // You can specify 3 what
someScheduler.schedule(someTask , timeDelay, TimeUnit.MINUTES);
Use a Timer in a separate Thread!
https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
Bryan Davis pointed the solution, but the link provided is not very elegant. here is a short sample:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
// 3 = number of thread in the thread pool
scheduler.scheduleAtFixedRate(new Runnable()
{
public void run()
{
// do something here
}
}, 20, TimeUnit.SECONDS);
For a single threaded game, you can just check every loop whether it is time to do foo(). For example:
long lastTime;
long timeBetweenFoosInMillis = 3*60*1000; //3 minutes
public void loop(){
while(true){
doOtherGameStuff();
if(isFooTime()){
foo();
lastTime = System.currentTimeMillis();
}
}
}
private boolean isFooTime(){
return System.currentTimeMillis() >= lastTime + timeBetweenFoosInMillis;
}
You probably want to use Threads. You can put your foo() function in one and make it sleep and execute every X minutes, and put the rest of the program in other threads so your other functions can keep executing. Here is a good tutorial on how to set up a multi-thread program in java: http://www.oracle.com/technetwork/articles/java/fork-join-422606.html

How to force a while loop execute one runnable at a time.

I am trying to make a simple timer with uneven time intervals after each repetition.
I start as follows:
case R.id.start:
timerRuns = true;
startCycle();
break;
The cycle itself looks like this:
private void startCycle() {
pomodoroLeft = numPomodoro;
while(pomodoroLeft > 0) {
pomodoroLeft--;
actualSeconds = pomodoroLength * ONE_MINUTE;
setTimeAndRun(actualSeconds);
actualSeconds = shortLength * ONE_MINUTE;
setTimeAndRun(actualSeconds);
}
}
Method call:
private void setTimeAndRun(long timePeriod) {
runTime = timePeriod;
runnable.run();
}
And finally runnable itself:
private Runnable runnable = new Runnable()
{
public void run() {
if (timerRuns) {
runTime -= ONE_SECOND;
String str = String.format("%1$02d : %2$02d",
TimeUnit.MILLISECONDS.toMinutes(runTime),
TimeUnit.MILLISECONDS.toSeconds(runTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(runTime))
);
timeShown.setText(str);
mHandler.postDelayed(this, 1000);
if(timeShown.getText().toString().contentEquals("00 : 00")) {
stopClock();
//here goes the alarm.
}
}
}
};
My problem is that when I start the timer while loop seems to execute everything despite
incompliete run() of the previous method call. As a consequence timeShown TextView displays this actualSeconds = shortLength * ONE_MINUTE right away and skips 1 second each second because 2 runnables are running at the same time.
I want to achieve sequential execution here. What would be the best way to do so? Maybe implementing non-anonymous subclass and instantiate it every time would help?
Also, if you have any other suggestions that would improve my code I would greatly appreciate.
You should take a look at queues.
Here is a link to a similar question:
How to implement a queue of runnables
You should use the Executors.newSingleThreadExecutor()
http://developer.android.com/reference/java/util/concurrent/Executors.html#newSingleThreadExecutor%28java.util.concurrent.ThreadFactory
And here is a tutorial about the Executor:
http://tutorials.jenkov.com/java-util-concurrent/executorservice.html
here is also something that may help you understanding better multithreading in java:
Understanding multi-threading
hope this helps somehow.

How to do a do/while after some time?

I would like to do something like that:
#Override
protected String doInBackground(Object... params) {
int i = 0;
int max = Integer.MAX_VALUE;
GPSTracker gps = new GPSTracker(context);
do
{
//Something
} while(10 seconds);
return null;
}
How do put a count time in a while statemente. I would like to make this in 10 seconds.
If you're wanting to run a task periodically, use Timer#scheduleAtFixedRate.
To delay execution, you can sleep a thread:
Thread.sleep(timeInMills);
This line may throw a thread exception, and it should never be executed on the main UI thread, as it will cause the app to halt communication with Android, causing a ANR.
To run processes in the background of a single activity, you should spawn a new Thread.
new Thread(){
public void run(){
//Process Stuff
}
}.start();
If you would like to have this section of code run throughout the entire life of your application, including when it is hidden to the user, you should look into running a service for long lived tasks.
A handy alternative to
Thread.sleep(timeInMillis)
is
TimeUnit.SECONDS.sleep(10)
Then the units are more explicit and easier to reason about.
Note that both these methods throw InterruptedException, which you will have to deal with. You can learn more about that here. If, as is often the case, you don't want to use interrupts, and you don't want your code to be cluttered with try/catch blocks, Google Guava's Uninterruptibles can be handy:
Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);
You can use Thread.sleep(); (Not very clean).
Better use a Handler to do this.
Ex:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// You code here
}
}, 775); // Time in millis
I did it:
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// run
}
Thank you for all the answers.

How to call a method once per ms in Java

HI.
I want a function in java that automatically called.
for example wen we use Time class like blew
the actionperformerd() function call every 1second.
Timer time = new Time(10,this);
.
.
.
public void actionperformed()
{
timer.run;
//i want move a pic every 1millisecond.
}
my problem is that Timer class only accept int value and it's minimum
value is 1 second and i want call actionperformed every 1 millisecond.
Java Timer accepts milliseconds in parameters. So you can do
new Timer().schedule(new TimerTask() {
public void run() {
// do stuff
}
}, 1, 1);
But to have real-time functionality with milliseconds precision you may need to switch to C.
Try some classes from java.util.concurrent, and ScheduledThreadPoolExecutor can do the thing you want to do:
public static void main(String[] args) throws Exception {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.schedule(new Runnable() {
#Override
public void run() {
// Do something here.
}
}, 1, TimeUnit.MILLISECONDS);
}
BTW, the timer class can't run a job periodically accurately, it can only create one thread to run the task.
You could use a separate Thread
class MyThread extends Thread {
public void run() {
while (!interrupted()) {
try {
// move my object, then sleep for a millisecond
sleep(1);
} catch (InterruptedException e) {
}
}
}
}
However, in practice, you will rarely manage to have you move function called every 1 ms because other threads are also consuming processor time. So you need to take into account the actual time between the end of the previous thread loop and the current time.
I suggest you read lots of tutorials about "Game Loops", you'll learn how to organise the functions moving objects, rendering, ...
This one is an interesting article. Made for Android but can be applied to standard Java.
If this happens to be something graphical be aware that you actually update the screen in the EDT (event dispatch thread). The GUI is not multithreaded.
By hammering your EDT with updates in 1 ms intervals (even worse if you do this per pic) you might in effect make the GUI unusable - it is busy redrawing is stead of responding to user input.
I really don't know whether that effect occurs 1 ms intervals, but the single threaded design of the GUI is something to take into account.

Categories