Апплет "понг": мяч проходит прямо через весло, если весло движется к мячу

Обычно в такой игре доступно только движение по оси 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);
}

и аналогично для направления х

Также обратите внимание, что если вы отделяете графику от игрового движка, ваш движок становится отдельно тестируемым и его легче отлаживать.

Другие вопросы по тегам