我正在创建一些小的精灵,在另一个视图的构造函数中使用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{发布于 2011-03-27 02:15:36
你的混合曲面绘图和视图绘图。表面对于快速的异步重绘(比如游戏)来说是很棒的,但它们不是视图容器。也就是说,SurfaceView上没有事件和布局所需的addView方法。
因此,您将需要在SurfaceView上实现单击处理,并手动实现正在单击哪个Sprite的检测(例如,是sprite的x/y/width/height边界框中的onClick事件)。
而且,如果以这种方式使用,MoleSprite扩展视图也没有意义。我希望你能创建自己的Sprite基类来支持边界框和绘图回调。您还可以添加onClick(..)接口添加到Spirte基类,但您可能还希望为可绘制/可移动/可单击项目保留单独的列表,以便在开发游戏时优化列表迭代。
祝好运!
发布于 2013-04-12 13:36:27
我不知道你的GameLoopThread在做什么,但它应该调用你的表面的onDraw方法和updatePhysics方法。
更新的物理将循环通过您的精灵,并提供信息,如当前的游戏时间,以便他们可以移动适当的距离,改变动画帧,或其他任何东西。
对于sprite基类,我使用了类似这样的东西(但我的基类处理动画、加速和其他东西):
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)
}还有其他更详细的文章介绍了这一点,但这将是你的入门之路。
https://stackoverflow.com/questions/5443925
复制相似问题