Your question is not at all clear, but it sounds like you should be able to wrap System.currentTimeMillis() in an object that maintains a starting point and returns the offset. Something like
public class Millis
{
long start;
public Millis() { this.reset(); }
public void reset() { this.start = System.currentTimeMillis(); }
public long getMillis() { return System.currentTimeMillis() - start; }
}
You create an instance of this class at startup
Millis timer = new Millis();
then call reset() to set it back to zero at the beginning of each game. Everywhere in your code you currently have millis() you would have timer.getMillis()
Reset millis() - Processing Forum
programming - Resetting millis() and micros() - Arduino Stack Exchange
How do I make the timer stop and reset? - Processing 2.x and 3.x Forum
Time reset - Processing Forum
Videos
Your question is not at all clear, but it sounds like you should be able to wrap System.currentTimeMillis() in an object that maintains a starting point and returns the offset. Something like
public class Millis
{
long start;
public Millis() { this.reset(); }
public void reset() { this.start = System.currentTimeMillis(); }
public long getMillis() { return System.currentTimeMillis() - start; }
}
You create an instance of this class at startup
Millis timer = new Millis();
then call reset() to set it back to zero at the beginning of each game. Everywhere in your code you currently have millis() you would have timer.getMillis()
Use a custom timer class
class Timer {
int savedTime; // When Timer started
int totalTime; // How long Timer should last
Timer(int tempTotalTime) {
totalTime = tempTotalTime;
}
// Starting the timer
void start() {
// When the timer starts it stores the current time in milliseconds.
savedTime = millis();
}
// The function isFinished() returns true if 5,000 ms have passed.
// The work of the timer is farmed out to this method.
boolean isFinished() {
// Check how much time has passed
int passedTime = millis()- savedTime;
if (passedTime > totalTime) {
return true;
} else {
return false;
}
}
}//end class
Then to call
firstTimer = new Timer(50000);
And then in the draw to check
if (firstTimer.isFinished()) {
//do sopemthing
//then restart timer
firstTimer.start();
}
else
{
// do soemthing else for the rest of the time....
}
millis() and micros() overflow periodically. However, this is not a
problem: as long as you compare durations instead of
timestamps you can
forget about the overflows.
The liked answer also gives the trick for resetting millis(). Can be
handy for testing purposes, but you do not need this to handle the
millis() rollover problem. Notice that there is no clean way to reset
micros(): it relies on a static variable, i.e. a variable private to
the file defining it.
Overflow is never really an issue if you always calculate time difference. (Unless the time difference is more that 50 days.)
unsigned long previousTime = millis();
... wait for some event to happen ...
unsigned long elapsedTime = millis() - previousTime;
Even if previousTime was before the overflow, and millis() is after the overflow (so essentially millis()<previousTime), elapsedTime will still be the correct value.
This is because the calculation itself will also overflow. Since millis()<previousTime, the result would be negative, but the type of the variable is unsigned, so it wraps around. I hope that makes sense.
Just don't ever do something like if( millis() > (previousTime+1000) )
If you still want to reset millis, you can use the following:
extern volatile unsigned long timer0_millis;
unsigned long new_value = 0;
void setup(){
//Setup stuff
}
void loop(){
//Do stuff
//--------
//Change Millis
setMillis(new_value);
}
void setMillis(unsigned long new_millis){
uint8_t oldSREG = SREG;
cli();
timer0_millis = new_millis;
SREG = oldSREG;
}
I'm working on a game in Processing and facing an issue where millis() is not resetting as expected in my rolling() method within the Player class. The method is triggered by pressing the down arrow, and it's supposed to reset the rolling timer. However, the values of roll and rollingTimer are not updating correctly. The stamina += 3 line in the same method works fine, indicating that the method is executing. I've added println statements for debugging, which suggest the issue is around the millis() reset. Below are the relevant classes of my code
class King extends Character{ float sideBlock; float attackBuffer; boolean miss; float attackTimerEnd; float elementBlock; float deathTimer; float animationTimer; float blockTimer; float missTimer;
King(PVector pos, int health, float attackTimer, int damage){
super(pos, health, attackTimer, damage);
sideBlock = 0;
MAX_HEALTH = 10;
attackTimer = millis();
attackBuffer = -1;
miss = false;
attackTimerEnd = 10000;
deathTimer = -1;;
activeKingImg = kingDefault;
blockTimer = -1;
missTimer = -1;
}
void drawMe(){
pushMatrix();
translate(pos.x, pos.y);
scale(3,3);
if (activeKingImg != null) {
image(activeKingImg, 0, 0);
}
popMatrix();
}
void death(){
attackTimer = millis();
knight.health = 10;
gameState = LEVEL_TWO;
}
void drawDeath(){
activeKingImg = kingDeathAnimation;
}
void attackingAnimation(){
activeKingImg = kingAttack;
animationTimer = millis();
}
void displayMiss(){
if (millis() - missTimer < 500){
translate(pos.x + 50, pos.y-100);
strokeWeight(1);
fill(0);
textSize(20);
text("Miss!", width/4, width/3);
}
}
void displayBlocked(){
if (millis() - blockTimer < 500){
pushMatrix();
translate(pos.x + 50, pos.y-100);
strokeWeight(1);
fill(0);
textSize(50);
text("Blocked!", width/4, width/3);
popMatrix();
}
}
void nullifyLeft(){
if (sideBlock < 1 && health >= 0 && millis() - animationTimer > 1100){
pushMatrix();
translate(pos.x,pos.y);
activeKingImg = kingLeftBlock;
popMatrix();
}
}
void nullifyRight(){
if (sideBlock >= 1 && health >= 0 && millis() - animationTimer > 1100){
pushMatrix();
translate(pos.x,pos.y);
activeKingImg = kingRightBlock;
popMatrix();
}
}
void autoAttack(){
if(health >= 0){
if (millis() - attackTimer >= attackTimerEnd) {
attackTimer = millis();
attackBuffer = millis();
}
if (attackBuffer >= 0 && millis() - attackBuffer <= 1000) {
if (millis() - knight.roll <= 500) {
println("missing");
miss = true;
missTimer = millis();
}
attackingAnimation();
}
if (attackBuffer >= 0 && millis() - attackBuffer >= 1000) {
println(miss);
if (miss == false) {
hit(knight,1);
activeKingImg = kingAttackFinish;
animationTimer = millis();
println(knight.health);
knight.clearCombos();
}
miss = false;
println(knight.health);
attackBuffer = -1;
}
}
}
void drawDamage(){
activeKingImg = kingTakeDamage;
animationTimer = millis();
}
void update(){
super.update();
if (health <= 0){
drawDeath();
if (deathTimer <= -1){
deathTimer = millis();
}
if (deathTimer >= 1000){
death();
}
}
if (millis() - animationTimer < 1000) {
return;
}
nullifyLeft();
nullifyRight();
nullify();
autoAttack();
displayBlocked();
displayMiss();
}
void drawHealthBar(){
super.drawHealthBar();
}
void nullify(){
if (knight.combos.size() >= 1){
if (sideBlock < 1 && knight.combos.get(0) == 1){
nullify = true;
}else if (sideBlock >= 1 && knight.combos.get(0) == 2){
nullify = true;
}
}
}
}
class Player extends Character{
boolean prep, dodge;
float roll;
int stamina;
float preppingTimer;
float rollingTimer;
float animationResetTimer;
float staminaTimer;
ArrayList<Integer> combos = new ArrayList<Integer>();
Player(PVector pos, int health, float attackTimer, int damage){
super(pos, health, attackTimer, damage);
prep = false;
dodge = false;
roll = millis();
attackTimer = millis();
stamina = 6;
preppingTimer = -1;
rollingTimer = -1;
MAX_HEALTH = 10;
activeFrames = defaultSword;
animationResetTimer = millis();
staminaTimer = -1;
}
void updateFrame() {
super.updateFrame();
}
void clearCombos(){
combos.clear();
}
void notEnoughStamina(){
if (millis() - staminaTimer < 500);
pushMatrix();
translate(pos.x, pos.y);
strokeWeight(1);
fill(0);
textSize(50);
text("Not enough \nstamina!", width/2 + width/4 + 50, width/3 + width/3);
popMatrix();
}
void restingSword(){
activeFrames = defaultSword;
}
void attackingAnimation(){
activeFrames = swingSword;
animationResetTimer = millis();
}
void swordDodge(){
activeFrames = swordDodge;
animationResetTimer = millis();
}
void drawDamage(){
activeFrames = swordDamage;
animationResetTimer = millis();
}
void animationReset(){
if (activeFrames != defaultSword && millis() - animationResetTimer > 500){
restingSword();
}
}
void rolling(){
stamina += 3;
if (stamina > 6){
stamina = 6;
}
roll = millis();
clearCombos();
rollingTimer = millis();
println(roll);
println(rollingTimer);
println("rolling");
}
void keyPressed(){
if (millis() - roll >= 250){
if (key==CODED && millis() - attackTimer >= 250) {
if (keyCode==UP) prep=true;
if (keyCode==DOWN) {println("rolling happening");rolling();swordDodge();}
if (prep == true) {
if (keyCode==LEFT) combos.add(1);
if (keyCode==RIGHT) combos.add(2);
}
} else if (key==CODED && millis() - attackTimer <= 500) {
preppingTimer = millis();
}
attackTimer = millis();
dodge = false;
println("Combos: " + combos);
}else if (millis() - roll <= 500){
dodge = true;
rollingTimer = millis();
}
}
void keyReleased(){
if (key==CODED) {
if (keyCode==LEFT) prep=false;
if (keyCode==RIGHT) prep=false;
}
}
void drawMe(){
pushMatrix();
translate(pos.x, pos.y);
scale(3,6);
if (img != null) {
image(img, 0, 0);
}
popMatrix();
}
void drawDeath(){
super.drawDeath();
}
void update(){
super.update();
displayRolling();
displayPrepping();
updateFrame();
animationReset();
}
void displayRolling(){
if (rollingTimer >= 0 && millis() - rollingTimer <= 1000){
strokeWeight(1);
fill(0);
textSize(20);
text("rolling!", width/2 + width/4 + 50, width/3 + width/3);
}
}
void displayPrepping(){
if (preppingTimer >= 0 && millis() - preppingTimer <= 1000){
strokeWeight(1);
fill(0);
textSize(20);
text("performing an \naction!", width/2 + width/4 + 50, width/3 + width/3);
}
}
void drawHealthBar(){
super.drawHealthBar();
}
}I know the rolling class is executing properly because the stamina += 3 is working as intended and I dont have the roll being set anywhere else aside from the constructor of the class and in the rolling method.
I've tried debugging by placing println at various points where the problem might have stemmed from and it all points back to here so I am a bit clueless as to how to solve the problem.
Since we can't run the code, all I can do is look at it. And there's nothing in that function that looks like it would make those variable changes not work. When you say they "don't update properly", do you mean you've checked the values of roll and rollingTimer before this code:
roll = millis();
clearCombos();
rollingTimer = millis();
and then checked them again after, and they're the same both before and after? What behavior exactly are you seeing that convinces you the problem is there?
https://Discourse.Processing.org/t/millis-not-resetting-properly-in-rolling-method/43375
Hello, I'm relatively new to Processing and programming languages in general. There's this one sketch that I've been trying to get to work where, every 10 seconds, the timer variable (millis()/1000) resets to 0 and the program switches one image to another. Image 1 to Image 2, Image 2 to Image 1, Image 1 to Image 2 and so on.
However, due to the finicky nature of millis() (for me, at least), I can only get the program to switch images once. It crashes whenever the timer (variable named 'seconds') is supposed to set to zero for the second time. Can someone more experienced examine the code and help me out?
Screenshots of the program running
void group1()
{
while (millis() < 5000)
{
developer();
}
while (millis() >= 5000)
{
titlescreen();
startbutton();
}}
Thats the code, I get an error "Target VM Failed to initiate". Logically this makes sense to me. I am having a title screen that transitions. The developer logo will show, and after a few seconds, will switch to the title screen. Any ideas? I get the same error when I used if and for.