views:

246

answers:

2

I'm working on my first video game for the Android platform as a bit of a nights and weekends project.

It is coming along nicely, but I am very unhappy with the control sensativity.

In this game, you move an object left and right on the screen. On the bottom of the screen is a "touchpad" of sorts, which is where your finger should rest.

/-------------------------\
|                         |
|                         |
|                         |
|       Game Area         |
|                         |
|                         |
|                         |
|                         |
|                         |
/-------------------------\
|                         |
|       Touch Area        |
|                         |
\-------------------------/

I am currently using a state variable to hold "MOVING_LEFT, MOVING_RIGHT, NOT_MOVING" and am updating the location of the player object each frame based on that variable.

However, my code that reads the touchscreen input and sets this state variable is either too sensative, or too laggy, depending on how I tweak it:

public void doTouch (MotionEvent e) {
 int action = e.getAction();

 if (action == MotionEvent.ACTION_DOWN) {
  this.mTouchX = (int)e.getX();
  this.mTouchY = (int)e.getY();   
 } 
 else if (action == MotionEvent.ACTION_MOVE) {
  if ((int)e.getX() >= this.mTouchX) {
   this.mTouchX = (int)e.getX();
   this.mTouchY = (int)e.getY(); 
   if (this.TouchRect.contains(this.mTouchX, this.mTouchY)) {    
    this.mTouchDirection = MOVING_RIGHT;
   }
  } 
  else if ((int)e.getX() <= this.mTouchX) {
   this.mTouchX = (int)e.getX();
   this.mTouchY = (int)e.getY();
   if (this.TouchRect.contains(this.mTouchX, this.mTouchY)) {    
    this.mTouchDirection = MOVING_LEFT;
   }
  }
  else {
   this.mTouchDirection = NOT_MOVING;
  }    
 } 
 else if (action == MotionEvent.ACTION_UP) {
  this.mTouchDirection = NOT_MOVING;
 }  
}

The idea is that when there is any movement, I check the previous location of the users finger and then figure out what direction to move the player.

This doesn't work very well, I figure there are some IPhone/Android developers on here who have figured out how to do good controls via a touchscreen and can give some advice.

+2  A: 

You could try something similar to "drag rectangles" on Windows. When you hold down the mouse button on something, you don't start a drag operation until the mouse moves outside a small region around the mouse-down location. Reason being that it's very hard to keep the cursor on the same pixel while clicking.

So a first attempt could be (int)e.getX() >= this.mTouchX + DEAD_ZONE and similar for the other case, where DEAD_ZONE is a small integer.

This does not deal with turning around in the same stroke, however. You could deal with that by only turning left when the current position is at least DEAD_ZONE pixels to the left of the last position after turning right, and vice versa.

Thomas
+2  A: 

One obvious problem is that nowhere do you take account of the time since the last touch.

I would suggest you treat the players touch as an expression of desired movement on an analogue range from -x/+x and -y/+y, then perform the actual movement elsewhere based on time.

E.g.

objectPos += objectPos + (joyPos * timeDelta * maxSpeed);

So if the max-speed of your object is 10ms-1 and the players finger is at 0.5 on the control pad then the object would be moving 5 meters every second. If your game is running at 10fps then each frame the object would move 0.5 meters.

These figures are fictional, but hopefully demonstrate the need to separate control from movement and then factor in time.

Andrew Grant