2013-07-22 3 views
0

Im используя технику для управления спрайтом, поворачивая влево/вправо, а затем ускоряясь вперед. У меня есть 2 вопроса. (Код она склеена из разных классов из-за полиморфизм. Если это не имеет смысла, дайте мне знать. Движение хорошо работает и обнаружение экрана выключены, а.)Держите Вращающийся спрайт от выхода с экрана, но возвращайтесь назад.

  1. Когда игрок перемещает выключение экрана я вызываю метод Bounce. Я хочу, чтобы игрок не мог передвигаться с экрана, но чтобы изменить направление и вернуться. Это работает сверху и снизу, но левый и правый края очень редко. Главным образом он делает wierd отскок и оставляет экран.

  2. Я хотел бы изменить алгоритм ускорения, чтобы установить максимальную скорость и скорость ускорения. Atm TangentalVelocity делает оба.

float TangentalVelocity = 8f;  

//Called when up arrow is down 
private void Accelerate() 
{ 
    Velocity.X = (float)Math.Cos(Rotation) * TangentalVelocity; 
    Velocity.Y = (float)Math.Sin(Rotation) * TangentalVelocity; 
} 

//Called once per update 
private void Deccelerate() 
{ 
    Velocity.X = Velocity.X -= Friction * Velocity.X; 
    Velocity.Y = Velocity.Y -= Friction * Velocity.Y; 
} 
// Called when player hits screen edge 
private void Bounce() 
{ 
    Rotation = Rotation * -1; 
    Velocity = Velocity * -1; 
    SoundManager.Vulture.Play(); 
} 

//screen edge detection 
public void CheckForOutOfScreen() 
{ 

    //Check if ABOVE screen 
    if (Position.Y - Origin.Y/2 < GameEngine.Viewport.Y) { OnExitScreen(); } 
    else 
     //Check if BELOW screen 
     if (Position.Y + Origin.Y/2 > GameEngine.Viewport.Height) { OnExitScreen(); } 
     else 
     //Check if RIGHT of screen 
     if (this.Position.X + Origin.X/2 > GameEngine.Viewport.Width) { OnExitScreen(); } 
     else 
      //Check if LEFT of screen 
      if (this.Position.X - Origin.X/2 < GameEngine.Viewport.X) { OnExitScreen(); } 
      else 
      { 
       if (OnScreen == false) 
       OnScreen = true; 
      } 
} 

    virtual public void OnExitScreen() 
    { 
     OnScreen = false; 
     Bounce(); 
    } 

ответ

0

Давайте посмотрим, если я правильно понял. Во-первых, вы вращаете свой спрайт. После этого вы ускоряете его вперед. В этом случае:

// Called when player hits screen edge 
private void Bounce() 
{ 
    Rotation = Rotation * -1; 
    Velocity = Velocity * -1; //I THINK THIS IS THE PROBLEM 
    SoundManager.Vulture.Play(); 
} 

Давайте ограничимся тем, что ваш спрайт не имеет поворота, когда он смотрит вверх. В этом случае, если он выглядит правильно, он поворачивается на 90º, а его скорость равна v = (x, 0), при x> 0. Когда он выходит из экрана, его вращение становится -90º, а скорость v = (- x, 0). НО вы нажимаете клавишу «вверх», и метод ускорения называется так сразу, что скорость снова становится v = (x, 0). Спрайт снова выходит из экрана, меняет свою скорость на v = (-x, 0) и т. Д. Это вызывает странный отскок. Я хотел бы попробовать сделать это:

private void Bounce() 
{ 
    Rotation = Rotation * -1; 
    SoundManager.Vulture.Play(); 
} 

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

Ваш второй вопрос ... Это немного сложно. В физике вещи достигают максимальной скорости, потому что сила трения воздуха (или другая сила) равна , зависящей от скорости. Итак, если вы увеличиваете скорость, сила также увеличивается ... в конце, эта сила будет балансировать другую, и скорость будет постоянной. Я думаю, что лучший способ моделирования конечной скорости - использовать эту концепцию. Если вы хотите узнать больше о предельной скорости, посмотрите в Википедии: http://en.wikipedia.org/wiki/Terminal_velocity

private void Accelerate() 
{ 
    Acceleration.X = Math.abs(MotorForce - airFriction.X); 
    Acceleration.Y = Math.abs(MotorForce - airFriction.Y); 

    if (Acceleration.X < 0) 
    { 
     Acceleration.X = 0; 
    } 
    if (Acceleration.Y < 0) 
    { 
     Acceleration.Y = 0; 
    } 


    Velocity.X += (float)Math.Cos(Rotation) * Acceleration.X 
    Velocity.Y += (float)Math.Sin(Rotation) * Acceleration.Y 

    airFriction.X = Math.abs(airFrictionConstant * Velocity.X); 
    airFriction.Y = Math.abs(airFrictionConstant * Velocity.Y); 
} 

Во-первых, мы вычислим accelartion с помощью «MotorForce» и трение воздуха. MotorForce - это сила, которую мы делаем для перемещения нашего спрайта. Воздушное трение всегда пытается «устранить» движение, поэтому оно всегда является постом. Мы, наконец, принимаем абсолютные значения, потому что вращение дает нам направление вектора. Если ускорение меньше 0, это означает, что трение воздуха больше, чем у нашего MotorForce. Это трение, поэтому он не может этого сделать: если ускорение < 0, мы делаем это 0 - воздушная сила достигла нашей двигательной силы, и скорость становится постоянной. После этого скорость будет увеличиваться с использованием ускорения. Наконец, мы обновляем значение трения.

Еще одно: вы можете обновить значение airFriction в методе Deccelarate, даже если вы не рассматриваете его в этом методе.

Если у вас есть какие-либо проблемы с этим, или вы что-то не понимаете (иногда мой английский не очень хорош ^^ "), скажите это =)