2014-07-17 2 views
1

stackoverflow 커뮤니티! 자바에서 작은 GUI 기반 게임을 만들고 있습니다. 지금 당장 약간의 문제가 있습니다. 내 프로그램에 대한 기본적인 이해를 돕기 위해JFrame 내부의 JPanel에서 제대로 다시 칠하는 방법

나는 메뉴 (JPanel)를 먼저 보여주는 창이있다. '게임 시작'버튼을 클릭하면 그것은 내가 게임을 할 수있는 다른 JPanel로 진행합니다. ! [menu_window] [1]

주기적으로 움직이는 작은 총알이 작동하는 타이머가 있습니다. 타이머가 작동 할 때마다 Panel은 총알을 다시 표시합니다. repaint 메서드가 작동하는 것을 볼 수는 있지만 이전 추적은 제거되지 않습니다.

! [2]

이 내 메인 클래스

import java.awt.Color; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class Main { 
    private final int window_x_size = 500; 
    private final int window_y_size = 500; 

    private JFrame frame; 
    private JPanel Menu; 
    private Game myGame = new Game();//extends from JPanel 



    private JButton startButton = new JButton("Game Start"); 
    private JButton exitButton = new JButton("Game Exit"); 
    private JButton showRank = new JButton("Rank"); 
    private JButton OneOnOne = new JButton("One on One"); 


    private ActionListener MyButtonListener = new MyButtonListener(); 
    public class MyButtonListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      Object source = e.getSource(); 

      if (source == startButton) { 

       frame.remove(Menu); 
       frame.setContentPane(myGame); 
       frame.validate(); 
       frame.repaint(); // prefer to write this always. 

      } else if (source == exitButton) { 
       System.exit(1); 
      } else if (source == showRank) { 

      } else {// one on one 

      } 

     } 
    } 


    public Main() { 
     frame = new JFrame(); 

     frame.setBackground(Color.white); 
     frame.setSize(window_x_size, window_y_size); 
     frame.setTitle("My First GUI Game"); 
     frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); 

     Menu = new JPanel(); 
     startButton.addActionListener(MyButtonListener); 
     exitButton.addActionListener(MyButtonListener); 
     showRank.addActionListener(MyButtonListener); 
     OneOnOne.addActionListener(MyButtonListener); 

     Menu.setLayout(new GridLayout(4, 1)); 
     Menu.add(startButton); 
     Menu.add(OneOnOne); 
     Menu.add(showRank); 
     Menu.add(exitButton); 

     frame.setContentPane(Menu); 
     frame.setVisible(true); 

    } 

    public static void main(String[] args) { 
     /* 
     * This is the most important part of your GUI app, never forget 
     * to schedule a job for your event dispatcher thread : 
     * by calling the function, method or constructor, responsible 
     * for creating and displaying your GUI. 
     */ 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       new Main(); 
      } 
     }); 


    } 

} 

이다 여기에 이미지 설명을 입력]이 내 게임 클래스

import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.Random; 
import javax.swing.ImageIcon; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class Game extends JPanel { 
    private Random rnd = new Random(); 
    private ActionListener MyBulletListener = new BulletListener(); 
    public KeyListener myKeyListen = new MyKeyListener(); 
    Timer bullet_timer; 

    private boolean IsExplosion = false; 
    private ImageIcon spacecraftImg = new ImageIcon("spacecraft.png"); 
    private Rectangle spacecraftBox = new Rectangle(5, 10, 
      spacecraftImg.getIconWidth(), spacecraftImg.getIconHeight()); 
    private ImageIcon explosionImg = new ImageIcon("explosion.png"); 
    private ImageIcon bulletImg = new ImageIcon("bullet.png"); 
    private Rectangle bulletBox = new Rectangle(70, 200, 
      bulletImg.getIconWidth(), bulletImg.getIconHeight()); 

    private MySound explosion_sound = new MySound(); 

    public Game() { 

     addKeyListener(myKeyListen); 
     bullet_timer = new Timer(500, MyBulletListener); 
     bullet_timer.start(); 

    } 

    public class MyKeyListener implements KeyListener { 

     private int x; 
     private int y; 

     @Override 
     public void keyPressed(KeyEvent e) { 

      // TODO Auto-generated method stub 
      int keyCode = e.getKeyCode(); 

      if (keyCode == 37) { 
       x = -10; 
       y = 0; 

      } else if (keyCode == 38) { 
       x = 0; 
       y = -10; 
      } else if (keyCode == 39) { 
       x = 10; 
       y = 0; 
      } else { 
       x = 0; 
       y = 10; 
      } 
      if (spacecraftBox.x + x < 0 
        || spacecraftBox.x + x > 500 
        || spacecraftBox.y + y < 0 
        || spacecraftBox.y + y > 500) { 

      } else { 
       move_plane(x, y); 
       repaint(); 
      } 
     } 

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

     } 

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

     } 

    } 
    public class BulletListener implements ActionListener { 
     private int x; 
     private int y; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      // TODO Auto-generated method stub 
      Object source = e.getSource(); 
      if (source == bullet_timer) { 

       int dir = rnd.nextInt(4); 
       if (dir == 0) {// move left 
        x = -10; 
        y = 0; 
       } else if (dir == 1) {// move right 
        x = 10; 
        y = 0; 
       } else if (dir == 2) {// move up 
        x = 0; 
        y = -10; 
       } else {// move down 
        x = 0; 
        y = 10; 
       } 
       if (bulletBox.x + x < 0 
         || bulletBox.x + x > 500 
         || bulletBox.y + y < 0 
         || bulletBox.y + y > 500) { 

       } else { 
        move_bullets(x, y); 
        repaint(); 
       } 
      } 

     } 
    } 


    @Override 
    public void paint(Graphics g) { 

     g.drawImage(bulletImg.getImage(), (int) bulletBox.getX(), 
       (int) bulletBox.getY(), null); 

     g.drawImage(spacecraftImg.getImage(), (int) spacecraftBox.getX(), 
       (int) spacecraftBox.getY(), null); 

     if (IsExplosion) { 
      g.drawImage(explosionImg.getImage(), (int) bulletBox.getX(), 
        (int) bulletBox.getY(), null); 
      MySound.play(); 
      IsExplosion = false; 

     } 

    } 

    public void move_plane(int x, int y) { 

     spacecraftBox.translate(x, y); 

     if (spacecraftBox.intersects(bulletBox)) { 
      IsExplosion = true; 
     } 
    } 

    public void move_bullets(int x, int y) { 
     bulletBox.translate(x, y); 

     if (spacecraftBox.intersects(bulletBox)) { 
      IsExplosion = true; 
     } 
    } 

} 

입니다 게다가 나는 모든 KeyListener를 추가하지만 '아무튼 일하지 마라. 나는 그것을 어떻게 풀어 낼지 전혀 모른다.

나는이 문제에 대해 인터넷 검색을 시도했다. 메인 클래스에서 집중할 수있는 게임 패널을 시도했지만 작동하지 않았습니다.

정말 감사드립니다. 인해 도장 방법에

최고 감사합니다,

Dongseop

답변

2

이 거의 항상 더러운 픽셀을 정리하는 슈퍼의 그림 메소드를 호출하지. 페인트를 오버라이드하고 있기 때문에 페인트 오버라이드의 첫 번째 메소드 호출로 super.paint(g);을 호출해야합니다.

다른 문제 :

  • 다음 나는이 같이 하지 재정의 페인트가 아니라 paintComponent(Graphics g)가, 애니메이션 자동 더블 버퍼링을 제공하고 애니메이션이 부드럽게 만들 것을 제안거야. 다시 메서드 재정의에서 super.paintComponent(g);을 호출하십시오.
  • 보기를 바꾸는 가장 쉬운 방법은 CardLayout을 사용하는 것입니다.
  • KeyListener보다는 KeyBinding을 사용하는 것이 더 좋으므로 KeyListener의 포커스 문제를 해결하는 데 도움이됩니다. KeyListener가 작동하지 않을 가능성이있는 문제입니다. 또한 재사용 가능한 작업을 사용할 수 있습니다. KeyListeners에서이 사이트를 검색하여 제가 의미하는 바를 확인하고 Key Bindings (일부는 저의 것)의 예를 봅니다. 또한 Google Java Key Bindings Tutorial을 사용하는 방법에 대한 공식 자습서를 참조하십시오.
관련 문제