2017-03-17 76 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