简体   繁体   English

LibGDX在游戏中暂停图像

[英]LibGDX pause image in game

i am new to libgdx and i have tried several ways to adding pause function and image. 我是libgdx的新手,我尝试了几种添加暂停功能和图像的方法。 Can anyone correct my mistakes? 谁能纠正我的错误? i am stuck 我被困住了

package com.badlogic.drop;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;

public class GameScreen implements Screen {
final Drop game;

Texture dropImage;
Texture bucketImage;
Texture pauseImage;
Sound dropSound;
Music rainMusic;
OrthographicCamera camera;
Rectangle bucket;
Rectangle pause;
Array<Rectangle> raindrops;
long lastDropTime;
int dropsGathered;

public GameScreen(final Drop gam) {
    this.game = gam;

    // load the images for the droplet and the bucket, 64x64 pixels each
    dropImage = new Texture(Gdx.files.internal("droplet.png"));
    bucketImage = new Texture(Gdx.files.internal("bucket.png"));
    pauseImage = new Texture(Gdx.files.internal("pause.png"));
    // load the drop sound effect and the rain background "music"
    dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
    rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
    rainMusic.setLooping(true);

    // create the camera and the SpriteBatch
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);

    // create a Rectangle to logically represent the bucket
    bucket = new Rectangle();
    bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
    bucket.y = 20; // bottom left corner of the bucket is 20 pixels above
    // the bottom screen edge
    bucket.width = 64;
    bucket.height = 64;

    pause = new Rectangle();
    pause.x =700;
    pause.y =380;
    pause.width = 64;
    pause.height = 64;

    // create the raindrops array and spawn the first raindrop
    raindrops = new Array<Rectangle>();
    spawnRaindrop();
}

private void spawnRaindrop() {
    Rectangle raindrop = new Rectangle();
    raindrop.x = MathUtils.random(0, 800 - 64);
    raindrop.y = 480;
    raindrop.width = 64;
    raindrop.height = 64;
    raindrops.add(raindrop);
    lastDropTime = TimeUtils.nanoTime();
}

public enum State{Running,Paused}
State state = State.Running;
@Override
public void render(float delta) {
    switch(state) {
        case Running:
            update();
            break;
        case Paused:
            Gdx.graphics.setContinuousRendering(false);
            break;
    }
    draw();
}
public void update(){
    Gdx.graphics.requestRendering();
}
public void draw(){// clear the screen with a dark blue color. The
    // arguments to glClearColor are the red, green
    // blue and alpha component in the range [0,1]
    // of the color to be used to clear the screen.
    Gdx.gl.glClearColor(0, 0, 0.2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // tell the camera to update its matrices.
    camera.update();

    // tell the SpriteBatch to render in the
    // coordinate system specified by the camera.
    game.batch.setProjectionMatrix(camera.combined);

    // begin a new batch and draw the bucket and
    // all drops
    game.batch.begin();
    game.font.draw(game.batch, "Drops Collected: " + dropsGathered, 0, 480);
    game.batch.draw(bucketImage, bucket.x, bucket.y);
    game.batch.draw(pauseImage, pause.x, pause.y);
    for (Rectangle raindrop : raindrops) {
        game.batch.draw(dropImage, raindrop.x, raindrop.y);
    }
    game.batch.end();

How to code the button into game` 如何将按钮编码为游戏`

    // process user input
    if (Gdx.input.isTouched()) {
        Vector3 touchPos = new Vector3();
        touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
        camera.unproject(touchPos);
        bucket.x = touchPos.x - 64 / 2;
    }
    if (Gdx.input.isKeyPressed(Keys.LEFT))
        bucket.x -= 200 * Gdx.graphics.getDeltaTime();
    if (Gdx.input.isKeyPressed(Keys.RIGHT))
        bucket.x += 200 * Gdx.graphics.getDeltaTime();

    // make sure the bucket stays within the screen bounds
    if (bucket.x < 0)
        bucket.x = 0;
    if (bucket.x > 800 - 64)
        bucket.x = 800 - 64;

    // check if we need to create a new raindrop
    if (TimeUtils.nanoTime() - lastDropTime > 1000000000)
        spawnRaindrop();

    // move the raindrops, remove any that are beneath the bottom edge of
    // the screen or that hit the bucket. In the later case we play back
    // a sound effect as well.
    Iterator<Rectangle> iter = raindrops.iterator();
    while (iter.hasNext()) {
        Rectangle raindrop = iter.next();
        raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
        if (raindrop.y + 64 < 0)
            iter.remove();
        if (raindrop.overlaps(bucket)) {
            dropsGathered++;
            dropSound.play();
            iter.remove();
        }
    }}   

@Override
public void hide() {
}

@Override
public void pause() {
}

@Override
public void resume() {
}  

CRY

There are several improvements to be made. 有几项改进。

Pausing the game 暂停游戏

It is common practise to create a new method called update , where you can dump all logic inside of (like moving the textures). 通常的做法是创建一个名为update的新方法,您可以在其中转储其中的所有逻辑(例如移动纹理)。 You call this method from your render loop. 您可以从render循环调用此方法。 If you wouldn't call this method if the game is paused. 如果游戏暂停,则不会调用此方法。

I see you've already done this. 我知道您已经做到了。 You do not need to call any of those setContinuousRendering methods. 您不需要调用任何这些setContinuousRendering方法。 Your statemachine should work. 您的状态机应该工作。 You could also opt to just use a boolean ( isPaused for example). 您也可以选择仅使用布尔值(例如isPaused )。

I haven't seen a method to set the state to Paused, so I don't know how you want to test your pause system. 我还没有看到将状态设置为“已暂停”的方法,所以我不知道您如何测试暂停系统。 You'll have to make a button or use console input or just pause immediately to test it. 您必须按下一个按钮或使用控制台输入,或者只是立即暂停以对其进行测试。

Sprites 精灵

I recommend you use Sprites instead of manually creating rectangles with textures, it makes your life a lot easier. 我建议您使用Sprites而不是使用纹理手动创建矩形,这样会使您的生活变得更加轻松。 Sprites are basically textures + rectangles and some rendering code. 精灵基本上是纹理+矩形和一些渲染代码。

Performance 性能

I would call Gdx.graphics.getDeltaTime() once, then save the return value inside a variable. 我将一次调用Gdx.graphics.getDeltaTime() ,然后将返回值保存在变量中。 This way the method doesn't get called for everything you need the value for. 这样,就不会为您需要的所有值调用该方法。

You use TimeUtils.nanoTime() . 您使用TimeUtils.nanoTime() I personally use Java's System.currentTimeMillis() , since it is a 100x higher value. 我个人使用Java的System.currentTimeMillis() ,因为它的值高100倍。 This way you don't have to type all those zeroes. 这样,您不必键入所有零。

The render method gets called automatically because you are using Scene2D. 由于使用的是Scene2D,因此将自动调用render方法。 It has a parameter called delta. 它具有称为delta的参数。 You can use this variable instead of manually making one. 您可以使用此变量,而不是手动创建一个。 Just change your update() method to update(float delta) and pass the variable. 只需将update()方法更改为update(float delta)并传递变量即可。

In your draw method, you update the camera. draw方法中,更新相机。 If you don't move the camera, this is redundant. 如果您不移动相机,这是多余的。

Good luck with your game! 祝您比赛顺利!

Edit : I misread your question. 编辑 :我误读了你的问题。 You can use Scene2D to create a button. 您可以使用Scene2D创建一个按钮。 This button will fire an event you can use to set the Paused state. 此按钮将触发一个事件,您可以使用该事件来设置“暂停”状态。 You are creating your game inside of a Screen, you should use a Stage instead. 您要在屏幕内创建游戏,而应该使用舞台。 Look up some more about Scene2D. 查找有关Scene2D的更多信息。

Edit 2 : Formatting 编辑2 :格式化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM