0

ポンゲームを作ろうとしていますが、なんらかの理由でポンパドルが上手く動かない。

下矢印キーを押すと、うまく下に移動します。しかし、上矢印キーを押すと、パドル全体が上向きに長くなります...ウィンドウのサイズを変更すると、パドルはその位置で通常の長さに戻ります。UPキーを押すと、再び上に伸び続けます。

私はそれが私のコードロジックではないと思いますが、以前に描かれたパドルをクリアすることについての何か...これが私のコードです、

パドルのコード:

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

public class Paddle extends JPanel {

    int x;
    int y;
    int width;
    int height;

    Paddle(){
        this.x = 0;
        this.y = 0;
        this.height = 40;
        this.width = 10;
    }

    Paddle(int x, int y, int width, int height){
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.fillRect(x, y, width, height);
    }

    public void moveDown(){
        this.y += 3;
        repaint();
        System.out.println("h: " + height + " x: " + x + " y: " + y + " getW: " + getWidth() + " getH: " + getHeight());
    }

    public void moveUp(){
        this.y -= 3;
        repaint();
        System.out.println("h: " + height + " x: " + x + " y: " + y + " getW: " + getWidth() + " getH: " + getHeight());
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

}

ゲーム全体のコード:

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Pong extends JFrame {

    Pong() {
        final Paddle p1Paddle = new Paddle();

        Paddle p2Paddle = new Paddle();
        p1Paddle.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                //super.keyPressed(arg0);

                switch (e.getKeyCode()) {
                    case KeyEvent.VK_DOWN:
                        p1Paddle.moveDown();
                        break;
                    case KeyEvent.VK_UP:
                        p1Paddle.moveUp();
                        break;
                    default:
                        System.out.println("please press up or down");
                }

            }
        });

        setLayout(new BorderLayout());
        add(p1Paddle, BorderLayout.CENTER);

        //only focused components can recieve key events...
        p1Paddle.setFocusable(true);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame frame = new Pong();
        frame.setTitle("Pong");
        frame.setSize(650, 300);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}

この問題に関するヘルプや一般的なコードのアドバイスをいただければ幸いです。

4

1 に答える 1

1

コードスニペットから判断するのは少し難しいですが、KeyListenersはあまり信頼できません。キーストロークが(UIおよび基盤となる実装によって)消費された場合、通知されない場合があります。

代わりに、InputMapとActionMapを見てみてください。

InputMap im = getInputMap(JTable.WHEN_FOCUSED_COMPONENT);
ActionMap am = getActionMap();

KeyStroke downKey = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
KeyStroke upKey = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);

im.put(downKey, "Action.down");
im.put(upKey, "Action.up");

am.put("Action.down", new DownAction());
am.put("Action.up", new UpAction());

そして、それがあなたをどこに連れて行くかを見てください...

更新: ああ、それはとても明白です、あなたはレイアウトマネージャーがコンポーネントをレイアウトするためにそれらを使用することを期待してパネルのx / y幅/高さメソッドをオーバーライドしましたが、実際には対処方法を知っているレイアウトマネージャーを提供していませんそれ。

BorderLayoutは、「サイズ」または「位置」の要件を考慮せず、コンポーネントが本来あるべきと考えるものでそれらをオーバーライドします。

あなたがしたいのは、代わりに絶対レイアウトマネージャーを使用することです(null)。また、X / Y、幅/高さの管理はすでに処理されているため、実装しないでください。

それで。

ポンクラスで。レイアウトマネージャーをBorderLayoutからnullに変更します(add(paddle)メソッドも更新してBorderLayout参照を削除します。必須ではありませんが、混乱を取り除きます)。

Paddleクラスで、x / y、width/heightへのすべての参照を削除します。これらは必要ありません。代わりに、setBounds/setLocationを使用してください。

public class Paddle extends JPanel {

Paddle(){

        this(0, 0, 20, 40);

}

Paddle(int x, int y, int width, int height){

        setBounds(x, y, width, height);

}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    // The graphics context has already been translated to x/y for use,
    // so we don't need to care about it
    g.fillRect(0, 0, getWidth(), getHeight());
}

public void moveDown(){

        setLocation(getX(), getY() + 3);

}

public void moveUp(){

        setLocation(getX(), getY() - 3);

}

}

そしてビオラ、それは動作します。

于 2012-07-10T05:32:36.910 に答える