Android SurfaceView toile dessin avec un fil
Je suis expérimenter avec dessin sur une toile à l'aide d'un fil pour créer un simple moteur de jeu, mais je vais avoir quelques problèmes bizarres je ne peux pas expliquer.
Le but de ce "jeu" est de dessiner un cercle à chaque seconde sur la toile.
Cela fonctionne, mais pas la façon dont je veux que ça fonctionne, il semble que l'application est la commutation entre les deux toiles et l'ajout d'un cercle à chaque toile, de sorte que vous obtenez un switch entre les deux toiles de chaque seconde avec le même nombre de cercles, mais dans un endroit différent sur la toile.
Je ne sais pas ce que je fais mal, mais je ne suis pas familier avec Treadding, il a quelque chose à voir avec le nombre de cœurs de mon appareil android a ou quelque chose comme ça?
Mon code est indiqué ci-dessous, alors j'ai juste utiliser un launchthread qui utilise un layoutfile que des liens vers les animationthread qui démarre un thread et dessine un cercle sur la toile à chaque seconde.
(Vous pouvez ignorer le touchevent, il n'est pas utilise encore).
Le projet existe principal launchthread:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
qui utilise ce fichier de mise en page:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.androidtesting.AnimationView
android:id="@+id/aview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout>
Et mon Surfaceview classe avec un intérieur classe Thread:
class AnimationView extends SurfaceView implements SurfaceHolder.Callback {
private boolean touched = false;
private float touched_x, touched_y = 0;
private Paint paint;
private Canvas c;
private Random random;
private AnimationThread thread;
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new AnimationThread(holder);
}
class AnimationThread extends Thread {
private boolean mRun;
private SurfaceHolder mSurfaceHolder;
public AnimationThread(SurfaceHolder surfaceHolder) {
mSurfaceHolder = surfaceHolder;
paint = new Paint();
paint.setARGB(255,255,255,255);
paint.setTextSize(32);
}
@Override
public void run() {
while (mRun) {
c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
doDraw(c);
sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
private void doDraw(Canvas canvas) {
//clear the canvas
//canvas.drawColor(Color.BLACK);
random = new Random();
int w = canvas.getWidth();
int h = canvas.getHeight();
int x = random.nextInt(w-50);
int y = random.nextInt(h-50);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
int size = 20;
canvas.drawCircle(x,y,size,paint);
canvas.restore();
}
public void setRunning(boolean b) {
mRun = b;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
touched_x = event.getX();
touched_y = event.getY();
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
touched = true;
break;
case MotionEvent.ACTION_MOVE:
touched = true;
break;
default:
touched = false;
break;
}
return true;
}
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
- Devraient-ils être AnimationView2 dans votre code? Une version corrigée serait appréciée.
- (ps lorsque vous copiez le code à partir d'un échantillons exemple ( ce qui est légèrement modifié LunarLander) c'est toujours mieux de le dire, car il fait la chasse aux bogues plus facile)).
Vous devez vous connecter pour publier un commentaire.
Oui, c'est la façon dont il fonctionne. Il est appelé double mise en mémoire tampon et que vous avez besoin de redessiner tous les cadre chaque fois:
De sorte que vous besoin de cette ligne
canvas.drawColor(Color.BLACK)
être décommentée dans votre code.Et vous ne devriez pas appeler
Thread.sleep(1000)
tout en toile est verrouillé, il sera la cause de la famine question.On dirait que vous avez ce travail, mais je n'ai juste remarquer une petite erreur que je tiens à souligner.
Que vous avez appelé la toile.restore() sans remettre en toile.save() à l'avance.
À partir de l'Android developer de référence pour la Toile: "C'est une erreur d'appeler restore() plus de fois que save() a été appelé."
Je ne vois pas de raison pour vous d'appeler une toile.save() dans votre cas, par conséquent, vous devez supprimer l'appel à la toile.restore().