2017-03-17 73 views
0

這是我的困境。我在使用我的GamePad類(我爲Android設備的遊戲控制器製作了這個類)時遇到了動畫閃電攻擊的問題。Libgdx - 着陸/潤色與Gdx.input.isKeyPressed/Gdx.input.isKeyJustPressed

我發現,如果使用Gdx.input.isKeyPressed(鍵名稱),則代碼產生一個雷電襲擊每幀,其堆疊在彼此的頂部上。因此,我使用了Gdx.input.isKeyJustPressed(),它只創建一個攻擊,這是動畫,這是完美的。

所以使得遊戲手柄類時,我做了聽衆的圖像處理觸摸事件。對於每個按鈕我有一個touchDown和touchUp方法。從左到右運行我的角色時,這些觸摸事件正常工作。但是,與Gdx.input.isKeyPressed()類似,閃電攻擊是在每幀中創建的,並且攻擊分層疊加。我嘗試了一種解決方法來修復每幀創建的攻擊,現在圖像只是靜態的,並且不會動畫。這比60 fps更好,但並不能解決我的問題。

有沒有觸下事件類似Gdx.input.isKeyJustPressed()?我該如何修復GamePad類,才能像Config類一樣工作?

GamePad.java

public class GamePad implements Disposable{ 

private Viewport viewport; 
public Stage stage; 
boolean leftPressed, rightPressed, pausePressed, aPressed, bReleased, bPressed, bPreviouslyPressed; 
private Config config = Config.getInstance(); 
private Table table; 

public GamePad(){ 
    viewport = new FitViewport(EIUGame.V_WIDTH, EIUGame.V_HEIGHT, new OrthographicCamera()); 
    stage = new Stage(viewport); 

    table = new Table(); 
    table.setFillParent(true); 
    table.bottom(); 

    bPreviouslyPressed = false; 

    // "Left" Button 
    Image leftImg = new Image(new Texture("controller/leftButton.png")); 
    leftImg.setSize(35, 35); 
    leftImg.addListener(new InputListener(){ 

     @Override 
     public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ 
      leftPressed = true; 
      return true; 
     } 


     @Override 
     public void touchUp(InputEvent event, float x, float y, int pointer, int button){ 
      leftPressed = false; 
     } 
    }); 

    // "Right" Button 
    Image rightImg = new Image(new Texture("controller/rightButton.png")); 
    rightImg.setSize(35, 35); 
    rightImg.addListener(new InputListener(){ 

     @Override 
     public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ 
      rightPressed = true; 
      return true; 
     } 

     @Override 
     public void touchUp(InputEvent event, float x, float y, int pointer, int button){ 
      rightPressed = false; 
     } 
    }); 

    // "Pause" Button 
    Image pauseImg = new Image(new Texture("controller/pauseButton.png")); 
    pauseImg.setSize(15, 15); 
    pauseImg.addListener(new InputListener(){ 

     @Override 
     public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ 
      pausePressed = true; 
      return true; 
     } 

     @Override 
     public void touchUp(InputEvent event, float x, float y, int pointer, int button){ 
      pausePressed = false; 
     } 
    }); 

    // "A" Button 
    Image aImg = new Image(new Texture("controller/aButton.png")); 
    aImg.setSize(35, 35); 
    aImg.addListener(new InputListener(){ 

     @Override 
     public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ 
      aPressed = true; 
      return true; 
     } 

     @Override 
     public void touchUp(InputEvent event, float x, float y, int pointer, int button){ 
      aPressed = false; 
     } 
    }); 

    // "B" Button 
    Image bImg = new Image(new Texture("controller/bButton.png")); 
    bImg.setSize(35, 35); 
    bImg.addListener(new InputListener(){ 

     @Override 
     public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){ 
      bPressed = true; 
      setBReleased(false); 
      return true; 
     } 

     @Override 
     public void touchUp(InputEvent event, float x, float y, int pointer, int button){ 
      setBReleased(true); 
      bPreviouslyPressed = false; 
      bPressed = false; 
     } 
    }); 

    table.add(leftImg).size(leftImg.getWidth(), leftImg.getHeight()); 
    table.add().size(5,35); 
    table.add(rightImg).size(rightImg.getWidth(), rightImg.getHeight()); 
    table.add().size(100, 35); 
    table.add(pauseImg).size(pauseImg.getWidth(), pauseImg.getHeight()).bottom(); 
    table.add().size(100, 35); 
    table.add(bImg).size(bImg.getWidth(), bImg.getHeight()); 
    table.add().size(5,35); 
    table.add(aImg).size(aImg.getWidth(), aImg.getHeight()); 

    stage.addActor(table); 
} 

// Returns the stage object so that it can be added to a multiplexer 
public Stage getStage() { 
    return stage; 
} 

public void draw(){ 
    stage.draw(); 
} 

public boolean isLeftPressed(){ 
    return leftPressed; 
} 

public boolean isRightPressed(){ 
    return rightPressed; 
} 

public boolean isPausePressed(){ 
    return pausePressed; 
} 

public boolean isAPressed(){ 
    return aPressed; 
} 

public boolean isBPressed(){ 
    return bPressed; 
} 

public boolean isBPreviouslyPressed(){ 
    return bPreviouslyPressed; 
} 

public boolean isBReleased(){ 
    return bReleased; 
} 

public void setBReleased(boolean released){ 
    bReleased = released; 
} 

public void resize(int width, int height){ 
    viewport.update(width, height); 
} 

public void animateChamp(Champion champ, PauseState pause){ 
    // Move Champion Right 
    if (isRightPressed() && champ.b2body.getLinearVelocity().x <= 2) 
     config.runRight(champ); 
    // Move Champion left 
    if (isLeftPressed() && champ.b2body.getLinearVelocity().x >= -2) 
     config.runLeft(champ); 
    // If A button is pressed and we are not jumping or falling, then Jump. 
    if (isAPressed() && (champ.getState() != champState.JUMPING && champ.getState() != champState.FALLING)){ 
     config.jump(champ); 
     aPressed = false; 
    } 
    // Toggle Pause Menu 
    if (isPausePressed()) 
     pause.togglePause(); 

    // Precondition for next else-if statement 
    if (isBPressed() && champ.b2body.getLinearVelocity().x == 0 && champ.b2body.getLinearVelocity().y == 0){ 
     bPressed = false; 
     bPreviouslyPressed = true; 
    } 
    // If b was pressed down but not released, and champion is not moving, use lightning attack 
    else if (bPreviouslyPressed && !isBReleased() && champ.b2body.getLinearVelocity().x == 0 && champ.b2body.getLinearVelocity().y == 0){ 
     champ.setMobileTrigger(true);  // Sets champion state to attacking region 
     config.setMLightningActive(true); 
     config.lightningAttack(champ); 
    } 
    // Exit lightning attack if moved 
    else if (!isBReleased() && (champ.b2body.getLinearVelocity().x != 0 || champ.b2body.getLinearVelocity().y != 0)){ 
     champ.setMobileTrigger(false); 
     config.setMLightningActive(false); 
     bReleased = true; 
    } 
    // Exit lightning attack if button released 
    else if (isBReleased() && config.getMLightningActive()){ 
     champ.setMobileTrigger(false);   // Does not alter champion state 
     config.setMLightningActive(false); 
     bReleased = true; 
    } 
    // Attack when moving 
    else if (isBPressed()){ 
     config.attack(champ); 
     bPressed = false; 
    } 

} 

@Override 
public void dispose(){ 
    stage.dispose(); 
} 
} 

Config.java

public final class Config { 
private static final Config instance = new Config(); 

private int moveLeft; 
private int moveRight;  
private int jump; 
private int attack; 
private String lStr; 
private String rStr; 
private String jStr; 
private String aStr; 
private boolean lightningActive = false; 
private boolean MlightningActive = false; // Mobile Game 

// Default constructor sets the keys to a default schema 
private Config() { 
    moveLeft = Input.Keys.A;  
    moveRight = Input.Keys.D;  
    jump = Input.Keys.L; 
    attack = Input.Keys.J; 
    lStr = "A"; 
    rStr = "D"; 
    jStr = "L"; 
    aStr = "J"; 
} 

// Return the instance of the class 
public static Config getInstance() { 
    return instance; 
} 

public void animateChamp(Champion champ){ 

    // Jump! 
    if(Gdx.input.isKeyJustPressed(jump) && (champ.getState() != champState.JUMPING && champ.getState() != champState.FALLING)) 
     jump(champ); 

    // Run Right (and make sure character is not moving faster than 2) 
    if(Gdx.input.isKeyPressed(moveRight) && champ.b2body.getLinearVelocity().x <= 2) 
     runRight(champ); 

    // Run Left (and make sure character is not moving faster than 2) 
    if(Gdx.input.isKeyPressed(moveLeft) && champ.b2body.getLinearVelocity().x >= -2) 
     runLeft(champ);  

    // Lightning Attack 
    if(Gdx.input.isKeyJustPressed(attack) && champ.b2body.getLinearVelocity().x == 0 && champ.b2body.getLinearVelocity().y == 0){ 
     setLightningActive(true); 
     lightningAttack(champ);   
    } 
    else if (getlightningActive() && (champ.b2body.getLinearVelocity().x != 0 || champ.b2body.getLinearVelocity().y != 0 || !Gdx.input.isKeyPressed(attack))) 
     setLightningActive(false); 

    else if (Gdx.input.isKeyJustPressed(attack)) 
     attack(champ); 
} 

public void runRight(Champion champ){ 
    champ.b2body.applyLinearImpulse(new Vector2(0.1f,0), champ.b2body.getWorldCenter(), true); 
} 

public void runLeft(Champion champ){ 
    champ.b2body.applyLinearImpulse(new Vector2(-0.1f,0), champ.b2body.getWorldCenter(), true); 
} 

public void jump(Champion champ){ 
    champ.b2body.applyLinearImpulse(new Vector2(0, 4.5f), champ.b2body.getWorldCenter(), true); 
} 

public void attack(Champion champ){ 
    champ.attack(); 
} 

public void lightningAttack(Champion champ){ 
    champ.lightningAttack(); 
} 

public boolean getlightningActive(){ 
    return lightningActive; 
} 

public void setLightningActive(boolean value){ 
    lightningActive = value; 
} 

// For Mobile Version 
public boolean getMLightningActive(){ 
    return MlightningActive; 
} 

// For Mobile Version 
public void setMLightningActive(boolean value){ 
    MlightningActive = value; 
} 

// sets the key to move left 
public void setMoveLeft(String n){ 
    moveLeft = Input.Keys.valueOf(n.toUpperCase()); 
    lStr = n; 
} 

// sets the key to move right 
public void setMoveRight(String n) { 
    moveRight = Input.Keys.valueOf(n.toUpperCase()); 
    rStr = n; 
} 

// sets the key to jump 
public void setJump(String n) { 
    jump = Input.Keys.valueOf(n.toUpperCase()); 
    jStr = n; 
} 

// sets the key to attack 
public void setAttack(String n) { 
    attack = Input.Keys.valueOf(n.toUpperCase()); 
    aStr = n; 
} 

// Returns the string representation of the move left key 
public String getMoveLeft(){ 
    return lStr; 
} 

// Returns the string representation of the move right key 
public String getMoveRight() { 
    return rStr; 
} 

// Returns the string representation of the jump key 
public String getJump() { 
    return jStr; 
} 

// Returns the string representation of the attack key 
public String getAttack() { 
    return aStr; 
} 

// Returns the int representation of the attack key 
public int getAttackInt(){ 
    return attack; 
} 
} 

回答

0

如果我可能會建議另一種方法,這聽起來像你真正想要的是應用冷卻到你的閃電攻擊 - 一個如果玩家按下按鈕,冷卻時間可以防止它重複發射,並且可以控制玩家敲擊鍵盤的速度,從而控制玩家的速度(您可能希望讓玩家將其閃電攻擊「升級」到更快的速度在將來)。

我扔在一起,下面的例子:

public class Cooldown { 
    private float cooldownTime = 0; 
    private float length = 0; 
    private Action action; 

    public Cooldown(float length, Action action) { 
     this.length = length; 
     this.action = action; 
    } 

    public boolean update(float delta) { 
     // Subtract the delta until we hit 0 
     this.cooldownTime = this.cooldownTime - delta <= 0 ? 0 : this.cooldownTime - delta; 
     // The boolean tells you that the cooldown has expired- useful for special effects 
     return this.cooldownTime == 0; 
    } 

    public void execute() { 
     if(this.cooldownTime > 0) return; 
     this.cooldownTime = this.length; 
     this.action.execute(); 
    } 

    public interface Action { 
     void execute(); 
    } 
} 

要使用這個類,只需添加類似下面的某處播放機的構造下:

this.lighteningAttack = new Cooldown(0.25f, new LightningAttack()); 

然後在您的gameloop地方:

this.lighteningAttack.update(deltaTime); 

最後,在你的事件監聽:

this.lighteningAttack.execute(); 

不管你按了多少次按鈕,它只應該每秒執行四次。

+0

這聽起來很有趣,當我找到時間時,我會試試看。我也可以將這種方法用於我的基本攻擊。感謝您的回覆,我會盡快回復您。 – FoxDonut