Próbuję dowiedzieć się, jak obejść mój problem. Przeczytałem http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664, który odpowiada na moje pytanie, ale z tego, co wiem, jest to rodzaj "trudnego szczęścia". Oto mój problem:SurfaceView migotanie/łzawienie
Używam SurfaceView w normalny sposób (lock/unlockAndPost), aby narysować mapę bitową mojego tła gry za każdym razem, gdy zmieni się jej powierzchnia (np. Orientacja itp.) I wykonuję serię ruchów kółka (do 30 o promieniu około 25f). Dane x, y dla pozycji tych kół pochodzą z serwera i wszystko działa poprawnie. Wszystkie obiekty w okręgu są przechowywane na liście, a ich pozycja jest aktualizowana, uważając, aby ta aktualizacja była zsynchronizowana. Jednak po narysowaniu tych okręgów na ekranie (podczas canvas.lock()), przez większość czasu renderują one dobrze, ale sporadycznie (np. Raz na kilka sekund), niektóre kręgi wydają się odrywać lub migotać krótko dla ramki. Liczba okręgów jest zawsze stała, więc to nie jest problem i nie ma równoczesnych modyfikacji listy kręgów (tak jak powiedziałem, jest zsynchronizowana). Próbowałem nawet rysować wszystkie te okręgi do bitmapy w każdej pętli renderowania i rysować tę mapę bitową na płótnie głównym. To tylko wydaje się wpływać na wydajność jeszcze bardziej (~ 13FPS w przeciwieństwie do ~ 30FPS przy rysowaniu kół bezpośrednio do głównego płótna). Przepraszam, jeśli informacje są trochę niewyraźne, (próbując utrzymać firmę w przyjemności: p), ale zastanawiałem się, czy ktoś może mi dać wskazówkę? Czy mam po prostu pecha? Należy zauważyć, że dane pozycjonowania pochodzące z serwera są danymi w czasie rzeczywistym i niezwykle ważne jest, aby renderowanie odzwierciedlało te pozycje w czasie rzeczywistym.
Dzięki za pomoc! Chris
EDIT:
Słusznie. Oto run() z wątku renderowania.
@Override
public void run() {
Canvas c;
while (mRun) {
c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
panel.onDraw(c);
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
dość standardowy rzeczy (prawie wierną kopią księżycowego lądownika: p)
@Override
public void surfaceCreated(SurfaceHolder holder) {
mBackground= Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.RGB_565);
screenOrientation = getResources().getConfiguration().orientation;
if(thread.getState()== Thread.State.TERMINATED){
thread = new RenderThread(holder, this);
thread.setRunning(true);
thread.start();
}else {
thread.setRunning(true);
thread.start();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Canvas c = new Canvas(mField);
c.drawARGB(255,0,144,0);
backgroundDetails.renderOnPanel(c, this);
screenOrientation = getResources().getConfiguration().orientation;
}
Dość łatwy do naśladowania, tylko przerysowanie bitmapy tła Jeżeli zmiany orientacji i rozpocząć wątek renderowania.
public void onDraw(Canvas canvas) {
canvas.drawBitmap(mField,0,0,null);
drawPositionBeans(canvas, this);
}
I wreszcie: znowu
public void onDraw(Canvas canvas, RadarView radarView) {
float beanX=0, beanY=0;
float radius = 25.0f;
final List<PositionBean> copyOfList = Collections.synchronizedList(positionBeans.getPositionBeans());
synchronized(copyOfList){
try {
for (final PositionBean pb : copyOfList)
{
if (panel.getOrientation() == Configuration.ORIENTATION_PORTRAIT) {
beanX = (float)pb.getY()*(-1);
beanY = (float)pb.getX();
} else {
beanX = (float)pb.getY()*(-1);
beanY = (float)pb.getX()*(-1);
}
mPaint.setARGB(255,pb.getRgbColor().getR(), pb.getRgbColor().getG(), pb.getRgbColor().getB());
panel.drawSpot(canvas, beanX, beanY, radius, mPaint);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setARGB(255,255,222,1);
for (int j = 0; j < selectedBean.size(); ++j)
{
if(pb.getTrack()==selectedBean.get(j)) {
panel.drawSpot(canvas, beanX, beanY, radius+1, mPaint);
}
}
mPaint.setStyle(Paint.Style.FILL);
}
} catch(Exception e) {
Log.e("render", "Exception Drawing Beans: " + e);
}
}
}
Dzięki chłopaki. Chris
da się odpowiedzieć bez widząc gameloop i kod rysowania. – Sebi
Tak jak Sebi powiedział - próbka kodu byłaby pomocna - ale czy brałeś pod uwagę możliwość, że pozycje, które otrzymujesz okazjonalnie są nieprawidłowe? Wystarczy pomyśleć, dlaczego kręgi mogą być "migotliwe", jeśli są tymczasowo umieszczone poza zasięgiem wzroku. Ponownie, bez żadnego kodu nie będzie można na nie odpowiedzieć. – Seidr
Wielkie dzięki za pomocników. Ale tak, jestem pewien, że dane dotyczące pozycjonowania są poprawne. –