我正在开发一款简单的Android游戏。
按下播放时,计时器从30开始倒计时,一旦计时器达到零,我想调用函数goToGameOver()。我似乎无法使Handler正常工作,所以我尝试了标准的Timer类,它甚至不接近实时。
此外,当计时器倒计时时,我想每秒将剩余时间传递给全局变量x,这样我就可以用单独的方法将它绘制到屏幕上。
关于我如何最好地接近这个的任何想法?谢谢!
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
x = millisUntilFinished / 1000;
}
public void onFinish() {
goToGameOver();
} }.start();
编辑:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import com.name.framework.Game;
import com.name.framework.Graphics;
import com.name.framework.Image;
import com.name.framework.Input.TouchEvent;
import com.name.framework.Screen;
// Creates live game screen
public class GameScreen extends Screen {
enum GameState {
Running, Paused, GameOver
}
GameState state = GameState.Running;
// Instance variables
Random r = new Random();
int z = r.nextInt(16);
private int score = 0;
int count = 0;
private Runnable run;
public GameScreen(Game game) {
super(game);
Assets.paint = new Paint();
Assets.paint.setTextSize(30);
Assets.paint.setTextAlign(Paint.Align.LEFT);
Assets.paint.setAntiAlias(true);
Assets.paint.setColor(Color.BLACK);
}
// Check if touch coordinates fall in certain range
private boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
if (event.x > x && event.x < x + width - 1 && event.y > y && event.y < y + height - 1)
return true;
else
return false;
}
@Override
public void update(float deltaTime) {
List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
// Call appropriate update method based on game state
if (state == GameState.Running)
updateRunning(touchEvents, deltaTime);
if (state == GameState.Paused)
updatePaused(touchEvents);
if (state == GameState.GameOver)
updateGameOver(touchEvents);
}
// Responds to in-game interaction
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
final Handler hand = new Handler();
run = new Runnable() {
@Override
public void run() {
if(count == 30) { //will end if count reach 30 which means 30 second
goToMenu();
}
else
{
count += 1; //add 1 every second
hand.postDelayed(run, 1000); //will call the runnable after 1 second
}
}
};
hand.postDelayed(run, 1000);
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = (TouchEvent) touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN) {
switch(z) {
// Blue is correct
case 0:
case 1:
case 2:
case 3:
if (inBounds(event, 125, 150, 250, 100)) {
Assets.pop.play(0.8f);
score += 1;
z = r.nextInt(16); }
else if (inBounds(event, 425, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 125, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
break;
// Green is correct
case 4:
case 5:
case 6:
case 7:
if (inBounds(event, 125, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 150, 250, 100)) {
Assets.pop.play(0.8f);
score += 1;
z = r.nextInt(16); }
else if (inBounds(event, 125, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
break;
// Red is correct
case 8:
case 9:
case 10:
case 11:
if (inBounds(event, 125, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 125, 300, 250, 100)) {
Assets.pop.play(0.8f);
score += 1;
z = r.nextInt(16); }
else if (inBounds(event, 425, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
break;
// Yellow is correct
case 12:
case 13:
case 14:
case 15:
if (inBounds(event, 125, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 150, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 125, 300, 250, 100)) {
Assets.bad.play(0.8f);
score -= 5;
z = r.nextInt(16); }
else if (inBounds(event, 425, 300, 250, 100)) {
Assets.pop.play(0.8f);
score += 1;
z = r.nextInt(16); }
break;
}
// Pause button
if (inBounds(event, 750, 0, 50, 50)) {
Assets.pop.play(0.8f);
Assets.theme.pause();
state = GameState.Paused;
}
}
// Prevents score from becoming negative
if (score < 0) {
score = 0;
}
}
}
// Responds to pause menu interaction
private void updatePaused(List<TouchEvent> touchEvents) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_UP) {
// Resume button
if (inBounds(event, 125, 150, 250, 100)) {
Assets.pop.play(0.8f);
Assets.theme.play();
state = GameState.Running; }
// Restart button
else if (inBounds(event, 425, 150, 250, 100)) {
Assets.pop.play(0.8f);
Assets.theme.play();
nullify();
state = GameState.Running; }
// Mute button
else if (inBounds(event, 125, 300, 250, 100)) {
Assets.pop.play(0.8f);
}
// Menu button
else if (inBounds(event, 425, 300, 250, 100)) {
Assets.pop.play(0.8f);
//Assets.theme.seekBegin(); // not sure if I should do this
Assets.theme.play();
nullify();
goToMenu(); }
}
}
}
// Responds to game over interaction
private void updateGameOver(List<TouchEvent> touchEvents) {
}
@Override
public void paint(float deltaTime) {
Graphics g = game.getGraphics();
g.clearScreen(16777215);
g.drawImage(Assets.score, 20, 430);
g.drawImage(Assets.blue, 125, 150);
g.drawImage(Assets.green, 425, 150);
g.drawImage(Assets.red, 125, 300);
g.drawImage(Assets.yellow, 425, 300);
g.drawString(""+ score, 135, 465, Assets.paint);
//g.drawString(""+x, 750, 430, Assets.paint);
// Adds text to array and draws random one
ArrayList<Image> colors = new ArrayList<Image>();
colors.add(Assets.blueInBlue);
colors.add(Assets.blueInGreen);
colors.add(Assets.blueInRed);
colors.add(Assets.blueInYellow);
colors.add(Assets.greenInBlue);
colors.add(Assets.greenInGreen);
colors.add(Assets.greenInRed);
colors.add(Assets.greenInYellow);
colors.add(Assets.redInBlue);
colors.add(Assets.redInGreen);
colors.add(Assets.redInRed);
colors.add(Assets.redInYellow);
colors.add(Assets.yellowInBlue);
colors.add(Assets.yellowInGreen);
colors.add(Assets.yellowInRed);
colors.add(Assets.yellowInYellow);
if (state == GameState.Running) {
g.drawImage(colors.get(z), 0, 0);
}
// Calls the appropriate function to draw the UI based on game state
if (state == GameState.Running)
drawRunningUI();
if (state == GameState.Paused)
drawPausedUI();
if (state == GameState.GameOver)
drawGameOverUI();
}
// Draws in-game UI
private void drawRunningUI() {
Graphics g = game.getGraphics();
g.drawImage(Assets.pause, 750, 0);
}
// Draws pause menu UI
private void drawPausedUI() {
Graphics g = game.getGraphics();
g.drawARGB(155, 0, 0, 0);
g.drawImage(Assets.paused, 0, 0);
g.drawImage(Assets.resume, 125, 150);
g.drawImage(Assets.restart, 425, 150);
g.drawImage(Assets.mute, 125, 300);
g.drawImage(Assets.returnToMenu, 425, 300);
}
// Draws game over UI
private void drawGameOverUI() {
}
// Pause function
@Override
public void pause() {
if (state == GameState.Running)
state = GameState.Paused;
}
// Resume function
@Override
public void resume() {
if (state == GameState.Paused)
state = GameState.Running;
}
@Override
public void backButton() {
pause();
}
private void goToGameOver() {
game.setScreen(new MainMenuScreen(game));
}
// Resets timer and score
private void nullify() {
score = 0;
// Calls garbage collector to clean up memory
System.gc();
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
}
答案 0 :(得分:1)
即使你说过你已经尝试过,我也建议handler
,但我认为你没有正确实现它。
这是实施,它在我的工作中很有用。
final Handler hand = new Handler();
run = new Runnable() {
@Override
public void run() {
if(count == 30) { //will end if count reach 30 which means 30 second
goToGameOver();
}
else
{
count += 1; //add 1 every second
hand.postDelayed(run, 1000); //will call the runnable after 1 second
}
}
};
hand.postDelayed(run, 1000);
确保count
和handler
为global fields
。