В игре, которую я создаю, идея состоит в том, что курсор мыши представляет центр масс, и вокруг него вращаются объекты.Сам курсор не является объектом, и между курсором и объектами нет столкновения.
Идеальным методом будет тот, в котором я могу ввести x и y координаты цели и, возможно, радиус орбиты, и объект выйдет на орбитуи будет ускоряться постоянно.
Когда я перемещаю мышь, объект будет следовать;и когда я остановлю его, он упадет на тот же радиус орбиты.
Ускорение объектов также должно меняться, так что это дает эффект, что мышь имеет большую или меньшую массу.
Я думал, что лучший способ достичь этого, вероятно, будет с векторами.
В классе «Снаряд» я дал каждому полету по 4 поля: координата x, координата y, скорость PVector и соотношения PVector (ускорение).
Первое, что я попробовал, это дать объекту постоянное ускорение.Вектор скорости начинается с нуля, вектор ускорения вычисляется, его величина затем устанавливается на некоторое значение и добавляется к вектору скорости.Это создавало очень большие орбиты, медленное ускорение, и когда мышь перемещалась, орбита становилась больше.
Далее я попытался увеличить ускорение, когда оно ближе к центру масс, вдохновленному реальными планетами.Это тоже не сработало.Орбиты были все еще слишком большими и неуправляемыми.Вроде разочарован, я пытался сделать ускорение постоянно увеличивающимся, что дало лучшие результаты.Теперь орбита становится меньше, но она продолжает уменьшаться до некоторого радиуса и затем останавливается.Это было бы идеально, если бы радиус, при котором он прекращал уменьшаться, был бы настраиваемым, но независимо от параметров, орбита всегда слишком велика, а размер орбиты постоянно уменьшался до безумия.Я предполагаю, что ускорение и скорость каким-то образом оказываются в равновесии, а затем орбита перестает уменьшаться.
void move(float x,float y,float accm)
{
PVector target = new PVector(x, y);
PVector ball = new PVector(this.x, this.y);
acc = PVector.sub(target, ball);
acc.setMag(accm);
speed.add(acc);
println(acc.mag() + " " + speed.mag());
this.x = this.x + speed.x;
this.y = this.y + speed.y;
}
Эта функция дала наилучшие результаты.Функция вызывается в draw()
:
if(mousePressed == true)
{
for(i=0;i<nproj;i++)
{
a[i].move(mouseX, mouseY,k);
}
k += n;
}
k - число, данное функции, а n - скорость, с которой ускорение увеличивается.Я пробовал много разных величин ускорения и разных скоростей ускорения и просто не мог понять это.Nproj - количество снарядов, a - название массива снарядов.
Я обнаружил, что для k = 0 и n = 0,002 он дает наиболее надежные и стабильные результаты.Если n больше (около 0,01 или больше), объекты иногда случайным образом отлетают намного дальше, чем ожидалось, и это фактически увеличивает радиус орбиты.По мере увеличения ускорения это происходит чаще, и объект иногда оказывается за пределами экрана, а затем никогда не возвращается.Я знаю, что радиус орбиты не существует, потому что орбиты эллиптические, но это просто облегчает объяснение.
Обновление: это то, что я до сих пор придумал
void move(float x,float y,float accm)
{
PVector target = new PVector(x, y);
PVector ball = new PVector(this.x, this.y);
acc = PVector.sub(target, ball);
acc.setMag(accm);
vel.add(acc);
this.x = this.x + vel.x;
this.y = this.y + vel.y;
vel.limit(15);
}
и в draw()
if(mousePressed == true)
{
for(i=0;i<nproj;i++)
{
a[i].move(mouseX, mouseY,k);
}
k += n;
if(k > 25)
n = 0;
}
Ограничивая вектор скорости и постоянно увеличивая вектор ускорения, разность величин начинает увеличиваться, и поскольку вектор ускорения увеличивается, а вектор скорости постоянен, а вектор ускорения направлен к целисумма векторов начинает медленно указывать все больше и больше на цель.Условие if(k < 25)
ограничивает ускорение, и, изменяя предел ускорения, вы можете изменить радиус орбиты.