Android简易老虎机(转动式)

      说起老虎机,玩过的人应该记得这种类型的图(这是主界面),下面就从最基本的知识分析整个APP的制作过程,也同时把android中的一些基础知识巩固一遍

               Android简易老虎机(转动式)_第1张图片


首先说一下这个APP的基本操作:

       1.点击下注按钮后,会进入下注界面


       Android简易老虎机(转动式)_第2张图片

    2.上下拖动选择下注比,并选择固定金额或自己输入金额,点击确定返回主界面

    3.然后开始游戏,出现如图效果,转动的位置的图片背景会变成黄色

       Android简易老虎机(转动式)_第3张图片

   主要功能描述就是这样,由于不会发动态图,所以真实效果无法展示,有兴趣的可以下载试试哈


下面开始一步步分析整个APP构建过程:


首先说一下这个界面的编写:

   主界面:

       1.整体采用线性布局,其中的每一行又是一个线性布局,采用权重的方式给每个子线性布局分配高度

       2.水果和金币是ImageView控件,金币数量和红色的提示文字采用TextView,而且红色文字实现跑马灯果,最后一行是两个隐藏背景的按钮

    下注界面:

         1.整体依旧采用线性布局

         2.最上面的水果比是ListView控件,该控件下方有4个按钮(下注金额),最后一行是一个输入框和一个确定按钮

 

然后是根据界面分析怎么写代码(核心部分):

      1.对于主界面,主要就是转动的过程不好做,需要两个定时器,一个负责转动的总时间(总时间采用随机数的方式,确保每次转动的时间尽可能地不同),一个负责获取转动过程中黄色背景所在的图片的id,当用户选好下注比及下注金额后,点击开始时,则同时启动这两个计时器,启动后,第一个定时器会处于sleep状态(时间是在一定范围随机生成的),而第二个定时器则会一直计算选中图片的序号(当然这个序号是0~11的循环,因为总共有12张图片啊),当第一个定时器的sleep状态结束后,则会立即通知第二个定时器停止计算序号,此时的序号即为中奖的序号,然后与用户选择的图片的id进行比较,最终得出结果

      2.对于下注界面,主要是采用SimpleAdapter实现可以下注的图片的ListView,指明图片的名称及下注比,由于下注是在下注界面完成,而游戏开始则是在主界面,所以就需要向主界面传递下注的相关信息(下注比、下注金额),这是采用onActivityReslt由下注界面进行值的回传来实现

     4.最后在Activity中重写onPause方法,在该方法中使用SharedPreferences保存数据,确保当应用被kill时,金币总数可以保存下来,当然,由于是采用SharedPreferences进行保存,所以当应用被卸载并重装时,保存的数据自然会丢失,应用则会初始化到最初的金币值


最后就代码来进行详述:

       主界面的Acivity类如下:

       

package com.hkk.hi.tiger;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Random;


public class MainActivity extends Activity {


    private ImageView mP1Iv, mP2Iv, mP3Iv, mP4Iv, mP5Iv, mP6Iv, mP7Iv, mP8Iv, mP9Iv, mP10Iv, mP11Iv, mP12Iv;
    private ImageView[] mImgArr = new ImageView[12];//使用数据存储这12张图片
    private Button mBetBtn, mStartBtn;

    private TextView moneyTv;
    private String mBetName = "";

    //下注的金币和剩余总金币
    private int mBetMoney = 0;
    private int mBetTotalMoney = 10000;

    //当前选中图片的id
    private int currentId = 0;

    //使用数据存储数据名
    private String[] mNameArr = {"苹果1", "香蕉1", "梨子", "西瓜", "猕猴桃1", "香蕉2", "苹果2", "芒果", "猕猴桃2", "草莓", "猕猴桃3", "橘子"};


    private MyHandler mHandler = new MyHandler();

    //创建定时器
    private AnimThread animThread = new AnimThread();
    private TimeThread timeThread = new TimeThread();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();//初始化控件

        checkMoney();//获取存储的金币

        mBetBtn.setOnClickListener(mClickListener);
        mStartBtn.setOnClickListener(mClickListener);

        //将图片添加到ImageView[]中
        mImgArr[0] = mP1Iv;
        mImgArr[1] = mP2Iv;
        mImgArr[2] = mP3Iv;
        mImgArr[3] = mP4Iv;
        mImgArr[4] = mP5Iv;
        mImgArr[5] = mP6Iv;
        mImgArr[6] = mP7Iv;
        mImgArr[7] = mP8Iv;
        mImgArr[8] = mP9Iv;
        mImgArr[9] = mP10Iv;
        mImgArr[10] = mP11Iv;
        mImgArr[11] = mP12Iv;
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mP1Iv = (ImageView) findViewById(R.id.p1_iv);
        mP2Iv = (ImageView) findViewById(R.id.p2_iv);
        mP3Iv = (ImageView) findViewById(R.id.p3_iv);
        mP4Iv = (ImageView) findViewById(R.id.p4_iv);
        mP5Iv = (ImageView) findViewById(R.id.p5_iv);
        mP6Iv = (ImageView) findViewById(R.id.p6_iv);
        mP7Iv = (ImageView) findViewById(R.id.p7_iv);
        mP8Iv = (ImageView) findViewById(R.id.p8_iv);
        mP9Iv = (ImageView) findViewById(R.id.p9_iv);
        mP10Iv = (ImageView) findViewById(R.id.p10_iv);
        mP11Iv = (ImageView) findViewById(R.id.p11_iv);
        mP12Iv = (ImageView) findViewById(R.id.p12_iv);

        mBetBtn = (Button) findViewById(R.id.bet_btn);
        mStartBtn = (Button) findViewById(R.id.start_btn);
        moneyTv = (TextView) findViewById(R.id.money_tv);
    }

    /**
     * 获取存储的金币,如果获取到,则将获取的金币作为总金币数,否则弹出提示第一次游戏、欢迎光临
     */
    private void checkMoney() {
        try {
            SharedPreferences pref = getSharedPreferences("money", MODE_PRIVATE);
            int mTotalMoney = pref.getInt("money", 10000);
            mBetTotalMoney = mTotalMoney;
            moneyTv.setText(mBetTotalMoney + "");
        } catch (Exception e) {
            Toast.makeText(MainActivity.this, "第一次游戏,欢迎你的光临", Toast.LENGTH_SHORT);
        }
    }

    /*
     *转盘转动开始,在此期间TimeThread保持sleep,AnimThread则一直计算序号
     */
    private class TimeThread extends Thread {
        @Override
        public void run() {
            Random random = new Random();
            int x = random.nextInt(3);
            try {
                Thread.sleep((x + 3) * 1000);//转动持续的时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //随机时间到后,AnimThread停止计算序号
            animThread.stopAnim();

            //发送结果给MyHandler进行处理
            Message msg = Message.obtain();
            msg.what = 2;
            mHandler.sendMessage(msg);
        }
    }


    /*
    * 在转动期间(即TimeThread保持sleep期间),一直计算序号
     */
    private class AnimThread extends Thread {

        private boolean isStopped = false;

        //停止计算序号
        public void stopAnim() {
            isStopped = true;
            animThread.interrupt();
        }

        @Override
        public void run() {
            while (!isStopped) {
                //计算当前选中图片的序号
                currentId++;
                if (currentId > 11) {
                    currentId = 0;
                }
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //发送结果给MyHandler进行处理
                Message msg = Message.obtain();
                msg.arg2 = currentId;
                msg.what = 1;
                mHandler.sendMessage(msg);

            }
        }
    }

    private View.OnClickListener mClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (v == mBetBtn) {
                Intent intent = new Intent(MainActivity.this, BetActivity.class);
                intent.putExtra("TotalMoney", mBetTotalMoney);
                MainActivity.this.startActivityForResult(intent, 1000);
            } else if (v == mStartBtn) {

                if (TextUtils.isEmpty(mBetName) || mBetMoney <= 0) {
                    Toast.makeText(MainActivity.this, "请您先下注", Toast.LENGTH_SHORT).show();
                } else {
                     timeThread = new TimeThread();
                    timeThread.start();//转动持续时间
                     animThread = new AnimThread();
                    animThread.start();//计算当前选中图片的序号
                }
            }
        }
    };

    /**
     * 处理转盘转动过程中的界面变化
     */
    private class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            //序号计算器发送过来的消息
            if (msg.what == 1) {
                //清空所有图片背景
                for (int i = 0; i < mNameArr.length; i++) {
                    ImageView iv = mImgArr[i];
                    iv.setBackgroundColor(Color.TRANSPARENT);
                }
                //将选中图片背景设置成黄色
                int index = msg.arg2;
                ImageView selectIv = mImgArr[index];
                selectIv.setBackgroundColor(Color.YELLOW);
            }
            //随机计时器发过来的消息
            else if (msg.what == 2) {
                //压中
                if (getResult(currentId)) {
                    if (mBetName.equals("猕猴桃")) {
                        mBetTotalMoney = mBetTotalMoney + mBetMoney * 1;
                        Toast.makeText(MainActivity.this, "恭喜您中彩金 " + mBetMoney * 1, Toast.LENGTH_SHORT).show();
                    } else if (mBetName.equals("苹果")) {
                        mBetTotalMoney = mBetTotalMoney + mBetMoney * 2;
                        Toast.makeText(MainActivity.this, "恭喜您中彩金 " + mBetMoney * 2, Toast.LENGTH_SHORT).show();
                    } else if (mBetName.equals("西瓜")) {
                        mBetTotalMoney = mBetTotalMoney + mBetMoney * 3;
                        Toast.makeText(MainActivity.this, "恭喜您中彩金 " + mBetMoney * 3, Toast.LENGTH_SHORT).show();
                    } else if (mBetName.equals("草莓")) {
                        mBetTotalMoney = mBetTotalMoney + mBetMoney * 4;
                        Toast.makeText(MainActivity.this, "恭喜您中彩金 " + mBetMoney * 4, Toast.LENGTH_SHORT).show();
                    }
                    moneyTv.setText(mBetTotalMoney + "");
                }
                //押错了
                else {
                    Toast.makeText(MainActivity.this, "没中,再来一次?", Toast.LENGTH_SHORT).show();
                }
                //计算完成之后,需要将押注人名和押注金额清空
                mBetName = "";
                mBetMoney = 0;
                timeThread.interrupt();
            }
        }
    }

    /**
     * 接收由BetActivity回传过来的数据(下注金币数额和下注的对象)
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1000 && resultCode == 500) {
            mBetName = data.getStringExtra("name");
            mBetMoney = data.getIntExtra("money", 0);
            mBetTotalMoney = mBetTotalMoney - mBetMoney;
            if (mBetTotalMoney >= 0) {
                moneyTv.setText(mBetTotalMoney + "");
            } else {
                moneyTv.setText(0 + "");
            }
        }
    }


    /**
     * 比较下注的水果名和当前选择器选中的水果名是否相同,返回一个boolean型数值
     *
     * @param index
     * @return
     */
    private boolean getResult(int index) {
        String selectName = mNameArr[index];
        return selectName.equals(mBetName);
    }

    //重写onPause方法,游戏被kill掉时,保存金币数量
    @Override
    protected void onPause() {
        SharedPreferences.Editor editor = getSharedPreferences("money", MODE_PRIVATE).edit();
        editor.putInt("money", mBetTotalMoney);
        editor.commit();
        super.onPause();
    }


}

    下注界面的Activity如下:

 

package com.hkk.hi.tiger;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BetActivity extends Activity {

    private int mMoney = 0;
    private String nName = "";
    private ListView mBetLv;
    private String[] mScoreArr = {"1 : 1", "1 : 2", "1 : 3", "1 : 4", ""};//中奖赔率
    private String[] mNameArr = {"猕猴桃", "苹果", "西瓜", "草莓"};//可以中奖的水果名
    private int[] mImgArr = {R.mipmap.kiwifruit, R.mipmap.apple, R.mipmap.watermelon, R.mipmap.strawberry};//可以中奖的水果图片id
    private Button mBtn100, mBtn200, mBtn500, mBtn1000, mConfirmBtn;
    private EditText mEdtMoney;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bet_layout);

        initView();//初始化控件

        mBtn100.setOnClickListener(mClickListener);
        mBtn200.setOnClickListener(mClickListener);
        mBtn500.setOnClickListener(mClickListener);
        mBtn1000.setOnClickListener(mClickListener);
        mConfirmBtn.setOnClickListener(mClickListener);

        SimpleAdapter sAdapter = new SimpleAdapter(BetActivity.this, getData(), R.layout.item,
                new String[]{"score", "name", "img"}, new int[]{R.id.score_tv, R.id.text_tv, R.id.image_iv});
        mBetLv.setAdapter(sAdapter);
        mBetLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                nName = mNameArr[position];
            }
        });
    }

    //初始化控件
    private void initView() {
        mBtn100 = (Button) findViewById(R.id.btn1);
        mBtn200 = (Button) findViewById(R.id.btn2);
        mBtn500 = (Button) findViewById(R.id.btn3);
        mBtn1000 = (Button) findViewById(R.id.btn4);
        mConfirmBtn = (Button) findViewById(R.id.btn5);
        mEdtMoney = (EditText) findViewById(R.id.money_et);

        mBetLv = (ListView) findViewById(R.id.lv1);
    }

    //准备数据源
    private List> getData() {

        List> dataList = new ArrayList>();

        for (int i = 0; i < 4; i++) {
            Map data = new HashMap();
            data.put("score", mScoreArr[i]);
            data.put("name", mNameArr[i]);
            data.put("img", mImgArr[i]);
            dataList.add(data);
        }
        return dataList;
    }

    private int money = 0;//下注金额
    private View.OnClickListener mClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v == mBtn1000) {
                money = 1000;
                mBtn1000.setBackgroundColor(Color.YELLOW);
                mBtn500.setBackgroundColor(Color.TRANSPARENT);
                mBtn200.setBackgroundColor(Color.TRANSPARENT);
                mBtn100.setBackgroundColor(Color.TRANSPARENT);
                mEdtMoney.setText("");
            } else if (v == mBtn500) {
                money = 500;
                mBtn500.setBackgroundColor(Color.YELLOW);
                mBtn1000.setBackgroundColor(Color.TRANSPARENT);
                mBtn200.setBackgroundColor(Color.TRANSPARENT);
                mBtn100.setBackgroundColor(Color.TRANSPARENT);
                mEdtMoney.setText("");
            } else if (v == mBtn200) {
                money = 200;
                mBtn200.setBackgroundColor(Color.YELLOW);
                mBtn500.setBackgroundColor(Color.TRANSPARENT);
                mBtn1000.setBackgroundColor(Color.TRANSPARENT);
                mBtn100.setBackgroundColor(Color.TRANSPARENT);
                mEdtMoney.setText("");
            } else if (v == mBtn100) {
                money = 100;
                mBtn100.setBackgroundColor(Color.YELLOW);
                mBtn500.setBackgroundColor(Color.TRANSPARENT);
                mBtn200.setBackgroundColor(Color.TRANSPARENT);
                mBtn1000.setBackgroundColor(Color.TRANSPARENT);
                mEdtMoney.setText("");
            } else if (v == mConfirmBtn) {

                mMoney = money;

                String edtMoney = mEdtMoney.getText().toString();//获取输入的金额
                judgeEdit(edtMoney);//判断是否输入金额,若是,则取消之前选中的金额

                Intent t = getIntent();
                int totalMoney = t.getIntExtra("TotalMoney", 0);
                /**
                 * 判断金币数量,如果金币不足会弹出提醒
                 */
                if (totalMoney < mMoney) {
                    AlertDialog.Builder dialog = new AlertDialog.Builder(BetActivity.this);
                    dialog.setTitle("请注意");
                    dialog.setMessage("您的押注金额超过剩余总金额,请重新押注");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });
                    dialog.show();
                }
                else if (!TextUtils.isEmpty(nName) && mMoney > 0 ) {
                    Intent intent = new Intent();
                    intent.putExtra("name", nName);
                    intent.putExtra("money", mMoney);
                    BetActivity.this.setResult(500, intent);
                    BetActivity.this.finish();
                } else {
                    Toast.makeText(BetActivity.this, "未押注或押注金额有误", Toast.LENGTH_SHORT).show();
                }
            }

        }

    };

    private  void judgeEdit(String m){
        if (!TextUtils.isEmpty(m)) {
            int inputMoney = Integer.parseInt(m);
            if (inputMoney > 0) {
                mMoney = inputMoney;
            }
        }
    }
}

      核心代码就是以上这些,遗憾的是不知道怎么把运行的效果放在这上面,总体感觉还是可以的,毕竟自己算是透彻的理解了这个应用的设计思想,当然了,这个应用是根据课堂上老师讲的例子进行了改进升级,增加了几个感觉必不可少的功能,同时解决了一些小bug,在改进的过程中也遇到一些问题,比如可以把TimeThread extends Thread 及AnimThread  extends Thread改成实现Runnable接口的,毕竟继承Thread会在每次开始游戏时都开启一个子线程,造成性能的损失,但是自己没有成功,希望哪位大神可以指导一下哈

你可能感兴趣的:(Android)