当其中的移动位图靠近屏幕的右边框时,android会翻译画布坐标?

Posted

技术标签:

【中文标题】当其中的移动位图靠近屏幕的右边框时,android会翻译画布坐标?【英文标题】:android translate canvas co-ordinates when the moving bitmap inside it closes to the right border of the screen? 【发布时间】:2015-09-07 23:44:53 【问题描述】:

我的位图在画布内向右移动 我想要这个位图靠近屏幕的右边框,即: x position

另一个意思; 我希望位图继续永久向右移动,当然当它靠近屏幕的右边框时它会很快消失,所以我希望画布本身与我一起移动以使位图始终可见 我想知道如何在翻译画布后设置x位置值

即:例如在所有游戏中,角色向右移动,屏幕也随之移动。

这是在这里找到的代码

http://www.edu4java.com/en/androidgame/androidgame3.html

我对其进行了编辑,现在位图在靠近屏幕右边框时重复其移动。

MyActivity.java


   @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);


       setContentView(new GameView(this));


  

和MyGameView(我的问题的主要类)

 import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.util.Log;
  import android.view.SurfaceHolder;
 import android.view.SurfaceView;

public class GameView extends SurfaceView 
 private Bitmap bmp;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private int x = 0;
private int xSpeed = 2;

public GameView(Context context) 
    super(context);
    gameLoopThread = new GameLoopThread(this);
    holder = getHolder();
    holder.addCallback(new SurfaceHolder.Callback() 

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) 
            boolean retry = true;
            gameLoopThread.setRunning(false);
            while (retry) 
                try 
                    gameLoopThread.join();
                    retry = false;
                 catch (InterruptedException e) 
                
            
        

        @Override
        public void surfaceCreated(SurfaceHolder holder) 
            gameLoopThread.setRunning(true);
            gameLoopThread.start();
        

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,
                                   int width, int height) 
        
    );
    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.attention);


@Override
protected void onDraw(Canvas canvas) 

    super.onDraw(canvas);


    if(x==getWidth())
    
        Log.e("cds","cdca");
        canvas.translate(x, 0);

        x=10;
    
    else
    
        x = x + xSpeed;

    

    if(canvas!=null) 
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(bmp, x, 10, null);
    


GameLoopThread .java

    import android.graphics.Canvas;

 public class GameLoopThread extends Thread 
static final long FPS = 10;
private GameView view;
private boolean running = false;

public GameLoopThread(GameView view) 
    this.view = view;


public void setRunning(boolean run) 
    running = run;


@Override
public void run() 
    long ticksPS = 1000 / FPS;
    long startTime;
    long sleepTime;
    while (running) 
        Canvas c = null;
        startTime = System.currentTimeMillis();
        try 
            c = view.getHolder().lockCanvas();
            synchronized (view.getHolder()) 
                view.onDraw(c);
            
         finally 
            if (c != null) 
                view.getHolder().unlockCanvasAndPost(c);
            
        
        sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
        try 
            if (sleepTime > 0)
                sleep(sleepTime);
            else
                sleep(10);
         catch (Exception e) 
    
  
  

【问题讨论】:

对这个问题有什么帮助吗? 【参考方案1】:

正如您提到的“在所有游戏中,角色向右移动,屏幕也随之移动”。

您需要定义相机视口的大小(让它成为屏幕大小 640X480)和世界 (1280X960)

您还需要定义相机的最小和最大偏移量

offsetMax_X= WorldSize_X-ViewPort_X; //(1280-640)
offsetMax_Y= WorldSize_Y-ViewPort_Y; //(960-480)
offsetMin_X=0;
offsetMin_Y=0;

现在您需要计算相对于播放器(Sprites)的相机位置,以便播放器始终位于屏幕中心。

cam_x=player_X-ViewPort_X/2; 
cam_y=player_Y-ViewPort_Y/2;

检查相机位置,使其不超过偏移量。

if(cam_x>offsetMax_X)
    cam_x=offsetMax_X;
else if(cam_x<offsetMin_X)
    cam_x=offsetMin_X;
if(cam_y> offsetMax_Y)
    cam_y=offsetMax_Y;
else if(cam_y<offsetMin_Y)
    cam_y=offsetMin_Y;

你还需要对画布进行 tanslate

canvas.translate(-cam_x,-cam_y);

我正在编写部分代码。创建一个相机类

 class Camera
  int ViewPort_X;
  int ViewPort_Y;
  int WorldSize_X;
  int WorldSize_Y;
  int offsetMax_X;
  int offsetMax_Y;
  int offsetMin_X;
  int offsetMin_Y;
  int CameraPos_X;
  int CameraPos_Y;
   Camera(int _ViewPort_X,int _ViewPort_Y,int _WorldSize_X,int _WorldSize_Y)
   
   ViewPort_X=_ViewPort_X;
   ViewPort_Y=_ViewPort_Y;
   WorldSize_X=_WorldSize_X;
   WorldSize_Y=_WorldSize_Y;
   offsetMax_X= WorldSize_X- ViewPort_X;
   offsetMax_Y= WorldSize_Y- ViewPort_Y;
   offsetMin_X=0;
   offsetMin_Y=0;
   
  void updateCamera(int player_X,int player_Y)
  
  CameraPos_X=player_X-ViewPort_X/2;
  CameraPos_Y=player_Y-ViewPort_Y/2;
  if(CameraPos_X>offsetMax_X)
     CameraPos_X=offsetMax_X;
  else if(CameraPos_X<offsetMin_X)
     CameraPos_X=offsetMin_X;
  if(CameraPos_Y> offsetMax_Y)
     CameraPos_Y=offsetMax_Y;
  else if(CameraPos_Y<offsetMin_Y)
    CameraPos_Y=offsetMin_Y;
   
 

并在 GameView 中创建相机实例

Camera cam;
int playerX;
int playerY;
public GameView(Context context) 
   super(context);
   cam=new Camera(640,480,1280,960);
   playerX=width/2;
   playerY=height/2;
   .....
   .....
  ......
 

现在更新画布

 @Override
protected void onDraw(Canvas canvas) 
 super.onDraw(canvas);
 canvas.translate(-cam.CameraPos_X,-cam.CameraPos_Y);
 cam.updateCamera(playerX,playerY); 

 if(playerX>cam. WorldSize_X)
  playerX= cam.WorldSize_X;
 else if(playerX<0)
  playerX=0;
 if(playerY>cam.WorldSize_Y)
  playerY=cam.WorldSize_Y;
 else if(playerY<0)
  playerY=0;
 .....
 ....
 //draw bitmap
  .....
 

添加 touchEvents 来控制 Sprite 的动作 (http://developer.android.com/reference/android/view/View.html#onTouchEvent(android.view.MotionEvent)

playerY-=5;//move towards up
playerY+=5;// move towards down
playerX-=5;// move toward left
playerX+=5; //move towards right

【讨论】:

非常感谢您的帮助,但我想让角色从左到右运行,并且手机屏幕的右边框不会阻止它运行,也不会成功(角色)不可见,所以我想例如让角色以大约 +10 的速度运行,而画布以 +7 的速度自行运行(即:小于角色速度)仅跟踪其运动并使其始终可见 当字符到达右边框时它是不可见的,因为它超出了屏幕的尺寸,所以如何翻译屏幕的坐标使其始终可见 并且一直在运行 好的..你需要向左移动画布,但你正在向右移动画布,一旦你检查它,我就写了新的答案。【参考方案2】:

好的,您需要将 canvas 向左平移,但您将 canvas 向右移动。

使用变量 moveCanvasX 将画布向左平移。您还需要以相同的速度移动画布和精灵,以“xSpeed”的速度将精灵向右移动,以“xSpeed”的速度将画布向左移动,这样精灵将始终保持向右。我希望这能解决您的问题。

int moveCanvasX=0;

@Override
protected void onDraw(Canvas canvas) 

super.onDraw(canvas);


if(x>=getWidth()-bmp.getWidth())

    Log.e("cds","cdca");
    canvas.translate(-moveCanvasX, 0);
    moveCanvasX=moveCanvasX+xSpeed;
    x=x + xSpeed;

else

    x = x + xSpeed;



if(canvas!=null) 
    canvas.drawColor(Color.BLACK);
    canvas.drawBitmap(bmp, x, 10, null);
 

【讨论】:

我非常抱歉迟到了,非常感谢你的帮助,但这对我来说没有成功,所以我最终使用了 libgdx 并问了这个问题***.com/questions/32595413/… 可能对你有用或任何人有这样的问题

以上是关于当其中的移动位图靠近屏幕的右边框时,android会翻译画布坐标?的主要内容,如果未能解决你的问题,请参考以下文章

当网页点击tab键切换输入的文本框时,整个网页会出现上移的情况?如何解决....急急.......

在android上调整位图大小的最节省内存的方法?

使用位图时,Android MLKit 人脸检测未检测到人脸

将视图转换为位图而不在 Android 中显示?

Android 软键盘隐藏了移动 HTML5 网络应用程序中的输入字段

如何将位图从 Activity 传递给服务