onClick层次结构

时间:2011-03-26 17:20:06

标签: android

我正在另一个视图的构造函数中创建一些带有bmp的小精灵作为背景。但是当我点击具有onClickListener的精灵时,我点击的视图就是背景视图。

一些代码:

我的构造函数:

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

        }
    });

}

Sprite的构造函数:

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{

2 个答案:

答案 0 :(得分:0)

使用View绘图混合Surface绘图。 Surface适用于快速异步重绘(例如游戏),但它们不是View容器。也就是说,SurfaceView上没有事件和布局所需的addView方法。

因此,您需要在SurfaceView上实现onClick处理并手动实现对点击哪个Sprite的检测(例如,sprite的x / y / width / height边界框内的click事件)。

另外,如果以这种方式使用,MoleSprite扩展View是没有意义的。我希望你会想要创建自己的Sprite基类来支持边界框和绘制回调。您还可以将onClick(..)接口添加到Spirte基类,但您可能还希望为可绘制/可移动/可点击项目保留单独的列表,以便在开发游戏时优化列表迭代。

祝你好运!

答案 1 :(得分:0)

我不知道你的GameLoopThread在做什么,但它应该调用你的表面的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)
}

还有其他帖子以更详细的方式介绍了这一点,但这将帮助您入门。

相关问题