2016-01-11 1 views
0

Je veux faire un "effet de brouillard" avec le bruit 3D Perlin, l'axe Z pour le nombre de trame d'animation. J'utilise une grille de LinearLayout 16x9 pour cela, toutes avec la même couleur de fond, et en changeant leur transparence alpha aux valeurs du bruit de Perlin. Fonctionne assez bien sur ma tablette, mais avec 32 x 18 choses commencent à ramper un peu, et sur mon téléphone, je ne vois rien, juste quelques artefacts - comme déchirement d'image aléatoire.Animer le bruit sur Android

Est-ce qu'une vue personnalisée et un dessin directement sur le canevas (en agrandissant le tout) seraient plus rapides et plus sûrs?

Ou le problème est-il si rapide lors de la mise à jour de l'écran? Dessin directement dans la toile est le moyen approprié pour le faire.

Répondre

1

Plus de problèmes "d'artefact", et bien meilleur framerate. C'est aussi très facile à faire.

Voici un exemple de travail d'une classe MistView:

package com.example.yourapp; // don't forget to change this 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff; 
import android.util.AttributeSet; 
import android.view.View; 
import android.os.Handler; 

import java.util.Random; 

public class MistView extends View { 

    SimplexNoise sN = new SimplexNoise(); // you'll need a working SimplexNoise class 
    Paint[][] paints = null; 
    float floathex[][]; 
    final static int W = 32; 
    final static int H = 18; 
    float widthf, heightf; 
    int z = 0; 
    final static int R = 128; // you can play with color here 
    final static int G = 128; 
    final static int B = 128; 
    Random rand = new Random(); 
    final int xoff = random(-100000, 100000); 
    final int yoff = random(-100000, 100000); 
    final int zoff = random(-100000, 100000); 
    Handler myHandler = new Handler(); 
    Runnable myRunnable = new Runnable() { 
     @Override 
     public void run() { 
      z++; 
      reDraw(); 
     } 
    }; 

    public MistView(Context context) { 
     super(context); 
     this.paints = new Paint[W][H]; 
     for (int w = 0; w < W; w++) 
     { 
      for (int h = 0; h < H; h++) 
      { 
       this.paints[w][h] = new Paint(); 
       this.paints[w][h].setStyle(Paint.Style.FILL); 
      } 
     } 
    } 

    public MistView(Context context, AttributeSet attributeSet) 
    { 
     super(context, attributeSet); 
     this.paints = new Paint[W][H]; 
     for (int w = 0; w < W; w++) 
     { 
      for (int h = 0; h < H; h++) 
      { 
       this.paints[w][h] = new Paint(); 
       this.paints[w][h].setStyle(Paint.Style.FILL); 
      } 
     } 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY); 
     if (widthf == 0) 
      widthf = canvas.getWidth()/(float) W; 
     if (heightf == 0) 
      heightf = canvas.getHeight()/(float) H; 
     floathex = sN.generateOctavedSimplexNoise(W, H, z, xoff, yoff, zoff, 8, 0.05f, 0.05f); 

     for (int w = 0; w < W; w++) 
     { 
      for (int h = 0; h < H; h++) 
      { 
       int a = Math.round(64* ((floathex[w][h] + 1f)/2f)); 
       if (a < 0) 
        a = 0; 
       this.paints[w][h].setColor(Color.argb(a, R, G, B)); 
       canvas.drawRect(w * widthf, h * heightf, (w + 1) * widthf, (h + 1) * heightf, this.paints[w][h]); 
      } 
     } 
     myHandler.postDelayed(myRunnable, 60); 
    } 

    protected void reDraw() { 
     this.invalidate(); 
    } 

    public int random(int min, int max) { 
     return (int) (rand.nextFloat() * (max - min + 1)) + min; 
    } 
}