Android-使用“操纵杆"处理屏幕 [英] Android - Handling screen with 'joysticks'

查看:67
本文介绍了Android-使用“操纵杆"处理屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

有谁能向我解释他们如何使用屏幕上的操纵杆处理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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆