Android-使用“操纵杆"处理屏幕 [英] Android - Handling screen with 'joysticks'
问题描述
大家好,
有谁能向我解释他们如何使用屏幕上的操纵杆处理android/iphone/Windows Phone游戏?
范例图片:
http://imageshack.us/photo/my-images/265/26616423.jpg/ [ ^ ]
顺祝商祺,
Lars
Hi guys,,
Anyone who could explain to me how they handle android / iphone / windows phone games with those onscreen joysticks?
example image:
http://imageshack.us/photo/my-images/265/26616423.jpg/[^]
Yours Sincerely,
Lars
推荐答案
我在周末通过改编此 [^ ]代码:
I implemented this one myself over the weekend from an adaptation of this[^] code:
/*Copyright Edward Nutting. This may be adapted but all adaptations must at least credit myself and http://blog.trostalex.com/?p=114 as the original sources.*/
import android.graphics.Point;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class GameControls implements OnTouchListener{
public enum ControlModes
{
Game,
Menu
}
//The centre x/y coordinates of the joystick thumb pad
public static int initx = 550;
public static int inity = 400;
//The min x/y and max x/y coordinates for the joystick touching point - defines the box surrounds the joystick basically
public static int minx = 0;
public static int miny = 0;
public static int maxx = 0;
public static int maxy = 0;
//The exact x/y coordinates of the latest point being touched on the screen
public Point _touchingPoint = new Point(initx,inity);
//The angle the thumb pad is from the centre of the joystick in degrees.
//Where 0 = south on the screen or in other words 1 unit in the direction of 0 degrees would mean an increase of 1 in the y coordinates
public double ControllerAngle = 0.0;
//Distance from the centre of the joystick to the thumb pad - set to a maximum of maxx - minx so that the thumb pad actually follows a circle round.
private double ControllerDistance = 0.0;
//The percentage (as decimal number so 0.97 not 97%) distance of the the thumb pad from the centre of the joystick
//Calculated by (ControllerDistance / ((maxx - minx) / 2)) or in simplified form (ControllerDistance * 2 / maxx - minx)
public float ControllerPercentage = 0.0f;
private Boolean _dragging = false;
//The x/y coordinates and width/height of the fire button
public static int FireButtonX = 0;
public static int FireButtonY = 0;
public static int FireButtonWidth = 0;
public static int FireButtonHeight = 0;
//Whether the fire button is currently being pressed or not
public boolean FireButton_Pressed = false;
//The current control mode - default is Game (see constructor below)
public ControlModes ControlsMode;
public GameControls()
{
super();
ControlsMode = ControlModes.Game;
}
public boolean onTouch(View v, MotionEvent event) {
update(event);
return true;
}
private MotionEvent lastEvent;
public void update(MotionEvent event){
if (event == null && lastEvent == null)
{
return;
}else if(event == null && lastEvent != null){
event = lastEvent;
}else{
lastEvent = event;
}
if(ControlsMode == ControlModes.Game)
{
for(int i = 0; i < event.getPointerCount(); i++)
{
int x = (int)event.getX(i);
int y = (int)event.getY(i);
boolean IsFireButton = false;
if(x > FireButtonX - 30 && x < FireButtonX + FireButtonWidth + 30 &&
y > FireButtonY - 30 && y < FireButtonY + FireButtonHeight + 30)
IsFireButton = true;
//drag drop
if (event.getActionIndex() == i && (event.getAction() == MotionEvent.ACTION_DOWN ||
event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN)){
if(IsFireButton)
FireButton_Pressed = true;
else
_dragging = true;
}else if (event.getActionIndex() == i && (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_POINTER_2_UP)){
if(IsFireButton)
FireButton_Pressed = false;
else
_dragging = false;
}
if(!IsFireButton)
{
_touchingPoint = new Point();
if ( _dragging ){
// get the pos
_touchingPoint.x = x;
_touchingPoint.y = y;
// bound to a box
if( _touchingPoint.x < minx){
_touchingPoint.x = minx;
}
if ( _touchingPoint.x > maxx){
_touchingPoint.x = maxx;
}
if (_touchingPoint.y < miny){
_touchingPoint.y = miny;
}
if ( _touchingPoint.y > maxy ){
_touchingPoint.y = maxy;
}
//get the angle
ControllerAngle = Math.atan2(_touchingPoint.x - initx,_touchingPoint.y - inity)/(Math.PI/180);
//Atan2 returns negative values for northen hemisphere angles and positive for below.
//I wanted all positive with a range of 0-360 so this code sorts that out.
ControllerAngle += 360;
if(ControllerAngle > 360)
{
ControllerAngle = ControllerAngle - 360;
}
}else if (!_dragging)
{
// Snap back to center when the joystick is released
_touchingPoint.x = (int) initx;
_touchingPoint.y = (int) inity;
}
//Using Pythagoras to calculate distance from centre.
double a = _touchingPoint.x - initx;
double b = _touchingPoint.y - inity;
//Use the absolute (i.e. non-negative) value
ControllerDistance = Math.abs(Math.sqrt((a * a) + (b * b)));
ControllerDistance = ControllerDistance > (maxx - minx) / 2 ? (maxx - minx) / 2 : ControllerDistance;
ControllerPercentage = (float)(ControllerDistance * 2) / (maxx - minx);
}
}
}
else if(ControlsMode == ControlModes.Menu)
{
if((event.getAction() == MotionEvent.ACTION_DOWN ||
event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN))
{
_touchingPoint = new Point((int)event.getX(), (int)event.getY());
}
else if((event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_POINTER_2_UP))
{
_touchingPoint = null;
}
}
}
}
这将处理操纵杆中的方向和加速度,其中方向基于用户指向的位置(0度为南,不是您期望的北,但它对我的应用程序有效),而加速度基于(由我的代码和提供的值计算)摇杆拇指垫距游戏垫中心的百分比距离.该代码不包括渲染,但是可以很容易地从给定变量中完成渲染.在调用update等之前,必须正确设置所有静态变量.该代码还允许第二个按钮,它只是我使用(并称为)FireButton的一个按钮,因此为FireButton_IsPressed
.该代码成功处理了最多两个指针的多点触摸输入.
最后要注意的是,该代码还允许将输入模式设置为菜单,在这种情况下,只需设置_touchingPoint
即可,从而减少了计算并简化了其他代码(还可以处理多达2个指针的菜单上的多点触摸,从而消除了大多数可能会同时击中两个菜单项).
希望这会有所帮助,
Ed
This will handle direction and acceleration in joystick where direction is based on where the user points it (0 degrees is south not north as you may expect but it worked for my application) and acceleration is based on the (calculated by my code and provided value of) the percentage distance of the joystick thumb pad from the centre of the game pad. The code does not include rendering but this can easily be done from the given variables. All static variables must be set up properly before calling update etc. The code also allows a second button which is just a push button which I used (and called) FireButton, hence FireButton_IsPressed
. The code successfully handles multi-touch input of up to two pointers.
Finally note the code also allows input mode to be set to menu, in which case the _touchingPoint
is simply set, reducing computation and simplifying other code (also handles multi-touch on a menu of up to 2 pointers, eliminating most of the risk of hitting two menu items at once).
Hope this helps,
Ed
这篇关于Android-使用“操纵杆"处理屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!