2011-03-26 44 views
0

我創建了一些小精靈,並且在另一個視圖的構造函數中使用bmp作爲背景。但是當我點擊那些有onClickListener的精靈時,我點擊的視圖就是背景視圖。onClick hierachy

一些代碼:

我的構造函數:

public ToposGameView(Context context) { 
    super(context); 

    moles = new ArrayList<MoleSprite>(); 
    setFocusable(true); 
    setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Log.i(tag, "Click en GameView"); 

     } 
    }); 

    gameLoopThread = new GameLoopThread(this); 

    int id = 0; 
    for(int x = 0; x<3; x++){ 
     for(int y = 0; y<4 ; y++){ 

      MoleSprite mole = new MoleSprite(this, x*WIDTH/3, HEIGHT/6+y*HEIGHT/6, FRONT); 
      mole.setId(id); 
      id++; 
      moles.add(mole); 
     } 
    } 

    holder = getHolder(); 
    holder.addCallback(new Callback() { 

     @Override 
     public void surfaceDestroyed(SurfaceHolder arg0) { 
      boolean retry=true; 
      gameLoopThread.setRunning(false); 
      while(retry){ 
       try{ 
        gameLoopThread.join(); 
        retry=false; 

       }catch(InterruptedException i){ 

       } 
      } 
     } 

     @Override 
     public void surfaceCreated(SurfaceHolder arg0) { 
      gameLoopThread.setRunning(true); 

      gameLoopThread.start(); 

     } 

     @Override 
     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, 
       int arg3) { 
      // TODO Auto-generated method stub 

     } 
    }); 

} 

雪碧的構造:

public MoleSprite(ToposGameView gameView, int x, int y, int direction) { 
    super(gameView.getContext()); //TODO 
    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.bad1); 
    this.width = bmp.getWidth()/BMP_COLUMNS;  
    this.height = bmp.getHeight()/BMP_ROWS; 

    this.x=x; 
    this.y= y; 

    this.setClickable(true); 
    this.setFocusable(true); 
    this.setFocusableInTouchMode(true); 
    setOnClickListener(this); 
    setOnTouchListener(this); 
    //I don't know what else to do! 
    } 

這是我的第一個問題,請問我要更多的信息。

EDIT1:

public class MoleSprite extends View implements OnClickListener, OnTouchListener{ 

public class ToposGameView extends SurfaceView{ 
+0

MoleSprite的基類是什麼?您在詢問onClick,通常是指View層次結構,但是您使用SurfaceView代表視圖外部的渲染。這裏有一些斷開連接,但是太少的信息來識別它。 – Anm 2011-03-26 17:28:52

+0

這個想法是做一個遊戲,需要重繪,但我與onClick卡住了。我用基類編輯。 – Rafaesp 2011-03-26 17:36:27

回答

0

你的混音界面與瀏覽圖畫。表面非常適合快速異步重繪(如遊戲),但它們不是查看容器。也就是說,對於事件和佈局,SurfaceView上沒有addView方法。因此,您將需要在SurfaceView上實現onClick處理,並手動實現檢測哪個Sprite被點擊(例如,是sprite的x/y/width/height邊界框內的點擊事件)。

此外,如果以這種方式使用MoleSprite,則無法擴展View。我希望你會想讓你自己的Sprite基類支持邊界框和繪製回調。您還可以將onClick(..)接口添加到Spirte基類,但您可能還希望爲可繪製/可移動/可點擊的項目保留單獨的列表,以便在開發遊戲時優化列表迭代。

祝你好運!

+0

謝謝!我將執行檢測。另外,你能解釋一下更多的Sprite基類嗎? – Rafaesp 2011-03-26 20:48:09

+0

當前您正在使用View類作爲超類來管理邊界矩形和繪製回調,但是,正如我所提到的,您並未將其用作視圖。它有點像看着一塊岩石,把它看作是具有足夠質量的移動物體來撞擊力量,因此稱它爲錘子。它可以工作,但它不是一個有效的錘子或其他屬性歸因於手柄和拔釘器之類的錘子。你可以使用方法getX(),getY(),getWidth(),getHeight()和onDraw()(對於初學者)來創建一個名爲Spirte的抽象基類,以完全按照您的需要進行操作。 – Anm 2011-03-30 23:28:27

0

我不知道你的GameLoopThread在做什麼,但它應該調用你的surface的onDraw方法和updatePhysics方法。

更新物理將通過你的精靈循環,並給他們的信息,如當前的遊戲時間,所以他們可以移動適當的距離,改變動畫幀,或任何。

因爲我使用這樣一個精靈基類(但我的處理動畫,加速度和其他的東西):

public class Sprite { 
    private Rect mScreenRect; 
    public Sprite() { 
     // init some stuff here, if you need it 
     // especially, somewhere in your init functions 
     // set your bounding rect 
     this.mScreenRect = Rect(xl, yt, xr, yb); 
    } 
    setStuff(int thing) { 
     // like setX(), setY() 
    } 

    // here is the good stuff 
    public boolean isTouched(int x, int y) { 
     if(mScreenRect.contains(x, y)) 
      return true; 
     else 
      return false; 
    } 
    // also include a function to draw the graphic 
    public void drawGraphic(Canvas canvas) { 
     canvas.drawBitmap(mBitmap, mScreenRect.left, mScreenRect.top, null); 
    } 
} 

然後,在你的面視圖,您需要使用:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    // this setup will move the sprite on the screen 
    switch(event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     if(sprite.isTouched(event.getX(), event.getY()) { 
      // do your stuff 
     } 
     break; 
    case MotionEvent.ACTION_MOVE: 
     // handle the moving pointer 
     sprite.setCoords(event.getX(), event.getY()); 
     break; 
    case MotionEvent.ACTION_UP: 
     // handle the exiting pointer 
     sprite.setCoords(event.getX(), event.getY()); 
     break; 
    } 
} 

然後在再次表面視圖:

@Override 
public void onDraw(Canvas canvas) { 
    sprite.drawGraphic(canvas) 
} 

有覆蓋其他職位這更詳細的方式,但這會讓你開始。

+0

感謝您的回答,但這是一個相當古老的問題,它已被接受。不管怎麼說,還是要謝謝你!! – Rafaesp 2013-04-12 09:14:25