虚拟操纵杆 - 多个动作而不是一个动作
Virtual Joystick - multiple actions instead of one action
我正在使用此 website 中的虚拟操纵杆代码。
它工作正常但不适用于我的应用程序。
我在执行任何操作时遇到问题。在 JoyStick.class 中,我可以控制每个方向的范围,所以如果范围在特定角度和距离之间,它 returns 每个方向的 int 值。
public int get4Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 225 && angle < 315 ) {
return STICK_UP;
} else if(angle >= 315 || angle < 45 ) {
return STICK_RIGHT;
} else if(angle >= 45 && angle < 135 ) {
return STICK_DOWN;
} else if(angle >= 135 && angle < 225 ) {
return STICK_LEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
我用 System.out.println 来说明什么不适合我的申请。当我将棍子朝特定方向放置时,例如向上然后向左,它会生成如下输出:
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.017 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.037 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.117 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.137 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.157 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.167 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.187 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.207 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.217 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.317 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.337 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.357 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.377 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.387 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.407 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.427 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.437 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.457 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.477 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.487 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.507 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.527 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.537 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.557 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.577 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.587 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.607 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.627 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.637 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.657 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.677 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.687 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.707 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
其他方向多路输出同理。这对我来说是个问题,因为更复杂的操作会导致应用程序崩溃或应用程序运行速度非常慢,并且我会收到警告:
The application may be doing too much work on its main thread
有没有办法只输出一次?例如,如果摇杆在左方向的范围内,它只会产生一条线:
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
如果UP等
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
这都是关于使用 if/else 语句检查角度和距离,所以我正在寻找一种解决方案,它允许我对每个方向或类似的东西只检查一次这个范围。我尝试了一切,我使用了单选按钮、复选按钮、变量,但没有用,我无法获得一行输出。
完整代码:
JoyStick.class
主要活动:
public class MainActivity extends Activity {
RelativeLayout layout_joystick;
ImageView image_joystick, image_border;
TextView textView1, textView2, textView3, textView4, textView5;
JoyStickClass js;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView)findViewById(R.id.textView1);
textView2 = (TextView)findViewById(R.id.textView2);
textView3 = (TextView)findViewById(R.id.textView3);
textView4 = (TextView)findViewById(R.id.textView4);
textView5 = (TextView)findViewById(R.id.textView5);
layout_joystick = (RelativeLayout)findViewById(R.id.layout_joystick);
js = new JoyStickClass(getApplicationContext(), layout_joystick, R.drawable.redball2);
js.setStickSize(150, 150);
js.setLayoutSize(500, 500);
js.setLayoutAlpha(150);
js.setStickAlpha(100);
js.setOffset(90);
js.setMinimumDistance(50);
layout_joystick.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
js.drawStick(arg1);
if(arg1.getAction() == MotionEvent.ACTION_DOWN
|| arg1.getAction() == MotionEvent.ACTION_MOVE) {
textView1.setText("X : " + String.valueOf(js.getX()));
textView2.setText("Y : " + String.valueOf(js.getY()));
textView3.setText("Angle : " + String.valueOf(js.getAngle()));
textView4.setText("Distance : " + String.valueOf(js.getDistance()));
int direction = js.get4Direction();
if(direction == JoyStickClass.STICK_UP) {
textView5.setText("Direction : Up");
System.out.println("UP");
} else if(direction == JoyStickClass.STICK_RIGHT) {
textView5.setText("Direction : Right");
System.out.println("RIGHT");
} else if(direction == JoyStickClass.STICK_DOWN) {
textView5.setText("Direction : Down");
System.out.println("DOWN");
} else if(direction == JoyStickClass.STICK_LEFT) {
textView5.setText("Direction : Left");
System.out.println("LEFT");
} else if(direction == JoyStickClass.STICK_NONE) {
textView5.setText("Direction : Center");
System.out.println("CENTER");
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
textView1.setText("X :");
textView2.setText("Y :");
textView3.setText("Angle :");
textView4.setText("Distance :");
textView5.setText("Direction :");
}
return true;
}
});
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="X"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:text="Y"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView2"
android:text="Angle"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView3"
android:text="Distance"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView3"
android:text="Direction"
android:textColor="#444444"
android:textSize="20dp" />
</LinearLayout>
<RelativeLayout
android:id="@+id/layout_joystick"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_below="@+id/linearLayout1"
android:layout_centerHorizontal="true"
android:layout_marginTop="29dp"
android:background="@drawable/image_button_bg" >
</RelativeLayout>
这似乎是预期的行为,因为每 ACTION_DOWN
会触发一次,ACTION_MOVE
会触发多次。似乎 ACTION_MOVE
被调用了很多次。为避免对每个 ACTION_MOVE
事件进行处理,请尝试添加全局变量:
int prevDirection = 0;
然后在public boolean onTouch(View arg0, MotionEvent arg1)
添加条件:
...
int direction = js.get4Direction();
if (direction != prevDirection) {
if(direction == JoyStickClass.STICK_UP) {
textView5.setText("Direction : Up");
System.out.println("UP");
} else if(direction == JoyStickClass.STICK_RIGHT) {
...
prevDirection = direction;
}
...
这不是一个好的解决方案,但不会破坏示例的代码,这不是很好)。理想情况下,您应该创建 custom view.
我正在使用此 website 中的虚拟操纵杆代码。 它工作正常但不适用于我的应用程序。 我在执行任何操作时遇到问题。在 JoyStick.class 中,我可以控制每个方向的范围,所以如果范围在特定角度和距离之间,它 returns 每个方向的 int 值。
public int get4Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 225 && angle < 315 ) {
return STICK_UP;
} else if(angle >= 315 || angle < 45 ) {
return STICK_RIGHT;
} else if(angle >= 45 && angle < 135 ) {
return STICK_DOWN;
} else if(angle >= 135 && angle < 225 ) {
return STICK_LEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
我用 System.out.println 来说明什么不适合我的申请。当我将棍子朝特定方向放置时,例如向上然后向左,它会生成如下输出:
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.017 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.037 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.117 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.137 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.157 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.167 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.187 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.207 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.217 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.317 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.337 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.357 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.377 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.387 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.407 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.427 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.437 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.457 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.477 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.487 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.507 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.527 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.537 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.557 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.577 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
08-18 14:02:10.587 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.607 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.627 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.637 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.657 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.677 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.687 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
08-18 14:02:10.707 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
其他方向多路输出同理。这对我来说是个问题,因为更复杂的操作会导致应用程序崩溃或应用程序运行速度非常慢,并且我会收到警告:
The application may be doing too much work on its main thread
有没有办法只输出一次?例如,如果摇杆在左方向的范围内,它只会产生一条线:
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ LEFT
如果UP等
08-18 14:02:10.007 11806-11806/com.example.aidan.joysticktest2 I/System.out﹕ UP
这都是关于使用 if/else 语句检查角度和距离,所以我正在寻找一种解决方案,它允许我对每个方向或类似的东西只检查一次这个范围。我尝试了一切,我使用了单选按钮、复选按钮、变量,但没有用,我无法获得一行输出。
完整代码:
JoyStick.class
主要活动:
public class MainActivity extends Activity {
RelativeLayout layout_joystick;
ImageView image_joystick, image_border;
TextView textView1, textView2, textView3, textView4, textView5;
JoyStickClass js;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView)findViewById(R.id.textView1);
textView2 = (TextView)findViewById(R.id.textView2);
textView3 = (TextView)findViewById(R.id.textView3);
textView4 = (TextView)findViewById(R.id.textView4);
textView5 = (TextView)findViewById(R.id.textView5);
layout_joystick = (RelativeLayout)findViewById(R.id.layout_joystick);
js = new JoyStickClass(getApplicationContext(), layout_joystick, R.drawable.redball2);
js.setStickSize(150, 150);
js.setLayoutSize(500, 500);
js.setLayoutAlpha(150);
js.setStickAlpha(100);
js.setOffset(90);
js.setMinimumDistance(50);
layout_joystick.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
js.drawStick(arg1);
if(arg1.getAction() == MotionEvent.ACTION_DOWN
|| arg1.getAction() == MotionEvent.ACTION_MOVE) {
textView1.setText("X : " + String.valueOf(js.getX()));
textView2.setText("Y : " + String.valueOf(js.getY()));
textView3.setText("Angle : " + String.valueOf(js.getAngle()));
textView4.setText("Distance : " + String.valueOf(js.getDistance()));
int direction = js.get4Direction();
if(direction == JoyStickClass.STICK_UP) {
textView5.setText("Direction : Up");
System.out.println("UP");
} else if(direction == JoyStickClass.STICK_RIGHT) {
textView5.setText("Direction : Right");
System.out.println("RIGHT");
} else if(direction == JoyStickClass.STICK_DOWN) {
textView5.setText("Direction : Down");
System.out.println("DOWN");
} else if(direction == JoyStickClass.STICK_LEFT) {
textView5.setText("Direction : Left");
System.out.println("LEFT");
} else if(direction == JoyStickClass.STICK_NONE) {
textView5.setText("Direction : Center");
System.out.println("CENTER");
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
textView1.setText("X :");
textView2.setText("Y :");
textView3.setText("Angle :");
textView4.setText("Distance :");
textView5.setText("Direction :");
}
return true;
}
});
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="X"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:text="Y"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView2"
android:text="Angle"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView3"
android:text="Distance"
android:textColor="#444444"
android:textSize="20dp" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView3"
android:text="Direction"
android:textColor="#444444"
android:textSize="20dp" />
</LinearLayout>
<RelativeLayout
android:id="@+id/layout_joystick"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_below="@+id/linearLayout1"
android:layout_centerHorizontal="true"
android:layout_marginTop="29dp"
android:background="@drawable/image_button_bg" >
</RelativeLayout>
这似乎是预期的行为,因为每 ACTION_DOWN
会触发一次,ACTION_MOVE
会触发多次。似乎 ACTION_MOVE
被调用了很多次。为避免对每个 ACTION_MOVE
事件进行处理,请尝试添加全局变量:
int prevDirection = 0;
然后在public boolean onTouch(View arg0, MotionEvent arg1)
添加条件:
...
int direction = js.get4Direction();
if (direction != prevDirection) {
if(direction == JoyStickClass.STICK_UP) {
textView5.setText("Direction : Up");
System.out.println("UP");
} else if(direction == JoyStickClass.STICK_RIGHT) {
...
prevDirection = direction;
}
...
这不是一个好的解决方案,但不会破坏示例的代码,这不是很好)。理想情况下,您应该创建 custom view.