作为Audiogames套件应用程序的一部分,我在Android中为一个uni项目实现了Simon Says。我试图生成一个随机序列5(就像一个开始测试)按钮播放,除了一件事情之外它一切顺利:按钮不应该亮起来(当他们的时候生成序列中的种子)但是在生成结束时它们会一起点亮。
遵循我的Java和XML的完整代码(这是一个混乱和不完整的代码,所以我会指出那些令我不安的部分)
Java Source
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>
所以基本上我要做的就是通过点击按钮&#34;开始&#34;来生成序列。这里是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中实现整个项目(不推荐,因为它可能非常错误),这里是(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();
}
答案 0 :(得分:1)
将synchronized
说明符添加到方法中。
击>
private synchronized void createSequence(int i) {
// allow only one thread to be executed
}
击> <击> 撞击> 修改:
刚看到你没有使用单独的线程..所以运行此代码以获得延迟:
new Handler().postDelayed(new Runnable(){
public void run() {
// do stuff
}}, 1000 * DELAY_IN_SECONDS);
编辑2:
我认为你正在寻找这样的东西:
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import java.util.concurrent.Callable;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread((TextView) findViewById(R.id.textView)).start();
}
class MyThread extends Thread implements Runnable {
TextView textView;
MyThread(TextView textView) {
this.textView = textView;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnMainUiThread(new Callable() {
@Override
public Object call() throws Exception {
textView.setText("" + System.currentTimeMillis());
return null;
}
});
}
}
void runOnMainUiThread(final Callable callable) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
callable.call();
} catch (Exception e) {
Log.e("MyThread", "runOnMainUiThread: ", e);
}
}
});
}
}
}
如果您有任何疑问,请随时问:)