0

我试图在 Java 中使用graphics2DJFrame. 我在 JFrame 输入方法中添加了背景this.setBackground(new Color(54, 71, 99))颜色initWindow()。事实证明,这backBuffer是清除该背景而不是重新绘制导致此问题的行在render()方法中,最后一行backBuffer.show()

如何使它清除主要背景?

package asteroids;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;

public class Main extends Canvas implements KeyListener {

    private boolean gameOver;
    private BufferStrategy backBuffer;  
    private Dimension dimension = new Dimension(Config.WINDOW_WH[0], Config.WINDOW_WH[1]);
    private List<Star> stars = new ArrayList<Star>();
    private HashMap<Integer,Boolean> keyDownMap = new HashMap<Integer, Boolean>();

    public Main() {
        // Initialize Window
        initWindow();
        addKeyListener(this);

        this.setBackground(new Color(54, 71, 99));
        this.createBufferStrategy(2);               
        backBuffer = this.getBufferStrategy();

        // init variables
        gameOver = false;

        // Generating stars
        generateStars();

        // Init loop
        gameLoop();
    }

    public void initWindow(){
        JFrame window = new JFrame("Asteroids"); 
        setPreferredSize(dimension); 

        window.add(this);           
        window.pack();  
        window.setResizable(false);
        window.setVisible(true); 
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBackground(new Color(54, 71, 99));

        window.requestFocus();
    }

    public void update() {
        if(keyDownMap.containsKey(KeyEvent.VK_ESCAPE)){
            gameOver = false;
            System.exit(0);
        }
    }

    public void render(){
        Graphics2D g = (Graphics2D) backBuffer.getDrawGraphics();
        g.setColor(Color.WHITE);
        for(Star s: stars) {
            g.fillOval(s.posx - (s.width/2), s.posy - (s.height/2), s.width, s.height);
        }
        g.dispose();
        backBuffer.show();
    }

    public void generateStars() {
        for(int i = 0;i < 20;i++) {
            int starX = new Random().nextInt(Config.WINDOW_WH[0]-10)+5;
            int starY = new Random().nextInt(Config.WINDOW_WH[1]-10)+5;
            stars.add(new Star(starX, starY));
        }
    }

    public void gameLoop(){
        while(!gameOver){
            update();
            render();

            try{ Thread.sleep(20);}catch(Exception e){};
        }
    }

    public static void main(String[] args) {
        new Main();
    }


    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        keyDownMap.put(e.getKeyCode(), true);
    }

    @Override
    public void keyReleased(KeyEvent e) {
        keyDownMap.remove(e.getKeyCode());
    }
}
4

1 回答 1

1

如何使它不清除主要背景?

你不能。除了Canvas不透明(无法更改)之外,BufferStrategy还有不止一个页面可以在其上绘制其内容(因此允许执行页面翻转)。结合起来,这将无法维护父容器的背景。

相反,您应该(事实上,您必须)清除Graphics每次render调用时要绘制的缓冲区的上下文,否则您将绘制到之前绘制的内容上。

一种技术可能是生成BufferedImage带有“静态”内容的 a 并首先将其绘制到缓冲区

于 2017-10-29T19:34:20.670 回答