2017-12-09 28 views
0

Java swing/awt로 간단한 게임을 만들려고합니다. 화면에서 이미지를 인쇄하거나 움직이는 동안 지연이 발생하는 문제가 있습니다.Java awt/swing 이미지 인쇄의 지연 문제는 어떻게 해결합니까?

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import java.io.File; 
import java.util.ArrayList; 
import javax.imageio.ImageIO; 
import javax.swing.*; 




public class StarDef extends JFrame implements Runnable, KeyListener{ 
    private BufferedImage back; 
    private boolean start = false, end = false; 
    public int w = 1500, h = 800, commandx = 200, commandy = 100, ground = 500, mineral = 100; 
    private int mineralx = 0, mineraly = commandy + 104; 
    private int dronecnt = 0; 
    private ArrayList<Drone> DrList = null; 
    private ArrayList<Enemy> EnList = null; 
    private ArrayList<Building> BuildList = null; 
    private ArrayList<Allies> AlyList= null; 
    public Image imagearr[] = new Image[10]; 
    private boolean makedrone = false, NeedMinerals = false; 
    public int picnum = 1; 
    private int OrderBuild = 0; 

    public static void main(String[] args){ 
     Thread t = new Thread(new StarDef()); 
     t.start(); 
    } 

    public StarDef(){ 
     back = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
     DrList = new ArrayList<>(); 
     BuildList = new ArrayList<>(); 
     EnList = new ArrayList<>(); 
     AlyList = new ArrayList<>(); 
     this.addKeyListener(this); 
     this.setSize(w,h); 
     this.setTitle("Starcraft"); 
     this.setResizable(false); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 
     try { 
      imagearr[0] = ImageIO.read(new File("Char/Command.png")); 
      imagearr[1] = ImageIO.read(new File("Char/droneleft.png")); 
      imagearr[2] = ImageIO.read(new File("Char/droneright.png")); 
      imagearr[3] = ImageIO.read(new File("Char/Mineral.png")); 
      imagearr[4] = ImageIO.read(new File("Char/barracks.png")); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void initGame(){ 
     DrList.clear(); 
     mineral = 100; 

    } 
    public void draw(){ 
     Graphics gs = back.getGraphics(); 
     gs.setColor(Color.white); 
     gs.fillRect(0,0,w,h); 
     gs.setColor(Color.DARK_GRAY); 
     gs.fillRect(0,ground,w,200); 

     if (!end) { 
      gs.drawImage(imagearr[0], commandx, commandy, null); // First Image-Command Center 
      gs.drawImage(imagearr[3], mineralx,mineraly,null); // Second Image-Mineral 

      for (int i = 0; i < DrList.size(); i++) { //Printing Drones 
       Drone m = DrList.get(i); 
       gs.drawImage(imagearr[m.state], m.x, m.y, null); //Drawing Drones 
       m.moveDr(); // Moving the Drone 
      } 

      for (int i = 0; i < BuildList.size(); i++){ //Printing Building 
       Building bd = BuildList.get(i); 
       if(bd.buildingtype == 'R'){ 
        gs.drawImage(imagearr[4], bd.x, bd.y, null); // Drawing Building-Problem starts..? 
       } 
      } 
      gs.drawImage(imagearr[0], commandx, commandy, null); 
     } 

     gs.setColor(Color.black); 
     gs.drawString("mineral : " + mineral, 10,50); 
     gs.drawString("Drones : " + DrList.size(), 10, 70); 

     Graphics ge = this.getGraphics(); 
     ge.drawImage(back, 0,0,w,h,this); 
    } 

    public void run(){ 

     try{ 
      int timer = 10; 

      while (true){ 
       Thread.sleep(timer); 
       if(start){ 
        if (makedrone) { 
         makedrone(); 
        } 
        if (OrderBuild>0){ 
         makeBuilding(OrderBuild); 
        } 
       } 
       draw(); 
      } 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void makeBuilding(int buildingnumber){ 
     int bdx, bdy; 
     char BuildingType; 
     if(buildingnumber == 1){ 
      bdx = 500; 
      bdy = 100; 
      BuildingType = 'R'; 
      Building barracks = new Building(this, bdx, bdy, BuildingType); 
      BuildList.add(barracks); 
     } 
    } 
    public void makedrone() { 

     if (mineral >= 50) { 
      int dronex = commandx; 
      int droney = commandy+129; 
      Drone dr = new Drone(this ,dronex, droney); 
      DrList.add(dr); 
      dronecnt++; 
      mineral -= 50; 
      makedrone = false; 

     } else if (mineral < 50) { 
      NeedMinerals = true; 
      makedrone = false; 
     } 

    } 

    public void keyPressed(KeyEvent ke){ 
     switch (ke.getKeyCode()){ 
      case KeyEvent.VK_ENTER: 
       start = true; 
       end = false; 
       break; 
      case KeyEvent.VK_D: 
       makedrone = true; 
       break; 
      case KeyEvent.VK_R: 
       OrderBuild = 1; 
       break; 
     } 
    } 

    public void keyReleased(KeyEvent ke){ 
     switch ((ke.getKeyCode())){ 

     } 
    } 
    public void keyTyped(KeyEvent ke) { 
    } 

}

코드를 컴파일

은, 처음 몇 정지 이미지를 잘 나타납니다

여기 아래에있는 내 코드입니다.

움직이는 이미지 (Drones)가 잘 나타난 후에 다음 정지 이미지 (건물)를 소환하면 무거운 지체가 나타나기 시작하고 움직이는 드론의 속도가 눈에 띄게 감소합니다.

건물은 약 300 * 150 픽셀이며 무인 항공기는 40 * 30 픽셀입니다.

이 문제의 근본 원인은 무엇입니까? 이것은 코드 (이미지 소환) 또는 그림의 크기 또는 컴퓨터 (노트북 (LG Gram 14in) 사용) 때문입니다.

+0

1) 한 가지 방법을 포함하여 탐구하려는 의지에 대한 링크이다 [이 Q & A] (http://stackoverflow.com/q/19209650/418556)에 나오는 이미지.2) 더 이상 고칠 수없는 문제에 대해서는 [코드 블록의 걸쇠 대괄호 탐지/수정] (http://meta.stackexchange.com/q/251795/155831)을 참조하십시오. –

답변

1

시작하지 않음 Graphics ge = this.getGraphics();.

독자도 Thread을 사용하고 있기 때문에 읽기/페인트가 더러워 질 수있는 스레드 경쟁 조건이 발생할 위험이 있습니다.

스윙 페인팅이 실제로 어떻게 작동하고 API 기능 내에서 작동하는지 이해하여 시작하십시오. Performing Custom Painting, Painting in AWT and SwingConcurrency in Swing

KeyListener를 살펴 가짐으로써

시작은 모니터 키 입력을위한 가난한 선택 당신은 키 바인딩 API를 사용한다 - 자세한 내용은 How to use key bindings를 참조하십시오.

ArrayList에 내용을 추가하면 성장주기가 진행되어 시간이 오래 걸리고 GC주기가 길어질 수 있습니다. ArrayList에 초기 용량을 시딩하는 것이 고려되면 성장주기 사이의 간격을 줄이는 데 도움이됩니다. 은 "페인트"논리에서 "업데이트"논리를 분리에

초점은, 당신이 성능 또한

Swing에서 렌더링 성능을 향상시키는 기술의 진가를 보여줍니다.

이 여전히 are't 경우 원하는 수준에 당신을 받고, 다음 자체에 대한 이미지 (들)을 얻을 예 A BufferStrategy