Android基于绘制缓冲实现烟花效果
surface.release();8 surface.release();7 surface.release();6surface.release();5 surface.release();4surface.release();3 surface.release();2
surface.release();1surface.release();0 9
8 7 6
5 4 3
2 1 0
}9}8 }7 }6}5}4
}3}2 }1 }0 9 8 7
6 5 4 3 2 1
0surface = 9
surface = 8surface = 7
surface = 6surface = 5
surface = 4surface = 3 surface = 2
surface = 1surface = 0null9null8null7
null6null5
null4null3 null2null1 null0
;9;8;7
;6;5;4;3
;2;1
;0 9 8 7
6 5 4 3
2 1 0}9
}8}7
}6}5
}4}3
}2}1
}0 9
8 7 6 5 4 3 2
1 0 }9 }8 }7}6}5
}4}3 }2 }1 }0}9}8
}7}6}5 }4
}3}2}1}0 float[3];
volatile boolean isCommand = false;
static final float speed = 60f;
Thread drawThread = null;
public void startExplore() {
isCommand = true;
}
void explode(float x, float y) {
float angleIncrement = (float) ((Math.PI * 2) / maxParticleCount);
for (int i = 0; i < maxParticleCount; i++) {
hsl[0] = (float) (Math.random() * 360);
hsl[1] = 0.5f;
hsl[2] = 0.5f;
int hslToColor = HSLToColor(hsl);
Particle p = null;
if (particles.size() > i) {
p = particles.get(i);
}
if (p == null) {
p = new Particle();
particles.add(p);
}
p.init(x, y,
4f,
hslToColor,
(float) (Math.cos(angleIncrement * i) * Math.random() * speed),
(float) (Math.sin(angleIncrement * i) * Math.random() * speed)
);
}
}
protected void drawParticles(Canvas canvas) {
canvas.drawColor(0x10000000);
for (int i = 0; i < particles.size(); i++) {
Particle particle = particles.get(i);
if (particle.opacity > 0) {
particle.draw(canvas, mPaint);
particle.update();
}
}
}
static class Particle {
private float opacity;
private float dy;
private float dx;
private int color;
private float radius;
private float y;
private float x;
public void init(float x, float y, float r, int color, float speedX, float speedY) {
this.x = x;
this.y = y;
this.radius = r;
this.color = color;
this.dx = speedX;
this.dy = speedY;
this.opacity = 1f;
}
void draw(Canvas canvas, Paint paint) {
int save = canvas.save();
paint.setColor(argb((int) (this.opacity * 255),Color.red(this.color),Color.green(this.color),Color.blue(this.color)));
canvas.drawCircle(this.x, this.y, this.radius, paint);
canvas.restoreToCount(save);
}
void update() {
this.dy += gravity;
this.dx *= fraction;
this.dy *= fraction;
this.x += this.dx;
this.y += this.dy;
this.opacity -= 0.02;
}
}
Matrix matrix = new Matrix();
@Override
public void run() {
while (true) {
synchronized (this) {
try {
this.wait(16);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!isRunning || Thread.currentThread().isInterrupted()) {
synchronized (lockSurface) {
if (surface != null && surface.isValid()) {
surface.release();
}
surface = null;
}
break;
}
Canvas canvas = null;
synchronized (lockSurface) {
if(mBitmapCanvas == null || updateOnSizeChanged) {
updateOnSizeChanged = false;
mBitmapCanvas = createBitmapCanvas(getWidth(),getHeight());
}
if(isCommand){
mBitmapCanvas.bitmap.eraseColor(0x00000000);
explode(mBitmapCanvas.getWidth() / 2f, mBitmapCanvas.getHeight() / 2f);
isCommand = false;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
canvas = surface.lockHardwareCanvas();
}else {
canvas = surface.lockCanvas(null);
}
Bitmap bitmap = mBitmapCanvas.getBitmap();
drawParticles(mBitmapCanvas);
matrix.reset();
matrix.setTranslate((getWidth() - bitmap.getWidth()) / 2f, (getHeight() - bitmap.getHeight()) / 2f);
canvas.drawBitmap(mBitmapCanvas.getBitmap(), matrix, null);
surface.unlockCanvasAndPost(canvas);
}
}
}
private BitmapCanvas createBitmapCanvas(int width,int height){
if(mBitmapCanvas != null){
mBitmapCanvas.recycle();
}
int size = Math.max(Math.min(width,height),1);
return new BitmapCanvas(Bitmap.createBitmap(size,size, Bitmap.Config.ARGB_8888));
}
static class BitmapCanvas extends Canvas{
Bitmap bitmap;
public BitmapCanvas(Bitmap bitmap) {
super(bitmap);
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
public void recycle() {
if(bitmap == null || bitmap.isRecycled()){
return;
}
bitmap.recycle();
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
this.drawThread = new Thread(this);
this.surfaceTexture = surfaceTexture;
this.surface = new Surface(this.surfaceTexture);
this.isRunning = true;
this.drawThread.start();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
updateOnSizeChanged = true;
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
isRunning = false;
if (drawThread != null) {
try {
drawThread.interrupt();
}catch (Throwable e){
e.printStackTrace();
}
}
drawThread = null;
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
@ColorInt
public static int HSLToColor(@NonNull float[] hsl) {
final float h = hsl[0];
final float s = hsl[1];
final float l = hsl[2];
final float c = (1f - Math.abs(2 * l - 1f)) * s;
final float m = l - 0.5f * c;
final float x = c * (1f - Math.abs((h / 60f % 2f) - 1f));
final int hueSegment = (int) h / 60;
int r = 0, g = 0, b = 0;
switch (hueSegment) {
case 0:
r = Math.round(255 * (c + m));
g = Math.round(255 * (x + m));
b = Math.round(255 * m);
break;
case 1:
r = Math.round(255 * (x + m));
g = Math.round(255 * (c + m));
b = Math.round(255 * m);
break;
case 2:
r = Math.round(255 * m);
g = Math.round(255 * (c + m));
b = Math.round(255 * (x + m));
break;
case 3:
r = Math.round(255 * m);
g = Math.round(255 * (x + m));
b = Math.round(255 * (c + m));
break;
case 4:
r = Math.round(255 * (x + m));
g = Math.round(255 * m);
b = Math.round(255 * (c + m));
break;
case 5:
case 6:
r = Math.round(255 * (c + m));
g = Math.round(255 * m);
b = Math.round(255 * (x + m));
break;
}
r = constrain(r, 0, 255);
g = constrain(g, 0, 255);
b = constrain(b, 0, 255);
return Color.rgb(r, g, b);
}
private static int constrain(int amount, int low, int high) {
return amount < low ? low : Math.min(amount, high);
}
public static int argb(
@IntRange(from = 0, to = 255) int alpha,
@IntRange(from = 0, to = 255) int red,
@IntRange(from = 0, to = 255) int green,
@IntRange(from = 0, to = 255) int blue) {
return (alpha << 24) | (red << 16) | (green << 8) | blue;
}
public void release(){
synchronized (lockSurface) {
isRunning = false;
updateOnSizeChanged = false;
if (surface != null && surface.isValid()) {
surface.release();
}
surface = null;
}
}
}
相关知识
基于Python实现一个浪漫烟花秀
基于Android的鲜花预定软件的设计与实现
基于Android的花卉交流平台的设计与实现
基于node.js+vue基于Android的平台书架的设计与实现后(开题+程序+论文)计算机毕业设计
JAVA表白浪漫烟花效果代码
实现类似android:clipChildren=“false”的效果,在使用android:clipChildren多次尝试无效时使用
python实现元旦倒计时、圣诞树、跨年烟花的绘画马上双旦了给大家带来一些python代码 1.元旦节日倒计时代码的实现
基于Android的阳台浇花控制系统设计
基于Android平台智能花卉养护系统.doc
Android简单实现汉字笔顺动画——Java版
网址: Android基于绘制缓冲实现烟花效果 https://www.huajiangbk.com/newsview1306370.html
上一篇: android 花屏问题 安卓手 |
下一篇: 爱花人的盛会!2025迎春花展将 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039