2014-07-25 3 views
0

나는 자바로 2D 게임을 만들고있다.Java 2D 게임. addnotify를 호출하는 대신 수행 할 작업은 무엇입니까?

Game.java :

지금까지 내 코드는 이것이다 내가있는 addNotify을 무시 곳이며,

package main; 

import javax.swing.JFrame; 

public class Game { 

public static void main(String[] args) { 
    JFrame gameWindow = new JFrame("Snake! - By Casida"); 
    gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    gameWindow.add(new GamePanel()); 
    gameWindow.pack(); 
    gameWindow.setResizable(false); 
    gameWindow.setVisible(true); 
} 
} 

GamePanel.java().

package main; 

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.image.BufferedImage; 

import javax.swing.JPanel; 

public class GamePanel extends JPanel implements Runnable, KeyListener { 

//Dimensions 
public static final int WIDTH = 384; 
public static final int HEIGHT = 384; 
public static final int SCALE = 2; 

//Game loop 
private Thread thread; 
private boolean running = false; 
private int FPS = 60; 
private long targetTime = 1000/FPS; 

//Image 
private BufferedImage image; 
private Graphics2D g; 

public GamePanel() { 
    setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 
    setFocusable(true); 
    requestFocus(); 
} 

@Override 
public void addNotify() { 
    super.addNotify(); 

    if(thread == null) { 
     thread = new Thread(this); 
     addKeyListener(this); 
     thread.start(); 
    } 
} 

private void init() { 
    running = true; 
    image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
    g = (Graphics2D) image.getGraphics(); 
} 

@Override 
public void run() { 
    init(); 

    long start; 
    long elapsed; 
    long wait; 

    while(running) { 

     start = System.nanoTime(); 

     update(); 
     draw(); 
     drawToScreen(); 

     elapsed = System.nanoTime() - start; 
     wait = targetTime - elapsed/1000000; 

     if(wait < 0) 
      wait = 5; 

     try { 
      Thread.sleep(wait); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public void update() { 

} 

public void draw() { 
    g.clearRect(0, 0, WIDTH, HEIGHT); 
} 

public void drawToScreen() { 
    Graphics g2 = getGraphics(); 
    g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null); 
    g2.dispose(); 
} 

@Override 
public void keyPressed(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void keyTyped(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 
} 

나는있는 addNotify 메소드를 오버라이드 (override)하는 낙담 것을 본 적이 있지만 내가 어떻게해야합니까 무엇인지, 그것을 무시하지 않고, 같은 결과를 얻을?

+1

KeyListener를 사용하지 말고 키 바인딩을 사용하고 getGraphics를 사용하지 않고 paintComponent를 재정의하고 ' 자신을 「생성」하지 않은 Graphics 문맥을 처리하지 말아주세요. 메인 쓰레드를 자신의 클래스로 옮기고, 패널의 레퍼런스를 넘겨 준다. UI의 나머지 부분을 만든 후에이 스레드를 만듭니다. 스윙 구성 요소는 기본적으로 버퍼링 될 수 있으므로 절대적인 이유가 없으면 휠을 다시 만들 필요가 없습니다. – MadProgrammer

+0

대부분 내 말이 의미가 있습니다. 메인 쓰레드를 자신의 클래스로 옮기는 것은 무엇을 의미합니까? paintComponent를 재정 의하여 게임 루프를 만들려고했지만 루프에 넣을 수있는 방법을 찾지 못했습니다. – user3149569

+0

paintComponent에 루프를 넣지 마십시오. paintComponent는 게임의 현재 상태를 페인트해야합니다. "게임 루프"를 자체 클래스에 배치하고 "게임 모델"에 대한 참조를 제공하고 UI에 직접 업데이트하도록 지시하는 방법 (모델을 사용하여 이벤트를 트리거하거나 직접 다시 칠할 수 있음)). 이렇게하면 코드를 분리하여 나중에 재사용 할 수 있습니다. – MadProgrammer

답변

1

Runnable을 구현하는 "게임 루프"를 자체 클래스로 분리하십시오. 패널과 "게임 루프"간에 공유되는 일종의 모델을 사용하십시오. "게임 루프"는 모델의 상태를 업데이트해야하고 패널은이를 모델링해야합니다. 필요한 경우

, 당신이 UI를 만든 후에는 자체

를 업데이트해야 UI를 알리기 위해 "게임 루프"를 허용 할 수있는 인터페이스를 사용하는 것이 좋습니다, 당신은 "게임 루프"를 구성 할 것 클래스와는

  • , KeyListener를 사용
  • Key bindingsgetGraphics를 사용 paintComponent을 무시하고이 사용자 지정 그림을 수행하지 마십시오 사용하지 마십시오 시작합니다. 자세한 내용은 Performing Custom Painting을 참조하십시오. 스윙은 패시브 렌더링 엔진을 사용합니다. 즉, 아무 것도하지 않고도 언제든지 업데이트가 발생할 수 있습니다. 이상 회화 될 것 getGraphics를 사용하여 그림 아무거나이이
  • 스윙 구성 요소를 두 번 있습니다 발생 이후의 업데이트를 막을 수, 예상치 못한 어려운
  • 당신이 "생성"하지 않은 Graphics 상황 폐기하지 마십시오 깜박 복제 될 수 있습니다 기본적으로 버퍼링되므로 단축키가 필요하지 않으면 바퀴를 다시 만들 필요가 없습니다.