【问题标题】:How to initialize Graphics g?如何初始化图形g?
【发布时间】:2012-11-09 22:36:22
【问题描述】:

我想在生命结束后在 pacman 游戏中显示 GameOver 图像。但是我调用paintGameOverScreen(Graphics g) 然后我需要初始化g。有没有其他方法可以做到这一点?

这是我的生活课

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;


public class Lives{

private int lives;


public Lives() {
    lives = 1;
}

public void removeLife() {

        lives--;
        if(lives==0){
            System.out.println("END GAME");
            paintGameOverScreen(g);
            System.exit(0);
        }
}

public void paintGameOverScreen(Graphics g) {


            ImageIcon i = new ImageIcon("src\image");
            Image image = i.getImage();
            int x = 0;
            int y = 0;
            g.drawImage(image, x, y, 100,100,null);
}


public void paint(Graphics g) {
    g.setColor(Color.WHITE);
    g.fillRect(5*20, 25*20, 100, 30);
    g.setColor(Color.BLACK);
    String result = "Lives: " + lives;
    g.drawString(result, 6*20, 26*20);
}
}

【问题讨论】:

  • “初始化g”是什么意思? g 变量在进入paint方法时应该已经被AWT初始化了。
  • 而是保持游戏状态并根据它进行绘制
  • 如果您希望可以使用屏幕外缓冲区(例如 BufferedImage),请对其进行绘制,然后在准备好后将其与 UI 重新同步
  • removeLife() 方法中带有 if 语句的行是多余的,除非您可以添加生命。如果您只是删除了玩家唯一的生命,则无需检查生命是否等于 0。

标签: java swing graphics awt


【解决方案1】:

你永远不会自己打电话给paint()paintComponent(),你总是通过repaint() 来设置适当的Graphics

只是为了说明@mKorbel 指的是什么:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Lives extends JPanel {
    private int lives;
    private ImageIcon gameOverImage;

    public Lives() {
        try {
            gameOverImage = new ImageIcon(new URL("http://imgup.motion-twin.com/dinorpg/0/f/77acf80b_989624.jpg"));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        lives = 5;
    }

    public void removeLife() {
        if (lives > 0) {
            lives--;
            System.out.println("Left lives: " + lives);
            repaint();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (lives > 0) {
            System.out.println("Still have " + lives + " lives");
            g.setColor(Color.WHITE);
            g.fillRect(5 * 20, 25 * 20, 100, 30);
            g.setColor(Color.BLACK);
            String result = "Lives: " + lives;
            g.drawString(result, 6 * 20, 26 * 20);
        } else if (gameOverImage != null) {
            System.out.println("Game over");
            int x = (getWidth() - gameOverImage.getIconWidth()) / 2;
            int y = (getHeight() - gameOverImage.getIconHeight()) / 2;
            g.drawImage(gameOverImage.getImage(), x, y, gameOverImage.getIconWidth(), gameOverImage.getIconHeight(), this);
        }
    }

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame(Lives.class.getSimpleName());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final Lives lives = new Lives();
                frame.add(lives);
                frame.pack();
                frame.setVisible(true);
                // Dummy timer that reduces the lives every second. For demo purposes only of course
                Timer t = new Timer(1000, new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        lives.removeLife();
                    }
                });
                t.start();
            }
        });
    }
}

【讨论】:

    【解决方案2】:
    • for public void paint(Graphics g) {是否有遗漏的容器,

    • JPanel(在某些情况下是JComponent)可能是当今 Java 的容器

    • 必须使用paintComponent 而不是paint()

    • paintComponent 内你可以标记paintGameOverScreen,然后只画BufferedImage

    • Objects之前准备好所有Objects,如local variable,不要在paint()paintComponent()里面加载任何FileIO(加载图片)

    【讨论】:

    • +1 一些好的建议先生 :)。 OP也不能忘记super.paintComponent(..)调用
    • 作为参考,“Swing 程序应该覆盖paintComponent(),而不是覆盖paint()。”—Painting in AWT and Swing: The Paint Methods
    【解决方案3】:

    我是这样做的:

    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    
    public class InitializeGraphics
      {
            static BufferedImage buffer = null;
            static int height = 10;
            static int width = 10;
            static Graphics2D g2;
    
            public InitializeGraphics() {
                    buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
                    g2 = buffer.createGraphics();
                    g2.fillOval(2, 2, 2, 2);
                    g2.dispose();
            }
            protected void paintComponent(Graphics g) {
                    int x = 0;
                    int y = 0;
                    g.drawImage(buffer, x, y, width, height, null);
            }
            public Graphics2D getGraphics(){
                    return g2;
            }
        }
    

    然后某处: InitializeGraphics 实例=新 InitializeGraphics(); Graphics2D gG2 = instance.getGraphics();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 2015-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2017-04-03
      相关资源
      最近更新 更多