my movement's sprite is not linear!!

I’ve a problem with my sprite’s movement, it’s not linear (the sprite move with “jumps”)

I’ve a principal class that calculate the elapsed time like this:


public void gameLoop()
    {
        // Calcola il tempo attuale
        long startTime = System.currentTimeMillis();
        long currTime = startTime;
        while(gameRunning)
        {
            long elapsedTime = System.currentTimeMillis() - currTime;
            currTime += elapsedTime;
            
            resource.update(elapsedTime);
            
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            resource.draw(g);
            strategy.show();  
        }
    }  

the draw method is in a class that manages all the objects:


// Disegna le sprites
        Iterator i = map.getSprites();
        while(i.hasNext())
        {
            Sprite sprite = (Sprite)i.next();
            int x = Math.round(sprite.getX()) * TILE_WIDTH;
            int y = Math.round(sprite.getY()) * TILE_HEIGHT;
            g.drawImage(sprite.getImage(),x,y,null);           
        } 

what I’ve to change?

Your logic is based on the assumption that currentTimeMillis() is accurate, but it isnt.

As I just wrote elsewere… The resolution of currentTimeMillis is 50-55 msec on win9x, 10msec on 2k/xp and 1msec on linux/mac.

So, you cant do it as straightforward as that. Your options are System.nanoTime (1.5+), my adaptive yield loop thingy or something completely different :slight_smile:

Another option is the gage timer at http://java.dnsalias.com/

Thanks for that, I was about to go digging to find something that would work on OS X as well as 1.1 (for an applet game about to be released commercially).

I’m suspicious it wont actually work, given you dont mention OS X’s timing problems :wink: which are conisderably worse than win XP :frowning: :(, but we’ll see how it goes. I can always force that to nanotime, since java2d doesn’t work on OS X with less than 1.4 anyway (PNG’s don’t load, for instance. Thankfully you can mostly count on 1.5 being installed these days (anyone who downloads the auto OS updates will have it)

PNG’s don’t load, for instance.

PNGs are overrated. While they are really great for webpages and the like, they are sorta pointless for java games. With java you put everything into jar files anyways, which means that raw formats (such as tga) are about as small (unless you use funky stuff like pngquant-ed pngs [effectively 8bit with rgba palette]).

And timing wasnt a problem ever on OSX afaik. I only had some annoying issues with the cursor and that freshly created translucent images arent filled with fully transparent black (same on linux).

just for the record, when I used the adaptive yield loop thingy™ in Goomba4K, the timing was perfect on 98SE, XP, and OSX =o

I’ve never heard of any timing problems on OS X.

Using this simple test program:

package timertest;
public class Main
{
	public static void main(String[] args) throws InterruptedException
	{
		long start = System.currentTimeMillis();
		long then = start;
		System.out.println("---- System.currentTimeMillis() Resolution Test ----");
		do {
			long now = System.currentTimeMillis();
			if (now != then)
				System.out.println(now-then);
			then = now;
		} while ((then - start) < 10000);
		
		System.out.println("---- Sleep Test ----");
		start = System.currentTimeMillis();
		for(int i = 0; i < 10000;i++)
			Thread.sleep(1);
		System.out.println("10000 * Thread.sleep(1) caused a delay of "+(System.currentTimeMillis()-start)+"ms");
	}
}


Timer resolution of System.currentTimeMillis() is 16 ms on Windows XP and 1 ms on OS X.
Thread.sleep(1) 10000 times delays 19531ms on Win XP.
Thread.sleep(1) 10000 times delays 10274ms on OS X.

So I don’t understand what you are referring to whenyou claim OS X has worse timing problems than Win XP.

[quote]but we’ll see how it goes. I can always force that to nanotime, since java2d doesn’t work on OS X with less than 1.4 anyway (PNG’s don’t load, for instance.
[/quote]
There was a release of Java 1.4 that swapped red and blue for some PNGs (those with alpha channels) on OS X, that was later fixed. It is certainly false to say that PNGs in general don’t load - I use them all the time without problems.

[quote]Thankfully you can mostly count on 1.5 being installed these days (anyone who downloads the auto OS updates will have it)
[/quote]
Well at least you got one thing right :).

I think that the problem isn’t currentTimeMillis(). I’ve tried to do a simple load of a sprite and to draw it. The problem there wasn’t anymore, the movement was linear without jumps.

I think the problem is 'cause I use tilemap, in fact, when I load a sprite from tilemap, the problem goes again.

this is the code to load the map:


private TileMap loadMap(String name)
    throws IOException
    {
        ArrayList lines = new ArrayList();        
        int height = 0;
        int width = 0;
        
        BufferedReader reader = new BufferedReader(new FileReader(name));
        while(true)
        {
            String line = reader.readLine();
            if(line == null)
            {
                reader.close();
                break;
            }            
            lines.add(line);            
            width = Math.max(width, line.length());
        }        
        height = lines.size();
        map = new TileMap(width, height);
 
        for(int y = 0; y < height; y++)
        {
            String line = (String)lines.get(y);
            for (int x = 0; x < line.length(); x++)
            {
                char ch = line.charAt(x);
                int tile = ch - 'A';                
                if(tile >= 0 && tile < tiles.length)
                {
                    map.setTile(x, y, tiles[tile]);
                }                
                else if(ch == '1')
                {
                    addSprite(map,enemy1Sprite,x,y);
                }                
            }
        }
        return map;
    }

and this is the method to draw sprites


Iterator i = map.getSprites();
        while(i.hasNext())
        {
            Sprite sprite = (Sprite)i.next();
            int x = Math.round(sprite.getX()) * TILE_WIDTH;
            int y = Math.round(sprite.getY()) * TILE_HEIGHT;
            g.drawImage(sprite.getImage(),x,y,null);            
        } 

… and I don’t use threads…

I’ve found the problem… in the draw method:


// Disegna le sprites
        Iterator i = map.getSprites();
        while(i.hasNext())
        {
            Sprite sprite = (Sprite)i.next();
            int x = Math.round(sprite.getX()) * TILE_WIDTH;
            int y = Math.round(sprite.getY()) * TILE_HEIGHT;
            g.drawImage(sprite.getImage(),x,y,null);           
        } 

the lines


int x = Math.round(sprite.getX()) * TILE_WIDTH;
int y = Math.round(sprite.getY()) * TILE_HEIGHT;

they were no correct… now I’ve changed with:


int x = Math.round(sprite.getX());
int y = Math.round(sprite.getY());