Апплет "понг": мяч проходит прямо через весло, если весло движется к мячу
Обычно в такой игре доступно только движение по оси Y, но я решил сделать так, чтобы допускались также движения по оси X. игра работает отлично, ЕСЛИ я не двигаю весло по оси X, КОГДА мяч ударяется о весло (в этом случае оно проходит прямо через него.) Если я остановлю движение по оси X до того, как мяч ударится, шарик весла отскочит от него каждый раз.
Сначала я думал, что это связано с пикселями, но я также попытался изменить столкновение весла несколькими способами без каких-либо положительных результатов. Мяч НИКОГДА не отскочит от весла, сколько бы раз я ни пытался.
код очень прост, и я перемещаю все по 1px за раз:
public void drawBall(Graphics g) { //ball speed, movement and collision
b.set(b.getX()+VX,b.getY()+VY); //velocity X and velocity Y both at 1px
g.setColor(Color.black);
b.draw(g);
if(b.getY()<0 || b.getY()>sizeY-b.getRadius()){ //top & bottom collision
VY = -VY;
}
if(b.getX()<0 || b.getX()>sizeX-b.getRadius()){ //left & right detection
b.center();
VX = -VX;
x = (int) (Math.random()*2+0);
if(x == 0)
VY = -VY;
}
if(b.getX() == p1.getX()+p1.width && b.getY()>p1.getY() && b.getY()<p1.getY()+p1.height){ // p1 paddle detection
VX = -VX;
}
if(b.getX()+b.getRadius()==p2.getX() && b.getY()>p2.getY() && b.getY()<p2.getY()+p2.height){ // p2 paddle detection
VX = -VX;
}
}
Для перемещения лопастей я использую простые флажки, которые устанавливают движение в определенном направлении: "включено" при нажатии клавиши и "выключено" при отпускании клавиши. Я запускаю это в бесконечном цикле, поэтому он выполняется постоянно.
Вот как выглядит метод run():
public void run() {
while(true){
repaint();
try {
Thread.sleep(5);
playerMovement(); //moves players paddle on X and/or Y axis
playerLimits(); //limits movment of players to specific area
} catch (InterruptedException e){
}
}
}
Я снова попытался создать столкновение весла таким образом, чтобы оно не было привязано к пикселям с помощью "if (ball Спасибо за любую помощь заранее, я очень ценю это.
1 ответ
Не смешивайте код игрового движка с графическим кодом - они должны храниться отдельно. Ключ к любому решению состоит в том, чтобы убедиться, что игровой движок распознает "столкновение" и обрабатывает его правильно и однозначно. Вместо переключения направлений скорости, рассмотрите возможность установки абсолютных значений этих скоростей в зависимости от того, где происходит столкновение.
Например, у вас есть этот код:
if(b.getY() < 0 || b.getY() > sizeY-b.getRadius()){ //top & bottom collision
VY = -VY;
}
но это рискует получить спрайт в ловушке, если он пойман за гранью. Возможно, лучше было бы сделать что-то вроде:
if (b.getY() < 0) {
// note that variables should start with lower-case letters
vy = Math.abs(vy); // make sure that it is going in a positive direction
}
if (b.getY() > sizeY - b.getRadius()) {
vy = -Math.abs(vy);
}
и аналогично для направления х
Также обратите внимание, что если вы отделяете графику от игрового движка, ваш движок становится отдельно тестируемым и его легче отлаживать.