Problema de control de juego espacial de arriba hacia abajo

8

Como sugiere el título, estoy desarrollando un juego espacial de arriba abajo.

No estoy buscando usar la física newtoniana con la nave controlada por el jugador. Estoy tratando de lograr un esquema de control algo similar al de FlatSpace 2 (juego increíble). Sin embargo, no puedo entender cómo lograr esta sensación con los controles del teclado en comparación con los controles del mouse. ¿Alguna sugerencia?

Estoy usando Unity3d y C # o javaScript (unityScript o el término correcto) funciona bien si desea colocar algunos ejemplos de código.

Editar: Por supuesto, debería describir el esquema de control de FlatSpace 2, lo siento. Mantenga presionado el botón del mouse y mueva el mouse en la dirección en que desea que se mueva la nave. Pero no son los controles los que no sé cómo hacer, sino la sensación de una combinación de conducir un automóvil y volar un avión. Está muy bien hecho. Enlace de Youtube: FlatSpace2 en iPhone

No estoy desarrollando un juego para iPhone, pero el video muestra el principio del estilo de movimiento.
Editar 2 Como parece haber un ligero interés, publicaré la versión del código que he usado para continuar. Funciona lo suficientemente bien. ¡A veces lo suficientemente bueno es suficiente!

using UnityEngine;
using System.Collections;

public class ShipMovement : MonoBehaviour 
{
    public float directionModifier;
    float shipRotationAngle;
    public float shipRotationSpeed = 0;
    public double thrustModifier;
    public double accelerationModifier;
    public double shipBaseAcceleration = 0;
    public Vector2 directionVector;
    public Vector2 accelerationVector = new Vector2(0,0);
    public Vector2 frictionVector = new Vector2(0,0);
    public int shipFriction = 0;
    public Vector2 shipSpeedVector;
    public Vector2 shipPositionVector;
    public Vector2 speedCap = new Vector2(0,0);

    void Update() 
    {

   directionModifier = -Input.GetAxis("Horizontal");


   shipRotationAngle += ( shipRotationSpeed * directionModifier ) * Time.deltaTime;


   thrustModifier = Input.GetAxis("Vertical");

   accelerationModifier = ( ( shipBaseAcceleration * thrustModifier ) ) * Time.deltaTime;

   directionVector = new Vector2( Mathf.Cos(shipRotationAngle ), Mathf.Sin(shipRotationAngle) );
   //accelerationVector = Vector2(directionVector.x * System.Convert.ToDouble(accelerationModifier), directionVector.y * System.Convert.ToDouble(accelerationModifier));
   accelerationVector.x = directionVector.x * (float)accelerationModifier;
    accelerationVector.y = directionVector.y * (float)accelerationModifier;
   // Set friction based on how "floaty" controls you want

    shipSpeedVector.x *= 0.9f; //Use a variable here
    shipSpeedVector.y *= 0.9f; //<-- as well
   shipSpeedVector += accelerationVector;


   shipPositionVector += shipSpeedVector;

   gameObject.transform.position = new Vector3(shipPositionVector.x, 0, shipPositionVector.y);
    }

}
Phil
fuente
2
¿Puedes describir el esquema de control de FlatSpace 2?
44
Newtoniano, después de Isaac Newton.
Gregory Avery-Weir
@ Joe - Explicación agregada y enlace.
Phil
Flatspace parece usar física "newtoniana" normal, como la mayoría de los juegos. Parece que a los barcos se les da una aceleración media, una velocidad máxima baja y un arrastre alto, lo que le da al usuario un alto control.
BlueRaja - Danny Pflughoeft

Respuestas:

4

Entonces, si entiendo correctamente, quieres que las flechas izquierda y derecha giren tu nave, y las flechas arriba y abajo para controlar el empuje.

He implementado este esquema de control en un prototipo de tirador espacial que hice una vez.

El siguiente código es un ejemplo de código no ingenioso, específico de un idioma. No lo tomes demasiado literalmente.

EDITAR: OOps, el código no limita la aceleración negativa causada por la fricción. Entonces la nave comenzará a retroceder después de un tiempo. Así que cambió el "código" un poco.

update( deltaTime ) 
{

   if( leftButtonPressed ) 
   { 
      directionModifier = 1
   }
   else if ( rightButtonPressed ) {
      directionModifier = -1
   }
   else {
     directionModifier = 0;
   }

   shipRotationAngle += ( shipRotationSpeed * directionModifier ) * deltaTime;


   if( upButtonPressed ) {
     thrustModifier = 1
   }
   else if( downButtonPressed ) {
     thrustModifier = -1
   }
   else {
     thrustModifier = 0
   }



   accelerationModifier = ( ( shipBaseAcceleration * thrustModifier ) ) * deltaTime

   directionVector = Vector2( cos( shipRotationAngle ), sin ( shipRotationAngle ) )
   accelerationVector = Vector2( directionVector.x * accelerationModifier, directionVector.y * accelerationModifier )

   // Set friction based on how "floaty" controls you want
   frictionVector = -directionVector * shipFriction

   shipSpeedVector += accelerationVector

   // APPLY friction vector to shipSpeedVector
   // Make sure that friction vector doesn't speed to go in the opposite of the 
   // original direction. Otherwise your ship will go backwards instead of stop.

   //IMPORTANT: (I'm too lazy to add code here) Cap speedvector to a maximum speed.
   //Remember to cap total speed, not just X and Y components of the speedVector 


   shipPositionVector += shipSpeedVector
}
Fabricante de clavos
fuente
Traté de portarlo al código pero no pude hacerlo funcionar. Estoy seguro de que el problema es que realmente no puedo entender su solución. La parte después de la entrada es donde me perdiste.
Phil
Le sugiero que busque videos en YouTube sobre cinemática. Aquí hay un ejemplo de las matemáticas detrás: directionVector = Vector2 (cos (shipRotationAngle), sin (shipRotationAngle)) youtube.com/watch?v=rGFaVoz2Jig&feature=related
Nailer
1

Convertí el código psuedo en C #:

void Update() 
{

   directionModifier = Input.GetAxis("Horizontal");


   shipRotationAngle += ( shipRotationSpeed * directionModifier ) * Time.deltaTime;


   thrustModifier = Input.GetAxis("Vertical");

   accelerationModifier = ( ( shipBaseAcceleration * thrustModifier ) ) * Time.deltaTime;

   directionVector = new Vector2( Math.Cos(shipRotationAngle ), Math.Sin(shipRotationAngle) );
   accelerationVector = new Vector2( directionVector.x * accelerationModifier, directionVector.y * accelerationModifier );

   // Set friction based on how "floaty" controls you want
   frictionVector = -directionVector * shipFriction;

   shipSpeedVector += accelerationVector;

   // APPLY friction vector to shipSpeedVector
   // Make sure that friction vector doesn't speed to go in the opposite of the 
   // original direction. Otherwise your ship will go backwards instead of stop.

   //IMPORTANT: (I'm too lazy to add code here) Cap speedvector to a maximum speed.
   //Remember to cap total speed, not just X and Y components of the speedVector 


   shipPositionVector += shipSpeedVector;
}

Si hay algo mal con esto, por favor deje un comentario.

Gracias a Nailer por proporcionar el código psuedo

Joe la persona
fuente
Hubo algunos problemas. Los corregí y publiqué el código actualizado en mi pregunta.
Phil
@zanlok oops, parecía que pasé por eso demasiado rápido ...
Joe the Person