Математика прыжка в 2D-игре

Я работаю в 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);
            }
        }
    }

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

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 и я устанавливаю логическое прыжки в 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 ответов


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

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

(предполагая разницу в миллисекундах)

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


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

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


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

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

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


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

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

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

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

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