将currentTime保存一段时间(AndroidStudio / libgdx

时间:2017-01-23 16:16:13

标签: java android time timer libgdx

我目前正在使用FlappyBird风格的Android Studio编写游戏。我有两个冷却时间,可以让用户使用额外的能力。

在主游戏视图中,您可以看到2个灰色图像和一个计时器。计时器从10变为0,当达到零时,数字消失,图像变亮,用户知道他能够在暂停屏幕中激活该功能。

问题:

当游戏开始时,计时器也会启动并按我的意愿停机。但是如果用户进入暂停菜单,定时器应该停止,如果他离开,定时器应该再次运行。

我有一个

long startTime = 0;

long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;

一切正常,但我无法长时间保存当前时间,也无法找到任何功能!

我知道代码很长但是重要的部分是在if语句GameState.Running中的drawWorld()方法中。

public class PlaneGame extends ApplicationAdapter{
private static final float PLANE_JUMP_IMPULSE = 350;
private static final float GRAVITY = -20;
private static final float PLANE_VELOCITY_X = 200;
private static final float PLANE_START_Y = 240;
private static final float PLANE_START_X = 50;
private static final int STATE_START = 0;
private static final int STATE_RUNNING = 1;
private static final int STATE_OVER = 2;

SpriteBatch batch;
OrthographicCamera camera;
OrthographicCamera uiCamera;
Texture background;
TextureRegion ground;
float groundOffsetX = 0;
TextureRegion ceiling;
TextureRegion rock;
TextureRegion rockDown;
TextureRegion planeSmall;
TextureRegion planeSmallBlack;
Animation plane;
TextureRegion ready;
TextureRegion gameOver;
TextureRegion pause;
BitmapFont font;

Vector2 planePosition = new Vector2();
Vector2 planeVelocity = new Vector2();
float planeStateTime = 0;
Vector2 gravity = new Vector2();
Array<Rock> rocks = new Array<Rock>();

GameState gameState = GameState.Start;          /*neeeeeeewwwww*/
int score = 0;
long startTime = 0;
long startTime2;
long elapsedTime;
long savedTime;
boolean wantToSeeTime = true;
boolean wantToSeeTimePause = true;
float timeCdRock = 0;
float timeCdPlane = 0;
Rectangle rect1 = new Rectangle();
Rectangle rect2 = new Rectangle();

Music music;
Sound point;
Sound explode;

//this gets called repeatedly to run the game
@Override
public void render () {
    //clear the screen so we can draw the next one
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    long saveTime = elapsedTime;
    //update the position of the plane and rocks
    updateWorld();
    elapsedTime = saveTime;
    //now draw the updated screen
    drawWorld();
}

//initialize objects and load assets when game starts
@Override

public void create () {
    startTime = TimeUtils.nanoTime();                                                       /*Neeeewwwwwwwww !!!*/
    Gdx.input.setInputProcessor(new GestureDetector(new MyGestureListener()));
    batch = new SpriteBatch();
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);
    uiCamera = new OrthographicCamera();
    uiCamera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    uiCamera.update();

    font = new BitmapFont(Gdx.files.internal("arial.fnt"));

    background = new Texture("background.png"); 
    ground = new TextureRegion(new Texture("ground.png"));
    ceiling = new TextureRegion(ground);
    ceiling.flip(true, true);

    rock = new TextureRegion(new Texture("rock.png"));
    rockDown = new TextureRegion(rock);
    rockDown.flip(false, true);

    Texture frame1 = new Texture("plane1.png");
    frame1.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    Texture frame2 = new Texture("plane2.png");
    Texture frame3 = new Texture("plane3.png");

    planeSmall = new TextureRegion(new Texture("planeSmall.png"));
    planeSmallBlack = new TextureRegion(new Texture("planeSmallBlack.png"));

    ready = new TextureRegion(new Texture("ready.png"));
    gameOver = new TextureRegion(new Texture("gameover.png"));
    pause = new TextureRegion(new Texture("pause.png"));

    plane = new Animation(0.05f, new TextureRegion(frame1), new TextureRegion(frame2), new TextureRegion(frame3), new TextureRegion(frame2));
    plane.setPlayMode(PlayMode.LOOP);

    music = Gdx.audio.newMusic(Gdx.files.internal("music.mp3"));
    music.setLooping(true);
    music.play();

    point = Gdx.audio.newSound(Gdx.files.internal("point.ogg"));
    explode = Gdx.audio.newSound(Gdx.files.internal("explode.wav"));

    resetWorld();
}

//reset the state of the game
private void resetWorld() {
    score = 0;
    startTime = 0;
    groundOffsetX = 0;
    planePosition.set(PLANE_START_X, PLANE_START_Y);
    planeVelocity.set(0, 0);
    gravity.set(0, GRAVITY);
    camera.position.x = 400;

    //randomize the position and direction of the rocks
    rocks.clear();
    for(int i = 0; i < 5; i++) {
        boolean isDown = MathUtils.randomBoolean();
        rocks.add(new Rock(700 + i * 200, isDown?480-rock.getRegionHeight(): 0, isDown? rockDown: rock));
    }
}

//use the time elapsed since the last call to render() to determine how much to update the game
private void updateWorld() {

    float deltaTime = Gdx.graphics.getDeltaTime();
    planeStateTime += deltaTime;

    /*if(Gdx.input.justTouched()) {
        if(gameState == STATE_START) {
            gameState = STATE_RUNNING;
        }
        if(gameState == STATE_RUNNING) {
            planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
        }
        if(gameState == STATE_OVER) {
            gameState = STATE_START;
            resetWorld();
        }
    }*/

    if(gameState != GameState.Start) planeVelocity.add(gravity);

    planePosition.mulAdd(planeVelocity, deltaTime);

    camera.position.x = planePosition.x + 350;      
    if(camera.position.x - groundOffsetX > ground.getRegionWidth() + 400) {
        groundOffsetX += ground.getRegionWidth();
    }

    rect1.set(planePosition.x + 20, planePosition.y, plane.getKeyFrames()[0].getRegionWidth() - 20, plane.getKeyFrames()[0].getRegionHeight());
    for(Rock r: rocks) {
        //if the rock is off the screen, give it a new location in front of the plane
        if(camera.position.x - r.position.x > 400 + r.image.getRegionWidth()) {
            boolean isDown = MathUtils.randomBoolean();
            r.position.x += 5 * 200;
            r.position.y = isDown?480-rock.getRegionHeight(): 0;
            r.image = isDown? rockDown: rock;
            r.counted = false;
        }
        rect2.set(r.position.x + (r.image.getRegionWidth() - 30) / 2 + 20, r.position.y, 20, r.image.getRegionHeight() - 10);

        //check if the plane crashed
        if(rect1.overlaps(rect2)) {
            if(gameState != GameState.GameOver) explode.play();
            gameState = GameState.GameOver;
            planeVelocity.x = 0;                
        }

        //award a point for not crashing into a rock
        if(r.position.x < planePosition.x && !r.counted) {
            score++;
            r.counted = true;
            point.play();
        }
    }

    //check if the plane crashed
    if(planePosition.y < ground.getRegionHeight() - 20 || 
        planePosition.y + plane.getKeyFrames()[0].getRegionHeight() > 480 - ground.getRegionHeight() + 20) {
        if(gameState != GameState.GameOver) explode.play();
        gameState = GameState.GameOver;
        planeVelocity.x = 0;
    }       
}

//draw the background, rocks, and plane to the screen and possibly some ui text
private void drawWorld() {
    elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
    camera.update();
    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(background, camera.position.x - background.getWidth() / 2, 0);
    for(Rock rock: rocks) {
        batch.draw(rock.image, rock.position.x, rock.position.y);
    }
    batch.draw(ground, groundOffsetX, 0);
    batch.draw(ground, groundOffsetX + ground.getRegionWidth(), 0);
    batch.draw(ceiling, groundOffsetX, 480 - ceiling.getRegionHeight());
    batch.draw(ceiling, groundOffsetX + ceiling.getRegionWidth(), 480 - ceiling.getRegionHeight());
    batch.draw(plane.getKeyFrame(planeStateTime), planePosition.x, planePosition.y);
    batch.end();

    batch.setProjectionMatrix(uiCamera.combined);
    batch.begin();
    if(gameState == GameState.Start) {
        batch.draw(ready, Gdx.graphics.getWidth() / 2 - ready.getRegionWidth() / 2, Gdx.graphics.getHeight() / 2 - ready.getRegionHeight() / 2);
    }
    if(gameState == GameState.GameOver) {
        batch.draw(gameOver, Gdx.graphics.getWidth() / 2 - gameOver.getRegionWidth() / 2, Gdx.graphics.getHeight() / 2 - gameOver.getRegionHeight() / 2);
    }
    if(gameState == GameState.GameOver || gameState == GameState.Running) {
        font.draw(batch, "" + score, Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() - 60);
    }
    if(gameState == GameState.Running || gameState == GameState.Pause) {
        //font.draw(batch, "" + (10 - elapsedTime), (Gdx.graphics.getWidth() / 2) / 3, Gdx.graphics.getHeight() - 260);
        if(wantToSeeTime){
            font.draw(batch, "" + (5 - elapsedTime), (Gdx.graphics.getWidth() / 2) / 3, Gdx.graphics.getHeight() - 260);
        }
        if((5 -(elapsedTime) > 0)) {
            batch.draw(planeSmallBlack, (Gdx.graphics.getWidth() / 2) / 3, Gdx.graphics.getHeight() - 250);
        }else  {
            batch.draw(planeSmall, (Gdx.graphics.getWidth() / 2) / 3, Gdx.graphics.getHeight() - 250);
            wantToSeeTime = false;
        }
    }
    if(gameState == GameState.Pause){
        batch.draw(pause, Gdx.graphics.getWidth() / 2 - pause.getRegionWidth() / 2, Gdx.graphics.getHeight() / 2 - pause.getRegionHeight() / 2);
        if(wantToSeeTimePause){
            font.draw(batch, "" + (savedTime), (Gdx.graphics.getWidth() / 2) / 3, Gdx.graphics.getHeight() - 260);
        }
    }
    batch.end();
}


//object to hold all pertinent information for a rock
static class Rock {
    Vector2 position = new Vector2();
    TextureRegion image;
    boolean counted;

    public Rock(float x, float y, TextureRegion image) {
        this.position.x = x;
        this.position.y = y;
        this.image = image;
    }
}

                            // Neeeeeeeewwwww
static enum GameState {
    Start, Running, GameOver, Pause
}

private class MyGestureListener implements GestureDetector.GestureListener {

    @Override
    public boolean touchDown(float x, float y, int pointer, int button) {
        return false;
    }

    @Override
    public boolean tap(float x, float y, int count, int button) {
        if(gameState == GameState.Start) {
            gameState = GameState.Running;
            startTime = System.currentTimeMillis();
        }
        if(gameState == GameState.Running) {
            planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
        }
        if(gameState == GameState.GameOver) {
            gameState = GameState.Start;
            resetWorld();
        }
        /*if((gameState == GameState.Pause) && (count == 2)) {
            planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
            gravity.set(0,GRAVITY);
            gameState = GameState.Running;

        }*/
        return true;
    }

    @Override
    public boolean longPress(float x, float y) {

        return false;
    }

    @Override
    public boolean fling(float velocityX, float velocityY, int button) {
        if(gameState == GameState.Running) {
            planePosition.set(planePosition.x, planePosition.y);
            planeVelocity.set(0,0);
            gravity.set(0, 0);
            savedTime = System.currentTimeMillis() / 1000;
            wantToSeeTime = false;
            wantToSeeTimePause = true;
            gameState = GameState.Pause;



        } else {
            planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
            gravity.set(0,GRAVITY);
            wantToSeeTime = true;
            wantToSeeTimePause = false;
            elapsedTime -= savedTime;
            gameState = GameState.Running;


        }

        /*if(gameState == GameState.Pause) {
            planeVelocity.set(PLANE_VELOCITY_X, PLANE_JUMP_IMPULSE);
            gravity.set(0,GRAVITY);
            gameState = GameState.Running;
        }*/

        return true;
    }

    @Override
    public boolean pan(float x, float y, float deltaX, float deltaY) {
        return false;
    }

    @Override
    public boolean panStop(float x, float y, int pointer, int button) {
        return false;
    }

    @Override
    public boolean zoom(float initialDistance, float distance) {
        return false;
    }

    @Override
    public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
        return false;
    }


    public void pinchStop() {

    }
}

}

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您可以使用joda时间进行高级操作 请查看链接以供参考 http://www.joda.org/joda-time/userguide.html

答案 1 :(得分:0)

我将假设您的游戏作为循环的一部分运行。理想情况下,您应该拥有的是激活该能力的开始时间,该时间根据自上次循环迭代后经过的时间在冷却期间倒计时。例如,对于具有10秒冷却时间的能力:

final long abilityLength = 10 * 1000;
long cooldownRemaining = 0;
long lastTimestamp;
boolean isPaused = false;

private void doAbility() {
    if (cooldownRemaining <= 0) {
        cooldownRemaining = abilityLength;
    }
}

public void main(int[] args) {
    lastTimestamp = System.currentTimeMillis();

    while(true) { // your main game loop

        // Time (in ms) elapsed since the last iteration of this loop
        long delta = System.currentTimeMillis() - lastTimestamp;

        ... // Other game code

        if (cooldownRemaining > 0 && !isPaused) {
            // Subtract the delta from the remaing cooldown time.
            cooldownRemaining -= delta;
        }

        lastTimeStamp = System.currentTimeMillis();
    }
}