Java g.dispose不清除屏幕

时间:2015-05-24 22:37:41

标签: java canvas graphics jframe dispose

我试图制作基于2D平铺的游戏。我在尝试绘制新图形时遇到了一个问题,旧图像似乎没有被删除。

如果有人知道g.dispose为什么不清除图形,那么请帮忙。

这是我的" Main"类:



package Main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class Main extends Canvas implements Runnable {

  private static final long serialVersionUID = 1L;

  private JFrame frame;

  static int size = 40;
  static int tilesX = 20;
  static int tilesY = 20;
  static int width = size * 10;
  static int height = size * 10;
  private boolean running = false;

  public static STATE state = STATE.MENU;
  public static PLAYER type = PLAYER.ARCHER;
  private Thread thread;

  static tileMap grid = new tileMap();
  tile[][] map = tileMap.map;

  public Main() {
    addKeyListener(new controls());
    addMouseListener(new mouse());
    Dimension wSize = new Dimension(width, height);
    setPreferredSize(wSize);
    frame = new JFrame();
  }

  public synchronized void start() {
    running = true;
    thread = new Thread(this, "game");
    thread.start();

  }

  public synchronized void stop() {
    running = false;
    try {
      thread.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public enum STATE {
    MENU, GAME
  }

  public enum PLAYER {
    ARCHER, KNIGHT
  }

  public static void main(String[] args) {
    Main game = new Main();
    game.frame = new JFrame("Game");
    game.frame.add(game);
    game.frame.setResizable(false);
    game.frame.pack();
    game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game.frame.setVisible(true);
    game.start();
  }

  public void run() {
    while (running) {
      if (state == STATE.MENU) {
        menu();
      } else if (state == STATE.GAME) {
        tick();
        render();
      }
      try {
        Thread.sleep(16);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  private void menu() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
      createBufferStrategy(2);
      return;
    }

    Graphics g = bs.getDrawGraphics();

    g.drawRect(Main.width / 8, 20, Main.width / 3, 200);
    g.drawString("Archer", Main.width / 8, 20);
    g.drawRect((Main.width - Main.width / 3) - Main.width / 8, 20,
      Main.width / 3, 200);
    g.drawString("Knight", (Main.width - Main.width / 3) - Main.width / 8,
      20);

    g.dispose();
    bs.show();
  }

  private void render() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
      createBufferStrategy(3);
      return;
    }

    Graphics g = bs.getDrawGraphics();

    Graphics2D d = (Graphics2D) g;

    camera.setCam();

    g.translate(-camera.camX, -camera.camY);

    for (int i = 0; i < map.length; i++) {
      for (int j = 0; j < map[i].length; j++) {
        d.setColor(map[i][j].getC());
        d.fillRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
        d.setColor(Color.BLACK);
        d.drawRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
      }
    }

    map[player.p.getX()][player.p.getY()].setC(player.p.getC());



    if (type == PLAYER.ARCHER) {
      d.drawString("Archer", 5, 15);
    } else if (type == PLAYER.KNIGHT) {
      d.drawString("Knight", 5, 15);
    }

    g.dispose();
    bs.show();
  }

  static public void moved() {
    tileMap.map[player.p.getX()][player.p.getY()].setC(Color.GREEN);
  }

  private void tick() {
    if (player.p == null) {
      player.createP();
    }
  }
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

Graphics#dispose释放Graphics上下文可能持有的所有内部资源,减少内存开销,不会“清除”上下文。

来自JavaDocs

  

处理此图形上下文并释放它正在使用的所有系统资源。调用dispose后,无法使用Graphics对象。

它没有做的是影响底层内容,这很烦人,因为使用Graphics对象的副本是一种很好的简单方法,可以在不影响原始上下文的情况下进行复杂的更改

要“清除”上下文,您可以在执行下一个绘画循环之前使用fillRect绘制颜色/背景。在Graphics g = bs.getDrawGraphics();

之后执行此操作