玩家不在2D游戏中移动

时间:2013-12-12 05:28:08

标签: java keylistener

当按下某些键时,我似乎无法让我的播放器移动。我做了一些调试并在if语句中放置了一个System.out.print("Pressed);来检查是否按下了一个键,并且每次按下键时它都会打印出消息,他们只是没有移动。有人可以帮忙!

这里是InputHandler类

public class InputHandler implements KeyListener {

    public InputHandler(Game game) {
        game.addKeyListener(this);
    }

    public class Key {
        private boolean pressed = false;

        public void toggle(boolean isPressed) {
            pressed = isPressed;
        }

        public boolean isPressed() {
            return pressed;
        }
    }

    // public List<Key> keys = new ArrayList<Key>();
    public Key up = new Key();
    public Key down = new Key();
    public Key left = new Key();
    public Key right = new Key();

    public void keyPressed(KeyEvent e) {
        toggleKey(e.getKeyCode(), true);
    }

    public void keyReleased(KeyEvent e) {
        toggleKey(e.getKeyCode(), false);
    }

    public void keyTyped(KeyEvent e) {

    }

    public void toggleKey(int keyCode, boolean isPressed) {
        if (keyCode == KeyEvent.VK_W) {
            up.toggle(isPressed);
        } else if (keyCode == KeyEvent.VK_S) {
            down.toggle(isPressed);
        } else if (keyCode == KeyEvent.VK_A) {
            left.toggle(isPressed);
        } else if (keyCode == KeyEvent.VK_D) {
            right.toggle(isPressed);
        }
    }
}

这里是Player类

public class Player extends Mob {

    private InputHandler input;
    private int r = 10;

    public Player(int x, int y, int speed, InputHandler input) {
        super("Player", x, y, 1);
        this.input = input;
        this.x = x;
        this.y = y;
    }

    public boolean hasCollided(int dx, int dy) {
        return false;
    }

    public void update() {
        int dx = 0;
        int dy = 0;

        if (input.up.isPressed()) {
            dy--;
        } else if (input.down.isPressed()) {
            dy++;
        } else if (input.left.isPressed()) {
            dx--;
        } else if (input.right.isPressed()) {
            dx++;
        }

        if (dx != 0 || dy != 0) {
            move(dx, dy);
            isMoving = true;
        } else {
            isMoving = false;
        }

        if (x < r)
            x = r;
        if (y < r)
            y = r;
        if (x > Game.WIDTH - r)
            x = Game.WIDTH - r;
        if (y > Game.HEIGHT - r)
            y = Game.HEIGHT - r;
    }

    public void render(Graphics2D g) {
        g.setColor(Color.BLACK);
        g.fillOval(x - r, y - r, 2 * r, 2 * r);

        g.setStroke(new BasicStroke(3));
        g.setColor(Color.GRAY);
        g.drawOval(x - r, y - r, 2 * r, 2 * r);
        g.setStroke(new BasicStroke(1));
    }
}

这里是其中包含move()方法的Mob类

    public Mob(String name, int x, int y, int speed) {
        this.name = name;
        this.speed = speed;
    }

    public void move(int dx, int dy) {
        if (dx != 0 && dy != 0) {
            move(dx, 0);
            move(dy, 0);
            numSteps--;
            return;
        }
        numSteps++;

        if (!hasCollided(dx, dy)) {
            if (dy < 0)
                movingDir = 0;
            if (dy > 0)
                movingDir = 1;
            if (dx < 0)
                movingDir = 2;
            if (dx > 0)
                movingDir = 3;

            x += dx * speed;
            y += dy * speed;
        }
    }

    public abstract boolean hasCollided(int dx, int dy);

    public String getName() {
        return _name;
    }
}

4 个答案:

答案 0 :(得分:1)

这段代码有各种各样的问题,但最紧迫的似乎是对_x和x都有参考。选择一个并使所有方法都使用该方法。这可能会有所帮助,但说实话,很难确切地知道要修复什么,可能从更简单的事情开始?

答案 1 :(得分:1)

Player类中的render方法从哪里调用?你有没有在某处覆盖paint(Graphics)或paintComponent(Graphics)?

原来JFrame没有焦点。一旦它成为焦点,代码就能很好地运作。

答案 2 :(得分:0)

我发现您的移动代码有一个错误。如果两者都不是0,则在if语句中调用move(dx, 0)move(dy, 0)。在随后的递归中,它们都是0并且没有任何操作。而是将&&更改为||

public void move(int dx, int dy) {
        if (dx != 0 || dy != 0) {
            move(dx, 0);
            move(dy, 0);
            numSteps--;
            return;
        }
        ...
}

答案 3 :(得分:0)

这里有很多代码,对于一个问题来说真的太多了。

更好的方法是继续使每个班级变小。具体来说,不要对墙壁进行错误检查。只需移动暴徒/周围的任何东西。如果出现问题,那么游戏(?)会抛出错误......

总的来说,我会说这种方法过于关注“假设怎么样?”问题而不是机动的基础知识是一个带有x,y坐标系的二维地牢。

(只是为了混淆问题,如果它在极坐标中怎么办??无论如何......)

在让你的代码运行之后,我继续把它放在github上给你:

https://github.com/THUFIR/Game2D/tree/master/src/genericGame

请随意分叉,请做。 Git或任何版本控制可以在代码运行时提供帮助,但有些东西已经破坏......

这是输出,非常简单:

thufir@dur:~/NetBeansProjects/Game2D$ 
thufir@dur:~/NetBeansProjects/Game2D$ java -jar dist/Game2D.jar 
x   1   y   1
x   4   y   6
thufir@dur:~/NetBeansProjects/Game2D$ 

驱动器:

package genericGame;

import static java.lang.System.out;

public class Driver {

    public static void main(String[] args) {
        Player player = new Player(0, 0, 0);
        player.move(1, 1);
        out.println(player);
        player.move(3, 5);
        out.println(player);
    }
}

和玩家:

package genericGame;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;

public class Player extends Mob {

    private int r = 10;

    public Player(int x, int y, int speed) {
        super("Player", x, y);
        this.x = x;
        this.y = y;
    }

    public boolean hasCollided(int dx, int dy) {
        return false;
    }

    public void update() {
        int dx = 0;
        int dy = 0;

        if (input.up.isPressed()) {
            dy--;
        } else if (input.down.isPressed()) {
            dy++;
        } else if (input.left.isPressed()) {
            dx--;
        } else if (input.right.isPressed()) {
            dx++;
        }

        if (dx != 0 || dy != 0) {
            move(dx, dy);
            isMoving = true;
        } else {
            isMoving = false;
        }

        if (x < r) {
            x = r;
        }
        if (y < r) {
            y = r;
        }
        if (x > Game.WIDTH - r) {
            x = Game.WIDTH - r;
        }
        if (y > Game.HEIGHT - r) {
            y = Game.HEIGHT - r;
        }
    }

    public void render(Graphics2D g) {
        g.setColor(Color.BLACK);
        g.fillOval(x - r, y - r, 2 * r, 2 * r);

        g.setStroke(new BasicStroke(3));
        g.setColor(Color.GRAY);
        g.drawOval(x - r, y - r, 2 * r, 2 * r);
        g.setStroke(new BasicStroke(1));
    }
}

希望有所帮助。请学习git。

我会阅读其他答案,看看更好的解决方案,我只是用锤子打它直到它编译。方法,类和字段的命名约定,组织和访问级别都可以说是改进的机会。