Движение "Галактическое движение" - программирование
Подтвердить что ты не робот

Движение "Галактическое движение"

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

position.X -= (Motion.X / Magnitude) * Speed;
position.Y -= (Motion.Y / Magnitude) * Speed;

Движение выработано:

this.Motion = InitialPosition - Destination;

Это заставляет их перемещаться по прямой линии к месту назначения.

Тем не менее, я хочу сделать их немного интереснее и путешествовать по греху или волне cos, немного похож на Galaxian.

Как я могу это сделать?

4b9b3361

Ответ 1

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

Вот ссылка на учебник по математике кривых Безье. Это довольно длинный документ, но он неплохо справляется с рассмотрением математики с большим количеством примеров.

Надеюсь, что это поможет вам вдохновить.

Ответ 2

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

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

Вы можете сделать то же самое и с вертикальной, хотя, конечно, пределы ускорения будут очень разными... для горизонтального ускорения вы, вероятно, захотите определить диапазон, который был бы равен по величине с обеих сторон от 0 (скажем от 0,02 до + 0,02), в то время как для вертикального ускорения вы, вероятно, всегда хотите, чтобы корабль в конечном итоге опустился вниз от экрана, поэтому вы, вероятно, хотите, чтобы ускорение всегда оказывалось положительным (или отрицательный в зависимости от того, как вы выполняете экранные координаты.)

Ответ 3

Вы сделали бы это, используя путевую точку в соответствии с вашим текущим кодом движения. Вы бы вычислили путевые точки, построив синусоидальную волну. Вы сделали бы это, используя что-то, что могло бы повлиять на Destination.Y = Math.Sin(Destination.X) - это немного сложно сказать, не видя ваш код в целом.

Ответ 4

Создание осциллятора и перемещение противника (даже без импульса) перпендикулярно его направлению смещением, равным синусу или косинусу осциллятора, будет достаточно.

Следующий пример, во время работы, явно является лишь ориентиром. Надеюсь, это поможет вам.

var dest = new PointF(200, 100);
var pos = new PointF(30, 140);
var oscAngle = 0d;
var dirAngle = Math.Atan2(dest.Y - pos.Y, dest.X - pos.X);
//Constants for your simulation
const int movSpeed = 2;
const int amp = 2;
const double frequency = Math.PI / 5;
//Inappropriate loop condition, change it to proper
while (true)
{
    oscAngle += frequency;
    //Scalar offset, you can use Cos as well
    var oscDelta = Math.Sin(oscAngle);
    //Linear movement
    var stepVector = new SizeF((float)(Math.Cos(dirAngle) * movSpeed), (float)(Math.Sin(dirAngle) * movSpeed));
    //Oscillating movement, making it transversal by adding 90° to the direction angle
    var oscNormalAngle = dirAngle + Math.PI / 2;
    //Vector for the oscillation
    var oscVector = new SizeF((float)(Math.Cos(oscNormalAngle) * oscDelta) * amp, (float)(Math.Sin(oscNormalAngle) * oscDelta) * amp);
    pos += stepVector + oscVector;
    //Operate below
}