Sync Gravity and FPS












0














I'm developing a simple game, but I have a problem with FPS and gravity.
So I need to sync FPS and gravity, because the higher FPS is the player fall faster. How can I sync them?



My code to update player:



            while (true) {
try {
Thread.sleep(1000 / GameMain.maxFPS); //Max Fps Limiter
GameMain.activeEntities.forEach((ent) -> { //Revalidade All Entities and Positions
ent.onTick();
});
gamePanel.repaint(); //Repaint Frame, Update Positions
} catch (InterruptedException e) {
e.printStackTrace();
}
}


My code to update gravity:



@Override
public void onTick() {
this.velocity = this.velocity.add(0, gravityForce()/*<- I'm using 9.807 divided by 60*/);
if (this.velocity.y > maxSpeed)
{
this.velocity.y = maxSpeed;
}
this.getPosition().y = this.getPosition().y + (this.velocity.y);
}









share|improve this question


















  • 1




    You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
    – Erwin Bolwidt
    Nov 21 '18 at 21:13










  • So, I need to separate repaint and ontick, establishing a default time to update them?
    – Superzinho
    Nov 21 '18 at 21:26








  • 1




    Or at least remember the time of the last update so you can find out how much time has elapsed.
    – Erwin Bolwidt
    Nov 21 '18 at 21:26
















0














I'm developing a simple game, but I have a problem with FPS and gravity.
So I need to sync FPS and gravity, because the higher FPS is the player fall faster. How can I sync them?



My code to update player:



            while (true) {
try {
Thread.sleep(1000 / GameMain.maxFPS); //Max Fps Limiter
GameMain.activeEntities.forEach((ent) -> { //Revalidade All Entities and Positions
ent.onTick();
});
gamePanel.repaint(); //Repaint Frame, Update Positions
} catch (InterruptedException e) {
e.printStackTrace();
}
}


My code to update gravity:



@Override
public void onTick() {
this.velocity = this.velocity.add(0, gravityForce()/*<- I'm using 9.807 divided by 60*/);
if (this.velocity.y > maxSpeed)
{
this.velocity.y = maxSpeed;
}
this.getPosition().y = this.getPosition().y + (this.velocity.y);
}









share|improve this question


















  • 1




    You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
    – Erwin Bolwidt
    Nov 21 '18 at 21:13










  • So, I need to separate repaint and ontick, establishing a default time to update them?
    – Superzinho
    Nov 21 '18 at 21:26








  • 1




    Or at least remember the time of the last update so you can find out how much time has elapsed.
    – Erwin Bolwidt
    Nov 21 '18 at 21:26














0












0








0







I'm developing a simple game, but I have a problem with FPS and gravity.
So I need to sync FPS and gravity, because the higher FPS is the player fall faster. How can I sync them?



My code to update player:



            while (true) {
try {
Thread.sleep(1000 / GameMain.maxFPS); //Max Fps Limiter
GameMain.activeEntities.forEach((ent) -> { //Revalidade All Entities and Positions
ent.onTick();
});
gamePanel.repaint(); //Repaint Frame, Update Positions
} catch (InterruptedException e) {
e.printStackTrace();
}
}


My code to update gravity:



@Override
public void onTick() {
this.velocity = this.velocity.add(0, gravityForce()/*<- I'm using 9.807 divided by 60*/);
if (this.velocity.y > maxSpeed)
{
this.velocity.y = maxSpeed;
}
this.getPosition().y = this.getPosition().y + (this.velocity.y);
}









share|improve this question













I'm developing a simple game, but I have a problem with FPS and gravity.
So I need to sync FPS and gravity, because the higher FPS is the player fall faster. How can I sync them?



My code to update player:



            while (true) {
try {
Thread.sleep(1000 / GameMain.maxFPS); //Max Fps Limiter
GameMain.activeEntities.forEach((ent) -> { //Revalidade All Entities and Positions
ent.onTick();
});
gamePanel.repaint(); //Repaint Frame, Update Positions
} catch (InterruptedException e) {
e.printStackTrace();
}
}


My code to update gravity:



@Override
public void onTick() {
this.velocity = this.velocity.add(0, gravityForce()/*<- I'm using 9.807 divided by 60*/);
if (this.velocity.y > maxSpeed)
{
this.velocity.y = maxSpeed;
}
this.getPosition().y = this.getPosition().y + (this.velocity.y);
}






java 2d-games gravity






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 21:00









SuperzinhoSuperzinho

34




34








  • 1




    You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
    – Erwin Bolwidt
    Nov 21 '18 at 21:13










  • So, I need to separate repaint and ontick, establishing a default time to update them?
    – Superzinho
    Nov 21 '18 at 21:26








  • 1




    Or at least remember the time of the last update so you can find out how much time has elapsed.
    – Erwin Bolwidt
    Nov 21 '18 at 21:26














  • 1




    You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
    – Erwin Bolwidt
    Nov 21 '18 at 21:13










  • So, I need to separate repaint and ontick, establishing a default time to update them?
    – Superzinho
    Nov 21 '18 at 21:26








  • 1




    Or at least remember the time of the last update so you can find out how much time has elapsed.
    – Erwin Bolwidt
    Nov 21 '18 at 21:26








1




1




You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
– Erwin Bolwidt
Nov 21 '18 at 21:13




You could support partial ticks (and multiple ticks if your machine has been slow) - say a tick takes one second, and you're now .3 second since the last tick, then you call onTick(0.3) where 0.3 is the tickFraction, and you do this.getPosition().y = this.getPosition().y + (this.velocity.y * tickFraction);
– Erwin Bolwidt
Nov 21 '18 at 21:13












So, I need to separate repaint and ontick, establishing a default time to update them?
– Superzinho
Nov 21 '18 at 21:26






So, I need to separate repaint and ontick, establishing a default time to update them?
– Superzinho
Nov 21 '18 at 21:26






1




1




Or at least remember the time of the last update so you can find out how much time has elapsed.
– Erwin Bolwidt
Nov 21 '18 at 21:26




Or at least remember the time of the last update so you can find out how much time has elapsed.
– Erwin Bolwidt
Nov 21 '18 at 21:26












1 Answer
1






active

oldest

votes


















0














Using Thread.sleep is going to be problematic as Thread.sleep will not guarantee that the Thread sleeps for exactly 1000ms, but rather than the Thread will sleep for at least 1000ms. Further, whenever it comes to working with threads there will be differences in behavior dependent upon the actually system, as thread scheduling logic is not a function of your application or the JVM, but rather the underlying hardware.



My recommendation: Either decouple draw logic from recalculation logic or let it run free without blocking the Thread with Thread.sleep. From there, to get good motion we should recall that change in position is not just a factor of speed, but also time. Therefore, we need to calculate the time passing between different draw frames by some mechanism such as System.currentTimeMillis() or System.nanoTime().



From there, you can recalculate positions by multiplying their velocity times the amount of time passing since recalculating.



Rough implementation:



double c = 1 / 60; // Some constant factor to bound motion over time
long previousCycleTime = System.currentTimeMillis();
while(somePredicate()) { // Logical cycle
long t = System.currentTimeMillis() - previousCycleTime;
gameObjects.forEach( o -> {
// t -> time passage
// dx -> change on the x axis
// c -> some constant factor to bound movement to the 'virtual space'
o.x += o.dx * t * c;
o.y += o.dy * t * c;
}
redraw();
}


Alternatively, you could redraw in a separate thread to decouple the two processes. This should not be taken lightly though, as transitioning from a single threaded application to multithreaded application introduces a great deal of additional complexity.






share|improve this answer



















  • 1




    I think I will do it separated, It's easier.
    – Superzinho
    Nov 21 '18 at 21:42










  • That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
    – msg45f
    Nov 21 '18 at 21:58











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420415%2fsync-gravity-and-fps%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Using Thread.sleep is going to be problematic as Thread.sleep will not guarantee that the Thread sleeps for exactly 1000ms, but rather than the Thread will sleep for at least 1000ms. Further, whenever it comes to working with threads there will be differences in behavior dependent upon the actually system, as thread scheduling logic is not a function of your application or the JVM, but rather the underlying hardware.



My recommendation: Either decouple draw logic from recalculation logic or let it run free without blocking the Thread with Thread.sleep. From there, to get good motion we should recall that change in position is not just a factor of speed, but also time. Therefore, we need to calculate the time passing between different draw frames by some mechanism such as System.currentTimeMillis() or System.nanoTime().



From there, you can recalculate positions by multiplying their velocity times the amount of time passing since recalculating.



Rough implementation:



double c = 1 / 60; // Some constant factor to bound motion over time
long previousCycleTime = System.currentTimeMillis();
while(somePredicate()) { // Logical cycle
long t = System.currentTimeMillis() - previousCycleTime;
gameObjects.forEach( o -> {
// t -> time passage
// dx -> change on the x axis
// c -> some constant factor to bound movement to the 'virtual space'
o.x += o.dx * t * c;
o.y += o.dy * t * c;
}
redraw();
}


Alternatively, you could redraw in a separate thread to decouple the two processes. This should not be taken lightly though, as transitioning from a single threaded application to multithreaded application introduces a great deal of additional complexity.






share|improve this answer



















  • 1




    I think I will do it separated, It's easier.
    – Superzinho
    Nov 21 '18 at 21:42










  • That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
    – msg45f
    Nov 21 '18 at 21:58
















0














Using Thread.sleep is going to be problematic as Thread.sleep will not guarantee that the Thread sleeps for exactly 1000ms, but rather than the Thread will sleep for at least 1000ms. Further, whenever it comes to working with threads there will be differences in behavior dependent upon the actually system, as thread scheduling logic is not a function of your application or the JVM, but rather the underlying hardware.



My recommendation: Either decouple draw logic from recalculation logic or let it run free without blocking the Thread with Thread.sleep. From there, to get good motion we should recall that change in position is not just a factor of speed, but also time. Therefore, we need to calculate the time passing between different draw frames by some mechanism such as System.currentTimeMillis() or System.nanoTime().



From there, you can recalculate positions by multiplying their velocity times the amount of time passing since recalculating.



Rough implementation:



double c = 1 / 60; // Some constant factor to bound motion over time
long previousCycleTime = System.currentTimeMillis();
while(somePredicate()) { // Logical cycle
long t = System.currentTimeMillis() - previousCycleTime;
gameObjects.forEach( o -> {
// t -> time passage
// dx -> change on the x axis
// c -> some constant factor to bound movement to the 'virtual space'
o.x += o.dx * t * c;
o.y += o.dy * t * c;
}
redraw();
}


Alternatively, you could redraw in a separate thread to decouple the two processes. This should not be taken lightly though, as transitioning from a single threaded application to multithreaded application introduces a great deal of additional complexity.






share|improve this answer



















  • 1




    I think I will do it separated, It's easier.
    – Superzinho
    Nov 21 '18 at 21:42










  • That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
    – msg45f
    Nov 21 '18 at 21:58














0












0








0






Using Thread.sleep is going to be problematic as Thread.sleep will not guarantee that the Thread sleeps for exactly 1000ms, but rather than the Thread will sleep for at least 1000ms. Further, whenever it comes to working with threads there will be differences in behavior dependent upon the actually system, as thread scheduling logic is not a function of your application or the JVM, but rather the underlying hardware.



My recommendation: Either decouple draw logic from recalculation logic or let it run free without blocking the Thread with Thread.sleep. From there, to get good motion we should recall that change in position is not just a factor of speed, but also time. Therefore, we need to calculate the time passing between different draw frames by some mechanism such as System.currentTimeMillis() or System.nanoTime().



From there, you can recalculate positions by multiplying their velocity times the amount of time passing since recalculating.



Rough implementation:



double c = 1 / 60; // Some constant factor to bound motion over time
long previousCycleTime = System.currentTimeMillis();
while(somePredicate()) { // Logical cycle
long t = System.currentTimeMillis() - previousCycleTime;
gameObjects.forEach( o -> {
// t -> time passage
// dx -> change on the x axis
// c -> some constant factor to bound movement to the 'virtual space'
o.x += o.dx * t * c;
o.y += o.dy * t * c;
}
redraw();
}


Alternatively, you could redraw in a separate thread to decouple the two processes. This should not be taken lightly though, as transitioning from a single threaded application to multithreaded application introduces a great deal of additional complexity.






share|improve this answer














Using Thread.sleep is going to be problematic as Thread.sleep will not guarantee that the Thread sleeps for exactly 1000ms, but rather than the Thread will sleep for at least 1000ms. Further, whenever it comes to working with threads there will be differences in behavior dependent upon the actually system, as thread scheduling logic is not a function of your application or the JVM, but rather the underlying hardware.



My recommendation: Either decouple draw logic from recalculation logic or let it run free without blocking the Thread with Thread.sleep. From there, to get good motion we should recall that change in position is not just a factor of speed, but also time. Therefore, we need to calculate the time passing between different draw frames by some mechanism such as System.currentTimeMillis() or System.nanoTime().



From there, you can recalculate positions by multiplying their velocity times the amount of time passing since recalculating.



Rough implementation:



double c = 1 / 60; // Some constant factor to bound motion over time
long previousCycleTime = System.currentTimeMillis();
while(somePredicate()) { // Logical cycle
long t = System.currentTimeMillis() - previousCycleTime;
gameObjects.forEach( o -> {
// t -> time passage
// dx -> change on the x axis
// c -> some constant factor to bound movement to the 'virtual space'
o.x += o.dx * t * c;
o.y += o.dy * t * c;
}
redraw();
}


Alternatively, you could redraw in a separate thread to decouple the two processes. This should not be taken lightly though, as transitioning from a single threaded application to multithreaded application introduces a great deal of additional complexity.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 21 '18 at 21:35

























answered Nov 21 '18 at 21:29









msg45fmsg45f

333613




333613








  • 1




    I think I will do it separated, It's easier.
    – Superzinho
    Nov 21 '18 at 21:42










  • That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
    – msg45f
    Nov 21 '18 at 21:58














  • 1




    I think I will do it separated, It's easier.
    – Superzinho
    Nov 21 '18 at 21:42










  • That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
    – msg45f
    Nov 21 '18 at 21:58








1




1




I think I will do it separated, It's easier.
– Superzinho
Nov 21 '18 at 21:42




I think I will do it separated, It's easier.
– Superzinho
Nov 21 '18 at 21:42












That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
– msg45f
Nov 21 '18 at 21:58




That's probably the better approach long term. In this situation, I would introduce Thread.sleep again, as sleeping the drawing thread will not block other important activities - just ensure that your recalculations are still leveraging time.
– msg45f
Nov 21 '18 at 21:58


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420415%2fsync-gravity-and-fps%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

Refactoring coordinates for Minecraft Pi buildings written in Python