Как правильно настроить скорость спрайта игрока? (В основном математический вопрос?) - PullRequest
2 голосов
/ 07 сентября 2010

Предыстория: у меня есть JavaScript-игра с высоты птичьего полета, где игрок управляет космическим кораблем, касаясь круга - например, коснитесь слева от центра круга, и корабль будет двигаться влево, коснитесь верхнего правого края и он переместится в верхний правый угол и т. д. Чем дальше от центра круга псевдо-джойстика, тем больше скорость в этом направление. Тем не менее, я не регулирую скорость корабля напрямую, а устанавливаю значения targetSpeed.x и targetSpeed.y, и тогда корабль будет регулировать свою скорость, используя что-то вроде:

if (this.speed.x < this.targetSpeed.x) {
    this.speed.x += this.speedStep;
}
else if (this.speed.x > this.targetSpeed.x) {
    this.speed.x -= this.speedStep;
}

... и то же самое для скорости y, и speedStep - это небольшое значение, чтобы сделать его более плавным и не слишком резким (корабль не должен двигаться из быстрого левого направления в непосредственное быстрое правое направление).

Мой вопрос: используя приведенный выше код, я считаю, что скорость будет регулироваться быстрее в диагональных направлениях и медленнее вдоль горизонтальных / вертикальных линий. Как я могу исправить это, чтобы иметь равную целевую скорость после?

Большое спасибо за любую помощь!

Ответы [ 2 ]

5 голосов
/ 07 сентября 2010
var xdiff = targetSpeed.x - speed.x;
var ydiff = targetSpeed.y - speed.y;
var angle = Math.atan2(ydiff, xdiff);
speed.x += speedStep * Math.cos(angle);
speed.y += speedStep * Math.sin(angle);
1 голос
/ 07 сентября 2010

Предполагая, что вы уже проверили, что касание находится внутри круга, и что край круга представляет максимальную скорость, и что центр круга равен circleTouch == [0, 0]

В некотором C ++ -подобном псевдокоде:

Scalar circleRadius = ...;
Scalar maxSpeed = ...;
Scalar acceleration = ...;

Vector calculateTargetSpeed( Vector circleTouch ) {
    Vector targetSpeed = maxSpeed * circleTouch / circleRadius;

    return targetSpeed;
}

Vector calculateNewSpeed( Vector currentSpeed, Vector targetSpeed ) {
    Vector speedDiff = targetSpeed - currentSpeed;

    Vector newSpeed = currentSpeed + acceleration * normalized(speedDiff);

    return newSpeed;
}

// Divide v by its length to get normalized vector (length 1) with same x/y ratio
Vector normalized( Vector v ) {
    return v / length(v);
}

// Pythagoras for the length of v
Scalar length( Vector v ) {
    Scalar length = sqrt(v.x * v.x + v.y * v.y); // or preferably hypot(v.x, v.y)

    return length;
}

Это просто у меня на макушке, и я не проверял это.Другой ответ - хорошо, я просто хотел дать ответ без тригонометрических функций.:)

...