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();
}
}
}