【问题标题】:KeyListener not working and map overlapping characterKeyListener 不起作用并映射重叠字符
【发布时间】:2014-04-16 23:05:44
【问题描述】:

我的KeyListener 和方法有效,但它们什么也没做。当我运行代码并尝试使用箭头键时,没有任何反应。我还有另一个问题。我在做游戏,我已经做了地图,但是当我把地图放进去时,地图有优先权并覆盖了我的角色。我将如何解决这些问题? 这是JFrame 包。

package MyGamePKG;

import java.awt.BorderLayout;

public class GameJFrame extends JFrame {

private JPanel contentPane;
private int x,y,x_vel,y_vel;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GameJFrame frame = new GameJFrame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public GameJFrame() {


    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 720, 520);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    GameJPanel Jpanel = new GameJPanel();
    Jpanel.setBounds(0, 0, 720, 480);
    contentPane.add(Jpanel);
    Jpanel.setLayout(null);




}


}

这是 JPanel。

package MyGamePKG;

import java.awt.BasicStroke;

public class GameJPanel extends JPanel implements ActionListener, KeyListener {

private int frameRate = 30;
private int x=0;
private int y=0;
private int x_vel, y_vel;
private Image map;

/**
 * Create the panel.
 */
public GameJPanel() {
    new ImageIcon(getClass().getResource("/Resources/gamemap.png"));
    gamemap = map.getImage(); //error here
    this.addKeyListener(this);
    this.setFocusable(true);
    Timer timer = new Timer(30, this);      
    timer.start();


}


}

public void background()
{
    ImageIcon icon = new ImageIcon(this.getClass().getResource("/Resources/gamemap.png"));
    map = icon.getImage();
}
@Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    setBackground(Color.WHITE);

    Graphics2D g2d = (Graphics2D) g;

    RenderingHints rh = new RenderingHints( RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    g2d.setRenderingHints(rh);

    g2d.setColor(Color.green);
    g2d.setStroke(new BasicStroke(5));


    myDrawBoxOvalsandRect(x,y,100,g2d);
    myDrawArc(x+25,y+40,50,50,550,170,g2d);
} // paintComponent
public void myDrawBoxOvalsandRect( int x, int y, int scale, Graphics my_g)
{
    my_g.setColor(Color.cyan);
    my_g.fillOval(x, y, 100, 100); //face

    my_g.setColor(Color.red);
    my_g.fillOval(x+20, y+25, 15, 15); //left eye

    my_g.setColor(Color.red);
    my_g.fillOval(x+60, y+25, 15, 15); //right eye

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+25,y+100,50,80);//body

    my_g.setColor(Color.cyan);
    my_g.fillRect(x-30,y+105,55,20); //left arm

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+70, y+105, 60, 20); //right arm

    my_g.setColor(Color.red); 
    my_g.fillOval(x-47, y+105, 20, 20); //left hand

    my_g.setColor(Color.red);
    my_g.fillOval(x+126,y+105,20,20); //right hand

    my_g.setColor(Color.cyan); 
    my_g.fillRect(x+25, y+175, 20, 50); //left leg

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+55,y+175,20,50); // right leg

}
public void myDrawArc(int x, int y, int height, int width, int angle1, int angle2, Graphics my_g)
{
    my_g.setColor(Color.red);
    my_g.drawArc(x, y, 50, 50, 550, 170); //happy face      
}
@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    int c = e.getKeyCode();

    if(c == KeyEvent.VK_LEFT)
    {
        x_vel = -1;
        y_vel = 0;
    }
    if(c == KeyEvent.VK_UP)
    {
        x_vel = 0;
        y_vel = -1;
    }
    if( c == KeyEvent.VK_RIGHT)
    {
        x_vel = 1;
        y_vel = 0;
    }
    if( c == KeyEvent.VK_DOWN)
    {
        x_vel = 0;
        y_vel = 1;
    }
    repaint();

}
@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
    x_vel = 0;
    y_vel = 0;
    repaint();
}
@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    if(x < 0)
    {
        x_vel = 0;
        x = 0;
    }
    if(x > 720)
    {
        x_vel = 0;
        x = 720;
    }
    if(y < 0)
    {
        y_vel = 0;
        y = 0;
    }
    if(y > 480)
    {
        y_vel = 0;
        y = 480;
    }
    x = x + x_vel;
    y = y + y_vel;
    repaint();

}


}

【问题讨论】:

    标签: java swing jframe jpanel keylistener


    【解决方案1】:

    你有几个问题需要处理

    1. 您已经创建了两组变量。一组在您的框架中,一组在您的面板中。使用 Keyalistener,您只需更改框架中的值,这不会影响面板中的值。

    2. 应在事件调度线程上更新 UI。不要使用带有while(true)Thread.sleep() 的新线程。而是使用 javax.swing.Timer 来制作动画。在How to Use Swing Timers 上查看更多信息。你还会看到一堆例子herehereherehereherehere

    3. 您应该将键绑定用于键特定操作,而不是 KeyListener。在How to Use Key Bindings 上查看更多信息。也可以看一个简单的例子here


    其他:

    • 为什么在没有添加任何内容的情况下使用 ActionListener?
    • 不要使用空布局。学习使用 LayoutManager,让它们为您调整大小和定位。
    • 对于涂漆面板,您应该覆盖 getPreferredSize() 以设置面板的首选尺寸,并且当您 pack() 您的框架时会尊重它(您应该这样做,而不是设置尺寸)
    • 不要在绘制方法中设置背景。在构造函数中执行。

    更新

    这是完整的代码。对我来说很好用

    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.border.EmptyBorder;
    
    public class GameFrame extends JFrame {
    
        private JPanel contentPane;
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        GameFrame frame = new GameFrame();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public GameFrame() {
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 720, 520);
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(null);
    
            GameJPanel Jpanel = new GameJPanel();
            Jpanel.setBounds(0, 0, 720, 480);
            contentPane.add(Jpanel);
            Jpanel.setLayout(null);
    
        }
    }
    
    class GameJPanel extends JPanel implements ActionListener, KeyListener {
    
        private int frameRate = 30;
        private int x = 0;
        private int y = 0;
        private int x_vel, y_vel;
        private Image map;
    
        /**
         * Create the panel.
         */
        public GameJPanel() {
            map = new ImageIcon(getClass().getResource("/resources/gamemap.png")).getImage();
            this.addKeyListener(this);
            this.setFocusable(true);
            Timer timer = new Timer(30, this);
            timer.start();
            /*
            Thread myAnimationThread = new Thread() {
                @Override
                public void run() {
                    while (true) {
                        repaint(); // Refresh the display which calls paintComponent
                        try {
                            Thread.sleep(1000 / frameRate);
                        } // try
                        catch (InterruptedException ex) {
                        }
                    } // while
                } // run
            }; // Thread
            */
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            setBackground(Color.WHITE);
    
            Graphics2D g2d = (Graphics2D) g;
    
            RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
    
            g2d.setRenderingHints(rh);
    
            g2d.setColor(Color.green);
            g2d.setStroke(new BasicStroke(5));
    
    
            g2d.drawImage(map, 0, 0, 720, 480, getParent());
            myDrawBoxOvalsandRect(x, y, 100, g2d);
            myDrawArc(x + 25, y + 40, 50, 50, 550, 170, g2d);
        } // paintComponent
    
        public void myDrawBoxOvalsandRect(int x, int y, int scale, Graphics my_g) {
            my_g.setColor(Color.cyan);
            my_g.fillOval(x, y, 100, 100); // face
    
            my_g.setColor(Color.red);
            my_g.fillOval(x + 20, y + 25, 15, 15); // left eye
    
            my_g.setColor(Color.red);
            my_g.fillOval(x + 60, y + 25, 15, 15); // right eye
    
            my_g.setColor(Color.cyan);
            my_g.fillRect(x + 25, y + 100, 50, 80);// body
    
            my_g.setColor(Color.cyan);
            my_g.fillRect(x - 30, y + 105, 55, 20); // left arm
    
            my_g.setColor(Color.cyan);
            my_g.fillRect(x + 70, y + 105, 60, 20); // right arm
    
            my_g.setColor(Color.red);
            my_g.fillOval(x - 47, y + 105, 20, 20); // left hand
    
            my_g.setColor(Color.red);
            my_g.fillOval(x + 126, y + 105, 20, 20); // right hand
    
            my_g.setColor(Color.cyan);
            my_g.fillRect(x + 25, y + 175, 20, 50); // left leg
    
            my_g.setColor(Color.cyan);
            my_g.fillRect(x + 55, y + 175, 20, 50); // right leg
    
        }
    
        public void myDrawArc(int x, int y, int height, int width, int angle1,
                int angle2, Graphics my_g) {
            my_g.setColor(Color.red);
            my_g.drawArc(x, y, 50, 50, 550, 170); // happy face
        }
    
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            int c = e.getKeyCode();
    
            if (c == KeyEvent.VK_LEFT) {
                x_vel = -1;
                y_vel = 0;
            }
            if (c == KeyEvent.VK_UP) {
                x_vel = 0;
                y_vel = -1;
            }
            if (c == KeyEvent.VK_RIGHT) {
                x_vel = 1;
                y_vel = 0;
            }
            if (c == KeyEvent.VK_DOWN) {
                x_vel = 0;
                y_vel = 1;
            }
            repaint();
    
        }
    
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
            x_vel = 0;
            y_vel = 0;
            repaint();
        }
    
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            if (x < 0) {
                x_vel = 0;
                x = 0;
            }
            if (x > 720) {
                x_vel = 0;
                x = 720;
            }
            if (y < 0) {
                y_vel = 0;
                y = 0;
            }
            if (y > 480) {
                y_vel = 0;
                y = 480;
            }
            x = x + x_vel;
            y = y + y_vel;
            repaint();
    
        }
    } 
    

    【讨论】:

    • 我们还没有了解 Key Binding、计时器、getPreferredSize() 和包。还有其他选择吗?
    • 我也尝试将 keylistener 放在 JPanel 中,但也没有效果。
    • 您可以阅读这些链接并自行学习,并给您的老师留下深刻印象:)我提到的方法是正确的方法。尝试并学习它们。继续努力,如果您在尝试时遇到困难,请编辑您的帖子,我很乐意提供帮助。
    • 我被告知将背景图像放在字符方法之前,但它仍然不起作用。我还编辑了 KeyListeners 并将其添加到 JPanel,但我的角色似乎仍然没有移动。
    • 我真的没有时间看你的逻辑,但是如果你把Timer timer = new Timer(30, this); timer.start();放在setFocusable之后,去掉线程代码,把repaint()放在你的keyXxx mwethods中, 有用。但我不知道它是否按你想要的方式工作。您目前有一个actionPerfomed,但您从未将ActionListener 添加到任何内容中。 actionPerformed 有一些代码逻辑。所以我所做的就是将监听器添加到Timer。计时器应该做动画,但它没有。你需要按键来移动图形。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多