Проблемы с обнаружением столкновения кирпича в игре BreakOut

Я выполнил свою первую игру BreakOut, выполняя задание для онлайн-курса Стэнфордского университета по Java.

Однако во время игровых тестов я заметил, что когда мяч иногда попадает в кирпич во время движения по диагонали, он неестественным образом ударяет по нескольким кирпичам подряд.

Я предполагаю, что мне нужно немного улучшить свой код обнаружения столкновений, и я уже пробовал несколько вещей безрезультатно.

Я использую библиотеку ACM для этой программы. Воображаемый прямоугольник окружает мой мяч, и я использую 4 угла этого прямоугольника, чтобы обнаружить столкновение.

Во время игры, поскольку я добавил несколько аддонов (предметов, которые выпадают и дают вам бонус), в игре происходит много изменений скорости - переменная vx сильно меняется.

Я думаю, что это связано с моей проблемой, потому что я заметил, что это когда мяч движется с большей скоростью, чем большая часть из нескольких кирпичей, разрушенных в результате проблемы подряд.

Я добавлю соответствующий код здесь. Однако вы можете проверить весь код здесь: https://gist.github.com/frodosda/5604272

// Defines the initial Direction of the Ball - inside the "MoveBall" Method
    vx = rGen.nextDouble(1.0, 3.0); // Random Horizontal Direction
    if (rGen.nextBoolean(0.5)) vx = -vx;
    vy = 2.0; // Vertical Direction

/** Checks if the ball collided or not with an object */

private void verificarColisaoBola () {

    GObject objColisao = getObjColisao(); // The object with wich the ball colided

    if (objColisao == raquete) { // If colidded with paddle
        vy = -vy; // Change vertical tranjectory of ball
        // prevents that the ball get "glued" to the paddle
        bola.setLocation(bola.getX(),bola.getY() - PADDLE_HEIGHT / 2);

        // Changes the direction of the ball when it hits the borders of the paddle - provides the player more control
        if ((bola.getX() < raquete.getX() + 0.20 * raquete.getWidth() && vx > 0)
            || (bola.getX() > raquete.getX() + 0.80 * raquete.getWidth() && vx < 0)) {
            vx = -vx;
        }

    } else if (objColisao != null) { // Colision with a brick
        remove (objColisao); // remove the brick
        nTijolos--; // counts one less brick
        vy = -vy; // Changes vertical direction
}

/** Finds if the limits of the ball - 4 corners - hits an object  
 * @return The object that collided with the ball - or null */

private GObject getObjColisao () {
    if (getElementAt (bola.getX(), bola.getY()) != null) { // Top left corner
        return getElementAt (bola.getX(), bola.getY());
    } else if (getElementAt (bola.getX() + bola.getWidth(), bola.getY()) != null) { // Top Right corner
        return getElementAt (bola.getX() + bola.getWidth(), bola.getY());
    } else if (getElementAt (bola.getX(), bola.getY() + bola.getWidth()) != null) { // Bottom Left corner
        return getElementAt (bola.getX(), bola.getY() + bola.getWidth());
    } else if (getElementAt (bola.getX() + bola.getWidth(), bola.getY() + bola.getWidth()) != null) { // Bottom Right corner
        return getElementAt (bola.getX() + bola.getWidth(), bola.getY() + bola.getWidth());
    } else {
        return null;
    }
}

Заранее спасибо за помощь!

1 ответ

Вы должны проверить свой временной шаг. Скорость с большими временными шагами часто заставляет объекты поражать несколько элементов на следующем временном шаге. Поэтому сделайте шаг меньше, чтобы обнаружение столкновений происходило чаще.

Вы также должны сделать более умный анализ и проверить первый кирпич, который вы бы ударили (тот, у которого значение max/min x или y), а затем остановиться на этом. Затем вам нужно будет рассчитать окончательное местоположение мяча после этого столкновения, чтобы даже при большом временном шаге шарик действовал так, как должен.

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