How do you fix the position of an image drawn onto a canvas with a large scrollable background?
picture this: the background image is that of a room, the object images are bed, door etc. the object images are drawn on top of the background.
when i scroll the background, the objects should move with respect to the background image, correct? the problem is the object images also move but the position doesn't stay the same, i.e they shift from their original positions.
here is my full class implementation.
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);
}
is this correct?