上次發了一篇近況文
也告訴了大家我下一步想要做的東西
那魔人就來一步一步的製作&分享給大家吧
今天要分享的是智慧手機控制器的搖桿控制
還記得上次我的介紹吧
我要用遙感的方式控制六足的前進方向
而遙桿在網路上的範例已經有很多了
實做的方法是這樣的
用canvas畫圖 & 用Thread讀取螢幕觸碰的事件
讀取後去計算 & 重新畫圖 就可以做到搖桿的效果了
以下影片範例
這個範例是控制小android在螢幕上移動
接著是程式碼囉
MainActivity.java
GameControl.java
GameJoystick.java
GameSurface.java
GameThread.java
也告訴了大家我下一步想要做的東西
那魔人就來一步一步的製作&分享給大家吧
今天要分享的是智慧手機控制器的搖桿控制
還記得上次我的介紹吧
我要用遙感的方式控制六足的前進方向
而遙桿在網路上的範例已經有很多了
實做的方法是這樣的
用canvas畫圖 & 用Thread讀取螢幕觸碰的事件
讀取後去計算 & 重新畫圖 就可以做到搖桿的效果了
以下影片範例
這個範例是控制小android在螢幕上移動
接著是程式碼囉
MainActivity.java
package com.example.joystick; import android.os.Bundle; import android.app.Activity; import android.view.WindowManager; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new GameSurface(this)); } }
GameControl.java
package com.example.joystick; import android.graphics.Point; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; public class GameControls implements OnTouchListener{ public float initx = 0; public float inity = 0; public Point _touchingPoint = new Point(0,0); public Point _pointerPosition = new Point(220,150); private Boolean _dragging = false; private double degree = 0; @Override 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 ( event.getAction() == MotionEvent.ACTION_DOWN ){ _dragging = true; }else if ( event.getAction() == MotionEvent.ACTION_UP){ _dragging = false; } if ( _dragging ){ _touchingPoint.x = (int)event.getX(); _touchingPoint.y = (int)event.getY(); _touchingPoint.x -= 250; _touchingPoint.y -= 250; if(_touchingPoint.x == 0 && _touchingPoint.y > 0) degree = Math.PI / 2; else if(_touchingPoint.x == 0 && _touchingPoint.y < 0) degree = Math.PI / 2 * 3; else if(_touchingPoint.x > 0) degree = Math.atan((double)_touchingPoint.y/_touchingPoint.x); else if(_touchingPoint.x < 0) degree = Math.PI + Math.atan((double)_touchingPoint.y/_touchingPoint.x); if(Math.sqrt(Math.pow(_touchingPoint.x,2) + Math.pow(_touchingPoint.y,2)) > 150){ _touchingPoint.x = (int) (150.0 * Math.cos(degree)); _touchingPoint.y = (int) (150.0 * Math.sin(degree)); } _pointerPosition.x += ((double)_touchingPoint.x/30); _pointerPosition.y += ((double)_touchingPoint.y/30); if ( _pointerPosition.x > 480) { _pointerPosition.x= 0; } if ( _pointerPosition.x < 0){ _pointerPosition.x = 480; } if (_pointerPosition.y > 840 ){ _pointerPosition.y = 0; } if (_pointerPosition.y < 0){ _pointerPosition.y = 840; } }else if (!_dragging) { if(Math.sqrt(Math.pow(_touchingPoint.x,2) + Math.pow(_touchingPoint.y,2)) <= 10){ _touchingPoint.x = (int) initx; _touchingPoint.y = (int) inity; }else{ _touchingPoint.x = (int) ((Math.sqrt(Math.pow(_touchingPoint.x,2) + Math.pow(_touchingPoint.y,2)) - 10)* Math.cos(degree)); _touchingPoint.y = (int) ((Math.sqrt(Math.pow(_touchingPoint.x,2) + Math.pow(_touchingPoint.y,2)) - 10)* Math.sin(degree)); } _pointerPosition.x += ((double)_touchingPoint.x/30); _pointerPosition.y += ((double)_touchingPoint.y/30); if (_pointerPosition.x > 480) _pointerPosition.x= 0; if (_pointerPosition.x < 0) _pointerPosition.x = 480; if (_pointerPosition.y > 840) _pointerPosition.y = 0; if (_pointerPosition.y < 0) _pointerPosition.y = 840; } } }
GameJoystick.java
package com.example.joystick; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class GameJoystick { private Bitmap _joystick; private Bitmap _joystickBg; private Bitmap _trigger; private Bitmap _triggerDown; public Bitmap get_triggerDown() { return _triggerDown; } public void set_triggerDown(Bitmap triggerDown) { _triggerDown = triggerDown; } public GameJoystick(Resources res){ _joystick = (Bitmap)BitmapFactory.decodeResource(res, com.example.joystick.R.drawable.joystick2); _joystickBg = (Bitmap)BitmapFactory.decodeResource(res, com.example.joystick.R.drawable.joystick_bg2); } public Bitmap get_joystick() { return _joystick; } public void set_joystick(Bitmap joystick) { _joystick = joystick; } public Bitmap get_joystickBg() { return _joystickBg; } public void set_joystickBg(Bitmap joystickBg) { _joystickBg = joystickBg; } public Bitmap get_trigger() { return _trigger; } public void set_trigger(Bitmap trigger) { _trigger = trigger; } }
GameSurface.java
package com.example.joystick; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Handler; import android.view.SurfaceHolder; import android.view.SurfaceView; public class GameSurface extends SurfaceView implements SurfaceHolder.Callback { private Context _context; private GameThread _thread; private GameControls _controls; private GameJoystick _joystick; private Bitmap _pointer; public GameSurface(Context context) { super(context); _context = context; init(); } private void init(){ SurfaceHolder holder = getHolder(); holder.addCallback( this); _thread = new GameThread(holder, _context, new Handler(),this); setFocusable(true); _joystick = new GameJoystick(getContext().getResources()); _pointer = (Bitmap)BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); _controls = new GameControls(); setOnTouchListener(_controls); } public void doDraw(Canvas canvas){ _controls.update(null); canvas.drawBitmap(_joystick.get_joystickBg(), 100,100, null); canvas.drawBitmap(_joystick.get_joystick(),_controls._touchingPoint.x + 200, _controls._touchingPoint.y + 200, null); canvas.drawBitmap(_pointer, _controls._pointerPosition.x, _controls._pointerPosition.y, null); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {} private boolean retry; @Override public void surfaceDestroyed(SurfaceHolder arg0) { retry = true; _thread.state = GameThread.STOPED; while (retry) { try { _thread.join(); retry = false; } catch (InterruptedException e) { } } } @Override public void surfaceCreated(SurfaceHolder arg0) { if(_thread.state==GameThread.PAUSED){ _thread = new GameThread(getHolder(), _context, new Handler(),this); _thread.start(); }else{ _thread.start(); } } public void Update() { } }
GameThread.java
package com.example.joystick; import java.util.logging.Level; import java.util.logging.Logger; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.view.SurfaceHolder; public class GameThread extends Thread { private SurfaceHolder mSurfaceHolder; private Handler mHandler; private Context mContext; private Paint mLinePaint; private Paint blackPaint; private long sleepTime; private long delay=70; int state = 1; public final static int RUNNING = 1; public final static int PAUSED = 2; public final static int STOPED = 3; GameSurface gEngine; public GameThread(SurfaceHolder surfaceHolder, Context context, Handler handler,GameSurface gEngineS){ mSurfaceHolder = surfaceHolder; mHandler = handler; mContext = context; gEngine=gEngineS; } private long beforeTime; @Override public void run() { //UPDATE while (state==RUNNING) { try { this.sleep(50); } catch (InterruptedException e1) { e1.printStackTrace(); } beforeTime = System.nanoTime(); gEngine.Update(); Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { c.drawColor(0x66000000); gEngine.doDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } this.sleepTime = delay-((System.nanoTime()-beforeTime)/1000000L); try { if(sleepTime>0){ this.sleep(sleepTime); } } catch (InterruptedException ex) { Logger.getLogger(GameThread.class.getName()).log(Level.SEVERE, null, ex); } while (state==PAUSED){ try { this.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}