Java Timer For Game for food system - java

I need a java timer to recognize when it hits a certain time for the game I am making. I am new to timers and I was wondering if this code works somehow. I need the if statement to work.
Timer timer = new Timer(whatevergoeshere,this);
public void farmingTimer()
{
timer.start();
if(timer == 1000)
{
food++;
timer.restart();
timer.start();
{
}

I found a good example page.
But I don't think you should be using timers for this kind of thing. You are probably better off updating things as often as you can, and keeping track of the time between updates. Then in the object that has then timer in, can just keep track of the amount of time passed.
public class FoodTimer
{
public int food = 0;
private double timer = 0;
public void update(double dt)
{
timer += dt;
if(timer > 1000)
{
food++;
timer = 0;
}
}
}

I suggest you read this: How to setup a timer (Java 7).
What you basically want to do is create an instance of the class Timer eg:
Timer timer = new Timer();
In your question above, your constructor call used two parameters. If you read the docs, you will find out those two parameters accept a string (name) and a boolean (isDaemon) eg
Timer(String name, boolean isDaemon)
If you want to learn more about daemon threads, I suggest you read this article: Daemon Threads in Java.
Now, once you have your instance ready, do this:
timer.scheduleAtFixedRate(new TimerTask() { //scheduleAtFixedRate means execution will repeat
#Override
public void run() {
//your code here eg food++;
}
}, 0, 60*1000); // the two values at the end are delay and period - delay is 0 seconds and period states that the block will be executed every minute (both values are in milliseconds)

Related

Start objects faster and update Textview faster

I want to create multiple timers.
I initialize this in an ArrayList in the MainActivity. These are then added in a ReyclerView so that they are also displayed. To start, I go through a for loop and execute the startTimer () method for each individual object.
Unfortunately, the times are not correct for every timer. That means one timer is faster, the second is slower and so on. So each timer starts at different times or the text changes at different times.
My question now is, are there other approaches to start the timers and change the texts in the TextView so that the GUI is updated faster and the program itself runs faster?
The goal should be that all timers are equally fast and there is no delay. Thanks in advance. Looking forward to answer!
MainActivity
timerList= new ArrayList<>();
for (int i = 1; i <= 10; i++) {
timerList.add(new Timer(i, 600000 * i))); //
Each timer has a different time
}
recyclerView.setLayoutManager(recyclerViewLayoutManager);
adapter = new TimerAdapter(this, timerList);
recyclerView.setAdapter(adapter);
context = this;
button_start.setOnClickListener(v -> {
for (Timer timer: timerList) {
timer.startTimer();
});
#Override
public void updateMyText(int index, long time) {
timerList.get(index-1).setTime(time);
adapter.notifyDataSetChanged();
}
Timer
public interface MyCallback {
public void updateMyText(int index, long time);
}
public Timer(int index, long startTimeMilliseconds) {
this.index = index;
this.time = startTimeMilliseconds;
mTimeLeftInMillis = startTimeMilliseconds;
startTime = startTimeMilliseconds;
}
public void startTimer() {
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
}
}.start();
mTimerRunning = true;
}
public void resetTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
mTimeLeftInMillis = startTime;
timeLeftFormatted = formattedTime(startTime);
changeText(index-1);
}
public void updateCountDownText() {
//MainActivity.timerList.get(getIndex()-1).setTime(mTimeLeftInMillis);
//MainActivity.adapter.notifyDataSetChanged();
if(myCallback != null) {
myCallback.updateMyText(getIndex(), mTimeLeftInMillis);
}
}
Use Live Data and Binding or MVVM design pattern. You don't have to worry about faster update operation of views.
The reason the code you wrote works slowly (and time isnt updated on all views together), is because you are creating a separate CountDownTimer for each of your timers.
You dont have to do that. All you need to do is have a single CountDownTimer, that runs every second and updates all of your views simultaneously.
Make Timer class only store the start time of the timer, and a string with the time it should show, dont create a CountDownTimer inside it.
Instead create a method inside it - "updateTimer()" for updating the string, based on
the current time and the start time of the counter.
Using a single CountDownTimer in your Activity, loop through the list of timers and call updateTimer() on each of your timers, and call adapter.notifyDataSetChanged() when the loop is done.
This will make all your views update together, remove the inefficiency of using multiple CountDownTimers, and only call adapter.notifyDataSetChanged() once every second (as opposed to the amount of timers you have - every second)
i think the main issue is the sequential executing of instructions, and adding Threads concept may resolve the issue ,what i think is Threads and Multi threading will allow timers to start at the same time and any updates or other instructions of code execution will not effect the already running code .
Multi threading refers to two or more tasks executing concurrently within a single program. Tutorial
now To start the threads at exactly the same time (at least as good as possible),we can use a CyclicBarrier:
// We want to start just 10 threads at the same time, but let's control that
// timing from the button_start click thread. That's why we have 11 "parties" instead
//of 10.
final CyclicBarrier gate = new CyclicBarrier(11);
button_start.setOnClickListener(v - > {
for (Timer timer: timerList) {
new Thread() {
public void run() {
gate.await(); // waiting for the gate to open
timer.startTimer();
}
// At this point, all the 10 timers are blocked on the gate.
// Since we gave "11" as the argument, gate is not opened yet.
// Now if we block on the gate from the main thread, it will open
// and all threads will start to do stuff!
gate.await(); // this is the extra 11th which will open the gate
};
This still can't make sure that they are started exactly at the same time on standard JVMs, but you can get pretty close.
replicate the same solution if it works , for the update part

Restart Runnable Variables Android

I want to do something that i am not sure can be done, and so far i haven't found any good answers to my question.
Here is my situation:
- I have implemented Timer as a Handler that has Runnable that is calling itself every 1s.
- I need now to implement a method like Timer.restart() that can restart my Runnable's params.
Here is my code so you can see it, and better understand what i have tried to achieve
private Runnable rStartCPRTick = new Runnable() {
public int seconds = 0;
public int minutes = 0;
public int hours = 0;
#Override
public void run() {
if(++seconds%60 == 0) //increases the time by one second
if(++minutes%60 == 0)
hours++;
mActivity.updateCPRTime(formatHHMMSS(hours,minutes,seconds));
mStartCodeHandler.postDelayed(this,1000); // tick again in 1s
}
public void restartCPRTick(){
seconds = 0;
minutes = 0;
hours = 0;
}
};
My runnable, i want to be able to call resetCPRTick() from outside Runnable and then call run that starts from the beggining.
Is such thing possible?
Thanks!!
Your runnable is a class. You can add any methods to it you want. Just keep a reference to it around and call a method that does it (to do this you probably want to make it a inner class rather than an annonymous class).

How to create a Java function which Once called, cannot be called Again unless there is some DELAY?

I'm trying to make a function which can ONLY be called again after there is some amount of time delay between the two calls, (Say 5 seconds).
I require this functionality for an android app I'm creating.
Since it is possible that the user would be calling that function too frequently within a few seconds, it would destroy his experience. Hence, I'm desperately looking for an answer on this.
public void doSomethin(){
//code here which makes sure that this function has not been called twice within the specified delay of 5 seconds
//Some code here
}
Any help would be awesome!
Adit
You could hold the time in milliseconds and check if the current time is greater than or equal to the previous time + 5 seconds. If it is, execute the method and replace the previous time with the current time.
See System.currentTimeMillis()
public class FiveSeconds {
private static Scanner scanner = new Scanner(System.in);
private static long lastTime = 0;
public static void main(String[] args) {
String input = scanner.nextLine();
while(!input.equalsIgnoreCase("quit")){
if(isValidAction()){
System.out.println(input);
lastTime = System.currentTimeMillis();
} else {
System.out.println("You are not allowed to do this yet");
}
input = scanner.nextLine();
}
}
private static boolean isValidAction(){
return(System.currentTimeMillis() > (lastTime + 5000));
}
}
If the code runs on your main thread, Thread.sleep(5000) is not an option. The easiest way to go then would be:
private long previous = 0;
public void doSomething() {
long now = Calendar.getInstance().getTimeInMillis();
if (now - previous < 5000)
return;
previous = now;
// do something
}
use a static field, which saves the datetime of last execution and before executing check the current datetime against this timestamp.
I won't write code for you but if you think a bit about this it's not that hard. You want to make sure it's not called before 5 seconds has passed since last function call. Let's split this into parts.
1) Get current time
2) Compare to stored time that keeps it value between calls.
3) If less than 5 seconds has passed don't do anything
4) Otherwise store the new value and do stuff.
I never did coding in Android. But if Android has threads (which is most likely, it does). Then within this function sleep the thread for 5 seconds, it means even though it is called, it won't be executed further until 5 seconds are passed
public void doSomething()
{
Thread.sleep(5000); // Please find the corresponding Android method
}
make doSomethin() as a private method.
Expose another function say exposedDoSomething().
public void exposeDoSomething(){
// Add to a queue
}
In a separate thread read the queue in every 5 mins and call doSomethin()
Maybe a TimerTask will help you, more details here:
TimerTask|Android Developers
Example:
private TimerTask tiemrTast= new TimerTask() {
#Override
public void run() {
}
};
And then use this method: public void scheduleAtFixedRate (TimerTask task, long delay, long period)
One problem is that you'll have to have a session level timer for each and every user. This could be a fair amount of overhead depending on how many simultaneous users you have.
It's easy for one user: start a timer on request. It's distinguishing between users that's the problem. Your service is now stateful, which is usually a bad thing. You're giving away idempotence.
You could also maintain state in a database. Don't worry about calls; check persistent operations to make sure they don't happen too frequently.
It's not clear to me whether you mean to exclude all users for five seconds once the method is called by anyone, or if every user is prevented from calling the method again for five seconds once it's called the first time.
This sounds like a throughput killer. I'd reconsider this design.
you can use hander.postDalayed method to call method to run after specific delay
you can use your method something like this
int delay=5000;
int k;
int iDelayTimeInMiliSeconds=2000;
for( k=0;k<arrBatch.size();k++)
{
delay=delay+iDelayTimeInMiliSeconds;
callAllDocumentList(arrBatch.get(k),k,delay);
}
public void callAllDocumentList(final String strInvoiceId,final int count,int delay)
{
mHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
// call your function here that you want to call after specific delay
//getOrderDetails(strInvoiceId,count,true);
}
}, delay);
}

How to call a method after some specific interval of time in Java

Here is the use case:
I am using Java (with Spring)
Once the user (through a web-app) confirms to the subscription, I want to send him an email exactly after 30 mins.
Now how to do this? Do I need a message broker? or something like ScheduledExecutorService?
Do I need some sort of queue?
Please advise.
Can look into quartz scheduler for this.
By the way a common strategy is to send a bulk of all pending mails in bulk in every 30 minutes or so. Quartz can help in do that as well.
You can use the Quartz Scheduler. Its fairly easy to use. You can schedule something every week or ever 30 minutes or whatever you want basically.
Create an object for Timer
private Timer myTimer;
in main method
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
//your method
}
}, 0, 200);
It is not that the thread will die after sending the mail. When you configure Quartz, a new thread will automatically be created and will execute the assigned task on specified interval. Or else you use Timer class also. It is very easy to use.
Timer timer = new Timer(); // Get timer
long delay = 30 * 60 * 1000; // 3o min delay
// Schedule the two timers to run with different delays.
timer.schedule(new MyTask(), 0, delay);
...................
class MyTask extends TimerTask {
public void run() {
// business logic
// send mail here
}
}

Decrement at Regular Intervals in Java

I'm writing an application in Java, but need to know how to subtract from a variable once every second. What's the easiest way to do this? Thanks!
The name of the very Java class you need to use to do repeating operations is already sitting there in one of your tags! ;)
While the Timer class will work, I recommend using a ScheduledExecutorService instead.
While their usage is extremely similar, ScheduledExecutorService is newer, more likely to receive ongoing maintenance, fits in nicely with other concurrent utilities, and might offer better performance.
class YourTimer extends TimerTask
{
public volatile int sharedVar = INITIAL_VALUE;
public void run()
{
--sharedVar;
}
public static void main(String[] args)
{
Timer timer = new Timer();
timer.schedule(new YourTimer(), 0, 1000);
// second parameter is initial delay, third is period of execution in msec
}
}
Remeber that Timer class is not guaranteed to be real-time (as almost everything in Java..)
What are you trying to achieve? I would not try relying on the timer to properly fire exactly once per second. I would simply record the start time, and whenever a timer fires, recalculate what the value of the variable should be. Here's how I would do it...
class CountdownValue {
private long startTime;
private int startVal;
public CountdownValue(int startVal)
{
startTime = System.currentTimeMillis();
}
public int getValue()
{
return startVal - (int)((System.currentTimeMillis() - startTime)/1000);
}
}
Use a java.util.Timer to create a TimerTask.

Categories

Resources