如何修复绘制到具有大型可滚动背景的画布上的图像的位置?
想象一下: 背景图像是房间的图像,对象图像是床,门等。 对象图像绘制在背景之上。
当我滚动背景时,对象应该相对于背景图像移动,对吗? 问题是物体图像也会移动,但位置不会保持不变,即它们从原始位置移开。
这是我的全班实施。
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);
}
这是正确的吗?
答案 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);