RoBoard魔人的機器人日誌

2013/12/6

[機械六足] 智慧手機控制器

上次發了一篇近況文

也告訴了大家我下一步想要做的東西

那魔人就來一步一步的製作&分享給大家吧

今天要分享的是智慧手機控制器的搖桿控制

還記得上次我的介紹吧

我要用遙感的方式控制六足的前進方向

而遙桿在網路上的範例已經有很多了

實做的方法是這樣的

用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();
    }
   }
  }
 }}

Share:
技術提供:Blogger.

追蹤者