【发布时间】:2017-05-28 19:48:41
【问题描述】:
我正在 Android 中为一个 uni 项目实现 Simon Says,作为 Audiogames 套件应用程序的一部分。我正在尝试生成一个由 5 个(仅作为开始测试)按钮播放的随机序列,并且一切顺利,除了一件事:按钮在它们应该亮起的时候没有亮起(当它们在序列中的种子生成时)但是相反,它们确实会在世代结束时一起点亮。
遵循我的 Java 和 XML 的完整代码(这有点混乱和不完整,所以我会指出对我来说很麻烦的部分)
Java 源码
package it.unimi.di.lim.audiogames;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import java.util.LinkedList;
import java.util.Random;
public class Game2PlayActivity extends AppCompatActivity {
private int mScore = 0;
private LinkedList<Integer> temp = new LinkedList<>();
private MediaPlayer mCMediaPlayer;
private MediaPlayer mDMediaPlayer;
private MediaPlayer mEMediaPlayer;
private MediaPlayer mFMediaPlayer;
private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer(mp);
turnOffButton(mp);
}
};
private void releaseMediaPlayer(MediaPlayer mediaPlayer) {
if (mediaPlayer != null) {
mediaPlayer.release();
}
}
private void turnOffButton(MediaPlayer mp) {
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
if(mp == mCMediaPlayer) {
mc_button.setBackgroundColor(getResources().getColor(R.color.game2_c_off));
} else if (mp == mDMediaPlayer) {
md_button.setBackgroundColor(getResources().getColor(R.color.game2_d_off));
} else if (mp == mEMediaPlayer) {
me_button.setBackgroundColor(getResources().getColor(R.color.game2_e_off));
} else {
mf_button.setBackgroundColor(getResources().getColor(R.color.game2_f_off));
}
}
private void playButton(int i) {
char j;
if(i==0)
j='0';
else if(i==1)
j='1';
else if(i==2)
j='2';
else
j='3';
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
switch(j) {
case '0':
mc_button.setBackgroundResource(R.color.game2_c_on);
//mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
//mCMediaPlayer.start();
//mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mCMediaPlayer.release();
// }
//});
break;
case '1':
md_button.setBackgroundResource(R.color.game2_d_on);
//mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
//mDMediaPlayer.start();
//mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mDMediaPlayer.release();
// }
//});
break;
case '2':
me_button.setBackgroundResource(R.color.game2_e_on);
//mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
//mEMediaPlayer.start();
//mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mEMediaPlayer.release();
// }
//});
break;
case '3':
mf_button.setBackgroundResource(R.color.game2_f_on);
//mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
//mFMediaPlayer.start();
//mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mFMediaPlayer.release();
// }
//});
break;
}
}
private void createSequence(int i) {
Random rand = new Random();
for(int j = 0; j < i; j++) {
int seed = rand.nextInt(4);
temp.add(seed);
playButton(seed);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
protected void onStop() {
super.onStop();
releaseMediaPlayer(mCMediaPlayer);
releaseMediaPlayer(mDMediaPlayer);
releaseMediaPlayer(mEMediaPlayer);
releaseMediaPlayer(mFMediaPlayer);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game2_play);
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
if (Build.VERSION.SDK_INT >= 21) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(this.getResources().getColor(R.color.game2Dark));
window.setNavigationBarColor(this.getResources().getColor(R.color.game2Primary));
}
android.support.v7.app.ActionBar bar = getSupportActionBar();
bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.game2Primary)));
mc_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playButton(0);
int check = temp.poll();
if(check!=0) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
md_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playButton(1);
int check = temp.poll();
if(check!=1) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
me_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playButton(2);
int check = temp.poll();
if(check!=2) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
mf_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playButton(3);
int check = temp.poll();
if(check!=3) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
Button start_button = (Button) findViewById(R.id.game2_start_button);
start_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createSequence(5);
}
});
}
}
XML 源
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
tools:context=".Game1PlayActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/game2_score"
android:textSize="16sp"
android:padding="16dp"
android:gravity="bottom"
android:textAlignment="center" />
<TextView
android:id="@+id/game2_score"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.2"
android:text="0"
android:textSize="48sp"
android:padding="16dp"
android:gravity="top"
android:textAlignment="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8"
android:text="@string/game2_criteria"
android:textSize="16sp"
android:padding="16dp"
android:gravity="bottom"
android:textAlignment="center" />
<Button
android:id="@+id/game2_start_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/game2_start"
android:layout_marginTop="8dp"
android:layout_marginLeft="64dp"
android:layout_marginRight="64dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<Button
android:id="@+id/c_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/game2_c_off"
android:layout_margin="16dp"
android:text="@string/game2_c" />
<Button
android:id="@+id/d_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/game2_d_off"
android:layout_margin="16dp"
android:text="@string/game2_d" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<Button
android:id="@+id/e_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/game2_e_off"
android:layout_margin="16dp"
android:text="@string/game2_e" />
<Button
android:id="@+id/f_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/game2_f_off"
android:layout_margin="16dp"
android:text="@string/game2_f" />
</LinearLayout>
</LinearLayout>
----------------------------------------------- --------------------------------
所以基本上我要做的是通过单击“开始”按钮生成序列,这是onClickListener(5 仅用于测试目的)
Button start_button = (Button) findViewById(R.id.game2_start_button);
start_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createSequence(5);
}
});
这会触发createSequence()方法如下
private void createSequence(int i) {
Random rand = new Random();
for(int j = 0; j < i; j++) {
int seed = rand.nextInt(4);
temp.add(seed);
playButton(seed);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
到目前为止一切都很好。我认为在我糟糕的编程经验中失败的是PlayButton() 方法
private void playButton(int i) {
char j;
if(i==0)
j='0';
else if(i==1)
j='1';
else if(i==2)
j='2';
else
j='3';
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
switch(j) {
case '0':
mc_button.setBackgroundResource(R.color.game2_c_on);
//mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
//mCMediaPlayer.start();
//mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mCMediaPlayer.release();
// }
//});
break;
case '1':
md_button.setBackgroundResource(R.color.game2_d_on);
//mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
//mDMediaPlayer.start();
//mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mDMediaPlayer.release();
// }
//});
break;
case '2':
me_button.setBackgroundResource(R.color.game2_e_on);
//mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
//mEMediaPlayer.start();
//mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mEMediaPlayer.release();
// }
//});
break;
case '3':
mf_button.setBackgroundResource(R.color.game2_f_on);
//mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
//mFMediaPlayer.start();
//mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// @Override
// public void onCompletion(MediaPlayer mp) {
// mFMediaPlayer.release();
// }
//});
break;
}
}
音频播放被评论,但过去工作得很好。这实际上是关于那些 SetBackgroundResource 调用的全部内容,它们不会立即执行,而只会在 CreateSequence 方法中的 for 循环结束时执行。
如果有人想在 Android Studio 中实现整个项目(不推荐,因为它可能有很多 bug),这里是 (25 MB):http://www.mediafire.com/file/2c86sbe3rkb231d/AudiogamesSuite.zip
提前致谢
----------------------------------------------- --------------------------------
编辑 - 感谢 Martin Pfeffer 和一些谷歌搜索,设法解决了这个问题。这是更新的代码
private void createSequence(final int i) {
Thread t = new Thread(new Runnable() {
public void run() {
Random rand = new Random();
for (int j = 0; j < i; j++) {
final int seed = rand.nextInt(4);
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
temp.add(seed);
playButton(seed);
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.setDaemon(true);
t.start();
}
【问题讨论】:
-
为什么不直接使用
switch(i)? -
我不能使用整数作为参数,我认为这是解决它的最简单方法:)
-
你只需要说 case 1 而不是 case '1'
-
应该在我的编程课上多加注意。谢谢大佬!
标签: java android xml android-layout