Математика прыжка в 2D игре - PullRequest
8 голосов
/ 29 мая 2009

Я работаю в J2ME, мой gameloop делает следующее:

public void run() {
        Graphics g = this.getGraphics();
        while (running) {
            long diff = System.currentTimeMillis() - lastLoop;
            lastLoop = System.currentTimeMillis();
            input();
            this.level.doLogic();
            render(g, diff);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                stop(e);
            }
        }
    }

Так что это просто основной игровой цикл, функция doLogic() вызывает все логические функции персонажей сцены, а render(g, diff) вызывает функцию animateChar каждого персонажа на сцене, после чего animChar Функция в классе Character устанавливает все на экране следующим образом:

protected void animChar(long diff) {
        this.checkGravity();
        this.move((int) ((diff * this.dx) / 1000), (int) ((diff * this.dy) / 1000));
        if (this.acumFrame > this.framerate) {
            this.nextFrame();
            this.acumFrame = 0;
        } else {
            this.acumFrame += diff;
        }
    }

Это гарантирует мне, что все должно двигаться в соответствии со временем, которое требуется машине для перехода от цикла к циклу (помните, что это телефон, а не игровая установка). Я уверен, что это не самый эффективный способ добиться такого поведения, поэтому я полностью открыт для критики моих навыков программирования в комментариях, но здесь моя проблема: когда я заставляю своего персонажа прыгать, то, что я делаю, - это помещаю его dy к отрицательному значению, скажем -200, и я установил логическое значение jumping в значение true, которое заставляет персонажа повышаться, и затем у меня есть эта функция с именем checkGravity(), которая обеспечивает все, что идет вверх, должно идти вниз, checkGravity также проверяет наличие персонажа над платформами, так что я немного урежу его ради вашего времени:

public void checkGravity() {
        if (this.jumping) {
            this.jumpSpeed += 10;
            if (this.jumpSpeed > 0) {
                this.jumping = false;
                this.falling = true;
            }
            this.dy = this.jumpSpeed;
        }
        if (this.falling) {
            this.jumpSpeed += 10;
            if (this.jumpSpeed > 200) this.jumpSpeed = 200;
            this.dy = this.jumpSpeed;
            if (this.collidesWithPlatform()) {
                this.falling = false;
                this.standing = true;
                this.jumping = false;
                this.jumpSpeed = 0;
                this.dy = this.jumpSpeed;
            }
        }
    }

Итак, проблема в том, что эта функция обновляет dy независимо от diff , заставляя персонажей летать как Супермен на медленных машинах, и я понятия не имею, как реализовать коэффициент diff , так что когда персонаж прыгает, его скорость уменьшается пропорционально скорости игры. Может кто-нибудь помочь мне решить эту проблему? Или подскажите, как правильно сделать 2D-прыжок в J2ME .

Ответы [ 4 ]

5 голосов
/ 29 мая 2009

Разве вы не должны регулировать jumpSpeed ​​на основе истекшего времени? То есть, возможно, скорость изменяется на -75 / сек, поэтому ваш diff должен быть весом для количества изменений, примененных к jumpSpeed.

Так что перейдите в diff к checkGrav и сделайте что-то вроде ... jumpSpeed ​​+ = (diff * (rate_per_second)) / 1000;

(при условии различий в миллисекундах)

(В идеале это было бы так же, как настоящая гравитация: D)

3 голосов
/ 29 мая 2009

Почему бы просто не масштабировать все константы с помощью diff?

Кстати, мне стыдно об этом говорить, но я работал над коммерческой игрой, в которой гравитация вдвое сильнее, чем у персонажей, падающих вверх. Почему-то люди предпочли это.

0 голосов
/ 22 апреля 2010

Я могу дать такую ​​формулу (я использую ее везде). X - это параметр, начиная с нуля и заканчивая длиной прыжка. если вы хотите, чтобы кто-то прыгнул на некоторой высоте (H) и некоторой длине (L), то функция прыжка будет выглядеть следующим образом (и никогда не сможет выглядеть иначе):

y = минус (мощность (x - длина прыжка, деленная на два) умножить на 4 и умножить на высоту прыжка) разделить на степень длины и сложить Высота прыжка в самом конце.

y = - (x-l / 2) (x-l / 2) * 4 * h / (l * l) + h

И если вы хотите, чтобы прыгающий объект приземлился на что-то, то вы можете проверить каждый новый X, если он приблизительно стоит на платформе и если он стоит на чем-то, то не останавливайте его, установите его в положение Y точно равный Y платформы.

Если вы используете что-то вроде Flash или другую базу с инвертированной осью y, умножьте выход функции на -1;

0 голосов
/ 29 мая 2009

Кажется, это больше вопрос игрового дизайна, чем математика прыжка. Общей проблемой является то, что в играх, работающих на разных процессорах, одна игра будет выполняться быстрее, а в других играх она будет выполняться медленнее (таким образом, изменяя всю скорость игры). Я не уверен, что является обычной практикой в ​​играх, но всякий раз, когда я делал домашние 2D-игры (их было весело делать), у меня возникала концепция игрового тика. На более быстрых машинах

long diff = System.currentTimeMillis() - lastLoop;
lastLoop = System.currentTimeMillis();

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

...