在安卓中正确制作场景的最基本方法是使用矩阵来修改视图,使用该矩阵的逆来修改触摸操作。下面是一个简化的回答,非常简短。
public class SceneView extends View {
Matrix viewMatrix = new Matrix(), invertMatrix = new Matrix();
Paint paint = new Paint();
ArrayList<RectF> rectangles = new ArrayList<>();
RectF moving = null;
public SceneView(Context context) { super(context); }
public SceneView(Context context, AttributeSet attrs) { super(context, attrs); }
public SceneView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override
public boolean onTouchEvent(MotionEvent event) {
//transform touch. (inverted matrix)
event.transform(invertMatrix);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
moving = null;
//collision detection
for (RectF f : rectangles) {
if (f.contains(event.getX(), event.getY())) {
moving = f;
return true;
}
}
// adding arbitrary transforms.
viewMatrix.postTranslate(50,50);
viewMatrix.postScale(.99f,.99f);
viewMatrix.postRotate(5);
// inverse matrix is needed for touches.
invertMatrix = new Matrix(viewMatrix);
invertMatrix.invert(invertMatrix);
break;
case MotionEvent.ACTION_MOVE:
if (moving != null) {
moving.set(event.getX() - 50, event.getY() - 50, event.getX() + 50, event.getY() + 50);
}
break;
case MotionEvent.ACTION_UP:
if (moving == null) {
rectangles.add(new RectF(event.getX() - 50, event.getY() - 50, event.getX() + 50, event.getY() + 50));
}
break;
}
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
// transform the view by the matrix.
canvas.concat(viewMatrix);
// draw objects
for (RectF f : rectangles) {
canvas.drawRect(f,paint);
}
}
这个展示非常简约,但它显示了所有相关的方面。
- 移动视图
- 触摸修改
- 碰撞检测
每次您触摸屏幕,它会对角线移动,缩小并旋转(基本上是螺旋移动),并创建一个黑色矩形。如果您触摸矩形,则可以随心所欲地移动它们。当您单击背景时,将继续螺旋状移动视图并且掉落黑色矩形。
参见:https://youtu.be/-XSjanaAdWA
另一种方式行不通。理论上,您可以通过View类而不是在画布中转换我们想要的场景。这将使触摸事件发生在与屏幕相同的空间内。但是,Android将无效触摸事件发生在视图之外的位置。因此,在原始裁剪部分之外开始的MotionEvents将被丢弃。所以这是行不通的。您需要转换画布,并反向转换MotionEvents。