2010-08-26 17 views
6

Sto cercando di capire come risolvere il problema. Ho letto http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664 che tipo di risposte alla mia domanda, ma per quanto posso dire, è una sorta di "sfortuna" risposta. Quindi ecco il mio problema:SurfaceView sfarfallio/strappo

Sto usando SurfaceView nel modo normale (lock/unlockAndPost) per disegnare una bitmap del mio background di gioco ogni volta che la superficie viene cambiata (es. Orientamento ecc.) E sto riproducendo una serie di movimenti cerchi (fino a 30 con un raggio di circa 25.f). I dati x, y per le posizioni di queste cerchie provengono da un server e tutto funziona alla perfezione. Tutti gli oggetti cerchia vengono memorizzati in un elenco e la loro posizione viene aggiornata avendo cura di garantire che questo aggiornamento sia sincronizzato. Tuttavia, quando disegno questi cerchi sullo schermo (durante canvas.lock()), il più delle volte rendono bene ma occasionalmente (ad esempio una volta ogni pochi secondi) alcuni cerchi sembrano strapparsi o sfarfallare brevemente per un fotogramma. Il numero di cerchi è sempre costante, quindi non è questo il problema e non ci sono modifiche simultanee all'elenco di cerchi (come ho detto, è sincronizzato). Ho anche provato a disegnare tutti questi cerchi in una bitmap su ciascun ciclo di rendering e disegno quella bitmap sulla tela principale. Questo sembra influenzare ancora di più la perfomance (~ 13 FPS in confronto a ~ 30 FPS quando si disegnano cerchi direttamente sulla tela principale). Scusate se l'informazione è un po 'vaga, ragazzi, (cercando di mantenere la compagnia felice: p) ma mi stavo chiedendo se qualcuno potesse darmi un indizio? O sono solo sfortunato. Dovrei notare che i dati di posizionamento provenienti dal server sono dati in tempo reale ed è di vitale importanza che il rendering rifletta queste posizioni in tempo reale.

Grazie per qualsiasi aiuto! Chris

EDIT:

Mi sembra giusto. Ecco run() dal thread di rendering.

@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); 
       } 
      } 
     } 
    } 

roba piuttosto standard (quasi una copia carbone del lander lunare: 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; 
} 

abbastanza facile da seguire, basta ridisegnare la bitmap di sfondo se i cambiamenti di orientamento e di avviare il thread di rendering.

public void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mField,0,0,null); 
    drawPositionBeans(canvas, this); 
} 

E infine:

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); 
     } 
    } 
} 

Grazie ancora ragazzi. Chris

+0

impossibile rispondere senza vedere il tuo gameloop e il disegno del codice. – Sebi

+0

Come ha detto Sebi - un esempio di codice sarebbe utile - ma hai considerato la possibilità che le posizioni che ricevi occasionalmente non siano corrette? Solo un pensiero sul motivo per cui i cerchi potrebbero essere "tremolanti", se vengono temporaneamente posizionati fuori vista. Ancora una volta, senza alcun codice questo sarà impossibile rispondere. – Seidr

+0

Mille grazie per l'aiuto ragazzi. Ma sì, sono sicuro che i dati di posizionamento sono corretti. –

risposta

0

Ho avuto questo problema. La soluzione adatta a me è la sincronizzazione del metodo onDraw e il metodo che aggiorna la matrice di trasformazione. Perché c'erano dei frame quando la matrice è identica (valore iniziale della nuova Matrix()) e nel frame successivo aveva i giusti valori.

0

ho trovato dopo aver letto un po 'di superficie vista che se si chiama

getHolder().lockCanvas(); 

È necessario disegnare tutto ancora.

A meno che non forniate la vostra area sporca.

getHolder().lockCanvas(Rect dirty); 

Se solo si desidera ridisegnare l'area definita dal Rect