java - Why is the energy of this ball is increasing? -


i've been trying hours setup gravity , relate time or call frame independent bounce ball. did correct guess, , tried implement system height of ball decrease after every bounce. did not start that, , code creating absurd don't understand why. here's code:

protected void ondraw(canvas canvas) {         super.ondraw(canvas);          currentframe = system.currenttimemillis();          dt = currentframe - lastframe;         dt = dt/1000;          lastframe = currentframe;          myfreakinrect.set(0,0, canvas.getwidth(), canvas.getheight());         freakinred.setcolor(color.red);         freakinred.setstyle(paint.style.fill);         canvas.drawrect(myfreakinrect, freakinred);           //          // o yuea          if(goingdown) {             //velocityy = math.sqrt(100 + 2*gravity*(posy));             velocityy = gravity*(currentframe - runtime);         } else {             velocityy = downv - gravity*(currentframe - runtime);         }           if(posx > w - ballradius*2) {             goingright = false;         }         if(posx < 0) {             goingright = true;         }         if(posy > h - ballradius*2) {             //inity = inity - 0.25f;             //if(inity < 0) inity = 0;             log.i("xxx", string.valueof(inity));             runtime = currentframe;             downv = velocityy;             goingdown = false;         }         if(velocityy <= 0) {             goingdown = true;             runtime = currentframe;         }          if(goingdown) posy += velocityy*dt;         else posy -= velocityy*dt;          if(goingright) posx += velocityx*dt;         else posx -= velocityx*dt;             canvas.drawtext(string.valueof(posx)+"  "+string.valueof(posy), 10, 10, new paint());         canvas.drawbitmap(rball, (float)posx, (float)posy, myfreakingfaintpaint);           invalidate();     } 

here's gif happening:

enter image description here

update:

here's updated code clean, understandable , works perfect:

protected void ondraw(canvas canvas) {         super.ondraw(canvas);          currentframe = system.currenttimemillis();          dt = currentframe - lastframe;         dt = dt/1000;          lastframe = currentframe;          velocityy = downv + gravity*(currentframe - runtime);         posy += velocityy*dt;         posx += velocityx*dt;         if(posx > w - ballradius*2 || posx < 0) {             velocityx = -velocityx;         }          if(posy >= h - ballradius*2) {             posy = h - ballradius*2 - 2;             runtime = currentframe;             downv = -0.8*velocityy;         }          canvas.drawbitmap(rball, (float)posx, (float)posy, null);           invalidate();     } 

here ...

    if(goingdown) {         //velocityy = math.sqrt(100 + 2*gravity*(posy));         velocityy = gravity*(currentframe - runtime);     } else {         velocityy = downv - gravity*(currentframe - runtime);     } 

... update velocity (speed, actually) assuming ball not bounce during frame.

then here ...

    if(posy > h - ballradius*2) {         //inity = inity - 0.25f;         //if(inity < 0) inity = 0;         log.i("xxx", string.valueof(inity));         runtime = currentframe;         downv = velocityy;         goingdown = false;     } 

... have not yet updated posy, determining whether ball hit floor result of previous update. if did, reverse direction of motion, keep speed computed frame. result, each time ball bounces, initial upward speed 1 frame's worth of acceleration greater speed traveling when hit floor.

you have similar effect @ top of ball's motion, it's smaller because speed small there.

there couple of ways might solve problem. simplest perform bounce check after position update instead of before.

additional notes:

  • use signs of x , y speeds instead of separate direction-of-motion flags (thus making names velocityy etc. accurate). code simpler, , you'll need handle 1 change of vertical direction, not two, because equations of motion handle other automatically.

  • you have bit of precision problem because assume ball travels in same direction whole frame. may become noticeable if allow ball reach high speeds: appear penetrate floor before bouncing up.

  • this computation suspicious: dt = dt/1000. since dt seems computed system.currenttimemillis(), inclined guess it, too, has type long. in case, performing integer division , thereby losing precision.