2012-02-13 35 views
1

我試圖學習Android圖形&事件handeling爲多人遊戲。Android,無法在模擬器上繪製基於Touch或MotionEvent的視圖

的構建塊林開發一些代碼,將利用基於觸摸/移動事件點的路徑,但林無法得出,沒有東西畫在模擬器

我有3個簡單的類(MyPoint,GameCanvas類,遊戲):

1)MyPoint類封裝X & y位置,得出方法繪製基於這些位置的點

public class MyPoint { 

    private float x; 
    private float y; 
    Paint pWhite = new Paint(R.color.white); 

    public MyPoint(float x, float y) { 

      this.x = x; 
      this.y = y; 
    }//end const 
    public void draw(Canvas canvas) { 
     canvas.drawPoint(this.x, this.y, pWhite); 
    }//end method 
}//end MyPoint Class 

2)的GameCanvas是將要繪製在視圖中,這類負責對於 其對事件通過實施OnTouchListener處理,onThouch()方法

public class GameCanvas extends View implements OnTouchListener { 

     //keep track on points created by touch events 
     java.util.List<MyPoint> pointsList = null; 

     public GameCanvas(Context context) { 
      super(context); 
      setFocusable(true); 
      setFocusableInTouchMode(true); 

      setOnTouchListener(this); 
      pointsList = new java.util.Stack(); 

     }//end const 

//onDraw iterates through points that were added during motion/touch events and calls the MyPoint.draw(canvas) 

     @Override 
     protected void onDraw(Canvas canvas) { 

      MyPoint p = null; 
      for (int i = 0; i < pointsList.size(); i++) { 
       p = (MyPoint) pointsList.remove(i); 
       p.draw(canvas); 
      } 

     }//end onDraw 

     //implemented in order to handel touch events 
     public boolean onTouch(View arg0, MotionEvent event) { 
      int action = event.getAction(); 
      float currentX = event.getX(); 
      float currentY = event.getY(); 

      //log x and y coordinates 
      Log.v(this.getClass().getName().toString(), "X=" + currentX); 
      //log x and y coordinates 
      Log.v(this.getClass().getName().toString(), "Y=" + currentY); 

      if (action == MotionEvent.ACTION_DOWN) { 

       // log action down 
       Log.v(this.getClass().getName().toString(), "MotionEvent = ACTION_DOWN"); 

       pointsList.add(new MyPoint(currentX, currentY)); 
       this.invalidate(); 
      } else if (action == MotionEvent.ACTION_MOVE) { 

       //log action move 
       Log.v(this.getClass().getName().toString(), "MotionEvent = ACTION_MOVE"); 

       pointsList.add(new MyPoint(currentX, currentY)); 
       this.invalidate(); 
      } else if (action == MotionEvent.ACTION_UP) { 

       //log action move 
       Log.v(this.getClass().getName().toString(), "MotionEvent = ACTION_UP"); 

       pointsList.add(new MyPoint(currentX, currentY)); 
       this.invalidate(); 
      } 
      //call invalidate in order to call trigger onDraw() 

      return true; 
     }//end onTouch() 
    }//end GameCanvas class 

3)遊戲類是活動推出的GameCanvas查看

public class Game extends Activity { 

GameCanvas newGameCanvas = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     //create GameCanvas object 
     newGameCanvas = new GameCanvas(this); 
     super.onCreate(savedInstanceState); 
     setContentView(newGameCanvas); 
     // 
     newGameCanvas.requestFocus(); 

    }//end OnCreate 
}//end Game class 
+0

那麼,我能說什麼:調試它。編寫代碼只是一個部分,讓它工作是另一個:)。嘗試找到你的問題:驗證觸摸是否進入你的視圖(請參閱onTouch()的日誌),然後檢查每次觸摸後是否執行onDraw(應該是無效的結果),檢查列表(它是否有點..)等等......你很快就會縮小問題範圍,並且能夠確定bug – 2012-02-13 02:21:01

+0

由於某些原因,他們沒有被記錄,我無法查看日誌。想到的一個問題是鼠標點擊/拖在emaulator被視爲觸摸事件 – cyber101 2012-02-13 03:15:03

+0

只是一個瘋狂的猜測,嘗試addind setClickable(true),看看點擊和觸摸是否會通過 – 2012-02-13 23:34:49

回答

1

下面是實際的工作代碼。我最多隻更改了幾行&也使View成爲Activity的內部類,所以在測試/調試時我不必看着不同的屏幕。

  1. 第一個變化是使查看內部類,只是爲了便於邏輯 沒有變化
  2. 我的畫布背景顏色設置爲白色, 在OnCreate()
  3. 我改變了我的邏輯的onDraw ()從 pointsQ.removw(我),只是pointsQ.get(I),以刪除(我)只正在擬訂
  4. 的 最後一點。最後你得到一個畫布,你可以使用 繪製/基於觸摸事件的跟蹤

    public class Game extends Activity { 
    
    private gameView newGameView = null; 
    private MyPoint newMyPoint = null; 
    
    private java.util.List<MyPoint> pointsQ = new ArrayList<MyPoint>(); 
    
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        try { 
    
         newGameView = new gameView(this); 
         newGameView.setBackgroundColor(Color.WHITE); 
         super.onCreate(savedInstanceState); 
         setContentView(newGameView); 
         //initially requestFocus 
         newGameView.requestFocus(); 
    
    
        } catch (NullPointerException exc) { 
         Log.d(this.getClass().getName().toString(), exc.getMessage()); 
        } 
    } 
    
    //inner class that represents View 
    public class gameView extends View { 
    
    
    private Paint wPaint = new Paint(Color.BLACK); 
    
    
    public gameView(Context context) { 
        super(context); 
        setFocusable(true); 
        setFocusableInTouchMode(true); 
        // 
        wPaint.setStyle(Paint.Style.FILL); 
        wPaint.setStrokeWidth(3); 
    
    } 
    
    //implemented in order to handle touch events 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        int action = event.getAction(); 
        float currentX = event.getX(); 
        float currentY = event.getY(); 
    
        //log x and y coordinates 
        Log.d(this.getClass().getName().toString(), "X=" + currentX); 
        //log x and y coordinates 
        Log.d(this.getClass().getName().toString(), "Y=" + currentY); 
    
        if (action == MotionEvent.ACTION_DOWN) { 
    
         // log action down 
         Log.d(this.getClass().getName().toString(), "MotionEvent = ACTION_DOWN"); 
    
         newMyPoint = new MyPoint(currentX, currentY); 
         pointsQ.add(newMyPoint); 
    
    
        } else if (action == MotionEvent.ACTION_MOVE) { 
    
         //log action move 
         Log.d(this.getClass().getName().toString(), "MotionEvent = ACTION_MOVE"); 
    
         newMyPoint = new MyPoint(currentX, currentY); 
         pointsQ.add(newMyPoint); 
    
        } else if (action == MotionEvent.ACTION_UP) { 
    
         //log action move 
         Log.d(this.getClass().getName().toString(), "MotionEvent = ACTION_UP"); 
    
         newMyPoint = new MyPoint(currentX, currentY); 
         pointsQ.add(newMyPoint); 
    
    
        } 
    
        //I moved the invalidate to the end of the method se=ince all action called it anyways 
        this.invalidate(); 
        return true; 
    }//end onTouch() 
    
    @Override 
    protected void onDraw(Canvas canvas) { 
        MyPoint p = null; 
        for (int i = 0; i < pointsQ.size(); i++) { 
         //get MyPoint & draw based on its x,y attributes 
         p = (MyPoint) pointsQ.get(i); 
           // 
         canvas.drawCircle(p.getX(),p.getY(),2,wPaint); 
         // 
         Log.d(this.getClass().getName().toString(), "onDraw X= "+p.getX()+" Y= "+p.getY());  
         } 
    
        } 
    }//end inner class gameView 
    }//end Game activity class 
    
+0

謝謝:)真的很有幫助 – nia 2012-10-14 04:29:00