Ich experimentiere mit Zeichnen auf einer Leinwand mit einem Thread, um eine einfache Spiel-Engine zu erstellen, aber ich habe einige seltsame Probleme, die ich nicht erklären kann. Der Zweck dieses "Spiels" ist, jede Sekunde auf der Leinwand einen Kreis zu zeichnen. Das funktioniert, aber nicht so, wie ich es möchte. Es scheint, als würde die App zwischen zwei Leinwänden wechseln und jeder Leinwand einen Kreis hinzufügen, so dass Sie jede Sekunde mit der gleichen Anzahl von Kreisen wechseln können Platz auf der Leinwand.Android SurfaceView Leinwand Zeichnung mit einem Thread
Ich weiß nicht, was ich falsch mache, aber ich bin nicht vertraut mit Treading, hat es etwas damit zu tun, wie viele Kerne mein Android-Gerät hat oder so ähnlich?
Mein Code ist unten gezeigt, also verwende ich nur einen LaunchThread, der eine Layoutdatei verwendet, die mit dem Animationsfaden verknüpft, der einen Thread startet und jede Sekunde einen Kreis auf der Zeichenfläche zeichnet. (Sie können das touchevent ignorieren, es wird noch nicht verwendet).
Das Projekt besteht aus einem Haupt launchthread:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
, die diese Layout-Datei verwendet:
<?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>
Und meine Surface Klasse mit einem Innengewinde Klasse:
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) {
}
}
}
}
Sollte das in Ihrem Code AnimationView2 sein? Eine korrigierte Version würde geschätzt werden. – RichieHH
(Wenn Sie den Code aus einem Samples Beispiel kopieren (dies ist ein leicht modifizierter LunarLander), ist es immer am besten, es zu sagen, da es die Fehlersuche erleichtert)). – RichieHH