首页 分享 Android基于绘制缓冲实现烟花效果

Android基于绘制缓冲实现烟花效果

来源:花匠小妙招 时间:2024-12-26 14:32

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迎春花展将

推荐分享