天天看點

Andorid Studio 制作歡樂寫數字(Timer啟動+幀動畫)

做的一個小遊戲,讓兒童照着螢幕上的根據筆順來寫數字 0-9

學會了一點細節還有實作幀動畫效果,将比較好的代碼放一放

首先是實作啟動應用後出現啟動界面2s後向主界面跳轉:

Andorid Studio 制作歡樂寫數字(Timer啟動+幀動畫)

實作代碼如下:

Timer timer = new Timer();  //用于設定啟動界面顯示的時間
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                startActivity(new Intent(StartActivity.this,MainActivity.class));
                finish();
            }
        };
        timer.schedule(timerTask,2000);   //設定兩秒後跳轉到主界面      

在主界面有三個button,分别為開關主音量、開始遊戲、關于界面

其他兩個功能實作簡單,點選開始遊戲後進入選擇數字界面,從0-9,選擇之後進入隻有第一幀的數字,要求玩家滑動螢幕來畫完數字,左上角有示範button,即實作幀動畫功能

進入頁面的時候初始化放置圖檔的第一幀,通過輸入流來打開,并且通過圖檔的原本大小和螢幕的尺寸來算出縮放比例

初始化代碼如下:

private void initView() {
        iv_frame = findViewById(R.id.iv_frame);
        linearLayout = findViewById(R.id.linearLayout1);
        LinearLayout write_layout = findViewById(R.id.LinearLayout_number);
        write_layout.setBackgroundResource(R.drawable.bg1);

        //擷取螢幕的高度和寬度
        widthPixels = this.getResources().getDisplayMetrics().widthPixels;
        heightPixels = this.getResources().getDisplayMetrics().heightPixels;
        //圖檔是按照1280*720準備的,要适應于其他的分辨率的螢幕
        scaleWidth = ((float)widthPixels/720);
        scaleHeight = ((float)heightPixels/1280);

        try{
            //通過輸入流打開第一張圖檔
            InputStream is = getResources().getAssets().open("on1_1.png");
            //通過使用bitmap解析第一張圖檔
            arrdown = BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //擷取布局的寬高資訊
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) iv_frame.getLayoutParams();
        //擷取圖檔縮放後寬度
        layoutParams.width = (int)(arrdown.getWidth() * scaleWidth);
        //擷取圖檔縮放後高度
        layoutParams.height = (int)(arrdown.getHeight() * scaleHeight);

        iv_frame.setLayoutParams(layoutParams);
        lodimagep(1);
    }

    private synchronized void lodimagep(int j) {
        i = j;
        if(i < 25){              //目前圖檔小于25
            String name = "on1_" + i;
            //擷取圖檔資源id
            int imgid = getResources().getIdentifier(name,"drawable","com.example.msi.writenumber");
            iv_frame.setBackgroundResource(imgid);
            i++;
        }
        if(j == 24){             //如果目前圖檔的位置為24
            if(typedialog){      //沒有對話框的情況下
                dialog();        //調用書寫完成對話框方法
            }
        }
    }      
Andorid Studio 制作歡樂寫數字(Timer啟動+幀動畫)

實作代碼如下:

其中R.drawable.frame1為放置所有幀的anmianimation-list

duration為幀持續的時間為0.15s即150ms

public void OnYS(View v){
            if(mdiaolg == null){
                mdiaolg = new mCustomProgressDialog(this,"示範中單擊邊緣取消",R.drawable.frame1);
            }
            mdiaolg.show();
    }
    
 //繼承dialog代碼如下:
 public class mCustomProgressDialog extends ProgressDialog{

    private AnimationDrawable mAnimation; //設定對話框的動畫資源
    private Context mContext;
    private ImageView mImageView;
    private String mLoadingTip;            //設定對話框文字
    private TextView mLoadingTv;          //顯示對話框文字
    private int mResid;                   //資源id

    public mCustomProgressDialog(Context context,String content,int id) {
        super(context);
        this.mContext = context;
        this.mLoadingTip = content;
        this.mResid = id;
        //設定單擊對話框周邊是否讓dialog消失,設定為True
        setCanceledOnTouchOutside(true);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progress_dialog);
        //擷取布局檔案中的TextView
        mLoadingTv = findViewById(R.id.loadingTv);
        mImageView = findViewById(R.id.loadingIv);
        if(mResid == 0){
            mImageView.setBackgroundDrawable(null);
        }else {
            mImageView.setBackgroundResource(mResid);
        }

        mAnimation = (AnimationDrawable) mImageView.getBackground();
        //為了防止在onCreate方法中隻顯示第一幀的解決方案之一
        mImageView.post(new Runnable() {
            @Override
            public void run() {
                mAnimation.start();
            }
        });
        mLoadingTv.setText(mLoadingTip);
    }
}      

還有操作時候根據滑鼠滑動來實作圖檔切換效果

Andorid Studio 制作歡樂寫數字(Timer啟動+幀動畫)

根據實時滑動螢幕的x2,y2來判斷手勢位置,畫完之後彈出dialog完成或者再來一次

如果在中途手離開螢幕,這是耗時操作(?),則發送message,子線程接收message進行handle将圖檔慢慢的撤回到第一幀

linearLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){           //擷取行動方式頭部
                    case MotionEvent.ACTION_DOWN:     //手指按下事件
                        x1 = event.getX();             //擷取手指按下的x坐标
                        y1 = event.getY();             //擷取按下的y坐标
                        igvx = iv_frame.getLeft();     //擷取手指按下圖檔的x坐标
                        igvy = iv_frame.getTop();      //圖檔的y坐标
                        //判斷當手指按下的坐标大于圖檔位置的坐标時,證明手指按住移動,開始書寫
                        if(x1 >= igvx && x1 <= igvx + (int)(arrdown.getWidth() * scaleWidth)
                                      && y1 >= igvy && y1 <= igvy + (int)(arrdown.getWidth() * scaleWidth) ){
                            type = 1;             //開啟書寫
                        }else {
                            type = 0;             //否則關閉書寫
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:   //手勢移動中判斷
                        igvx = iv_frame.getLeft();
                        igvy = iv_frame.getTop();
                        x2 = event.getX();
                        y2 = event.getY();
                        //下面是根據筆畫以及手勢做圖檔的處理,滑到不同位置,加載不同圖檔
                        if(type == 1){
                            if(x2 >= igvx && x2 <= igvx + (int)(arrdown.getWidth() * scaleWidth)){
                                if(y2 <= igvy +(int)(arrdown.getHeight() * scaleHeight) / 24 &&
                                        y2 >= igvy)
                                    lodimagep(1);
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 2){
                                    lodimagep(2);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 3){
                                    lodimagep(3);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 4){
                                    lodimagep(4);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 5){
                                    lodimagep(5);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 6){
                                    lodimagep(6);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 7){
                                    lodimagep(7);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 8){
                                    lodimagep(8);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 9){
                                    lodimagep(9);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 10){
                                    lodimagep(10);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 11){
                                    lodimagep(11);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 12){
                                    lodimagep(12);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 13){
                                    lodimagep(13);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 14){
                                    lodimagep(14);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 15){
                                    lodimagep(15);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 16){
                                    lodimagep(16);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 17){
                                    lodimagep(17);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 18){
                                    lodimagep(18);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 19){
                                    lodimagep(19);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 20){
                                    lodimagep(20);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 21){
                                    lodimagep(21);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 22){
                                    lodimagep(22);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 23){
                                    lodimagep(23);
                                }
                                else if(y2 <= igvy + (int)(arrdown.getHeight() * scaleHeight) / 24 * 24){
                                    lodimagep(24);
                                }
                            }

                        }
                        break;

                    case MotionEvent.ACTION_UP:    //手勢擡起判斷
                        type = 0;
                        if(touchTimer != null){    //中斷計時器
                            touchTimer.cancel();
                            touchTimer = null;
                        }
                        touchTimer = new Timer();
                        touchTimer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                Thread thread = new Thread(new Runnable() { //建立子線程
                                    @Override
                                    public void run() {
                                        //建立Message用于發送消息
                                        Message message = new Message();
                                        message.what = 2;     //Message消息為2
                                        //發送消息給handle實作倒退顯示圖檔
                                        mHandler.sendMessage(message);
                                    }
                                });
                                thread.start();
                            }
                        },300,200);
                }
                return true;
            }
        });
    }


    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 2:                       //當接收到手勢擡起子線程消息時
                    jlodimage();              //調用資源圖檔倒退顯示方法
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    };

        private void jlodimage() {
            if(i == 25){
            }else if(i < 25){
                if(i > 1){
                    i--;
                }else if(i == 1){
                    i =1;
                    if(touchTimer != null){
                        touchTimer.cancel();
                        touchTimer = null;
                    }
                }
                String name ="on1_" + i;
                int imgid = getResources().getIdentifier(name,"drawable",
                        "com.example.msi.writenumber");
                iv_frame.setBackgroundResource(imgid);
            }
        }