如何在可滚动的背景上修复图像的位置?

时间:2011-04-01 05:11:59

标签: android image

如何修复绘制到具有大型可滚动背景的画布上的图像的位置?

想象一下: 背景图像是房间的图像,对象图像是床,门等。 对象图像绘制在背景之上。

当我滚动背景时,对象应该相对于背景图像移动,对吗? 问题是物体图像也会移动,但位置不会保持不变,即它们从原始位置移开。

这是我的全班实施。

Bitmap bmImage;
SpriteAnim8 anim;
MThread thread;
PersonAnimated person, person2;
Canvas canvas = new Canvas();

Rect displayRect = null;
Rect scrollRect = null;
int scrollRectX = 0, scrollRectY = 0;
float scrollByX = 0, scrollByY = 0;
float startX = 0, startY = 0;
int initX = 200, initY = 200;

float a = initX, b = initY;

public MGamePanel(Context context) {
    super(context);

    // adding the callback (this) to the surface holder to intercept events
    getHolder().addCallback(this);

    // create Person and load bitmap
    person = new PersonAnimated(BitmapFactory.decodeResource(getResources(), R.drawable.dad_anim),
            10, 200 /* initial position */,
            45, 56 /* width and height of sprite */,
            5, 10); /* FPS and number of frames in the animation */
    // Destination rect for our main canvas draw
    displayRect = new Rect(0, 0, SpriteAnim8.displayWidth, SpriteAnim8.displayHeight);

    // Scroll rect: this will be used to 'scroll around' over the bitmap
    scrollRect = new Rect(0, 0, SpriteAnim8.displayWidth, SpriteAnim8.displayHeight);

    // Load a large bitmap
    bmImage = BitmapFactory.decodeResource(getResources(), R.drawable.l1_plain);

    // create the game loop thread
    thread = new MThread(getHolder(), this);

    // make the GamePanel focusable so it can handle events
    setFocusable(true);
}

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

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // at this point the surface is created and we can safely start the game
    // loop
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    Log.d(TAG, "Surface is being destroyed");
    // tell the thread to shut down and wait for it to finish
    // this is a clean shutdown
    boolean retry = true;
    while (retry) {
        try {
            thread.setRunning(false);
            ((Activity) getContext()).finish();
            retry = false;
        } catch (Exception e) {
            // try again shutting down the thread

        }
    }
    Log.d(TAG, "Thread was shut down cleanly");
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        // delegating event handling to the person

         startX = event.getRawX();
         startY = event.getRawY();

        // }
         case MotionEvent.ACTION_MOVE:

        float x = event.getRawX();
        float y = event.getRawY();
        // Calculate move update.
        mScrollByX = x - mStartX + mOldScrollByX; // move update x increment
        mScrollByY = y - mStartY + mOldScrollByX; // move update y increment

        onDraw(canvas);

        break;
    case MotionEvent.ACTION_UP:
        mOldScrollByX = mScrollByX;
        mOldScrollByY = mScrollByY;
        break;
    }
    return true;
}

public void render(Canvas canvas) {

     Paint paint = new Paint();
     canvas.drawBitmap(bmImage, scrollRect, displayRect, paint);
    person.draw(canvas);

}

@Override
protected void onDraw(Canvas canvas) {
    int newScrollRectX = scrollRectX - (int) scrollByX;
    int newScrollRectY = scrollRectY - (int) scrollByY;

    // Prevent scrolling off the left or right edges of the bitmap.
    if (newScrollRectX < 0) {
        newScrollRectX = 0;
    } else if (newScrollRectX > (bmImage.getWidth() - SpriteAnim8.displayWidth)) {
        newScrollRectX = (bmImage.getWidth() - SpriteAnim8.displayWidth);
    }

    // Prevent scrolling off the top or bottom edges of the bitmap.
    if (newScrollRectY < 0) {
        newScrollRectY = 0;
    } else if (newScrollRectY > (bmImage.getHeight() - SpriteAnim8.displayHeight)) {
        newScrollRectY = (bmImage.getHeight() - SpriteAnim8.displayHeight);
    }

    // set the updated scroll rect coordinates.
    scrollRect.set(newScrollRectX, newScrollRectY, newScrollRectX
            + SpriteAnim8.displayWidth, newScrollRectY
            + SpriteAnim8.displayHeight);


    // Reset current scroll coordinates to reflect the latest updates so we
    // can repeat
    scrollRectX = newScrollRectX;
    scrollRectY = newScrollRectY;

    person.setX(person.getX() + scrollByX);
    person.setY(person.getY() + scrollByY);

}

这是正确的吗?

2 个答案:

答案 0 :(得分:0)

不确定您的代码,但您可以使用带有背景的FrameLayout,并将ScrollView添加为其子项,其中包含可滚动的其他对象。

HTH!

答案 1 :(得分:0)

以下是如何滚动画布上绘制的图片/图片的代码:

//define points on the custome view class level
PointF touchStart = new PointF();
PointF picStart = new PointF();
PointF prevPicStart = new PointF();

处理触摸并记住之前的图片效果

@Override
public boolean onTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN: {

  touchStart.set(ev.getX(), ev.getY());


  break;
}

case MotionEvent.ACTION_MOVE: {

  float newX = ev.getX() - touchStart.x + prevPicStart.x;
  float newY = ev.getY() - touchStart.y + prevPicStart.y;

  //assuming the the picture is bigger than the screen                      
  if ((newX <= 0 && newX > 0 - pic.getWidth() + screenW)){
    picStart.x = newX;                 
  }

  if ((newY <= 0 && newY > 0 - pic.getHeight() + screenH)){
    picStart.y = newY;
  }

  invalidate();
  break;                            
}           

case MotionEvent.ACTION_UP:

  prevPicStart.x = picStart.x;
  prevPicStart.y = picStart.y;
  break;

}
return true;
}

在onDraw

canvas.drawBitmap(pic, picStart.x, picStart.y, null);