此刻我很困惑。你知道你的应用程序应该工作得很好的感觉,但由于某种原因它不是吗?!
在我的应用程序的PlayState中,我有3个状态,由变量" currentState"定义。
currentState = 0 =正在运行
currentState = 1 =暂停
currentState = 2 =游戏结束
public class PlayState extends State {
public static final int TUBE_SPACING = 420;
private static final int TUBE_COUNT = 4;
public static SpriteBatch batch;
public static Preferences prefs;
private Array<Tube> tubes;
private Array<Coin> coins;
private boolean hasBeenPlayed = false;
private Texture pausemenu, coin, bg, grass, gameover;
private Sound boop, wow, ding;
private Music failed;
private Bird bird;
private Vector2 groundPos1, groundPos2, groundPos3;
private PlayStateButtons pauseButton;
private BitmapFont highScoreFont, coinsFont, font120;
private Viewport viewport;
private int score = 0;
private int gameState;
private boolean tableVisible, restartVisible;
public PlayState(GameStateManager gsm, AssetLoader assets) {
super(gsm, assets);
initFonts();
gameState = 0;
hasBeenPlayed = false;
tableVisible = false;
restartVisible = false;
viewport = new StretchViewport(720, 1280,cam);
viewport.apply();
cam.position.set(cam.viewportWidth / 2, cam.viewportHeight / 2,0);
batch = new SpriteBatch();
bg = assets.manager.get("textures/bg2.png", Texture.class);
pausemenu = assets.manager.get("pausemenu.png", Texture.class);
grass = assets.manager.get("grass.png", Texture.class);
gameover = assets.manager.get("gameover.png", Texture.class);
boop = assets.manager.get("boop.wav", Sound.class);
failed = assets.manager.get("failed.wav", Music.class);
wow = assets.manager.get("wow.wav", Sound.class);
coin = assets.manager.get("coin.png", Texture.class);
ding = assets.manager.get("ding.wav", Sound.class);
prefs = Gdx.app.getPreferences("Bird");
if (!prefs.contains("highScore")) {
prefs.putInteger("highScore", 0);
}
if (!prefs.contains("coins"))
prefs.putInteger("coins", 0);
bird = new Bird(100, 375, assets);
tubes = new Array<Tube>();
coins = new Array<Coin>();
pauseButton = new PlayStateButtons(assets);
for (int i = 1; i <= TUBE_COUNT; i++){
tubes.add(new Tube(i * (TUBE_SPACING + Tube.TUBE_WIDTH),assets));
}
for(int i = 1; i<= 2; i++)
coins.add(new Coin(2 * i * (TUBE_SPACING + Tube.TUBE_WIDTH),assets));
}
public static void setHighScore(int val) {
prefs.putInteger("highScore", val);
prefs.flush();
}
public void addCoin(){
ding.play();
prefs.putInteger("coins", prefs.getInteger("coins") + 1);
prefs.flush();
}
public static int getHighScore() {
return prefs.getInteger("highScore");
}
public int getCoins() { return prefs.getInteger("coins"); }
private void initFonts(){
font120 = assets.manager.get("fonts/myfont.ttf", BitmapFont.class);
highScoreFont = assets.manager.get("fonts/highscore.ttf", BitmapFont.class);
coinsFont = assets.manager.get("fonts/coins.ttf", BitmapFont.class);
}
@Override
public void resize(int width, int height){
viewport.update(width, height);
cam.position.set(cam.viewportWidth / 2, cam.viewportHeight / 2,0);
}
@Override
public void handleInput() {
if (Gdx.input.justTouched() && gameState == 0){
wow.play(0.6f);
bird.jump();
}
if(pauseButton.isPauseButtonPressed() && gameState != 1) {
boop.play(0.9f);
gameState = 1;
bird.die();
}
if(gameState == 2) {
if(pauseButton.isRestartPressed())
gsm.set(new PlayState(gsm, assets));
}
if(gameState == 1) {
if (pauseButton.isResumePressed()) {
boop.play(0.9f);
gameState = 0;
bird.resume();
}
if (pauseButton.isMenuPressed()) {
boop.play(0.9f);
gsm.set(new MenuState(gsm, assets));}
if (pauseButton.isShopPressed()) {
boop.play(0.9f);
gsm.set(new ShopStateFaces(gsm, assets));
}
}
}
@Override
public void update(float dt) {
handleInput();
updateGround();
if(gameState == 0 && tableVisible){
pauseButton.removePauseButtons();
pauseButton.pauseVisible();
tableVisible = false;
}
else if(gameState == 2 && !restartVisible) {
pauseButton.restartVisible();
restartVisible = true;
}
else if(gameState == 1 && !tableVisible) {
pauseButton.restartInvisible();
pauseButton.pauseInvisible();
pauseButton.displayPauseButtons();
tableVisible = true;
}
bird.update(dt);
cam.position.x = bird.getPosition().x + 80;
for(Tube tube : tubes){
if(cam.position.x - cam.viewportWidth / 2 > tube.getPosTopTube().x + TUBE_WIDTH + 300) {
tube.reposition(tube.getPosTopTube().x + (TUBE_WIDTH + TUBE_SPACING) * TUBE_COUNT);
tube.setScored(false);
}
if(tube.collides(bird.getBounds())) {
if(!hasBeenPlayed) {
failed.play();
}
gameState = 2;
bird.die();
if(score > getHighScore())
setHighScore(score);
hasBeenPlayed = true;
return;
}
if (!tube.isScored() && bird.getPosition().x > tube.getPosTopTube().x + TUBE_WIDTH /2 + 300) {
addScore(1);
tube.setScored(true);
}
}
for(Coin coin : coins){
if(cam.position.x - cam.viewportWidth / 2 > coin.getPosCoin().x + 100 + 300){
coin.reposition(coin.getPosCoin().x + (TUBE_WIDTH + TUBE_SPACING) * TUBE_COUNT);
}
if(coin.touches(bird.getBounds())){
addCoin();
coin.reposition(coin.getPosCoin().x + 4 * (TUBE_WIDTH + TUBE_SPACING));
}
}
cam.update();
if (bird.getPosition().y <= grass.getHeight() - 40) {
if(!hasBeenPlayed) {
failed.play();
}
gameState = 2;
bird.die();
if(score > getHighScore())
setHighScore(score);
hasBeenPlayed = true;
}
if(gameState != 2)
failed.stop();
}
public void addScore(int increment) {
score += increment;
}
@Override
public void render(SpriteBatch sb) {
cam.update();
sb.setProjectionMatrix(cam.combined);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
sb.begin();
sb.setColor(Color.WHITE);
sb.draw(bg, cam.position.x - cam.viewportWidth / 2, 0, cam.viewportWidth, cam.viewportHeight);
for(Coin coin : coins){
sb.draw(coin.getCoin(), coin.getPosCoin().x + 300, coin.getPosCoin().y, 100, 100);
}
sb.draw(bird.getTexture(), bird.getPosition().x, bird.getPosition().y, bird.getBounds().getWidth(), bird.getBounds().getHeight());
for (Tube tube : tubes) {
sb.draw(tube.getTopTube(), tube.getPosTopTube().x + 300, tube.getPosTopTube().y, 230, 1660);
sb.draw(tube.getBottomTube(), tube.getPosBotTube().x + 300, tube.getPosBotTube().y, 230, 1660);}
sb.draw(grass, groundPos1.x, groundPos1.y);
sb.draw(grass, groundPos2.x, groundPos2.y);
sb.draw(grass, groundPos3.x, groundPos3.y);
font120.draw(sb, score + "", cam.position.x - 29, cam.viewportHeight - 100, 100, Align.center, false);
String highScore = getHighScore() + "";
String coins = getCoins() + "";
if(gameState == 2){
sb.draw(gameover, cam.position.x - gameover.getWidth() / 2 - 85 , cam.viewportHeight / 2 - gameover.getHeight() / 2, 600 , 500);
highScoreFont.draw(sb, "Highscore: " + highScore, cam.position.x - highScoreFont.getScaleX() / 2 - 250 , cam.viewportHeight - 425, 500, Align.center, true);
coinsFont.draw(sb, coins, cam.position.x - coinsFont.getScaleX() / 2 - 195, cam.viewportHeight - 590, 500, Align.center, true);
sb.draw(coin, cam.position.x - 95, cam.viewportHeight - 660, 90, 90);
}
else if(gameState == 1){
sb.draw(pausemenu, cam.position.x - 315,cam.viewportHeight / 2 - 625 / 2, 625, 625);
}
sb.end();
pauseButton.act();
pauseButton.draw();
}
@Override
public void dispose() {
}
}
我有一个不同的类,我为PlayState类创建了所有按钮,称为PlayStateButtons。
public class PlayStateButtons {
private Viewport viewport;
private Stage stage;
boolean pauseButtonClicked, RestartPressed, shopPressed, resumePressed, menuPressed;
OrthographicCamera cam;
private Table table;
private Button shopButton, menuButton, resumeButton, restartButton, pauseButton;
private Skin pauseButtonSkin, resumeButtonSkin, menuButtonSkin, restartButtonSkin, shopButtonSkin;
public PlayStateButtons(AssetLoader assets){
cam = new OrthographicCamera();
viewport = new StretchViewport(720,1280, cam);
viewport.apply();
stage = new Stage(viewport, PlayState.batch);
Gdx.input.setInputProcessor(stage);
table = new Table();
stage.addActor(table);
Button.ButtonStyle pauseButtonStyle = new Button.ButtonStyle();
pauseButtonSkin = new Skin(assets.manager.get("pauseButton.atlas", TextureAtlas.class));
pauseButtonStyle.up = pauseButtonSkin.getDrawable("pausebutton");
pauseButtonStyle.down = pauseButtonSkin.getDrawable("pausebutton2");
pauseButton = new Button(pauseButtonStyle);
pauseButton.setPosition(55, 1150);
pauseButton.setSize(70, 70);
stage.addActor(pauseButton);
pauseButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
pauseButtonClicked = true;
}
});
Button.ButtonStyle restartButtonStyle = new Button.ButtonStyle();
restartButtonSkin = new Skin(assets.manager.get("restartButton.atlas", TextureAtlas.class));
restartButtonStyle.up = restartButtonSkin.getDrawable("restartbutton");
restartButtonStyle.down = restartButtonSkin.getDrawable("restartbutton.down");
restartButton = new Button(restartButtonStyle);
restartButton.setSize(350, 90);
restartButton.setPosition(cam.viewportWidth / 2 - restartButton.getWidth() / 2, 525);
stage.addActor(restartButton);
restartButton.setVisible(false);
restartButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
RestartPressed = true;
}
});
Button.ButtonStyle resumeButtonStyle = new Button.ButtonStyle();
resumeButtonSkin = new Skin(assets.manager.get("resumeButton.atlas", TextureAtlas.class));
resumeButtonStyle.up = resumeButtonSkin.getDrawable("resumebutton");
resumeButtonStyle.down = resumeButtonSkin.getDrawable("resumebutton.down");
resumeButton = new Button(resumeButtonStyle);
stage.addActor(resumeButton);
resumeButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
resumePressed = true;
}
});
Button.ButtonStyle menuButtonStyle = new Button.ButtonStyle();
menuButtonSkin = new Skin(assets.manager.get("menuButton.atlas", TextureAtlas.class));
menuButtonStyle.up = menuButtonSkin.getDrawable("menubutton");
menuButtonStyle.down = menuButtonSkin.getDrawable("menubutton.down");
menuButton = new Button(menuButtonStyle);
stage.addActor(menuButton);
menuButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
menuPressed = true;
}
});
Button.ButtonStyle shopButtonStyle = new Button.ButtonStyle();
shopButtonSkin = new Skin(assets.manager.get("shopButton.atlas", TextureAtlas.class));
shopButtonStyle.up = shopButtonSkin.getDrawable("shopbutton");
shopButtonStyle.down = shopButtonSkin.getDrawable("shopbutton.down");
shopButton = new Button(shopButtonStyle);
stage.addActor(shopButton);
shopButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
shopPressed = true;
}
});
table.add(resumeButton).padBottom(25);
table.row();
table.add(menuButton).padBottom(25);
table.row();
table.add(shopButton);
table.setPosition(cam.viewportWidth / 2, 560);
table.setVisible(false);
}
public void draw(){
stage.draw();
}
public void act(){
stage.act();
}
public boolean isPauseButtonPressed() {
return pauseButtonClicked;
}
public boolean isRestartPressed(){return RestartPressed;}
public boolean isResumePressed(){return resumePressed;}
public boolean isShopPressed() {
return shopPressed;
}
public boolean isMenuPressed() {
return menuPressed;
}
public void restartVisible(){
restartButton.setVisible(true);
}
public void restartInvisible() { restartButton.setVisible(false); }
public void displayPauseButtons(){
table.setVisible(true);
}
public void pauseInvisible(){
pauseButton.setVisible(false);
}
public void pauseVisible(){
pauseButton.setVisible(true);
}
public void removePauseButtons(){
table.setVisible(false);
}
public void resize(int width, int height) {
viewport.update(width, height);
}
public void dispose(){
stage.clear();}
}
&#34;简历&#34;按钮应该从暂停到跑步恢复游戏,但当我点击它时,它会恢复游戏,但是&#34; boop&#34;声音永远不断播放,当鸟儿与任何物体碰撞时,它不会停止,它只是在触摸物体时显示游戏结束菜单。
我的理论是它&#34;恢复&#34;鸟似乎总是按下“恢复按钮”,这就是为什么它不能死而且它一直播放声音的原因。但问题是,为什么这样做呢?!
答案 0 :(得分:0)
单击按钮并设置一些布尔值表示按下它们后,代码中没有任何内容可以将按下的布尔值设置为假。因此,一旦按下按钮,它就像是永远按下了。
无论如何,这是处理这些按钮的复杂且容易出错的方式。令人费解的是让你的渲染方法轮询所有按钮以查看最近按下了哪些按钮。
在handleInput()
方法中删除按钮按下的所有布尔值以及所有那些按下的情况。每个按钮的单击侦听器应调用一个方法来更改状态,播放声音等。您的代码的结构方式,您需要将PlayState的实例传递给您的PlatStateButtons构造函数,因此其各种ClickListener可以访问它。
另外,如果你对它们使用ChangeListener而不是ClickListener,那么LibGDX中的按钮表现得更自然。