package com.jyc.threegames.activity; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.text.Html; import android.view.Gravity; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; import com.jyc.threegames.App; import com.jyc.threegames.R; import com.jyc.threegames.activity.base.BaseActivity; import com.jyc.threegames.bean.GameInfo; import com.jyc.threegames.bean.result.ResGameInfo; import com.jyc.threegames.controller.GameController; import com.jyc.threegames.controller.LoginController; import com.jyc.threegames.net.SimpleRequest; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import butterknife.BindView; import butterknife.OnClick; import it.sephiroth.android.library.numberpicker.NumberPicker; public class GameActivity extends BaseActivity { private static final String PARAM_GAME_INFO = "gameInfo"; private static final String PARAM_RES_GAME_INFO = "resGameInfo"; private int mCurrentPreGameCountDown = 0; private Handler mPreGameHandler; private Integer[] mPractiseNumbers; private Handler mPractiseHandler; private int mCurrentPractiseIndex; private GameInfo mGameInfo; private ResGameInfo mResGameInfo; private int mSpecialNumberOne; private int mSpecialNumberTwo; @BindView(R.id.pre_game_hint) TextView mTVPreGameHint; @BindView(R.id.game_hint) TextView mTVGameHint; @BindView(R.id.number) TextView mTVNumber; @BindView(R.id.click_area) View mVClickArea; @BindView(R.id.form) ConstraintLayout mCLForm; @BindView(R.id.right) NumberPicker mNPRight; @BindView(R.id.grasp) NumberPicker mNPGrasp; private boolean mClickable = false; private long mClickTime = 0; private long mCurrentTime = 0; private List mRecordList; private List mResponseList; private List mPressRecordList; private long mStartTime = System.currentTimeMillis(); private long mEndTime = 0; @Override protected void init(Bundle instance) { super.init(instance); if (instance == null) { mGameInfo = getIntent().getParcelableExtra(PARAM_GAME_INFO); mResGameInfo = getIntent().getParcelableExtra(PARAM_RES_GAME_INFO); } else { mGameInfo = instance.getParcelable(PARAM_GAME_INFO); mResGameInfo = getIntent().getParcelableExtra(PARAM_RES_GAME_INFO); } if (!LoginController.getInstance().isCurrentUserAdmin()){ new SimpleRequest<>().request(this, GameController.getInstance().enterGame(mResGameInfo.playGameId)); } startPrePractise(); App.CAN_PLAY_GAME = false; } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(PARAM_GAME_INFO, mGameInfo); outState.putParcelable(PARAM_RES_GAME_INFO, mResGameInfo); } @Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mGameInfo = savedInstanceState.getParcelable(PARAM_GAME_INFO); mResGameInfo = savedInstanceState.getParcelable(PARAM_RES_GAME_INFO); } @Override protected int getRootLayout() { return R.layout.activity_game_one; } @Override protected void onDestroy() { super.onDestroy(); App.CAN_PLAY_GAME = true; } @Override public void onBackPressed() {} @Override protected String getAlertText() { return "您好,\n閒置超時,\n請繼續操作!"; } @OnClick(R.id.click_area) public void clickNumber(){ if (mClickable && mClickTime == 0){ mClickTime = System.currentTimeMillis(); } } @OnClick(R.id.sure) public void clickSure(){ if (LoginController.getInstance().isCurrentUserAdmin()){ goFinish(); }else{ Dialog loading = new ProgressDialog(this); loading.setTitle("正在提交數據"); loading.show(); new SimpleRequest<>() .request(this, GameController.getInstance().addAnswer(mResGameInfo.playGameId, mPractiseNumbers, mRecordList, mResponseList, mPressRecordList, mSpecialNumberOne, mSpecialNumberTwo, mGameInfo.gameVersion, mStartTime, mEndTime, mNPRight.getProgress(), mNPGrasp.getProgress()), "提交數據失敗!請檢查網絡狀態", loading, new SimpleRequest.Executor() { @Override public void execute(Object obj) { goFinish(); } }); } } private void goFinish(){ hideAllView(); mTVPreGameHint.setGravity(Gravity.CENTER); mTVPreGameHint.setText("數據提交成功\n\n謝謝參與"); mTVPreGameHint.setVisibility(View.VISIBLE); new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message message) { finish(); return true; } }).sendEmptyMessageDelayed(0, 3000); } private void startPrePractise(){ hideAllView(); mSpecialNumberOne = getRandomNumber(); mSpecialNumberTwo = getRandomNumber(mSpecialNumberOne); mCurrentPreGameCountDown = mGameInfo.getPractiseDurationSecond(); mPreGameHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message message) { if (mCurrentPreGameCountDown > 0){ mTVPreGameHint.setVisibility(View.VISIBLE); mTVPreGameHint.setGravity(Gravity.START); mTVPreGameHint.setText(Html.fromHtml(getPrePractiseText(mSpecialNumberOne, mSpecialNumberTwo, mCurrentPreGameCountDown), Html.FROM_HTML_MODE_LEGACY)); mCurrentPreGameCountDown --; mPreGameHandler.sendEmptyMessageDelayed(0, 1000); }else{ mTVPreGameHint.setVisibility(View.GONE); startGame(true); } return true; } }); mPreGameHandler.sendEmptyMessage(0); } private String getPreGameText(int countDown){ return String.format(Locale.TRADITIONAL_CHINESE,"練習結束,

%1$d秒后進入正式測試", countDown); } private String getPrePractiseText(int numberOne, int numberTwo, int countDown){ switch (mGameInfo.gameVersion){ case GameInfo.VERSION_GAME_ONE: return String.format(Locale.TRADITIONAL_CHINESE,"當屏幕出現數字%1$d的時候,
請您以最快的速度按下

正式開始前,會有小段練習

%2$d秒后進入練習", mSpecialNumberOne, countDown); case GameInfo.VERSION_GAME_TWO: return String.format(Locale.TRADITIONAL_CHINESE,"當數字%1$d,%2$d連續出現時,
%1$d出現時不要按下,
%2$d出現時,
請您以最快的速度按下

正式開始前,會有小段練習

%3$d秒后進入練習", numberOne, numberTwo, countDown); case GameInfo.VERSION_GAME_THREE: return String.format(Locale.TRADITIONAL_CHINESE,"除數字%1$d以外的數字出現時,
請您以最快的速度按下

正式開始前,會有小段練習

%2$d秒后進入練習", numberOne, countDown); default: return ""; } } private void startGame(boolean isPractise){ hideAllView(); mPractiseNumbers = getPractiseNumbers(isPractise ? mGameInfo.practiseRightNumber : mGameInfo.correctNumberOccurrenceNumber, isPractise ? mGameInfo.practiseOccurrenceNumber : mGameInfo.errorNumberOccurrenceNumber); mRecordList = new ArrayList<>(); mResponseList = new ArrayList<>(); mPressRecordList = new ArrayList<>(); mCurrentPractiseIndex = 0; restoreClickInfo(false); mPractiseHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message message) { switch (message.what){ case 0: if (mCurrentPractiseIndex == mPractiseNumbers.length){ restoreClickInfo(false); if (isPractise) startPregame(); else startFeedBack(); }else{ restoreClickInfo(true); mCurrentTime = System.currentTimeMillis(); mTVNumber.setVisibility(View.VISIBLE); mTVGameHint.setVisibility(View.GONE); mTVNumber.setText(String.valueOf(mPractiseNumbers[mCurrentPractiseIndex])); mPractiseHandler.sendEmptyMessageDelayed(1, mGameInfo.displayDuration); } break; case 1: mTVNumber.setVisibility(View.GONE); if (isPractise) { mTVGameHint.setText(Html.fromHtml(getGameHint(), Html.FROM_HTML_MODE_LEGACY)); mTVGameHint.setVisibility(View.VISIBLE); }else { int result = getClickResult(); mRecordList.add(result); mPressRecordList.add(mClickTime == 0 ? 0 : 1); if (mClickTime != 0 && result == GameInfo.CLICK_RIGHT) mResponseList.add(mClickTime - mCurrentTime); else mResponseList.add(-1L); } restoreClickInfo(false); mCurrentPractiseIndex ++; mPractiseHandler.sendEmptyMessageDelayed(0, mGameInfo.intervalDuration); break; } return true; } }); mPractiseHandler.sendEmptyMessage(0); } private void startPregame(){ hideAllView(); mCurrentPreGameCountDown = mGameInfo.getPractiseDurationSecond(); mPreGameHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message message) { if (mCurrentPreGameCountDown > 0){ mTVPreGameHint.setVisibility(View.VISIBLE); mTVPreGameHint.setGravity(Gravity.CENTER); mTVPreGameHint.setText(Html.fromHtml(getPreGameText(mCurrentPreGameCountDown), Html.FROM_HTML_MODE_LEGACY)); mCurrentPreGameCountDown --; mPreGameHandler.sendEmptyMessageDelayed(0, 1000); }else{ mTVPreGameHint.setVisibility(View.GONE); startGame(false); } return true; } }); mPreGameHandler.sendEmptyMessage(0); } private void startFeedBack(){ hideAllView(); mCLForm.setVisibility(View.VISIBLE); mEndTime = System.currentTimeMillis(); startWatch(); } private String getGameHint(){ String result; int clickResult = getClickResult(); result = clickResult == GameInfo.CLICK_RIGHT ? "正確" : (clickResult == GameInfo.CLICK_WRONG ? "錯誤" : "錯失"); if (mClickTime != 0 && clickResult == GameInfo.CLICK_RIGHT) result += String.format(Locale.TRADITIONAL_CHINESE, "
反應時間: %1$d 毫秒", mClickTime - mCurrentTime); return result; } private int getClickResult(){ int preNumber = mCurrentPractiseIndex == 0 ? -1 : mPractiseNumbers[mCurrentPractiseIndex - 1]; int currentNumber = mPractiseNumbers[mCurrentPractiseIndex]; if (mGameInfo.gameVersion == GameInfo.VERSION_GAME_ONE){ if (mClickTime == 0){ if (mSpecialNumberOne == currentNumber) return GameInfo.CLICK_MISS; else return GameInfo.CLICK_RIGHT; }else{ if (mSpecialNumberOne == currentNumber) return GameInfo.CLICK_RIGHT; else return GameInfo.CLICK_WRONG; } }else if(mGameInfo.gameVersion == GameInfo.VERSION_GAME_TWO){ if (preNumber < 0 && mClickTime != 0) return GameInfo.CLICK_WRONG; if (mClickTime == 0){ if (preNumber == mSpecialNumberOne && currentNumber == mSpecialNumberTwo) return GameInfo.CLICK_MISS; else return GameInfo.CLICK_RIGHT; }else{ if (preNumber == mSpecialNumberOne && currentNumber == mSpecialNumberTwo) return GameInfo.CLICK_RIGHT; else return GameInfo.CLICK_WRONG; } }else if(mGameInfo.gameVersion == GameInfo.VERSION_GAME_THREE){ if (mClickTime == 0){ if (mSpecialNumberOne == currentNumber) return GameInfo.CLICK_RIGHT; else return GameInfo.CLICK_MISS; }else{ if (mSpecialNumberOne == currentNumber) return GameInfo.CLICK_WRONG; else return GameInfo.CLICK_RIGHT; } } return GameInfo.CLICK_MISS; } private Integer[] getPractiseNumbers(int rightNumber, int otherNumberOccurrence){ List result = new ArrayList<>(); for (int i = 0; i < otherNumberOccurrence; i ++) result.add(mGameInfo.gameVersion != GameInfo.VERSION_GAME_TWO ? getRandomNumber(mSpecialNumberOne) : getRandomNumber()); int less = 0; if (mGameInfo.gameVersion == GameInfo.VERSION_GAME_TWO && result.size() > 1) for(int i = 0; i < result.size(); i ++){ if (i != result.size() - 1){ if (result.get(i) == mSpecialNumberOne && result.get(i + 1) == mSpecialNumberTwo) less ++; } } if (less > rightNumber) return getPractiseNumbers(rightNumber, otherNumberOccurrence); for (int i = 0; i < rightNumber - less; i ++) { int index = (int) (Math.random() * result.size()); if (mGameInfo.gameVersion != GameInfo.VERSION_GAME_TWO) result.add(index, mSpecialNumberOne); else{ if (index != result.size() - 1 && (result.get(index) == mSpecialNumberOne && result.get(index + 1) == mSpecialNumberTwo)){ i--; continue; } result.add(index, mSpecialNumberOne); result.add(index + 1, mSpecialNumberTwo); } } return result.toArray(new Integer[0]); } private void restoreClickInfo(boolean clickable){ mClickable = clickable; mClickTime = 0; mCurrentTime = 0; } private int getRandomNumber(){ return (int)(Math.random() * 10); } private int getRandomNumber(int number){ int value = getRandomNumber(); return value == number ? getRandomNumber(number) : value; } private void hideAllView(){ ConstraintLayout rootView = getWindow().getDecorView().findViewById(R.id.root); for (int i = 0; i < rootView.getChildCount(); i ++){ if (rootView.getChildAt(i).getId() != R.id.click_area) rootView.getChildAt(i).setVisibility(View.GONE); } } public static void LAUNCH_GAME_ONE(Activity context, GameInfo gameInfo){ Intent intent = new Intent(context, GameActivity.class); intent.putExtra(PARAM_GAME_INFO, gameInfo); context.startActivity(intent); } public static void LAUNCH_GAME(Activity context, ResGameInfo resGameInfo){ Intent intent = new Intent(context, GameActivity.class); intent.putExtra(PARAM_GAME_INFO, resGameInfo.getGameInfo()); intent.putExtra(PARAM_RES_GAME_INFO, resGameInfo); context.startActivity(intent); } }