【问题标题】:Android: Move several bitmap on a SurfaceVievAndroid:在 SurfaceViev 上移动多个位图
【发布时间】:2012-10-05 01:45:36
【问题描述】:

我想用手指在表面视图上移动两个简单的位图。使用一个位图,它工作正常,但我无法处理两个位图。我使用 imageview onTouchListener 进行了尝试,但后来我不得不使用 API 级别 11 的 View.setX(float x) 并且我不想超过 API 级别 8。我该如何实现它?

    public class ItemClass extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    private SurfaceHolder surface;
    private Paint p = new Paint();
    private Bitmap[] item = new Bitmap[2];
    private int[] coord = new int[2];

    public DrawClass(Context context) {
        super(context);
        getHolder().addCallback(this);
        surface = getHolder();
        item[0] = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
        item[1] = BitmapFactory.decodeResource(getResources(), R.drawable.img2);        
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        Thread drawThread = new Thread(this);
        drawThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}

    @Override
    public void run() {

        Canvas c;
        while (true) {
            c = null;
            try {
                c = surface.lockCanvas(null);
                synchronized (surface) {
                    onDraw(c);

                }
            } finally {
                if (c != null) {
                    surface.unlockCanvasAndPost(c);
                }
            }
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        coord[0]=(int)event.getX();
        coord[1]=(int)event.getY();

        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);

        canvas.drawBitmap(item[0], coord[0], coord[1], null);
        canvas.drawBitmap(item[1], 100, 100, null);
    }

}

【问题讨论】:

  • 你能再具体一点,“不能处理两个位图”是什么意思?您是否正在研究多点触控,例如将第一个位图移动到一个触摸点,将另一个图像移动到第二个?
  • 我想将第一个位图移动到新位置,然后再移动第二个。不在同一时间。
  • 请重读我的评论。目前尚不清楚“无法处理两个位图”是什么意思。另外,您要将第二个位图移动到哪里?和第一个位置一样吗?请更准确地说您遇到了什么问题。
  • 不,我想将位图移动到不同的位置,它们应该是完全独立的。例如,首先我触摸其中一个球并将其拖动到一个新位置,然后我触摸第二个球并将其拖动到一个新位置。问题是,我不知道如何在 onTouchEvent 方法中找出导致事件的球。

标签: java android bitmap draw surfaceview


【解决方案1】:

好的,这是一个简化答案的尝试,假设您使用的是矩形位图(无透明度)。

首先,您需要存储两个对象的 x、y 坐标和宽度、高度。我建议为您的位图创建一个自定义类,而不是当前的位图数组 Bitmap[] 项:

private class MyImage{
            Bitmap image;
            int x,y,w,h;
        }
private MyImage[] images = new MyImage[2];

您必须相应地更改您的代码,例如。 item[0] = BitmapFactory.decodeResource(getResources(), R.drawable.img1); -> images[0].image = BitmapFactory.decodeResource(getResources(), R.drawable.img1);

坐标[0] -> 图像[0].x

坐标[1] -> 图像[0].y

您可以从图像中获取宽度和高度属性,例如:

images[0].h = images[0].image.getHeight();
images[0].w = images[0].image.getWidth();

根据您的偏好 - 为这些图像提供固定的 x,y 值,或者您可以在您的屏幕尺寸范围内为它们提供随机值。查看示例如何在此处使用 Math.random How do I generate random integers within a specific range in Java? 并在此处显示大小 Get screen dimensions in pixels

然后 onTouchEvent 检查 x,y 是否在您的一张图像内并且是 - 而不是仅移动该图像。比如:

for (int i = 0; i<=images.length; i++){
            //if touch event is inside this image - move it
            if (coord[0] >= (images[i].x) && coord[0] <= (images[i].x+images[i].w) &&
                    coord[1] >= (images[i].y) && coord[1] <= (images[i].y+images[i].h) ){
                //offset the image by the distance of the touch event from the center of the image
                images[i].x += coord[0] - (images[i].x+images[i].w/2);
                images[i].y += coord[1] - (images[i].y+images[i].h/2);
                canvas.drawBitmap(images[i].image, images[i].x, images[i].y, null);
            } else {
                //draw the iamge at its old position
                canvas.drawBitmap(images[i].image, images[i].x, images[i].y, null);
            }
        }

还要考虑您的对象是否可以重叠,否则您需要相应地防止这种情况发生。

希望这会有所帮助。

【讨论】:

  • 感谢您的帮助。如果有很多位图会不会太慢?如果我使用透明位图该怎么办?
  • 您的问题是针对两个位图,但即使有更多,它也会t be slow, as there are no expensive operations on the runtime. Transparent images - you can use them of course, my point was that in case you are not using rectangular objects in your bitmaps - you need a different implementation in order to check if the registered touch event is inside one of your objects and also for collision, in case your objects cant 重叠。
  • 请注意,建议的算法有一些缺陷。最值得注意的是 - 只要触摸事件在对象内,图像的拖动就可以工作。如果用户触摸了一个对象并且手指移动得太快,那么该对象就会被抛在后面。要解决这个问题,您应该注册 onPress 和 onRelease 事件。 onPress - 检测哪个是被拖动的对象, onRelease - 将对象移动到这些坐标。检查 onTouchListener 或查看此blorb.tumblr.com/post/347157141/…
  • user1721713 如果我的回答对您有帮助,请将您的问题标记为已回答
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多