La *_*bla 2 java graphics android surfaceview
我正在开发游戏并遇到一些麻烦,我可能不会这样做,因为我是Android的图形方面的新手.
我有一个SurfaceView和ArrayList我自己的Card对象延伸View.我重写了对象的onDraw方法Card,然后在SurfaceView's onDraw我绘制所有内容.绘图部分正常工作.
我现在尝试检测单个卡何时被触摸onTouchListener,我为每张卡设置了监听器,但它检测到触摸,就好像被触摸的视图是SurfaceView.我对此的整体思考方式可能是错误的,所以我在征求您的意见.
一些代码:
public GameSurfaceView(Context context) {
super(context);
GAME_STATE = GameState.LOADING;
this.context = context;
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
}
Run Code Online (Sandbox Code Playgroud)
SurfaceView onDraw():
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRGB(30, 180, 30);
for (Card card : user.getTableCards()) {
card.draw(canvas);
}
}
Run Code Online (Sandbox Code Playgroud)
卡的onDraw():
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(getBitmap(), x, y, null);
}
Run Code Online (Sandbox Code Playgroud)
和onTouch
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TOUCH", "Class: " + v.getClass().toString());
if (v.getClass() == Card.class) {
Log.d("CARD", "Touched: " + ((Card) v).getValue());
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
我总是把SurfaceView课程记录下来.这甚至是做这样的事情的正确方法吗?我需要检测同一类的各个对象的触摸.
我目前这样做是通过向Rect每张卡添加一个类型的成员然后循环并检查触摸的x和y是否包含在该rect中,但它似乎是一种昂贵的方式,迭代每张卡(即使最大的52)并检查它..
谢谢
你混合了两个不同的概念,我将在A)和B)中解释.
您有两种选择:
A)如果你想继续使用SurfaceView(它可能是游戏的正确选择,因为它可以让你更好地控制绘制事物的方式),你的Card对象应该扩展Drawable,而不是View.Drawable是一个愚蠢的类,你只是绘制到画布或传递给小部件作为他们的背景等.Android不需要了解更多.在这种情况下,您需要检查自己打出的卡片,就像您描述的那样.Android无法为您处理此问题.你用View而不是Drawable来做这个,这是错误的!或者至少是一个巨大的浪费.请参阅下文,了解如何正确使用视图.
B)使用视图,它将处理触摸事件和许多其他事情.
View是一个复杂的类,应该存在于android的视图层次结构中.你正在使用它的方式就是丢掉它的大部分功能 - 当你直接绘制一个视图时,android根本就没有真正意识到这个视图,所以它无法处理触摸事件.
基于视图的卡的正确实现可能如下所示:使用视图组作为基础,这是您在setContentView()中设置的.这个ViewGroup可能只是一个LinearLayout,或者如果你想在你的卡的卡上设置任意位置和大小,你可以使用AbsoluteView,虽然这已被弃用.
然后使用addView()将您的卡添加到ViewGroup.Card视图在此范围内的定位由您传递给addView()的LayoutParams对象控制.这样android知道它的存在,并将处理这样的触摸事件:
要非常清楚:你没有将视图添加到SurfaceView,事实上,你不能,因为它不是一个ViewGroup.它只是一个复杂的View对象,允许您在其中执行任意绘制操作.但它始终是View层次结构的一个叶子,并且只能处理它自己的onTouchEvents,它不会将它发送给子节点,因为它不能有任何.