zoukankan      html  css  js  c++  java
  • 一个放烟花的android程序

    HolderSurfaceView.java(看名字就知道这是个啥了)

    复制代码
    package com.yh;
    
    import android.graphics.PixelFormat;
    import android.view.SurfaceView;
    
    /**
     * 对surfaceView进行一些设置 这是一个单例
     * 
     * @author gary
     * 
     */
    public class HolderSurfaceView {
        private HolderSurfaceView() {
    
        }
    
        private static HolderSurfaceView mHolderSurfaceView = null;
    
        public static HolderSurfaceView getInstance() {
            if (mHolderSurfaceView == null)
                mHolderSurfaceView = new HolderSurfaceView();
            return mHolderSurfaceView;
        }
    
        private SurfaceView mSurfaceView;
    
        /**
         * 设置SurfaceView
         * 
         * @param view
         */
        public void setSurfaceView(SurfaceView view) {
            mSurfaceView = view;
            mSurfaceView.setZOrderOnTop(true);
            mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
        }
    
        public SurfaceView getSurfaceView() {
            return mSurfaceView;
        }
    }
    复制代码

     

    DrawTop.java(其实没怎么用到其中的代码,这是为另一个目的编写的代码)

    复制代码
    package com.yh;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.PorterDuff.Mode;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnTouchListener;
    
    public class DrawTopBase implements Runnable, Callback ,OnTouchListener{
        protected SurfaceView mSurfaceView;
        protected SurfaceHolder mSurfaceHolder;
        protected Context mContext;
        protected Rect mSurfaceRect = new Rect(0, 0, 0, 0);
    
        public DrawTopBase() {
            setSurfaceView(HolderSurfaceView.getInstance().getSurfaceView());
        }
    
        public void setSurfaceView(SurfaceView view) {
            mSurfaceView = view;
            mContext = mSurfaceView.getContext();
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceRect.set(new Rect(0, 0, mSurfaceView.getWidth(), mSurfaceView
                    .getHeight()));
            set();
        }
    
        /**
         * 根据长宽来设置范围
         */
        public void set() {
            setRect(mSurfaceRect);
        }
    
        protected Thread mThread = null;
    
        /**
         * 开始,为了必免重复开始,定义线程变量
         */
        public void begin() {
            if (mThread == null) {
                mThread = new Thread(this);
                mThread.start();
            }
        }
    
        public void end() {
            mStatus = DrawStatus.Ending;
        }
    
        /**
         * 画内容
         * 
         * @param canvas
         */
        protected void doWork(Canvas canvas) {
    
        }
    
        /**
         * 结束工作
         */
        protected void endWork() {
    
        }
    
        protected Paint mPaint = new Paint();
    
        /**
         * 清空
         * 
         * @param canvas
         */
        protected void clear(Canvas canvas) {
            mPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
            canvas.drawPaint(mPaint);
            mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
        }
    
        protected void clear() {
            synchronized (mSurfaceHolder) {
                Canvas canvas = this.mSurfaceHolder.lockCanvas();
                try {
                    clear(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (canvas != null)
                        mSurfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    
        protected void doChange() {
            change();
        }
    
        /**
         * 变化
         */
        protected void change() {
    
        }
    
        protected Rect mRect = new Rect(0, 0, 0, 0);
    
        public void setRect(Rect r) {
            mRect.set(r);
        }
    
        public Rect getRect() {
            return mRect;
        }
    
        protected DrawStatus mStatus = DrawStatus.NoWork;
    
        /**
         * 工作状态 noWork 没有工作 draw 在主循环中 end 正常结束 destroy 非正常结束
         * 
         * @author gary
         * 
         */
        protected enum DrawStatus {
            NoWork, Drawing, Ending, Destroyed
        };
    
        protected long mBegintime;
    
        @Override
        public void run() {
            mStatus = DrawStatus.Drawing;
            starttime = System.currentTimeMillis();
            mBegintime = System.currentTimeMillis();
            // 建立两次缓存
            clear();
            clear();
            while (mStatus == DrawStatus.Drawing) {
                synchronized (mSurfaceHolder) {
                    Canvas canvas = this.mSurfaceHolder.lockCanvas(getRect());
                    try {
                        if (canvas != null) {
                            clear(canvas);
                            doWork(canvas);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (canvas != null)
                            mSurfaceHolder.unlockCanvasAndPost(canvas);
                    }
                    doChange();                
                }
                calculatePerframe();
    
            }
            if (mStatus != DrawStatus.Destroyed)
                clear();
            mThread = null;
            endWork();
        }
    
        protected long starttime;
        // 每帧时间 60帧附近 第一次计算前使用 毫秒
        private float perframe = 16;
    
        private int count = 0;
    
        // 每隔多长时间测试一次帧时间
        private int mRefreshSpeed = 12;
    
        // 设定要求多长时间每帧 24帧每秒
        private float mFPS = 1000 / 12;
        private float sleep = mFPS;
    
        // 设置刷新频率
        public void setFPS(int fps) {
            mFPS = 1000 / fps;
        }
    
        /**
         * 等待时间
         */
        protected void calculatePerframe() {
            count++;
            if (count == mRefreshSpeed) // 由于每帧计算会降低游戏效率。20到50差不多
            {
                long timepass = System.currentTimeMillis();
                long time = timepass - starttime;
                perframe = time / mRefreshSpeed;// 每帧时间
                sleep = perframe > mFPS ? mFPS - (perframe - mFPS) / mRefreshSpeed
                        : mFPS;
                starttime = timepass;
                count = 0;
            }
            try {
                Thread.sleep((long) (sleep));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            mSurfaceRect.set(new Rect(0, 0, width, height));
            set();
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            mStatus = DrawStatus.Destroyed;
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            return false;
        }
    }
    复制代码

    GameSoundMedia.java(这也是来自另一个项目懒得重写)

    View Code
    复制代码
    package com.yh;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.media.MediaPlayer;
    
    /**
     * 需要返回值
     * 
     * @author gary
     * 
     */
    public class GameSoundMedia {
        public static final int GAME_SOUND_MEDIA_COMPLETION = 1;
        private Context mContext;
    
        public GameSoundMedia(Context context) {
            mContext = context;
        }
    
        private List<MediaPlayer> mList = new ArrayList<MediaPlayer>();
    
        public void stopAll() {
            for (MediaPlayer i : mList) {
                if (i != null) {
                    try {
                        if (i.isPlaying()) {
                            i.stop();
                            i.release();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } 
            }
            mList.clear();
        }
    
        public MediaPlayer playInMediaPlayer(int resid, final GameSoundEvent event) {
            MediaPlayer player = MediaPlayer.create(mContext, resid);
            player.start();
            player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    if (event != null)
                        event.onEvent(GAME_SOUND_MEDIA_COMPLETION);
                    mp.release();
                    mList.remove(mp);
                }
            });
            mList.add(player);
            return player;
        }
    
        public interface GameSoundEvent {
            public void onEvent(int what);
        }
    }
    复制代码

     

    GameSoundPool.java(这个也是)

    View Code
    复制代码
    package com.yh;
    
    import java.util.HashMap;
    
    import android.content.Context;
    import android.media.AudioManager;
    import android.media.SoundPool;
    
    /**
     * 多音效
     * @author gary
     *
     */
    public class GameSoundPool {
        private Context mContext;
    
        public GameSoundPool(Context context) {
            mContext = context;
            initSounds();
        }
    
        // 音效的音量
        int streamVolume;
    
        // 定义SoundPool对象
        private SoundPool soundPool;
    
        // 定义HASH表
        private HashMap<Integer, Integer> soundPoolMap;
    
        /***************************************************************
         * Function:initSounds(); Parameters:null Returns:None. Description:初始化声音系统
         * Notes:none.
         ***************************************************************/
        public void initSounds() {
            // 初始化soundPool对象,第一个参数是允许有多少个声音流同时播放,第2个参数是声音类型,第三个参数是声音的品质
            soundPool = new SoundPool(100, AudioManager.STREAM_MUSIC, 100);
    
            // 初始化HASH表
            soundPoolMap = new HashMap<Integer, Integer>();
    
            // 获得声音设备和设备音量
            AudioManager mgr = (AudioManager) mContext
                    .getSystemService(Context.AUDIO_SERVICE);
            streamVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
        }
    
        /***************************************************************
         * Function:loadSfx(); Parameters:null Returns:None. Description:加载音效资源
         * Notes:none.
         ***************************************************************/
        public void loadSfx(int raw, int ID) {
            // 把资源中的音效加载到指定的ID(播放的时候就对应到这个ID播放就行了)
            soundPoolMap.put(ID, soundPool.load(mContext, raw, ID));
        }
    
        /***************************************************************
         * Function:play(); Parameters:sound:要播放的音效的ID,loop:循环次数 Returns:None.
         * Description:播放声音 Notes:none.
         ***************************************************************/
        public void play(int sound, int uLoop) {
            soundPool.play(soundPoolMap.get(sound), streamVolume, streamVolume, 1,
                    uLoop, 1f);
            
        }
    }
    复制代码

    DrawYH.java(重要代码,这个是从网找到的那个烟花代码改装的,里面有一些关键位置改一改会有不同效果)

    View Code
    复制代码
    package com.yh;
    
    import java.util.Random;
    
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Rect;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.View;
    
    public class DrawYH extends DrawTopBase {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            super.surfaceCreated(holder);
            this.begin();
            stopBGMedia();
            bgMedia = new GameSoundMedia(mContext);
            bgMedia.playInMediaPlayer(R.raw.bg, null);
        }
    
        private void stopBGMedia() {
            if (bgMedia != null) {
                try {
                    bgMedia.stopAll();                
                    bgMedia = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
            }
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            stopBGMedia();
            super.surfaceDestroyed(holder);
        }
    
        @Override
        public void set() {
            super.set();
            if (this.getRect().width() > 10 && this.getRect().height() > 10)
                init();
        }
    
        public DrawYH() {
            super();
            m_mouseX = 0;
            m_mouseY = 0;
            m_sleepTime = 5;
            isError = false;
            isInitialized = false;
            rand = new Random();
            bits = 10000;
            bit_px = new double[bits];
            bit_py = new double[bits];
            bit_vx = new double[bits];
            bit_vy = new double[bits];
            bit_sx = new int[bits];
            bit_sy = new int[bits];
            bit_l = new int[bits];
            bit_f = new int[bits];
            bit_p = new int[bits];
            bit_c = new int[bits];
            ru = 50;
            rv = 50;
            // init();
        }
    
        Canvas mCanvas;
        private Rect drawRect = new Rect(0, 0, 0, 0);
        GameSoundMedia sm;
    
        private GameSoundPool soundPool;
        private int id_sound1 = R.raw.firework;
        private int id_sound2 = R.raw.syu;
        GameSoundMedia bgMedia;
    
        public void init() {
            soundPool = new GameSoundPool(mContext);
            // Log.i("gary", mContext.toString());
            soundPool.loadSfx(R.raw.firework, id_sound1);
            soundPool.loadSfx(R.raw.syu, id_sound2);
            // soundPool.loadSfx(R.raw.bg, id_bg);
    
            m_nAppX = this.getRect().width() / 2;
            m_nAppY = this.getRect().height() / 2;
            drawRect = new Rect(0, 0, m_nAppX, m_nAppY);
            m_centerX = m_nAppX / 2;
            m_centerY = m_nAppY / 2;
            m_mouseX = m_centerX;
            m_mouseY = m_centerY;
            // resize(m_nAppX, m_nAppY);
            pixls = m_nAppX * m_nAppY;
            pixls2 = pixls - m_nAppX * 2;
            pix0 = new int[pixls];
            offImage = Bitmap.createBitmap(m_nAppX, m_nAppY,
                    Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas();
            mCanvas.setBitmap(offImage);
            for (int i = 0; i < pixls; i++)
                pix0[i] = 0xff000000;
    
            // sound1 = getAudioClip(getDocumentBase(), "firework.au");
            // sound2 = getAudioClip(getDocumentBase(), "syu.au");
            for (int j = 0; j < bits; j++)
                bit_f[j] = 0;
    
            isInitialized = true;
        }
    
        @Override
        protected void doWork(Canvas canvas) {
            // TODO Auto-generated method stub
            super.doWork(canvas);
            if (offImage != null)
                canvas.drawBitmap(offImage, drawRect, this.getRect(), mPaint);
             
        }
    
        @Override
        protected void change() {
            super.change();
            if (isInitialized) {
                for (int j = 0; j < pixls2; j++) {
                    int k = pix0[j];
                    int l = pix0[j + 1];
                    int i1 = pix0[j + m_nAppX];
                    int j1 = pix0[j + m_nAppX + 1];
                    int i = (k & 0xff0000) >> 16;
                    int k1 = ((((l & 0xff0000) >> 16) - i) * ru >> 8) + i;
                    i = (k & 0xff00) >> 8;
                    int l1 = ((((l & 0xff00) >> 8) - i) * ru >> 8) + i;
                    i = k & 0xff;
                    int i2 = (((l & 0xff) - i) * ru >> 8) + i;
                    i = (i1 & 0xff0000) >> 16;
                    int j2 = ((((j1 & 0xff0000) >> 16) - i) * ru >> 8) + i;
                    i = (i1 & 0xff00) >> 8;
                    int k2 = ((((j1 & 0xff00) >> 8) - i) * ru >> 8) + i;
                    i = i1 & 0xff;
                    int l2 = (((j1 & 0xff) - i) * ru >> 8) + i;
                    int i3 = ((j2 - k1) * rv >> 8) + k1;
                    int j3 = ((k2 - l1) * rv >> 8) + l1;
                    int k3 = ((l2 - i2) * rv >> 8) + i2;
                    pix0[j] = i3 << 16 | j3 << 8 | k3 | 0x77000000;
                    // if(pix0[j]==0x77000000)pix0[j]=0x55000000;
                }
    
                rend();
    
                mCanvas.drawBitmap(pix0, 0, m_nAppX, 0, 0, m_nAppX, m_nAppY, true,
                        mPaint);
            }
        }
    
        public void dot() {
            dot(rand.nextInt(m_nAppX), rand.nextInt(m_nAppY));
        }
    
        public void dot(int x, int y) {
            m_mouseX = x;
            m_mouseY = y;
            int k = (int) (rand.nextDouble() * 256D);
            int l = (int) (rand.nextDouble() * 256D);
            int i1 = (int) (rand.nextDouble() * 256D);
            int j1 = k << 16 | l << 8 | i1 | 0xff000000;
            int k1 = 0;
            for (int l1 = 0; l1 < bits; l1++) {
                if (bit_f[l1] != 0)
                    continue;
                bit_px[l1] = m_mouseX;
                bit_py[l1] = m_mouseY;
                double d = rand.nextDouble() * 6.2800000000000002D;
                double d1 = rand.nextDouble();
                bit_vx[l1] = Math.sin(d) * d1;
                bit_vy[l1] = Math.cos(d) * d1;
                bit_l[l1] = (int) (rand.nextDouble() * 100D) + 100;
                bit_p[l1] = (int) (rand.nextDouble() * 3D);
                bit_c[l1] = j1;
                bit_sx[l1] = m_mouseX;
                bit_sy[l1] = m_nAppY - 5;
                bit_f[l1] = 2;
                if (++k1 == bit_max)
                    break;
            }
        }
    
        void rend() {
            boolean flag = false;
            boolean flag1 = false;
            boolean flag2 = false;
            for (int k = 0; k < bits; k++)
                switch (bit_f[k]) {
                default:
                    break;
    
                case 1: // '\001'
                    bit_vy[k] += rand.nextDouble() / 50D;
                    bit_px[k] += bit_vx[k];
                    bit_py[k] += bit_vy[k];
                    bit_l[k]--;
                    if (bit_l[k] == 0 || bit_px[k] < 0.0D || bit_py[k] < 0.0D
                            || bit_px[k] > (double) m_nAppX
                            || bit_py[k] > (double) (m_nAppY - 3)) {
                        bit_c[k] = 0xff000000;
                        bit_f[k] = 0;
                    } else if (bit_p[k] == 0) {
                        if ((int) (rand.nextDouble() * 2D) == 0)
                            bit_set((int) bit_px[k], (int) bit_py[k], -1);
                    } else {
                        bit_set((int) bit_px[k], (int) bit_py[k], bit_c[k]);
                    }
                    break;
    
                case 2: // '\002'
                    bit_sy[k] -= 5;
                    if ((double) bit_sy[k] <= bit_py[k]) {
                        bit_f[k] = 1;
                        flag2 = true;
                    }
                    if ((int) (rand.nextDouble() * 20D) == 0) {
                        int i = (int) (rand.nextDouble() * 2D);
                        int j = (int) (rand.nextDouble() * 5D);
                        bit_set(bit_sx[k] + i, bit_sy[k] + j, -1);
                    }
                    break;
                }
    
            if (flag2 && bit_sound > 0)
                // sm.playInMediaPlayer(R.raw.firework, null);
                soundPool.play(id_sound1, 0);
        }
    
        void bit_set(int i, int j, int k) {
            int l = i + j * m_nAppX;
             pix0[l] = k;
        }
    
        protected void calculatePerframe() {
              try {
                Thread.sleep(m_sleepTime);
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }
        }
    
        private int m_nAppX;
        private int m_nAppY;
        private int m_centerX;
        private int m_centerY;
        private int m_mouseX;
        private int m_mouseY;
        private int m_sleepTime;
        private boolean isError;
        private boolean m_isPaintFinished;
        boolean isRunning;
        boolean isInitialized;
        Thread runner;
        int pix0[];
        Bitmap offImage;
        // Image dbImg;
        int pixls;
        int pixls2;
        Random rand;
        int bits;
        double bit_px[];
        double bit_py[];
        double bit_vx[];
        double bit_vy[];
        int bit_sx[];
        int bit_sy[];
        int bit_l[];
        int bit_f[];
        int bit_p[];
        int bit_c[];
        int bit_max = 100;
        int bit_sound = 2;
        int ru;
        int rv;
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // return super.onTouch(v, event);
            int x = (int) event.getX();
            int y = (int) event.getY();
            x = x / 2;
            y = y / 2;
            if (x > m_nAppX)
                x = m_nAppX;
            if (y > m_nAppY)
                y = m_nAppY;
            if (x < 0)
                x = 0;
            if (y < 0)
                y = 0;
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
    
                break;
            case MotionEvent.ACTION_UP:
                this.dot(x, y);
                if (this.bit_sound > 1)
                    // sm.playInMediaPlayer(R.raw.syu, null);
                    soundPool.play(id_sound2, 0);
                break;
            }
            m_mouseX = x;
            m_mouseY = y;
            return true;
        }
    }
    复制代码

    使用例子

    复制代码
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // setContentView(R.layout.main);
            SurfaceView v = new SurfaceView(this);
            HolderSurfaceView.getInstance().setSurfaceView(v);
            v.setBackgroundResource(R.drawable.bg);
            this.setContentView(v);
            DrawYH yh=new DrawYH();        
            v.setOnTouchListener(yh);
            yh.begin();
    复制代码

    最终效果

  • 相关阅读:
    常见的压缩命令
    Linux忘记root密码的解决
    QQFM 中转站(囧转站)OOXX V1.1 by wy811007 (附SkinH_Net的使用) 程序失效 更新1.3版 未发布
    直接插入排序和希尔排序
    SIGABRT错误的调试办法
    UIGestureRecognizer有用文档摘抄
    HTC G14 Sensation Z710e 刷机总结
    iOS 之生命周期(转)
    算法时间复杂度分析基础(转)
    NSURLConnection的同步与异步
  • 原文地址:https://www.cnblogs.com/firecode/p/2862998.html
Copyright © 2011-2022 走看看