What Endos said; Basically you're moving the character on the *screen* not on the *map*, then moving the map as well. The player isnt actually speeding up, he's staying at the same speed.. But you're also moving the map at the same speed in the opposite direction, thus he ends up traveling twice as fast. (Think of it like this: He's walking the same speed, but now on an escalator, so he's covering 2x the ground)
A possible solution is to seperate the camera and player completely, what I do is render the player on the screen in relation to where the map is, and then make the map move in relation to where the player is. They don't have any connection to each other.
(NOTE: Stripped all the way down to be super simple)
Example of renders/moving my character, where entityX and Y are in relation to where the map is being rendered, NOT in relation to where the character is on the screen. :
1 2 3 4 5 6 7
| public void render(Graphics g, boolean debug) throws SlickException{ entity.render(entityX+mapX,entityY+mapY); }
public void moveEntityNorth() throws SlickException{ entityY -= entitySpeed; } |
and moving the map/camera around to follow the player, but it's coordinates aren't "attached" to the player. NOTE: You will have to change the values after >=/<= to match your screen size to where you want the movement to start. My game is rendered in 720p and scaled x3, thats why my values are so low. Yours will probably be much higher than mine:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{ if((mapX*-1)-entityX >= -161){ mapX += entitySpeed; }
if((mapX*-1)-entityX <= -233){ mapX -= entitySpeed; } if((mapY*-1)-entityY() >= -86){ mapY += entitySpeed; } if((mapY*-1)-entityY() <= -106){ mapY -= entitySpeed; } } |
The results are a camera that follows around the player, not a camera that moves based on your inputs. If that makes sense.
(Note: This may also help solve your TileID problem in your other thread)