web-dev-qa-db-ja.com

Android SurfaceViewとスレッドを使用して描画

3つのクラスを使用して画面にボールを描画しようとしています。これについて少し読んだところ、1ページで3つのクラスを使用して機能するコードスニペットを見つけました Androidでグラフィックを再生する

下の写真のように壁にぶつかると移動して方向を変えるボールができるようにコードを変更しました(これはリンクのコードを使用しています)

moving ball screenshot

今、私はすべてをそれほど混雑させないためにクラスを3つの異なるページに分割するのが好きです、すべてが同じように設定されます。

これが私が持っている3つのクラスです。

  1. BallActivity.Java
  2. Ball.Java
  3. BallThread.Java

package com.brick.breaker;
import Android.app.Activity;
import Android.os.Bundle;
import Android.view.Window;
import Android.view.WindowManager;


public class BallActivity extends Activity {

private Ball ball;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

    ball = new Ball(this);
    setContentView(ball);
}

@Override
protected void onPause() {

    super.onPause();

    setContentView(null);
    ball = null;

    finish();
}

}

package com.brick.breaker;

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.Canvas;
import Android.view.SurfaceHolder;
import Android.view.SurfaceView;

public class Ball extends SurfaceView implements SurfaceHolder.Callback {

private BallThread ballThread = null;

private Bitmap bitmap;

private float x, y;
private float vx, vy;

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

    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ball);

    x = 50.0f;
    y = 50.0f;

    vx = 10.0f;
    vy = 10.0f;

    getHolder().addCallback(this);
    ballThread = new BallThread(getHolder(), this);
}

protected void onDraw(Canvas canvas) {

    update(canvas);

    canvas.drawBitmap(bitmap, x, y, null);
}

public void update(Canvas canvas) {

    checkCollisions(canvas);

    x += vx;
    y += vy;
}

public void checkCollisions(Canvas canvas) {

    if(x - vx < 0) {

        vx = Math.abs(vx);

    } else if(x + vx > canvas.getWidth() - getBitmapWidth()) {

        vx = -Math.abs(vx);
    }

    if(y - vy < 0) {

        vy = Math.abs(vy);

    } else if(y + vy > canvas.getHeight() - getBitmapHeight()) {

        vy = -Math.abs(vy);
    }
}

public int getBitmapWidth() {

    if(bitmap != null) {

        return bitmap.getWidth();

    } else {

        return 0;
    }
}

public int getBitmapHeight() {

    if(bitmap != null) {

        return bitmap.getHeight();

    } else {

        return 0;
    }
}

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

}

public void surfaceCreated(SurfaceHolder holder) {

    ballThread.setRunnable(true);
    ballThread.start();

}

public void surfaceDestroyed(SurfaceHolder holder) {

    boolean retry = true;
    ballThread.setRunnable(false);

    while(retry) {

        try {

            ballThread.join();
            retry = false;

        } catch(InterruptedException ie) {

            //Try again and again and again
        }

        break;
    }

    ballThread = null;

}

}

package com.brick.breaker;

import Android.graphics.Canvas;
import Android.view.SurfaceHolder;

public class BallThread extends Thread {

private SurfaceHolder sh;
private Ball ball;

private Canvas canvas;

private boolean run = false;

public BallThread(SurfaceHolder _holder,Ball _ball) {

    sh = _holder;
    ball = _ball;
}

public void setRunnable(boolean _run) {

    run = _run;
}

public void run() {

    while(run) {

        canvas = null;

        try {

            canvas = sh.lockCanvas(null);

            synchronized(sh) {

                ball.onDraw(canvas);
            }

        } finally {

            if(canvas != null) {

                sh.unlockCanvasAndPost(canvas);
            }

        }

    }
}

public Canvas getCanvas() {

    if(canvas != null) {

        return canvas;

    } else {

        return null;
    }
}
}

これらのクラスの結果を示す写真があります。

enter image description here

私はこれを理解しようとしましたが、Android開発にかなり慣れていないので、助けを求めることができると思いました。

何がボールをそのように引くのか知っている人はいますか?コードはリンクのコードとほとんど同じで、解決策を見つけるために実験を試みましたが、うまくいきませんでした。

10
Morten Høgseth

さて、画像でわかるように、ボールを描いただけです。代わりに、ボールを描画するたびに、黒い背景(または必要なもの)を再描画する必要があります。

または、前の位置にのみ黒い領域を描画することもできますが、後でより多くのオブジェクトを使用すると、問題が発生する可能性があります。

これは素晴らしいサンプルです 、あなたがしていることと同じです

15

簡単に見てみると、同じサーフェス上に描画しているだけで、サーフェスビューに再描画を要求することはありません。 finalブロックの最後で、IFステートメントで次を使用します。postInvalidate();これにより、サーフェスビューが再描画されます。

1
Sorceri

これを入れて

public void onDraw(Canvas canvas){
   canvas.drawColor(Color.BLACK);

.....

}
1
wdog

http://som-itsolutions.blogspot.in/2012/06/Android-graphics-and-animation-pendulum.html で振り子シミュレーションをどのように行ったかをご覧ください。

このプロジェクトのソースコードは https://github.com/sommukhopadhyay/pendulumsimulation から複製できます。