# Top down space game control problem

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

}
``````
-
Can you describe FlatSpace 2's control scheme? – user744 Oct 1 '10 at 16:24
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 '14 at 6:32

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
}
``````
-
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
– 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;
}
``````