Libgdx - touchDown / touchUp与Gdx.input.isKeyPressed / Gdx.input.isKeyJustPressed

时间:2017-03-17 05:16:47

标签: java android libgdx

这是我的困境。我通过使用我的GamePad类(我为Android设备的游戏控制器制作了这个类)来解决我的闪电攻击的问题。

我发现如果使用Gdx.input.isKeyPressed(keyname),代码会在每个帧上产生一次闪电攻击,它们堆叠在一起。所以,我然后使用了Gdx.input.isKeyJustPressed(),它只创建了一个动画的攻击,这是完美的。

因此,在制作GamePad课程时,我使用听众制作图像来处理触摸事件。对于每个按钮,我有一个touchDown和touchUp方法。从左到右运行我的角色时,这些触摸事件可以正常工作。但是,与Gdx.input.isKeyPressed()类似,每帧都会创建一次闪电攻击,并且攻击会相互叠加。我尝试了一种解决方法来修复每帧攻击的创建,现在图像只是静态的,并且没有动画。这比60 fps要好,但不能解决我的问题。

是否有类似于Gdx.input.isKeyJustPressed()的touchDown事件?我如何修复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;
}
}

1 个答案:

答案 0 :(得分: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());

然后在你的游戏环中某处:

this.lighteningAttack.update(deltaTime);

最后,在你的eventlistener中:

this.lighteningAttack.execute();

无论您按下按钮多少次,它都应该每秒执行四次。