遵循路径游戏说明:
在此游戏中,屏幕上有一些不可见的正方形(在我们的案例中为9),它们的随机序列开始出现在屏幕上(此处我们仅显示4)。并且用户必须按照屏幕上显示的顺序选择正方形。
有什么问题?
1.在显示过程中,不允许用户选择正方形。我可以禁用按钮,但是如何在计时器结束后启用它们?我找不到postLaunch或timerCanceled事件来再次启用按钮进行选择吗?
2.用户玩完游戏后,游戏应在1秒内自动重新开始。如果我在setBackgroundColor()之后使用Thread.sleep(1000),它将给我1秒,但忽略setBackground()。我希望用户在游戏重置之前看到错误的答案(背景颜色不正确)。
代码:
// allSquares, generatedSquares,generationSpeed can be used to change game difficulty
int allSquares = 9;
int generatedSquares = 4;
int generationSpeed = 500;
Button[] buttons = new Button[allSquares];
@IdRes
int[] ids = {R.id.b1, R.id.b2, R.id.b3, R.id.b4, R.id.b5, R.id.b6, R.id.b7, R.id.b8, R.id.b9};
Button bGenerate;
List<Integer> randomOrder;
int selectedSquare = 0;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bGenerate = findViewById(R.id.bGenerate);
bGenerate.setOnClickListener(this);
}
private void runAlgorithm()
{
// initiate + invisible all squares
for (int i = 0; i < allSquares; i++)
{
buttons[i] = findViewById(ids[i]);
buttons[i].setAlpha(0.0f);
buttons[i].setOnClickListener(this);
buttons[i].setBackgroundColor(getResources().getColor(R.color.squareColor));
buttons[i].setEnabled(false);
}
// generate random sequence
randomOrder = new ArrayList<>();
randomOrder.clear();
Random random = new Random();
while (randomOrder.size() < generatedSquares)
{
int generatedNumber = random.nextInt(allSquares);
if (!randomOrder.contains(generatedNumber))
{
randomOrder.add(generatedNumber);
Log.i("FollowThePath", generatedNumber + "");
}
}
// show random sequence by order
final int[] counter = {0};
selectedSquare = 0;
final Timer timer = new Timer();
timer.schedule(new TimerTask()
{
@Override
public void run()
{
buttons[randomOrder.get(counter[0])].setAlpha(1.0f);
counter[0]++;
if (counter[0] == generatedSquares)
{
timer.cancel();
}
}
}, 0, generationSpeed);
// Bug 1: need to enable buttons after timer finishes, user should not be allowed to choose a square during square reveal
}
@Override
public void onClick(View v)
{
if (v.getId() == R.id.bGenerate)
runAlgorithm();
else
{
Log.i("FollowThePath", v.getTag().toString() + " " + randomOrder.get(selectedSquare));
if (v.getTag().toString().equals(randomOrder.get(selectedSquare).toString()))
{
v.setBackgroundColor(getResources().getColor(R.color.correctColor));
v.setEnabled(false);
selectedSquare++;
} else
{
// Game Over
Toast.makeText(this, "You failed.", Toast.LENGTH_SHORT).show();
// Bug: setBackground executes so fast
v.setBackgroundColor(getResources().getColor(R.color.incorrectColor));
// Bug 2: we need a delay here, so that user sees the incorrect color and gets ready for next game
// Thread.sleep(1000) ignores the color change, it means user can't see incorrectColor even if i add a Thread.sleep after that
// starting a new game
runAlgorithm();
}
if (selectedSquare == generatedSquares)
{
// Succeeded
// Toast.makeText(this,"You did it.",Toast.LENGTH_SHORT).show();
// run a new game
runAlgorithm();
}
}
}
private void enableAllButtons(boolean enable)
{
for (int i = 0; i < allSquares; i++)
{
buttons[i].setEnabled(enable);
}
}
答案 0 :(得分:1)
要解决您的第一个问题,由于完成TimerTask
的唯一方法是根据条件counter[0] == generatedSquares
取消@Override
public void run() {
buttons[randomOrder.get(counter[0])].setAlpha(1.0f);
counter[0]++;
if (counter[0] == generatedSquares)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
enableAllButtons(true);
}
});
timer.cancel();
}
}
,因此您要做的就是这样:>
Thread.sleep(1000)
对于第二个问题,可能不会显示颜色变化,因为重新启动算法开始得太快,并且所有这些都在UI线程上,因此使用runAlgorithm()
并没有帮助。尝试将Handler handler = new Handler();
Runnable r = new Runnable()
{
public void run()
{
//what ever you do here will be done after 500 mili seconds delay.
runAlgorithm();
}
};
handler.postDelayed(r, 500);
调用包装为以下内容:
{{1}}
希望该方法能正常工作,因为我无法对其进行测试。