Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

As the title suggests I'm developing a top down space game.

I'm not looking to use newtonian physics with the player controlled ship. I'm trying to achieve a control scheme somewhat similar to that of FlatSpace 2 (awesome game). I can't figure out how to achieve this feeling with keyboard controls as opposed to mouse controls though. Any suggestions?

I'm using Unity3d and C# or javaScript (unityScript or whatever is the correct term) works fine if you want to drop some code examples.

Edit: Of course I should describe FlatSpace 2's control scheme, sorry. You hold the mouse button down and move the mouse in the direction you want the ship to move in. But it's not the controls I don't know how to do but rather the feeling of a mix of driving a car and flying an aircraft. It's really well made. Youtube link: FlatSpace2 on iPhone

I'm not developing an iPhone game but the video shows the principle of the movement style.
Edit 2 As there seems to be a slight interest, I'll post the version of the code I've used to continue. It works good enough. Sometimes good enough is sufficient!

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);
    }

}
share|improve this question
2  
Can you describe FlatSpace 2's control scheme? –  user744 Oct 1 '10 at 16:24
4  
Newtonian, after Isaac Newton. –  Gregory Avery-Weir Oct 1 '10 at 17:31
    
@Gregory - Of course, how silly of me. Thanks –  Phil Oct 4 '10 at 8:11
    
@Joe - Added explanation and link. –  Phil Oct 4 '10 at 8:12
    
Flatspace appears to use normal "Newtonian" physics, like most games. It looks like ships are given medium acceleration, a low max-velocity, and high drag, which gives the user high control. –  BlueRaja - Danny Pflughoeft Feb 1 at 6:32

2 Answers 2

up vote 4 down vote accepted

So if I understand correctly, you want left and right arrows to turn your ship, and up and down arrows to control thrust.

I have implemented this control scheme in a space shooter prototype I made once.

The below code is very naive non-language specific code example. Don't take it too literally.

EDIT: OOps, the code doesn't cap negative acceleration caused by friction. So the ship will actually start going backwards after a while. So changed the "code" a bit.

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
}
share|improve this answer
    
Thanks, I'll try this out ASAP. –  Phil Oct 6 '10 at 13:25
    
I tried to port it to code but couldn't get it to work.. I'm sure the problem is that I can't really get my head around your solution. The part after the input is where you lost me. –  Phil Oct 6 '10 at 16:16
    
I suggest you search for videos on YouTube about Kinematics. Here's an example of the math behind: directionVector = Vector2( cos( shipRotationAngle ), sin ( shipRotationAngle ) ) youtube.com/watch?v=rGFaVoz2Jig&feature=related –  Nailer Oct 6 '10 at 17:39
    
Also: gamedev.stackexchange.com/questions/4336/… –  Nailer Oct 7 '10 at 15:08
    
Thanks, I'll check it out! –  Phil Oct 8 '10 at 15:52

i converted the psuedo-code into 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;
}

If there is something wrong with this, please leave a comment.

Thanks to Nailer for providing psuedo-code

share|improve this answer
    
There were some issues. I corrected them and have posted the updated code in my question. –  Phil Dec 14 '10 at 0:32
    
@zanlok oops, looked like i went through that a little too fast... –  Joe the Person Dec 15 '10 at 0:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.