1

该类用于在您按空格键时启动我制作的游戏,然后在游戏结束屏幕中按空格键时重新启动空格。当我按空格键并按预期启动游戏时,它第一次起作用,但是当我通过屏幕进入游戏并按空格键时,什么也没有发生。我试图扩展 JFrame 而不是 JApplet,然后它工作得很好。

这是我的代码:

package Game;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GameTest extends JApplet{
    private PAPITest papi;
    private TestPane panel;
    private boolean inMenu = true;
    private ImageIcon ii;
    private Image image;

    public void init(){
        setFocusable(true);
        requestFocusInWindow();
        requestFocus();
        ii = new ImageIcon("Ball Jump.png");
        image = ii.getImage();
        papi = new PAPITest();
        panel = new TestPane();
        add(panel);
        setSize(600,600);
        setVisible(true);
    }

    public void paint(Graphics g){
        if(inMenu == true){
            Graphics2D g2D = (Graphics2D) g;
            g2D.drawImage(image, 0, 0, this);
            repaint();
        }
    }

    public class TestPane extends JPanel {

        public TestPane() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "released");

            am.put("pressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(inMenu == true){
                        inMenu = false;
                        remove(panel);
                        papi.setSize(600,600);
                        papi.setAlive(true);
                        add(papi);            
                        setVisible(true); 
                    }

                    if (papi.isAlive() != true){ 
                        remove(papi);
                        papi = new PAPITest();
                        papi.setSize(600,600);
                        add(papi);
                        setVisible(true);
                        repaint();    
                    } 
                }
            });

            am.put("released", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(inMenu == true){
                        inMenu = false;
                        remove(panel);
                        papi.setSize(600,600);
                        papi.setAlive(true);
                        add(papi);            
                        setVisible(true); 
                    }

                    if (papi.isAlive() != true){ 
                        remove(papi);
                        papi = new PAPITest();
                        papi.setSize(600,600);
                        add(papi);
                        setVisible(true);
                        repaint();    
                    }
                }
            });

            setFocusable(true);
            requestFocusInWindow();        
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2D = (Graphics2D) g;
            g2D.drawImage(image, 0, 0, this);
            repaint();
        }
    }
}
4

2 回答 2

1

不要覆盖 JApplet 的 paint() 方法。

public void paint(Graphics g){
    if(inMenu == true){
        Graphics2D g2D = (Graphics2D) g;
        g2D.drawImage(image, 0, 0, this);
        repaint();
    }
}

自定义绘画在 JPanel 的 paintComponent() 方法中完成。

于 2013-04-12T14:49:29.723 回答
1

JPanel是阻止KeyListener

KeyListener只有当它们注册到的组件是可聚焦的并且具有焦点时才会响应事件。

您应该改用键绑定。它们允许您注册对键的兴趣,即使它们注册的组件没有直接焦点。

此外,您应该调用super.paint,事实上,您根本不应该覆盖paint顶级容器的方法。

创建一个自定义JPanel并覆盖它的paintComponent方法(确保调用super.paintComponent)并替换您要添加到小程序的面板

工作示例

这是一个基于您提供的代码的工作示例,现在缺少编码,所以我不得不将其注释掉,但还有一大堆东西只是......奇怪......

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class GameTest extends JApplet {

//    private PAPITest papi;
    private TestPane panel;
    private boolean inMenu = true;
    private ImageIcon ii;
    private Image image;

    public void init() {
// Don't need any of this, this will still focus from our control pane
//        setFocusable(true);
//        requestFocusInWindow();
//        requestFocus();
        setLayout(new BorderLayout());
        ii = new ImageIcon("Ball Jump.png");
        image = ii.getImage();
//        papi = new PAPITest();
        panel = new TestPane();
        add(panel);
        // Useless, the size of applet is actually normally defined by the html tags
//        setSize(600, 600);
//        setVisible(true);
    }

//    This is a very bad idea
//    This is not double buffered and you are over painting the applets
//    content.  Use a CardLayout and a series of JPanels to provide this
//    functionality or the Glass Pane...
//    You MUST call super.paint!!
//    public void paint(Graphics g) {
//        if (inMenu == true) {
//            Graphics2D g2D = (Graphics2D) g;
//            g2D.drawImage(image, 0, 0, this);
//            repaint();
//        }
//    }

    public class TestPane extends JPanel {

        public TestPane() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "released");

            am.put("pressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Space Pressed");
                    if (inMenu == true) {
                        inMenu = false;
//                        Removing the panel will remove the key binings...
//                        remove(panel);

//                        Don't have this code...
//                        Set size will have no effect as the layout manager
//                        apply it's own sizing based on the components
//                        preferred size...
//                        papi.setSize(600, 600);
//                        papi.setAlive(true);
//                        This seems a bit pointless, cause you just removed the "panel"
//                        which this now been added to...
//                        add(papi);

//                        Why call this when you've just removed it??
//                        setVisible(true);
                    }

//                    if (papi.isAlive() != true) {
//                        remove(papi);
//                        papi = new PAPITest();
//                        papi.setSize(600, 600);
//                        add(papi);
//                        setVisible(true);
//                        repaint();
//                    }
                }
            });

            am.put("released", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Space Released");
                    if (inMenu == true) {
                        inMenu = false;
//                        remove(panel);
//                        papi.setSize(600, 600);
//                        papi.setAlive(true);
//                        add(papi);
//                        setVisible(true);
                    }

//                    if (papi.isAlive() != true) {
//                        remove(papi);
//                        papi = new PAPITest();
//                        papi.setSize(600, 600);
//                        add(papi);
//                        setVisible(true);
//                        repaint();
//                    }
                }
            });

            setFocusable(true);
            requestFocusInWindow();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2D = (Graphics2D) g;
//            Don't have the image...
//            g2D.drawImage(image, 0, 0, this);
            repaint();
        }
    }
}
于 2013-04-12T08:23:45.540 回答