Podczas pisania gry 2d w javie natrafiłem na pewien problem.
Przed każdą zmianą pozycji gra zapisuje poprzednia pozycje gracza.
Jeśli w kolejnym cyklu będzie miał kolizję z innym obiektem wczytywana jest poprzednia pozycja.
I w tym momencie powstaje problem ponieważ przez to, że prędkość gracza jest np. liczbą 7 to kiedy x będzie się równał np.495 ,a x bloku 500. W momencie wykrycia kolizji gracz zostanie cofnięty na pozycję 495.
Przez to ,że między jego pozycją ,a pozycją bloku zostanie 5 pikseli różnicy nie będzie mógł wjechać w "korytarz".

Co zrobić aby taka sytuacja nie mogła zaistnieć?

public class Player extends Actor {
	protected int PLAYER_SPEED = 3;
	protected int vx, vy;
	protected int oldX, oldY;
	protected double HP;
	protected double MaxHP;

	private int score = 0;
	private boolean up, down, left, right;
	public static int tankPoz;

	private double strzal;

	public Player(Stage stage) {
		super(stage);
		setSpriteName("tanks.png", 3, 45, 45);

	}

	public void act() {
		super.act();
		if (HP <= 0) {
			stage.EndGame(false);
		}
		updateSpeed();

		x += vx;
		y += vy;

	}

	public void addScore(int i) {
		score += i;
	}

	public void setHP(double hP) {
		HP = hP;
		MaxHP = hP;
	}

	public int getVx() {
		return vx;
	}

	public void setVx(int i) {
		vx = i;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int i) {
		score = i;
	}

	public int getVy() {
		return vy;
	}

	public void setVy(int i) {
		vy = i;
	}

	protected void updateSpeed() {
		oldX = x;
		oldY = y;

		vx = 0;
		vy = 0;
		if (y < Stage.H - 100) {
			if (down && vx == 0) {
				vy = PLAYER_SPEED;
				tankPoz = 0;
			}
		}
		if (y > 0) {
			if (up && vx == 0) {
				vy = -PLAYER_SPEED;
				tankPoz = 1;
			}
		}
		if (x > 0) {
			if (left && vy == 0) {
				vx = -PLAYER_SPEED;
				tankPoz = 2;
			}
		}
		if (x < Stage.W - 60) {
			if (right && vy == 0) {
				vx = PLAYER_SPEED;
				tankPoz = 3;
			}
		}

	}

	public void setPLAYER_SPEED(int pLAYER_SPEED) {
		PLAYER_SPEED = pLAYER_SPEED;
	}

	public void paint(Graphics2D g) {
		g.drawImage(spriteCache.getSprite(spriteName, tankPoz, w, h), x, y,
				stage);
		if (MaxHP == HP) {

		} else {
			double wgreen = (w / MaxHP) * (HP) + (MaxHP - HP);
			double wred = (w / MaxHP) * -(MaxHP - HP);
			if (wgreen > 0) {
				g.setColor(Color.green);
				g.fillRect(x, y + h + 10, (int) wgreen, 5);
				g.setColor(Color.red);
				g.fillRect(x + w, y + h + 10, (int) wred, 5);
			} else {
				g.setColor(Color.red);
				g.fillRect(x, y + h + 10, w, 5);
			}
		}
	}

	public void fire() {
		double usedTime = System.currentTimeMillis() - strzal;
		if (usedTime > 400) {
			Bullet b = new Bullet(stage, "p");
			switch (tankPoz) {
			case 0:
				b.setPosition(x + (w / 2) - b.getWidth() / 2, y + h - b.getY());
				stage.addActor(b);
				strzal = System.currentTimeMillis();
				b.setVy(b.BULLET_SPEED);
				stage.getSoundCache().playSound("strzal.wav");
				break;
			case 1:
				b.setPosition(x + (w / 2) - b.getWidth() / 2, y - b.getHeight());
				stage.addActor(b);
				strzal = System.currentTimeMillis();
				b.setVy(-b.BULLET_SPEED);
				stage.getSoundCache().playSound("strzal.wav");
				break;
			case 2:
				b.setPosition(x - b.getWidth(), y + (h / 2) - b.getHeight() / 2);
				stage.addActor(b);
				strzal = System.currentTimeMillis();
				b.setVx(-b.BULLET_SPEED);
				stage.getSoundCache().playSound("strzal.wav");
				break;
			case 3:
				b.setPosition(x + w, y + (h / 2) - b.getHeight() / 2);
				stage.addActor(b);
				strzal = System.currentTimeMillis();
				b.setVx(b.BULLET_SPEED);
				stage.getSoundCache().playSound("strzal.wav");
				break;
			}

		}
	}

	public void backToOldPosition() {
		setPosition(oldX, oldY);
	}

	public void collision(Actor a) {

		if (a instanceof Bullet) {
			Bullet b = (Bullet) a;
			if (b.getKto() == "m") {
				HP = HP - 2;
				stage.getSoundCache().playSound("koniecammo.wav");
				a.remove();
			}

		}
		if (a instanceof Monster) {
			HP = HP - 4;
			addScore(5);
			stage.getSoundCache().playSound("koniecammo.wav");
			a.remove();

		}

	}

	public void collision(Blok b) {
		if (b instanceof Beton) {
			backToOldPosition();

		}
		if (b instanceof Krzak) {
		}

	}

	public void keyReleased(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_DOWN:
			down = false;
			break;
		case KeyEvent.VK_UP:
			up = false;
			break;
		case KeyEvent.VK_LEFT:
			left = false;
			break;
		case KeyEvent.VK_RIGHT:
			right = false;
			break;
		}
		updateSpeed();
	}

	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_UP:
			up = true;
			break;
		case KeyEvent.VK_LEFT:
			left = true;
			break;
		case KeyEvent.VK_RIGHT:
			right = true;
			break;
		case KeyEvent.VK_DOWN:
			down = true;
			break;
		case KeyEvent.VK_SPACE:
			fire();
			break;
		}
		updateSpeed();
	}
}
		}

user image