我想用Perlin 3D噪音做一些“雾效应”,Z轴用于动画帧数。
我正在使用16x9 LinearLayouts网格,它们都具有相同的背景颜色,并将其alpha透明度更改为Perlin噪声值。
在我的平板电脑上工作得很好,但是32x18的东西开始爬行了一点,在我的手机上我什么都没看到,只是一些文物 - 比如随机图像撕裂。
直接在画布上自定义视图和绘图(然后增大整个内容)会更快更安全吗?
或者更新屏幕时产生3D噪音的问题是如此之快?
答案 0 :(得分:1)
直接绘制到画布是适当的方法。没有更多的“神器”问题,以及更好的帧率。这也很容易。
以下是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;
}
}