2010-08-26 15 views
6

Estoy tratando de encontrar la forma de solucionar mi problema. He leído http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664, que responde a mi pregunta, pero hasta donde puedo decir, es una especie de respuesta de "mala suerte". Así que aquí está mi problema:SurfaceView parpadeo/rasgado

Estoy usando SurfaceView de la manera normal (lock/unlockAndPost) para dibujar un mapa de bits del fondo de mi juego cada vez que cambia la superficie (por ejemplo, orientación, etc.) y hago una serie de movimientos círculos (hasta 30 con un radio de aproximadamente 25.f). Los datos x, y para las posiciones de estos círculos provienen de un servidor y todo funciona bien. Todos los objetos del círculo se almacenan en una lista y su posición se actualiza teniendo cuidado de asegurar que esta actualización esté sincronizada. Sin embargo, cuando dibujo estos círculos en la pantalla (durante canvas.lock()), la mayoría de las veces se muestran bien pero ocasionalmente (por ejemplo, una vez cada pocos segundos) algunos círculos parecen desgarrarse o parpadear brevemente para un fotograma. La cantidad de círculos siempre es constante, así que ese no es el problema y no hay modificaciones simultáneas en la lista de círculos (como dije, está sincronizado). Incluso he intentado dibujar todos estos círculos en un mapa de bits en cada ciclo de renderizado y dibujar ese mapa de bits en el lienzo principal. Esto parece afectar aún más el rendimiento (~ 13FPS en vez de ~ 30FPS al dibujar círculos directamente en el lienzo principal). Disculpa si la información es un poco vaga chicos, (tratando de mantener la compañía feliz: p) pero me preguntaba si alguien podría darme una pista? O simplemente estoy fuera de suerte. Debo señalar que los datos de posicionamiento que provienen del servidor son datos en tiempo real y es de vital importancia que la representación refleje estas posiciones en tiempo real.

¡Gracias por cualquier ayuda! Chris

EDIT:

Justo lo suficiente. Aquí está la ejecución() desde el hilo de renderizado.

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

Cosas bastante estándar (casi un calco del módulo lunar: 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; 
} 

bastante fácil de seguir, simplemente volver a dibujar el mapa de bits de fondo si los cambios de orientación e iniciar el hilo de renderizado.

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

Y, por último:

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

Gracias de nuevo chicos. Chris

+0

de responder sin ver su gameloop y el dibujo de código. – Sebi

+0

Lo mismo que Sebi dijo, una muestra de código sería útil, pero ¿ha considerado la posibilidad de que las posiciones que recibe ocasionalmente sean incorrectas? Solo una idea de por qué los círculos podrían "parpadear", si se están posicionando fuera de la vista temporalmente. Nuevamente, sin ningún código esto será imposible de responder. – Seidr

+0

Muchas gracias por la ayuda chicos. Pero sí, estoy seguro de que los datos de posicionamiento son correctos. –

Respuesta

0

Tuve ese problema. La solución adecuada para mí es la sincronización del método y método onDraw que actualiza la matriz de transformación. Porque había cuadros cuando la matriz es idéntica (valor inicial de la nueva matriz()) y en el cuadro siguiente tenía valores correctos.

0

me encontré después de leer un poco acerca de vista de la superficie que si usted llama

getHolder().lockCanvas(); 

Es necesario dibujar todo de nuevo.

A menos que proporcione su área sucia.

getHolder().lockCanvas(Rect dirty); 

Si sólo desea volver a dibujar el área definida por el imposible Rect

Cuestiones relacionadas