Android(安卓)猜歌曲游戏开发
16lz
2021-01-26
一、界面如图:
1)主界面
2)对话框界面
3)过关界面
4)通关界面
二、实现步骤
三、详细代码
1)主界面代码:
/** * @Project App_Imooc * @Package com.android.imooc.song * @author chenlin * @version 1.0 * @Date 2014年2月27日 * @Note 猜歌游戏主界面..... */public class MainActivity extends Activity implements OnWordButtonClickListener { private static final String TAG = "song"; // --常量----------------------- public static final int STATE_ANSWER_LACK = 0x11;// 不存在 public static final int STATE_ANSWER_RIGHT = 0x12;// 正确 public static final int STATE_ANSWER_WRONG = 0x13;// 错误 private static final int SPARK_TIMES = 6; private static final int ID_DIALOG_DEL = 0x21; private static final int ID_DIALOG_TIP = 0x22; private static final int ID_DIALOG_LACK = 0x23; // --动画相关的----------------------- private Animation mPanAnim; // 加速器 private LinearInterpolator mPanInterpolator; private Animation mBarInAnin; private LinearInterpolator mBarInterpolator; private Animation mBarOutAnin; private LinearInterpolator mBarOutInterpolator; // ---控件相关-------------------------------------- // 播放按钮 private ImageButton mBtnPlayStart; // 盘 private ImageView mImgPan; // 盘杆 private ImageView mImgBar; // 文字布局 private XGridView mGridView; // 所选择的文字容器 private LinearLayout mViewSelectContainer; // --数据相关--------------------------------- // 盘片是否在运行 private boolean isRunnging; // 当前歌曲 private Song mCurrentSong; // 当前文字索引 private int mCurrendIndex = -1; /** 文字框容器 */ private List<WordButton> mAllWords; /** 所选文字 */ private List<WordButton> mSelectWords; /** 当前金币数量 */ private int mCurrentCoins = Const.TOTAL_COINS; // ---通关控件----------------------------------------------------- /** 通关视图 */ private View mViewPass; /** 中间角textview */ private TextView mTVCurrentCoins; // 删除金币按钮 private ImageButton mBtnDelWord; // 问题提示按钮 private ImageButton mBtnTipAnswer; /** 通关弹出界面的状态 */ private TextView mTVStagePass; /** 主界面的状态 */ private TextView mTVStage; /** 显示歌曲名称 */ private TextView mTVSong; /** 下一关按钮 */ private ImageButton mBtnNext; /** 微信分享按钮 */ private ImageButton mBtnShare; // ---通关常量----------------------------------------------------- // private int mCurrentStateIndex = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); initDatas(); initAnimation(); initEvents(); initCurrentStageDatas(); } private void initDatas() { int[] datas = GameUtil.loadData(this); // 为什么是-2,因为保存的时候是上一关的数据 if (datas[GameUtil.DATA_INDEX] != 0 && datas[GameUtil.DATA_INDEX] != Const.SONG_INFO.length - 2) { mCurrendIndex = datas[GameUtil.DATA_INDEX]; } if (datas[GameUtil.DATA_COIN] != 0) mCurrentCoins = datas[GameUtil.DATA_COIN]; mTVCurrentCoins.setText(mCurrentCoins+""); } private void initViews() { mGridView = (XGridView) findViewById(R.id.gridview); mBtnPlayStart = (ImageButton) findViewById(R.id.btn_play_start); mImgBar = (ImageView) findViewById(R.id.img_pan_bar); mImgPan = (ImageView) findViewById(R.id.img_pan); mViewSelectContainer = (LinearLayout) findViewById(R.id.word_select_container); // 通关后视图 mViewPass = findViewById(R.id.pass_view); // 中间当前金币 mTVCurrentCoins = (TextView) findViewById(R.id.txt_bar_coins); // 删除金币按钮 mBtnDelWord = (ImageButton) findViewById(R.id.btn_delete_word); mBtnTipAnswer = (ImageButton) findViewById(R.id.btn_tip_answer); // --通关控件初始化---------------------------------- mTVStagePass = (TextView) findViewById(R.id.textView_current_stage); mTVStage = (TextView) findViewById(R.id.text_current_stage); mTVSong = (TextView) findViewById(R.id.textView_song_name); mBtnNext = (ImageButton) findViewById(R.id.btn_next_stage); mBtnShare = (ImageButton) findViewById(R.id.btn_gto_wechat); } // --初始化数据---------------------------------------------------------------------- /** * 初始化数据 */ private void initCurrentStageDatas() { // 1.加载歌曲信息,每过一关加1 mCurrentSong = GameUtil.loadStageSongInfo(++mCurrendIndex); // 2.获得数据 mAllWords = GameUtil.initAllWords(mCurrentSong); // 3.更新数据 mGridView.updateData(mAllWords); // 4.播放音乐 MediaPlayerHelper.playSong(this, mCurrentSong.getFilename()); // 5.初始化选中的文字 mSelectWords = GameUtil.initSelectWords(this, mCurrentSong, mAllWords); // 6.清除原有的视图 mViewSelectContainer.removeAllViews(); // 7.把自布局添加到linearLayout容器里 addSelectViewToContainer(); // 8.更新界面上的关数 mTVStage.setText((mCurrendIndex + 1) + ""); } /** * 动态添加以选择的button到容器里 */ private void addSelectViewToContainer() { LayoutParams params = new LayoutParams(UITools.px2dip(this, 35), UITools.px2dip(this, 35)); for (int i = 0; i < mSelectWords.size(); i++) { View child = mSelectWords.get(i).button; mViewSelectContainer.addView(child, params); } } // --事件处理--------------------------------------------------------------- private void initEvents() { /** 播放动画 */ mBtnPlayStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startAnim(); } }); /** 删除不是答案的文字 */ mBtnDelWord.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handleDeleteWord(); } }); /** 提示答案的文字 */ mBtnTipAnswer.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handleTipAnswer(); } }); /** 分享到微信 */ mBtnShare.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { WeiXinHelper.getInstance(MainActivity.this).sendRequest("我正在玩疯狂猜歌游戏,一起来玩吧! "); } }); mGridView.setOnWordButtonClickListener(this); } /** GridView点击事件 */ @Override public void onButtonClick(WordButton wb) { // Toast.makeText(MainActivity.this, wb.button.getText().toString(), 1).show(); GameUtil.setSelectWord(wb, mSelectWords); // 获得答案状态 int state = GameUtil.checkTheAnswer(mSelectWords, mCurrentSong); switch (state) { case STATE_ANSWER_LACK: // 遍历每个文字 for (int i = 0; i < mSelectWords.size(); i++) { mSelectWords.get(i).button.setTextColor(Color.WHITE); } break; case STATE_ANSWER_RIGHT: // 处理通关事件 handlePassEvent(); break; case STATE_ANSWER_WRONG: // 上锁文字 sparkWords(); break; default: break; } } /** * 一闪文字 */ protected void sparkWords() { TimerTask task = new TimerTask() { int mSparkTimes = 0; boolean mChange = false; @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { if (++mSparkTimes > SPARK_TIMES) return; // 遍历每个文字 for (int i = 0; i < mSelectWords.size(); i++) { mSelectWords.get(i).button.setTextColor(mChange ? Color.RED : Color.WHITE); } mChange = !mChange; } }); } }; new Timer().schedule(task, 1, 150); } // ----动画设置---------------------------------------------------------------------- private void startAnim() { // 盘杆到左边后开始播放 // 盘转了3圈之后盘杆到右边 // 1.先自行盘杆到左边 if (mImgBar != null) { if (!isRunnging) { mImgBar.startAnimation(mBarInAnin); isRunnging = true; mBtnPlayStart.setVisibility(View.INVISIBLE); // 播放音乐 MediaPlayerHelper.playSong(MainActivity.this, mCurrentSong.getFilename()); } } } private void setAnimListener() { mBarInAnin.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 2.播放 mImgPan.startAnimation(mPanAnim); } }); // 播放结束后盘杆到右边恢复 mPanAnim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 3.回到右边 mImgBar.startAnimation(mBarOutAnin); } }); // 盘杆回到原位后触发的动作... mBarOutAnin.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // 表示全部播放完成后,重新运行 isRunnging = false; mBtnPlayStart.setVisibility(View.VISIBLE); } }); } private void initAnimation() { // 1.右杆向左到盘片 mBarInAnin = AnimationUtils.loadAnimation(this, R.anim.rotate_45); mBarInterpolator = new LinearInterpolator(); mBarInAnin.setFillAfter(true); mBarInAnin.setInterpolator(mBarInterpolator); // 2.右杆向右 mBarOutAnin = AnimationUtils.loadAnimation(this, R.anim.rotate_d_45); mBarOutInterpolator = new LinearInterpolator(); mBarOutAnin.setFillAfter(true); mBarOutAnin.setInterpolator(mBarOutInterpolator); // 3.盘旋转 mPanAnim = AnimationUtils.loadAnimation(this, R.anim.rotate); mPanInterpolator = new LinearInterpolator(); mPanAnim.setFillAfter(true); mPanAnim.setInterpolator(mPanInterpolator); // 给动画设置监听 setAnimListener(); } @Override protected void onPause() { mImgPan.clearAnimation(); mImgBar.clearAnimation(); MediaPlayerHelper.stopSong(); // 保存数据 GameUtil.saveData(this, mCurrendIndex - 1, mCurrentCoins); super.onPause(); } // ----通关后事件处理---------------------------------------------------------- protected void handlePassEvent() { mViewPass.setVisibility(View.VISIBLE); // 清除动画 mImgPan.clearAnimation(); mImgBar.clearAnimation(); // 停止播放音乐 MediaPlayerHelper.stopSong(); // 播放音效 MediaPlayerHelper.playSong(MainActivity.this, MediaPlayerHelper.INDEX_STONE_COIN); // 更新索引 if (mTVStagePass != null) { mTVStagePass.setText((mCurrendIndex + 1) + ""); } if (mTVSong != null) { mTVSong.setText(mCurrentSong.getName()); } // 下一关 mBtnNext.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (hasPass()) { // 跳转到通关视图 GameUtil.startActivity(MainActivity.this, PassActivity.class); } else { // 下一关 initCurrentStageDatas(); // 过关添加金币 handleCoins(100); // 关闭过关页面 mViewPass.setVisibility(View.GONE); } } }); } /** * 全部过关 * * @return */ protected boolean hasPass() { return mCurrendIndex == Const.SONG_INFO.length - 1; } /** 处理待选文字事件 */ private void handleDeleteWord() { showConfirmDialog(ID_DIALOG_DEL); } /** 处理提示事件, */ private void handleTipAnswer() { showConfirmDialog(ID_DIALOG_TIP); } /** 删除一个文字 */ private void deleteOneWord() { // 减少30个金币 if (!handleCoins(-getDelConis())) { // 如果不够,提示 // Toast.makeText(this, "您的金币不够,请购买", Toast.LENGTH_LONG).show(); showConfirmDialog(ID_DIALOG_LACK); return; } // 设置不是答案的文字隐藏 GameUtil.setButtonVisiblity(findNotAnswerWordButton(), View.INVISIBLE); } /** 提示一个文字 */ private void tipOneWord() { boolean isTip = false; for (int i = 0; i < mSelectWords.size(); i++) { if (mSelectWords.get(i).name.length() == 0) { // findIsTheAnswer(i); // 调用此方法把文字加到以选择的文字框内 onButtonClick(findIsTheAnswer(i)); isTip = true; // 减少金币数量 if (!handleCoins(-getTipConis())) { // 金币数量不够,显示对话框 showConfirmDialog(ID_DIALOG_LACK); return; } break; } } if (!isTip) { // 如果不是提示文字, sparkWords(); } } /** 随机获得 */ private WordButton findNotAnswerWordButton() { Random random = new Random(); WordButton wb = null; while (true) { int index = random.nextInt(XGridView.WORD_COUNTS); wb = mAllWords.get(index); if (wb.isVisible && !isTheAnswer(wb)) { return wb; } } } private WordButton findIsTheAnswer(int index) { WordButton wb = null; for (int i = 0; i < XGridView.WORD_COUNTS; i++) { wb = mAllWords.get(i); if (wb.name.equals("" + mCurrentSong.getNameChar()[index])) { return wb; } } return null; } /** 判断是否是被选择的文字 */ private boolean isTheAnswer(WordButton wb) { boolean result = false; for (int i = 0; i < mCurrentSong.getNameLength(); i++) { if (wb.name.equals(mCurrentSong.getNameChar()[i] + "")) { result = true; break; } } return result; } /** 从配置文件中获得是删除的金币数目 */ private int getDelConis() { return getResources().getInteger(R.integer.pay_delete_word); } /** 从配置文件中获得是提示信息要的金币数目 */ private int getTipConis() { return getResources().getInteger(R.integer.pay_tip_answer); } /** 处理增加金币或减少金币事件 */ private boolean handleCoins(int data) { if (mCurrentCoins + data >= 0) { mCurrentCoins += data; mTVCurrentCoins.setText(mCurrentCoins + ""); return true; } else { // 金币不够 return false; } } // ---对话框设置-------------------------------------------------------------------------- private void showConfirmDialog(int index) { switch (index) { case ID_DIALOG_DEL: DialogHelper.showDialog(this, "您确认花" + getDelConis() + "删除一个错误答案吗?", null, delListener); break; case ID_DIALOG_TIP: DialogHelper.showDialog(this, "您确认花" + getTipConis() + "得到一个提示答案吗?", null, tipListener); break; case ID_DIALOG_LACK: DialogHelper.showDialog(this, "您的金币不足,请及时充值!", null, lackListener); break; default: break; } } private OnDialogListener delListener = new OnDialogListener() { @Override public void onClick() { // 删除一个错误答案 deleteOneWord(); } }; private OnDialogListener tipListener = new OnDialogListener() { @Override public void onClick() { tipOneWord(); } }; private OnDialogListener lackListener = new OnDialogListener() { @Override public void onClick() { } }; // ---菜单设置-------------------------------------------------------------------------- @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}
2)通关界面:
/** * 通关后的界面 * @Project App_Imooc * @Package com.android.imooc.song * @author chenlin * @version 1.0 * @Date 2014年3月18日 * @Note TODO */public class PassActivity extends Activity { private ImageButton mBtnBack; private ImageButton mBtnShare; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.all_pass_view); initViews(); initEvents(); } private void initEvents() { mBtnBack.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int coins = GameUtil.loadData(PassActivity.this)[GameUtil.DATA_COIN]; //过完关后初始化数据 GameUtil.saveData(PassActivity.this, 0, coins); startActivity(new Intent(PassActivity.this, MainActivity.class)); finish(); } }); mBtnShare.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { WeiXinHelper.getInstance(PassActivity.this).sendRequest("我正在玩疯狂猜歌游戏,一起来玩吧!"); } }); } private void initViews() { //隐藏右上角的总金额图标 findViewById(R.id.flayout_coin).setVisibility(View.INVISIBLE); mBtnBack = (ImageButton) findViewById(R.id.btn_bar_back); mBtnShare = (ImageButton) findViewById(R.id.btn_share_weixin); }}
3)自定义的格子视图
/** * @Project App_Imooc * @Package com.android.imooc.myui * @author chenlin * @version 1.0 * @Date 2014年3月1日 * @Note 自定义的格子视图 */public class XGridView extends GridView { public static final int WORD_COUNTS = 24; public static final int WORD_SELECT_COUNTS = 4; private GridAdapter mAdapter; private List<WordButton> mDatas = new ArrayList<WordButton>(); private Context mContext; private Animation mScaleAnimation; private OnWordButtonClickListener mListener; public interface OnWordButtonClickListener{ void onButtonClick(WordButton button); } public void setOnWordButtonClickListener(OnWordButtonClickListener listener){ this.mListener = listener; } public XGridView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; mAdapter = new GridAdapter(); setAdapter(mAdapter); } public void updateData(List<WordButton> datas){ this.mDatas = datas; setAdapter(mAdapter);; } public XGridView(Context context) { this(context, null); } /** * @Project App_Imooc * @Package com.android.imooc.myui * @author chenlin * @version 1.0 * @Note 适配器 */ private class GridAdapter extends BaseAdapter { private LayoutInflater mInflater; public GridAdapter(){ mInflater = LayoutInflater.from(mContext); } @Override public int getCount() { if (mDatas != null) { return mDatas.size(); } return 0; } @Override public Object getItem(int position) { if (mDatas != null) { return mDatas.get(position); } return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { final WordButton holder; if (view == null) { holder = mDatas.get(position); view = mInflater.inflate(R.layout.item_gridview, parent, false); //加载动画 mScaleAnimation = AnimationUtils.loadAnimation(mContext, R.anim.scale); //依次设置延迟时间 mScaleAnimation.setStartOffset(position * 100); holder.button = (Button) view.findViewById(R.id.item_btn); holder.index = position; view.setTag(holder); }else { holder = (WordButton) view.getTag(); } holder.button.setText(holder.name); holder.button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mListener != null) { if (v.getTag() != null) { WordButton holder = (WordButton) v.getTag(); mListener.onButtonClick(holder); } } } }); //播放动画 view.startAnimation(mScaleAnimation); return view; } }}
4)歌曲实体类
/** * 歌曲实体类 * @Project App_Imooc * @Package com.android.imooc.bean * @author chenlin * @version 1.0 * @Date 2014年3月7日 * @Note TODO */public class Song { private String name;//歌曲名称 private String filename;//文件名称 private int nameLength;//文件名称长度 public char[] getNameChar(){//得到名称里的一个个文字 return name.toCharArray(); } public String getName() { return name; } public void setName(String name) { this.name = name; this.nameLength = name.length(); } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public int getNameLength() { return nameLength; }// public void setNameLength(int nameLength) {// this.nameLength = nameLength;// }}
5)文字 按钮实体类:
/** * 文字按钮 * * @Project App_Imooc * @Package com.android.imooc.bean * @author chenlin * @version 1.0 * @Date 2014年3月1日 * @Note TODO */public class WordButton { /** * 搜索的索引 */ public int index; /** * 是否可见 */ public boolean isVisible; /** * 按钮上面的文字 */ public String name; /** * 按钮 */ public Button button; public WordButton() { this.isVisible = true; this.name = ""; }}
6)相关工具类:
(1)主工具类
/** * * @Project App_Imooc * @Package com.android.imooc.helper * @author chenlin * @version 1.0 * @Date 2014年3月21日 * @Note TODO */@SuppressWarnings("all")public class GameUtil { private static final String TAG = "song"; private static final String GAME_DATA_SEPARATOR = ":"; public static final int DATA_INDEX = 0; public static final int DATA_COIN = 1; /** * 保存加密数据到data.dat文件 * * @param context * @param index * @param coins */ public static void saveData(Context context, int index, int coins) { FileOutputStream fos = null; try { fos = context.openFileOutput(Const.FILE_NAME_DATA, Context.MODE_PRIVATE); // 通过base64加密过的关卡索引和金币数 DataOutputStream dos = new DataOutputStream(fos); String indexCode = encodeUseBase64(index + ""); String coinsCode = encodeUseBase64(coins + ""); Logger.i(TAG, "coins ==" + coins); dos.writeBytes(indexCode); dos.writeBytes(GAME_DATA_SEPARATOR); dos.writeBytes(coinsCode); } catch (Exception e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 获取签名 * * @param context * @param packageName * @param view * @return */ public String getSignature(Context context, String packageName, View view) { StringBuilder sb = new StringBuilder(); try { boolean isEmpty = TextUtils.isEmpty(packageName); PackageInfo packageInfo; PackageManager manager = context.getPackageManager(); Signature signatures[]; if (isEmpty) { Toast.makeText(context, "应用程序的包名不能为空!", Toast.LENGTH_SHORT).show(); } else { packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); signatures = packageInfo.signatures; for (Signature s : signatures) { sb.append(s.toCharsString()); } } } catch (NameNotFoundException e) { e.printStackTrace(); } return sb.toString(); } /** * 加密数据 * * @param data * @return */ private static String encodeUseBase64(String data) { if (TextUtils.isEmpty(data)) { return null; } byte[] bytes = Base64.encodeBase64(data.getBytes()); return new String(bytes); } /** * 使用Base64将字符解码 */ public static String decodeUseBase64(String data) { if (TextUtils.isEmpty(data)) { return null; } byte[] bytes = Base64.decodeBase64(data.getBytes()); return new String(bytes); } /** * 读取数据 * * @param context * @return */ public static int[] loadData(Context context) { int[] datas = null; FileInputStream in = null; DataInputStream dis = null; ByteArrayOutputStream baos = null; try { datas = new int[] { 0, Const.TOTAL_COINS }; in = context.openFileInput(Const.FILE_NAME_DATA); dis = new DataInputStream(in); baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while ((len = dis.read(buffer)) != -1) { baos.write(buffer, 0, len); } baos.flush(); String data = baos.toString("UTF-8"); Logger.i(TAG, "loadData ===" + data); String indexStr = data.split(GAME_DATA_SEPARATOR)[DATA_INDEX]; String coinStr = data.split(GAME_DATA_SEPARATOR)[DATA_COIN]; datas[DATA_INDEX] = Integer.parseInt(decodeUseBase64(indexStr)); datas[DATA_COIN] = Integer.parseInt(decodeUseBase64(coinStr)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (baos != null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } return datas; } /** * 生成随机文字 汉字有高地位组成 */ public static char getRandomChar() { String str = ""; int hightPos = 0; int lowPos = 0; Random random = new Random(); hightPos = (176 + Math.abs(random.nextInt(39))); lowPos = (161 + Math.abs(random.nextInt(93))); byte[] b = new byte[2]; b[0] = Integer.valueOf(hightPos).byteValue(); b[1] = Integer.valueOf(lowPos).byteValue(); try { str = new String(b, "GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return str.charAt(0); } /** * 生成24个随机汉字 * * @return */ public static String[] generateWords2(Song mCurrentSong) { String[] words = new String[XGridView.WORD_COUNTS]; // 1.存入歌曲名称 for (int i = 0; i < mCurrentSong.getNameLength(); i++) { words[i] = mCurrentSong.getNameChar()[i] + ""; } // 2.存入随机字 for (int i = mCurrentSong.getNameLength(); i < XGridView.WORD_COUNTS; i++) { words[i] = getRandomChar() + ""; } // 3.打乱字的排列循序 Random random = new Random(); // 打乱文字顺序:首先从所有元素中随机选取一个与第一个元素进行交换, // 然后在第二个之后选择一个元素与第二个交换,知道最后一个元素。 // 这样能够确保每个元素在每个位置的概率都是1/n。 for (int i = XGridView.WORD_COUNTS - 1; i >= 0; i--) { int index = random.nextInt(i + 1); String temp = words[index]; words[index] = words[i]; words[i] = temp; } return words; } /** * 生成所有的待选文字 */ private static String[] generateWords(Song mCurrentSong) { String[] words = new String[XGridView.WORD_COUNTS]; // 存入歌名 for (int i = 0; i < mCurrentSong.getNameLength(); i++) { words[i] = mCurrentSong.getNameChar()[i] + ""; } // 存入随机汉字 for (int i = mCurrentSong.getNameLength(); i < XGridView.WORD_COUNTS; i++) { words[i] = getRandomChar() + ""; } // 打乱汉字顺序 List<String> wordList = (List<String>) Arrays.asList(words); Collections.shuffle(wordList); for (int i = 0; i < words.length; i++) { words[i] = wordList.get(i); } return words; } /** * 点击后设置选中文字状态 * * @param wb */ public static void setSelectWord(WordButton wb, List<WordButton> mSelectWords) { for (int i = 0; i < mSelectWords.size(); i++) { // 1.判断是否有文字 WordButton selectedButton = mSelectWords.get(i); // 如果没有文字 if (selectedButton.name.length() == 0) { //设置过渡动画 setAnimationToSelectedWord(selectedButton, wb); // --设置选择框内容----------------------- selectedButton.button.setText(wb.name); selectedButton.isVisible = true; selectedButton.name = wb.name; // 设置索引 selectedButton.index = wb.index; // ---设置待选框可见性---------- setButtonVisiblity(wb, View.INVISIBLE); // 必须加这一句,否则两个框都会被加上文字 break; } } } /** * 设置文字按钮的平移动画效果 */ public static void setAnimationToSelectedWord(final WordButton selectedWord, final WordButton wordButton) { TranslateAnimation animation = (TranslateAnimation)getAnimationFromViewToAnother(wordButton.button, selectedWord.button); wordButton.button.startAnimation(animation); } /** * 将控件从一个位置移动到另一个位置 */ public static Animation getAnimationFromViewToAnother(View from, View to) { int[] fromPosition = getViewLocation(from); int[] toPosition = getViewLocation(to); TranslateAnimation animation = new TranslateAnimation(0, toPosition[0] - fromPosition[0], 0, toPosition[1] - fromPosition[1]); animation.setDuration(500); animation.setFillAfter(false); return animation; } /** * 获取一个控件在屏幕中的显示位置 */ public static int[] getViewLocation(View view) { int[] position = new int[2]; view.getLocationOnScreen(position); return position; } /** * 设置字体按钮的状态信息 * * @param hoder * @param visible */ public static void setButtonVisiblity(WordButton hoder, int visible) { if (hoder != null) { Logger.i(TAG, "hoder.name==" + hoder.name); Logger.i(TAG, "visible==" + visible); Logger.i(TAG, "holder.index=" + hoder.index); hoder.button.setVisibility(visible); hoder.isVisible = (visible == View.VISIBLE ? true : false); } } /** * 清除被选中的答案 * * @param holder */ public static void clearTheAnswer(WordButton holder, List<WordButton> mAllWords) { if (holder != null) { holder.button.setText(""); holder.name = ""; holder.isVisible = false; // 隐藏以选择的文字 if (mAllWords != null && mAllWords.size() > 0) { setButtonVisiblity(mAllWords.get(holder.index), View.VISIBLE); } } } /** * 加载歌曲信息 * * @param index * @return */ public static Song loadStageSongInfo(int index) { Song song = new Song(); String[] stage = Const.SONG_INFO[index]; song.setFilename(stage[0]); song.setName(stage[1]); return song; } /** * 初始化已选中文字 * * @return */ public static List<WordButton> initSelectWords(Context context, Song mCurrentSong, final List<WordButton> mAllWords) { List<WordButton> datas = new ArrayList<WordButton>(); // 根据歌曲名称长度决定选择的框多少 for (int i = 0; i < mCurrentSong.getNameLength(); i++) { View view = GameUtil.getView(context, R.layout.self_ui_gridview_item); final WordButton holder = new WordButton(); holder.button = (Button) view.findViewById(R.id.item_btn); holder.button.setTextColor(Color.WHITE); holder.button.setText(""); holder.button.setBackgroundResource(R.drawable.game_wordblank); holder.isVisible = false; holder.button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 清除被点击的已选文字框的文字 if (!TextUtils.isEmpty(holder.name)) { clearTheAnswer(holder, mAllWords); } } }); datas.add(holder); } return datas; } /** * 初始化所有的文字 * * @return */ public static List<WordButton> initAllWords(Song mCurrentSong) { List<WordButton> list = new ArrayList<WordButton>(); // 得到所有的随机文字 String[] words = generateWords(mCurrentSong); // 循环,给每个button添加文字 for (int i = 0; i < XGridView.WORD_COUNTS; i++) { WordButton wb = new WordButton(); wb.name = words[i]; list.add(wb); } return list; } /** * 检查选择的信息是否正确 * * @return */ public static int checkTheAnswer(List<WordButton> mSelectWords, Song mCurrentSong) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < mSelectWords.size(); i++) { if (mSelectWords.get(i).name.length() == 0) { return MainActivity.STATE_ANSWER_LACK; } sb.append(mSelectWords.get(i).name); } return sb.toString().equals(mCurrentSong.getName()) ? MainActivity.STATE_ANSWER_RIGHT : MainActivity.STATE_ANSWER_WRONG; } /** * 加载view * * @param context * @param layoutId * @return */ public static View getView(Context context, int layoutId) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(layoutId, null); return layout; } /** * 启动activity * * @param context * @param clazz */ public static void startActivity(Context context, Class clazz) { Intent intent = new Intent(context, clazz); context.startActivity(intent); ((Activity) context).finish(); }}
(2)常量
/** * @Project App_Imooc * @Package com.android.imooc.helper * @author chenlin * @version 1.0 * @Date 204年3月15日 * @Note TODO */public class Const { public static final int INDEX_FILE_NAME = 0; public static final int INDEX_SONG_NAME = 1; public static int TOTAL_COINS = 1000;//金币总量 public static final String FILE_NAME_DATA = "data.dat"; /** * 歌曲名称列表 */ public static final String SONG_INFO[][]={ {"__00000.m4a", "征服"}, {"__00001.m4a", "童话"}, {"__00002.m4a", "同桌的你"}, {"__00003.m4a", "七里香"}, {"__00004.m4a", "传奇"}, {"__00005.m4a", "大海"}, {"__00006.m4a", "后来"}, {"__00007.m4a", "你的背包"}, {"__00008.m4a", "再见"}, {"__00009.m4a", "老男孩"}, {"__00010.m4a", "龙的传人"}, };}
四、源码下载:链接:http://pan.baidu.com/s/1geN7FYN 密码:tveb
更多相关文章
- android 适配华为透明状态栏 ,保留虚拟导航键,设置状态栏透明,且设
- Android(安卓)EditText禁止输入中文字符
- 2-3-6 ToggleButton&Switch
- ActionBar的简单使用(修改背景颜色,文字居中,图标)
- Android简单实现Socket通信,客户端连接服务器后,服务器向客户端发
- Android中测量控件的内部文字内容的宽、高度
- TextView组件改变部分文字的颜色
- TextView显示连续空格
- Android(安卓)TextView自适应文字大小