Математика прыжка в 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;