# Getting sprites to move exactly the same on different devices

Background

When moving a sprite along the X axis, this is my code:

spriteXReal = spriteXReal + (spriteXVel * dt);  //.5 would be halfway point of, 1 would be right hand side screen etc...
spriteXScreen=spriteXReal*deviceWidth;


And the spriteXVel value above is worked out as:

spriteXVel = 1/spriteXTime;


So I would set spriteXTime to 10 if I wanted my sprite to work it's way across the screen in 10 seconds.

My code:

• Uses a fixed delta time

• Has tics per second capped at 60 (so my delta is 1/60)

The issue

This is great and works well, however, I am getting odd results when running on a different device (with a different screen res).

When comparing the 2 devices (simply by starting the game on both devices at the exact same time, they are almost identical save for a tiny difference in speed.

The game world is tile based. Let's say the play area on my development device is 16 tiles wide. 16 tiles fit perfectly onto this device So, if I'm moving between 8 tiles, I'm effectively crossing 1/2 of the screen.

Initially, the sprite appears to move the same on both devices, (going back and forth between say the 1st 'proper' tile and the 8th 'proper' tile), but after about 25 seconds, they are clearly out of sync.

On this device, the tiles would look something like this:

So, I'm working out my sprite movement using the device's width as above.

However, if the tiles don't fit exactly, I'm centering the original tiles and adding 'padding' tiles to the play-area like so:

Therefore, my confusion lies in how I should be working out my sprite's new position. because, now 8 tiles is actually less than 1/2 of the device's screen. So should I still be using the code above or something like this:

spriteXScreen=spriteXReal*(Block18X - Block2X);

I have actually tried both and when I did, the problem was still evident, so I'm not sure which one I'm supposed to be using.

What is really odd is that when I set my sprite's Time variable to certain amounts, it appears that everything stays in perfect sync between these 2 devices so I'm completely stumped - that's what I've observed thus far anyway. I'm going to test that theory a bit more.

What else could be causing this discrepancy?!

Really appreciate some help with this one!

Edit

I've pretty much tried everything I can, I've even tried implementing a very simple 'test' game loop that updates sprite positions once every second, and put the two devices side by side, however, the Samsung Galaxy Ace Always runs ahead of the Google tablet, is it possible that System.CurrentTimeMillis(); is actually running faster on the Ace than on the tablet?

• Can I asked why you use a fixed delta? – Green_qaue Mar 2 '14 at 8:59
• Hi @iQue, no specific reason to be honest, when I was writing the gam fixed delta just seemed the easier option, I will probably look at a variable delta at some point, maybe for my next game :-) – BungleBonce Mar 2 '14 at 12:27

You've got the right idea of using a normalized coordinate (namely, spriteXReal). However, you're still coupling it to the screen size.

What you should be doing is expressing every position in terms of a common unit. In your case, a unit square could be a tile. Letting a unit equal a meter also vastly simplifies physics code.

When you go to render, you have to convert your basic units into pixels. You might want to make each tile 50x50 pixels large when rendered, so you just multiply the position in units by 50 to get the position in pixels (you can then add an offset for scrolling).

• Hi @Boreal, do you mean for example, instead of me saying 'spriteXtime is the time it takes the sprite to cross the screen', and doing spriteXScreen=spriteXReal*(deviceWidth); just make spriteXTime the amount of time I want the sprite to move across the width of a tile in and then just say spriteXScreen=spriteXReal*(tile.width); ? That being the case, is that not the same (more or less) as the 2nd graphic in my question? (spriteXScreen=spriteXReal*(block.width*16); (only I'm using a group of tiles rather than a single tile)? Cheers!! :-) – BungleBonce Mar 2 '14 at 2:24

You should use a deterministic physics approach, where floating points, all the data types would be integrated in the way that are always certainly work in every CPU Architecture.

The problem was actually when my sprites were turning around between their boundaries.

I was using their int positions (their physical pixels positions after they had been converted from their float positions) which wasn't very accurate. Therefore, on one device a sprite may not have reached the boundary and turn around where on the other device the sprite hasn't even reached it's boundary.

I got around this by using it's float position (spriteXReal) and setting it's boundary's to float values too then comparing the two.

After doing this everything appears (at least devices to run perfectly in sync).