Google play storeで公開しました。
https://play.google.com/store/apps/details?id=com.nyaa.braintrainer
Androidスマホを使っている方は遊んでみてもらえると嬉しいです。
また、コードレビューしていただき、ソースコードを少し修正しました。
メモも追加したり、学習用のメモを消したりしました。
もとのソースコード
https://qiita.com/KToushi/items/6e1a369111e904a6a22f
//playaAgainボタンを押したときの挙動を定義
public void playAgain(View view) {
score = 0;
numberOfQusetions = 0;
timerTextview.setText("15s");
scoreTextView.setText("0/0");
・
・
・
new CountDownTimer(15100, 1000) {
//CountDownTimerクラスのメソッドを上書き
@Override
//カウントダウンしている間の挙動
public void onTick(long millisUntilFinished) {
//残り何秒か表示
timerTextview.setText(String.valueOf(millisUntilFinished / 1000) + "s");
}
・
・
・
public void newQuetion() {
//インスタンス生成
//クラス名 変数 = new クラス名();
Random rand = new Random();
//整数の変数a,bを定義 0~20の21通りの整数をランダムに代入
int a = rand.nextInt(21);
int b = rand.nextInt(21);
sumTextView.setText(Integer.toString(a)+ " + " + Integer.toString(b));
//0~3の4通りの整数をランダムに代入 Tagも0~3の4通り
locationOfCorrectAnswer = rand.nextInt(4);
//answersリストの中身(4つの答え)を消去
answers.clear();
for(int i=0; i<4; i++) {
if(i==locationOfCorrectAnswer) {
answers.add(a+b);
} else {
//0~40の41通りの整数をランダムに代入(a,bにはそれぞれ0~20の整数が入るため 最小0+0 最大20+20)
int wrongAnswer = rand.nextInt(41);
//wrongAnswerが正解と一緒の場合、再び0から40の41通りの整数をランダムに代入
while(wrongAnswer == a+b) {
wrongAnswer = rand.nextInt(41);
15,15100,1000,4,21,41のような数値を直接メソッド内に書いてしまっていると、後から修正したいときに該当箇所を探すのが大変ということで、
始めに定数としてまとめて宣言することにしました↓
//ゲーム開始時のカウントダウンタイマーの残り時間を表す定数
final int remainingTime = 16;
//カウントダウンタイマーのカウントダウンの間隔を表す定数
final int countDownInterval = 1000;
//選択肢の数
final int numberOfTags = 4;
//(問題に使うランダムな数が)何通りあるか
final int numberOfWays = 20;
ソースコード全体↓
package com.nyaa.braintrainer;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
import static android.media.MediaPlayer.create;
public class MainActivity extends AppCompatActivity {
//ゲームを開始するボタン
Button goButton;
//残り時間、問題、得点/問題数、4つの選択肢(ボタン)
ConstraintLayout gameLayout;
Button playAgainButton;
TextView resultTextView;
TextView commentTextView;
TextView timerTextview;
int score = 0;
int numberOfQusetions = 0;
//猫画像
ImageView imageNirami;
ImageView imageKakure;
ImageView imageYousumi;
//ゲーム開始時のカウントダウンタイマーの残り時間を表す定数
final int remainingTime = 16;
//カウントダウンタイマーのカウントダウンの間隔を表す定数
final int countDownInterval = 1000;
ArrayList<Integer> answers = new ArrayList<Integer>();
//正解の位置(ボタン)のtag
int locationOfCorrectAnswer;
//選択肢の数
final int numberOfTags = 4;
//(問題に使うランダムな数が)何通りあるか
final int numberOfWays = 20;
TextView scoreTextView;
TextView sumTextView;
Button button0, button1, button2, button3;
//Goボタンを押したときの挙動(ゲームをスタートさせる)を定義
public void start(View view) {
//goボタンが消える
goButton.setVisibility(View.INVISIBLE);
//残り時間、問題、得点/問題数、4つの選択肢(ボタン)を出現させる
gameLayout.setVisibility(View.VISIBLE);
//playAgainButtonを押した時と同じ挙動をする
playAgain(findViewById(R.id.timerTextView));
}
//playaAgainボタンを押したときの挙動を定義
public void playAgain(View view) {
score = 0;
numberOfQusetions = 0;
//残り何秒か表示
timerTextview.setText(remainingTime + "s");
//何問中何問正解しているか表示
scoreTextView.setText("0/0");
//新しい問題と選択肢を表示
newQuetion();
//resultTextViewを見えるようにする
resultTextView.setVisibility(View.VISIBLE);
//commentTextViewを見えなくする
commentTextView.setVisibility(View.INVISIBLE);
//playAgainButtonを見えなくする
playAgainButton.setVisibility(View.INVISIBLE);
//猫の画像見えなくする
imageNirami.setVisibility(View.INVISIBLE);
imageYousumi.setVisibility(View.INVISIBLE);
imageKakure.setVisibility(View.INVISIBLE);
resultTextView.setText("");
//4つのボタン(選択肢)出現
buttonShow();
//カウントダウンタイマーをスタートさせる
new CountDownTimer(remainingTime * 1000, countDownInterval) {
//CountDownTimerクラスのメソッドを上書き
@Override
//カウントダウンしている間の挙動
public void onTick(long millisUntilFinished) {
//残り何秒か表示
timerTextview.setText(String.valueOf(millisUntilFinished / 1000) + "s");
}
@Override
//カウントダウンが0になった時の挙動
public void onFinish() {
MediaPlayer mediaPlayer;
//4つのボタン(選択肢)を見えなくする
buttonHide();
resultTextView.setVisibility(View.INVISIBLE);
commentTextView.setVisibility(View.VISIBLE);
//得点によって表示される画像とテキスト、効果音を変える
if(score > 9) {
commentTextView.setText("ほ、ほめてあげるわ//");
//隠れ猫表示
imageKakure.setVisibility(View.VISIBLE);
//効果音キラキラが鳴る
mediaPlayer = create(getApplicationContext(), R.raw.shine1);
mediaPlayer.start();
} else if(score > 5) {
commentTextView.setText("ふん、まあまあね");
//様子見猫表示
imageYousumi.setVisibility(View.VISIBLE);
//効果音シャキーン!が鳴る
mediaPlayer = create(getApplicationContext(), R.raw.shakin1);
mediaPlayer.start();
} else {
commentTextView.setText("あんたやる気あるの?");
//にらみ猫表示
imageNirami.setVisibility(View.VISIBLE);
//効果音チーンが鳴る
mediaPlayer = create(getApplicationContext(), R.raw.tin1);
mediaPlayer.start();
}
//playAgainButton出現
playAgainButton.setVisibility(View.VISIBLE);
}
}.start();
}
//4種類のボタンを押したときの挙動(メソッド)を定義
public void chooseAnswer(View view) {
//正解のタグと押したタグが同じとき(4つのボタンに0~3の4種類のタグを設定している)
if (Integer.toString(locationOfCorrectAnswer).equals(view.getTag().toString())) {
resultTextView.setText("正解にゃ");
//得点が1増える
score++;
} else {
resultTextView.setText("間違いにゃ");
}
//現在の問題数が1増える
numberOfQusetions++;
//何問中何問正解しているか表示
scoreTextView.setText(Integer.toString(score) + "/" + Integer.toString(numberOfQusetions));
//新しい問題と選択肢を表示
newQuetion();
}
//新しい問題を出現させるメソッドを定義
public void newQuetion() {
Random rand = new Random();
//整数の変数a,bを定義 0~numberOfWaysの(numberOfWays + 1)通りの整数をランダムに代入
int a = rand.nextInt(numberOfWays);
int b = rand.nextInt(numberOfWays);
//a + bを表示
sumTextView.setText(Integer.toString(a)+ " + " + Integer.toString(b));
//0~3の4通りの整数をランダムに代入 Tagも0~3の4通り
locationOfCorrectAnswer = rand.nextInt(numberOfTags);
//answersリストの中身(4つの答え)を消去
answers.clear();
for(int i=0; i<4; i++) {
if(i == locationOfCorrectAnswer) {
//anserwsリストに正解(a + b)を追加
answers.add(a+b);
} else {
//0~numberOfWays * 2 の numberOfWays * 2 -1 通りの整数をランダムに代入
int wrongAnswer = rand.nextInt(numberOfWays * 2 -1);
//wrongAnswerが正解と一緒の間、0~numberOfWays * 2 の numberOfWays * 2 -1 通りの整数をランダムに代入
while(wrongAnswer == a+b) {
wrongAnswer = rand.nextInt(numberOfWays * 2 -1);
}
//answersリストに間違った答えを追加
answers.add(wrongAnswer);
}
}
button0.setText(Integer.toString(answers.get(0)));
button1.setText(Integer.toString(answers.get(1)));
button2.setText(Integer.toString(answers.get(2)));
button3.setText(Integer.toString(answers.get(3)));
}
//4つのボタン(選択肢)を見えるようにするメソッドを定義
public void buttonShow() {
button0.setVisibility(View.VISIBLE);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.VISIBLE);
}
//4つのボタン(選択肢)を見えなくするメソッドを定義
public void buttonHide(){
button0.setVisibility(View.INVISIBLE);
button1.setVisibility(View.INVISIBLE);
button2.setVisibility(View.INVISIBLE);
button3.setVisibility(View.INVISIBLE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//それぞれlayoutのViewと紐づけ
goButton = findViewById(R.id.goButton);
sumTextView = findViewById(R.id.sumTextView);
button0 = findViewById(R.id.button0);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
resultTextView = findViewById(R.id.resultTextView);
commentTextView = findViewById(R.id.commentTextView);
scoreTextView = findViewById(R.id.scoreTextView);
timerTextview = findViewById(R.id.timerTextView);
playAgainButton = findViewById(R.id.playAgainButton);
gameLayout = findViewById(R.id.gameLayout);
imageNirami = findViewById(R.id.nirami);
imageKakure = findViewById(R.id.kakure);
imageYousumi = findViewById(R.id.yousumi);
goButton.setVisibility(View.VISIBLE);
}
}
レイアウト↓
<?xml version="1.0" encoding="utf-8"?>
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/goButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@android:color/holo_green_dark"
android:onClick="start"
android:padding="40dp"
android:text="GO!"
android:textSize="60sp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/kakure"
android:layout_width="474dp"
android:layout_height="900dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/konekokakure" />
<ImageView
android:id="@+id/yousumi"
android:layout_width="409dp"
android:layout_height="738dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/nekoyousumi" />
<ImageView
android:id="@+id/nirami"
android:layout_width="375dp"
android:layout_height="245dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/nekonirami" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/gameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<TextView
android:id="@+id/timerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="@android:color/holo_orange_dark"
android:text="30s"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/scoreTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@android:color/holo_blue_dark"
android:padding="10dp"
android:text="0/0"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/sumTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:padding="15dp"
android:text="31 + 7"
android:textSize="40dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TableLayout
android:id="@+id/TableLayout"
android:layout_width="330dp"
android:layout_height="350dp"
android:layout_marginTop="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TableRow
android:id="@+id/TableRow1"
android:layout_width="match_parent"
android:layout_height="258dp">
<Button
android:id="@+id/button0"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_row="0"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_weight="1"
android:background="@android:color/holo_red_light"
android:onClick="chooseAnswer"
android:tag="0"
android:text="14"
android:textSize="80sp" />
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_row="0"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_weight="1"
android:background="@android:color/holo_purple"
android:onClick="chooseAnswer"
android:tag="1"
android:text="14"
android:textSize="80sp" />
</TableRow>
<TableRow
android:id="@+id/TableRow2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_row="1"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_weight="1"
android:background="@android:color/holo_blue_dark"
android:onClick="chooseAnswer"
android:tag="2"
android:text="14"
android:textSize="80sp" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_row="1"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_gravity="fill"
android:layout_weight="1"
android:background="@android:color/holo_green_dark"
android:onClick="chooseAnswer"
android:tag="3"
android:text="14"
android:textSize="80sp" />
</TableRow>
</TableLayout>
<TextView
android:id="@+id/resultTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="45dp"
android:text="Correct!"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/commentTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="45dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/playAgainButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="10dp"
android:onClick="playAgain"
android:text="play again"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/resultTextView" />
</androidx.constraintlayout.widget.ConstraintLayout>