2

I want to move two simple bitmap on a surfaceview by finger. With one bitmap, it works fine, but I can't handle two bitmaps. I tried it with imageview onTouchListener, but then I had to use View.setX(float x) which is API level 11 amd I don't want go above API level 8. How can I implement it?

    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);
    }

}
user1721713
  • 483
  • 3
  • 15
  • Can you be a bit more specific, what do you mean by "can't handle two bitmaps"? Are you looking into multi-touch, for example moving the first bitmap to one touch point and another image to a second? – ılǝ Oct 05 '12 at 01:59
  • I want to move the first bitmap to a new place and after that the second. Not in the same time. – user1721713 Oct 05 '12 at 02:12
  • Please reread my comment. It is still unclear what you mean by "can`t handle two bitmaps". Also, where do you want to move the second bitmap to where? The same position as the first one? Please be more precise what is the problem that you are experiencing. – ılǝ Oct 05 '12 at 02:22
  • No, I want to move the bitmaps to a different position, they should be completely independent. So for example, firstly I touch one of the balls and drag it to a new place, after that I touch the second ball and drag to a new place. The problem is that, I don't know how can I figure out in the onTouchEvent method which ball caused the event. – user1721713 Oct 05 '12 at 02:36

1 Answers1

0

Ok, here is an attempt for a simplified answer, assuming you are using rectangular bitmaps (no transparency).

Firstly, you would need to store the x, y coordinates and width, height of both objects. I suggest creating a custom class for your bitmaps instead of the current bitmap array Bitmap[] item:

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

You would have to change your code accordingly eg. item[0] = BitmapFactory.decodeResource(getResources(), R.drawable.img1); -> images[0].image = BitmapFactory.decodeResource(getResources(), R.drawable.img1);

coord[0] -> images[0].x

coord[1] -> images[0].y

You can get your width and height properties from the image like:

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

Based on your preference - give those images fixed x,y values or you could give them random values within your screen size. See example how to use Math.random here How do I generate random integers within a specific range in Java? and display size here Get screen dimensions in pixels

Then onTouchEvent check if the x,y is within one of your images and is yes - than move only that image. Something like:

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);
            }
        }

Also consider if your objects can overlap, if not you need to prevent that accordingly.

Hope this helps.

Community
  • 1
  • 1
ılǝ
  • 3,440
  • 2
  • 33
  • 47
  • Thank you for your help. Will it not be too slow if there would be a lot of bitmap? And what is to be done if I use transparent bitmaps? – user1721713 Oct 05 '12 at 03:26
  • Your question was for two bitmaps, but even with more it wouldn`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 can`t overlap. – ılǝ Oct 05 '12 at 03:55
  • Note that the suggested algorithm has some flaws. Most notably - the dragging of the image would work as long as the touch event is within the object. If the user touched an object and moved his finger too fast the object would be left behind. To deal with this you should register onPress and onRelease events. onPress - detect which is the object being dragged, onRelease - move the object to those coordinates. Check onTouchListener or see this http://blorb.tumblr.com/post/347157141/simple-ontouch-press-and-release-code-for-android – ılǝ Oct 05 '12 at 04:12
  • user1721713 please mark your question as answered if my responses helped you – ılǝ Oct 09 '12 at 02:21