Android - 在画布上绘制不在Runnable中工作

时间:2017-03-12 13:15:34

标签: android multithreading canvas draw

这是我第一次使用android时,我在线程内反复绘制画布时遇到了一些麻烦。它似乎只被绘制一次,虽然线程正在运行,我确保使用每次执行线程时弹出的toast(我已经删除它,因为它困扰我)但线程正在运行并且内部代码被执行,它只是不重绘...

public class GameActivity extends Activity implements Runnable{
    ImageView gameView;
    public int screenWidth, screenHeight, objectSize;
    private static int FPS = 30;
    private boolean rightPressed = false, leftPressed = false;
    private Player player;
    private Thread thread;
    private Canvas canvas;
    private Bitmap blankBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        screenWidth = size.x;
        screenHeight = size.y;
        objectSize = screenWidth/8;
        player = new Player(objectSize, screenWidth/2 - objectSize/2, screenHeight - (objectSize+10));

        blankBitmap = Bitmap.createBitmap(screenWidth,screenHeight,Bitmap.Config.ARGB_8888);
        canvas = new Canvas(blankBitmap);
        gameView = new ImageView(this);
        gameView.setImageBitmap(blankBitmap);
        draw();

        setContentView(gameView);

        thread = new Thread(this);
        thread.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            leftPressed = true;
            if((int)event.getX()<=screenWidth/2){
                leftPressed = true;
                rightPressed = false;
                Toast.makeText(this, "left", Toast.LENGTH_SHORT).show();
            }
            if((int)event.getX()>screenWidth/2){
                rightPressed = true;
                leftPressed = false;
                Toast.makeText(this, "right", Toast.LENGTH_SHORT).show();
            }
        }
        if(event.getAction() == MotionEvent.ACTION_UP) {
            rightPressed = false;
            leftPressed = false;
            Toast.makeText(this, "released", Toast.LENGTH_SHORT).show();
        }

        return super.onTouchEvent(event);
    }

    public void draw(){
        canvas.drawColor(Color.argb(255, 255, 255, 255));
        player.draw(canvas);
    }

    @Override
    public void run() {
        while (!player.shouldDie()) {
            try {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!rightPressed && !leftPressed) player.setDx(0);
                        if(rightPressed) player.setDx(player.getSpeed());
                        if(leftPressed) player.setDx(-player.getSpeed());
                        player.update();
                        draw();
                    }
                });
                Thread.sleep(1000/FPS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

我还检查了播放器的x确实发生了变化,如果我手动将dx设置为100,它实际上会在第一次执行时移动,但是即使线程仍在运行,也不会更晚

无论如何,这里是Player.class

public class Player  {

    private int health, size, x, y;
    private double dx, speed;
    private Paint paint;

    public Player(int size, int x, int y){
        health = 3;
        speed = 1;
        dx = 0;
        this.size = size;
        this.x = x;
        this.y = y;

        paint = new Paint();
        paint.setColor(Color.argb(255,  26, 128, 182));
    }

    public void draw(Canvas canvas){
        canvas.drawRect(x, y, x+size, y+size, paint);
      }

    public void update(){
        x += dx;
    }

    public void hurt(){
        health--;
    }

    public boolean shouldDie(){
        if(health<=0)return true;
        return false;
    }
    public void posToast(Context context){
        Toast.makeText(context, "X: " + x, Toast.LENGTH_SHORT).show();
    }

    public int getHealth() {
        return health;
    }
    public void setHealth(int health) {
        this.health = health;
    }
    public Paint getPaint() {
        return paint;
    }
    public double getSpeed() {
        return speed;
    }
    public void setSpeed(double speed) {
        this.speed = speed;
    }
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }
    public double getDx() {
        return dx;
    }
    public void setDx(double dx) {
        this.dx = dx;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
}

如果有人在这里看错了我会感激一些帮助,因为我真的很困惑为什么这不起作用,特别是因为这是我第一次使用android。

1 个答案:

答案 0 :(得分:0)

似乎你忘了调用rePaint()方法。在Android中,你有一个名为inValidate()的东西可以重绘你的画布。您可以添加播放器绘制方法或活动绘制方法。这应该可以解决问题。