Problema de controle de jogo espacial de cima para baixo

8

Como o título sugere, estou desenvolvendo um jogo espacial de cima para baixo.

Eu não estou olhando para usar a física newtoniana com a nave controlada pelo jogador. Estou tentando alcançar um esquema de controle um pouco semelhante ao do FlatSpace 2 (jogo incrível). Não consigo descobrir como alcançar esse sentimento com os controles do teclado, em vez dos controles do mouse. Alguma sugestão?

Estou usando Unity3d e C # ou javaScript (unityScript ou qualquer que seja o termo correto) funcione bem se você quiser soltar alguns exemplos de código.

Edit: Claro que eu deveria descrever o esquema de controle do FlatSpace 2, desculpe. Você mantém o botão do mouse pressionado e move o mouse na direção em que deseja que a nave se mova. Mas não são os controles que não sei fazer, mas a sensação de uma mistura de dirigir um carro e pilotar uma aeronave. É muito bem feito. Link do YouTube: FlatSpace2 no iPhone

Não estou desenvolvendo um jogo para iPhone, mas o vídeo mostra o princípio do estilo de movimento.
Edit 2 Como parece haver um ligeiro interesse, publicarei a versão do código que usei para continuar. Funciona bem o suficiente. Às vezes, bom o suficiente é 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
fonte
2
Você pode descrever o esquema de controle do FlatSpace 2?
4
Newtoniano, depois de Isaac Newton.
Gregory Avery-Weir
@ Joe - Adicionado explicação e link.
Phil
O espaço plano parece usar a física "newtoniana" normal, como a maioria dos jogos. Parece que os navios recebem aceleração média, baixa velocidade máxima e arrasto alto, o que confere ao usuário alto controle.
BlueRaja - Danny Pflughoeft 01/02

Respostas:

4

Então, se eu entendi direito, você quer que as setas esquerda e direita girem sua nave e as setas para cima e para baixo para controlar o impulso.

Eu implementei esse esquema de controle em um protótipo de atirador espacial que fiz uma vez.

O código abaixo é um exemplo de código específico não-idioma muito ingênuo. Não leve muito a sério.

EDIT: Ops, o código não limita a aceleração negativa causada pelo atrito. Assim, o navio começará a recuar depois de um tempo. Então, mudou o "código" um pouco.

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
}
Nailer
fonte
Tentei portá-lo para codificar, mas não consegui fazê-lo funcionar. Tenho certeza de que o problema é que não consigo entender minha solução. A parte após a entrada é onde você me perdeu.
Phil
Sugiro que você pesquise vídeos no YouTube sobre Cinemática. Aqui está um exemplo da matemática por trás: directionVector = Vector2 (cos (shipRotationAngle), sin (shipRotationAngle)) youtube.com/watch?v=rGFaVoz2Jig&feature=related
Nailer
1

eu converti o código psuedo em 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;
}

Se houver algo errado com isso, deixe um comentário.

Agradecimentos a Nailer por fornecer o código psuedo

Joe the Person
fonte
Houve alguns problemas. Eu os corrigi e publiquei o código atualizado na minha pergunta.
Phil
@zanlok oops, parecia que eu passei por isso um pouco rápido demais ...
Joe Pessoa