我正在另一个视图的构造函数中创建一些带有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{
答案 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)
}
还有其他帖子以更详细的方式介绍了这一点,但这将帮助您入门。