Movement not so smooth as it used to be?

Previous topic - Next topic

Nathan

So before I started writing my game, I prototyped a lot of the stuff I was going to be doing in small test programs, and one of the obvious ones was smooth movement based on timing.  Using a routine written by MrAToad and I believe Ampos, I created the following test program which draws two rectangles just to see which routine is smoother/better/etc.  And I sure at time, which was probably a couple of months ago now, the movement was perfectly smooth without any jumping or "jerkiness".  However, I try the same routine now and it seems jumpy and non-smooth. 

Is anyone else having similar issues?

Code (glbasic) Select

GLOBAL movementRate
GLOBAL screenWidth
GLOBAL screenHeight

GETSCREENSIZE screenWidth, screenHeight

GLOBAL x = 0
GLOBAL y = ( screenHeight / 2 )

GLOBAL x2 = 0
GLOBAL y2 = ( screenHeight / 2 ) + 100

GLOBAL timer AS TAppTime
timer.Initialise(60)

WHILE (x2+50) < screenWidth
movementRate = ( screenHeight / 2) * 0.001 * GETTIMER()

DRAWRECT x, y, 50, 50, RGB(0, 0, 255)
INC x, (0.2 * movementRate)

DRAWRECT x2, y2 + 50, 50, 50, RGB(255, 0, 0)
INC x2, (0.8 * timer.Update())

SHOWSCREEN
WEND
MOUSEWAIT
END

// --------------------------------- //
// Project: AppTimer
// Start: Thursday, September 11, 2008
// IDE Version: 5.360

TYPE TAppTime
AppTime_UPS;AppTime_Iterator;AppTime_CurrentTime;AppTime_PauseStart;AppTime_Speed;AppTime_DesiredLoopTime;AppTime_LastUpdateTime
AppTime_LastUPSTime;AppTime_DesiredFrequency%

//! This function initialises the AppTimer system, and must be called first.
//\param frameRate% - This is the frame rate that you want all movement to be based on.  It defaults to 60 FPS, which is the lowest rate that should be used.
//\return Nothing is returned
FUNCTION Initialise%:frameRate%=60
self.AppTime_UPS=0.0
self.AppTime_Iterator=0.0
self.AppTime_CurrentTime=0.0
self.AppTime_PauseStart=0.0
self.AppTime_Speed=1.0
self.AppTime_LastUpdateTime=0.0
self.AppTime_LastUPSTime=0.0
self.AppTime_DesiredLoopTime=1000.0/(frameRate*1.0)
RETURN TRUE
ENDFUNCTION

//! This function updates the timing system.  It needs to be called once per loop.
//\param No parameters are passed
//\return A movement value is returned.  This should be muliplied by the amount you want to move.  If the routine is paused, then 0.0 is returned
FUNCTION Update:
LOCAL time
LOCAL elapsed

IF self.AppTime_PauseStart<>0
RETURN 0.0
ENDIF

time=GETTIMERALL()

IF self.AppTime_LastUpdateTime=0.0
self.AppTime_Speed=1.0
self.AppTime_LastUPSTime=time
ELSE
elapsed=time-self.AppTime_LastUpdateTime
IF elapsed=0.0
elapsed=1.0
SLEEP 1
INC time,1.0
ENDIF

self.AppTime_Speed=elapsed/self.AppTime_DesiredLoopTime
ENDIF
self.AppTime_LastUpdateTime=time
self.AppTime_CurrentTime=time

INC self.AppTime_Iterator,1.0 // Its a float as it can go very large...

IF self.AppTime_CurrentTime-self.AppTime_LastUPSTime>=1000.0
self.AppTime_UPS=self.AppTime_Iterator/((self.AppTime_CurrentTime-self.AppTime_LastUPSTime)/1000)
self.AppTime_LastUPSTime=self.AppTime_CurrentTime
self.AppTime_Iterator=0
ENDIF

RETURN self.AppTime_Speed
ENDFUNCTION

//! This function is used when your program is paused or not.  If it is, then the step speed is still updated
//\param pause% - If this is TRUE, then your program is paused.  If FALSE, then it isn't
//\return Nothing is returned
FUNCTION Pause%:DoPause%
LOCAL elapsed

IF DoPause%=TRUE
IF self.AppTime_PauseStart=0.0
self.AppTime_PauseStart=GETTIMERALL()
self.AppTime_UPS=0
self.AppTime_Speed=0
ENDIF
ELSE
IF self.AppTime_PauseStart<>0.0
IF self.AppTime_LastUpdateTime<>0.0
elapsed=GETTIMERALL()-self.AppTime_PauseStart
INC self.AppTime_LastUpdateTime,elapsed
ENDIF

self.AppTime_PauseStart=0.0
self.Update()
ENDIF
ENDIF
ENDFUNCTION

//!  This function returns the updates per second, and is an approximation
//\param No parameters are passed
//\return Updates per second
FUNCTION UPS:
RETURN self.AppTime_UPS
ENDFUNCTION
ENDTYPE

MrTAToad

#1
No, can't say I have...  They are very smooth here.

Do you have debug mode on ?  Any intensive hard drive activity ?


Hatonastick

#2
Hmm seems to run ok on my PC.  If you are talking about jerkiness every once in a while, then sometimes there looks like there is a tiny little bit.  Really though mine pretty much mimics the movie Mr TA Toad has posted.

Seems to run quite well on my extremely low end Android tablet too, although one square finishes way ahead of the other. :)
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

monono

For me it is very jerky in the code and in the video. I had the same problem, even with older versions. I used to never have slow movements :)
Now I solved it somehow. I changed 2 things and don´t know which one changed it.
1. Instead of using GETTIMER() I use GETTIMERALL() to get the time since last showscreen (timer=GETTIMERALL()- lasttime)
2. I calculate time, positions and have all gamelogic in as many fps as it gets. Just drawing and SHOWCREEN is every 1000/60.
Code (glbasic) Select
LIMITFPS 500
WHILE GAMESTATE = STATE_GAME
  WHILE Usedtime <= FrameTime
     //do everything
     INC UsedTime,timer
  WEND
  //draw everything
  SHOWSCREEN
WEND


Nathan

Mmm, yeah, that video is showing the exact same behaviour as as the two PC's I've tested it on.  Maybe I'm remembering how smooth it was with rose tinted glasses because I'm sure it was less "jumpy" than that.

In fact, I've justed tried it with my work PC, which has an older version of GLB, IDE 10.113, and while the first run wasn't very smooth and was similar to the video, subsequent runs were, so maybe my home PC is doing loads of rubbish in the background.

I'll have to try it on a phone or something that won't have anything running in the background.