Hallo, ich habe folgendes Problem: Ich habe ein kleines Android-Spiel, das in runden unterteilt ist. Jede runde dauert 60 Sekunden. In der ersten Runde dauert die Runde auch wirklich 60 Sekunden. Die zweite Runde läuft aber doppelt so schnell, obwohl sie auch nur 60 Sekunden dauern sollte. Das Zeitintervall ist in einer final-Variable gespeichert, kann also nicht verändert werden. Der Code sieht folgendermaßen aus:
Warum wird die run()-Methode nun also in der zweiten runde doppelt so schnell aufgerufen?
Java:
import java.util.Date;
import java.util.Random;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class GameActivity extends Activity implements Runnable, OnClickListener {
private static final long INTERVAL = 100L;
private static final int MAX_TIME = 600;
private static final long MOSQUITO_EXISTING_TIME = 2000;
private static final String ELEPHANT = "elephant";
private Random random = new Random();
private Handler handler;
private FrameLayout gameSpace;
private boolean running;
private int gameSpaceWidth;
private int gameSpaceHeight;
private int round;
private int score;
private int mosquitosNeeded;
private int mosquitosCatched;
private int mosquitosLeft;
private int timeLeft;
private float scale;
private TextView tvScore;
private TextView tvRound;
private TextView tvHits;
private TextView tvTime;
private FrameLayout flHits;
private LayoutParams lpHits;
private FrameLayout flTime;
private LayoutParams lpTime;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
handler = new Handler();
gameSpace = (FrameLayout) findViewById(R.id.gameSpace);
scale = getResources().getDisplayMetrics().density;
tvScore = (TextView) findViewById(R.id.score);
tvRound = (TextView) findViewById(R.id.round);
tvHits = (TextView) findViewById(R.id.hits);
tvTime = (TextView) findViewById(R.id.time);
flHits = (FrameLayout) findViewById(R.id.bar_hits);
lpHits = flHits.getLayoutParams();
flTime = (FrameLayout) findViewById(R.id.bar_time);
lpTime = flTime.getLayoutParams();
startGame();
}
private void startGame() {
round = 0;
score = 0;
running = true;
startRound();
}
private void startRound() {
round += 1;
mosquitosNeeded = 20 + round * 2;
mosquitosLeft = (int) Math.round(mosquitosNeeded * 1.5);
mosquitosCatched = 0;
mosquitosCatched = 0;
timeLeft = MAX_TIME;
int id = getResources().getIdentifier(
"hintergrund" + Integer.toString(round), "drawable",
this.getPackageName());
if (id > 0) {
LinearLayout l = (LinearLayout) findViewById(R.id.background);
l.setBackgroundResource(id);
}
updateScreen();
handler.postDelayed(this, INTERVAL);
}
private boolean testRoundEnd() {
if (timeLeft == 0) {
startRound();
return true;
}
return false;
}
private boolean testGameEnd() {
if (timeLeft == 0 && mosquitosCatched < mosquitosNeeded) {
gameOver();
return true;
}
return false;
}
private void gameOver() {
Dialog dialog = new Dialog(this,
android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog.setContentView(R.layout.gameover);
dialog.show();
}
@Override
public void run() {
if (running) {
mosquitosCatched++;
try {
handler.postDelayed(this, INTERVAL);
} catch (Throwable t) {
}
timeLeft--;
float randomNumber = random.nextFloat();
double probability = mosquitosLeft * 1.5 / timeLeft;
while (probability > 1) {
showMosquito();
}
if (randomNumber < probability) {
showMosquito();
}
deleteMosquito();
updateScreen();
if (!testGameEnd()) {
testRoundEnd();
}
}
}
private void updateScreen() {
tvScore.setText(Integer.toString(score));
tvRound.setText(Integer.toString(round));
tvHits.setText(Integer.toString(mosquitosCatched));
tvTime.setText(Integer.toString(timeLeft));
lpHits.width = Math
.round(scale * 300
* Math.min(mosquitosCatched, mosquitosNeeded)
/ mosquitosNeeded);
lpTime.width = Math.round(scale * timeLeft * 300 / MAX_TIME);
}
private void showMosquito() {
gameSpaceWidth = gameSpace.getWidth();
gameSpaceHeight = gameSpace.getHeight();
ImageView mosquito = new ImageView(this);
if (random.nextFloat() < 0.05) {
mosquito.setImageResource(R.drawable.elephant);
mosquito.setTag(R.id.animal, "elephant");
} else {
mosquito.setImageResource(R.drawable.mosquito);
mosquito.setTag(R.id.animal, "mosquito");
mosquitosLeft--;
}
mosquito.setTag(R.id.geburtsdatum, new Date());
mosquito.setOnClickListener(this);
int mosquitoWidth = (int) Math.round(scale * 50);
int mosquitoHeight = (int) Math.round(scale * 42);
int links = random.nextInt(gameSpaceWidth - mosquitoWidth);
int oben = random.nextInt(gameSpaceHeight - mosquitoHeight);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
mosquitoWidth, mosquitoHeight);
params.leftMargin = links;
params.topMargin = oben;
params.gravity = Gravity.TOP + Gravity.LEFT;
gameSpace.addView(mosquito, params);
}
private void deleteMosquito() {
gameSpace = (FrameLayout) findViewById(R.id.gameSpace);
int i = 0;
while (i < gameSpace.getChildCount()) {
ImageView muecke = (ImageView) gameSpace.getChildAt(i);
Date geburtsdatum = (Date) muecke.getTag(R.id.geburtsdatum);
long alter = (new Date()).getTime() - geburtsdatum.getTime();
if (alter > MOSQUITO_EXISTING_TIME) {
gameSpace.removeView(muecke);
} else {
i++;
}
}
}
@Override
public void onClick(View mosquito) {
if (mosquito.getTag(R.id.animal) == ELEPHANT) {
score -= 1000;
} else {
mosquitosCatched++;
score += 100;
}
updateScreen();
gameSpace.removeView(mosquito);
}
}