2017-09-07 1 views
1

안녕하세요 저는 벽돌 깨기 게임을 만들려고합니다. Real_Main이라는 주 클래스와 JPanel을 확장하는 Real_Create라는 또 다른 클래스가 있습니다. 내 코드가 맘에 들지만 오른쪽 및 왼쪽 화살표 키를 사용하여 사각형을 움직일 수없는 것처럼 느껴집니다. 아무도 저에게 뭐가 잘못 됐는지 말해 줄 수 있습니까? 그리고 사각형을 움직이기 위해 타이머가 필요한 이유는 무엇입니까?사각형이 움직이지 않는다

import javax.swing.JFrame; 
public class Real_Main { 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     JFrame jf= new JFrame(); 

     Real_Create panel=new Real_Create(); 

     jf.setSize(500, 500); 
     jf.setVisible(true); 
     jf.setResizable(false); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jf.add(panel); 

    } 

} 

Real_Create : 게임에서

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JPanel; 
import javax.swing.Timer; 

public class Real_Create extends JPanel implements KeyListener,ActionListener { 

    int baseX=200; 

    int ballX=250; 
    int ballY=250; 
    int delay=20; 

    Timer tim; 


    Boolean play=false; 


    public Real_Create(){ 

     addKeyListener(this); 
     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); 

     tim=new Timer(delay,this); 

     tim.start(); 

    } 


    public void paint(Graphics g){ 

     //background 
     g.setColor(Color.black); 
     g.fillRect(1,1,500,500); 

     //baseplayer 

     g.setColor(Color.white); 
     g.fillRect(baseX, 430, 80, 10); 

     //ball 
     g.setColor(Color.green); 
     g.fillOval(ballX, ballY, 20, 20); 


     g.dispose(); 




    } 



    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     // TODO Auto-generated method stub 
     tim.start(); 
     repaint(); 

    } 

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

     if(e.getKeyCode()== KeyEvent.VK_RIGHT){ 

      if(baseX >=420){ 

       baseX=420; 
      } 

      else{ 

       moveRight(); 
      } 

     } 

     if(e.getKeyCode()== KeyEvent.VK_LEFT){ 

      if(baseX <=0){ 

       baseX=0; 
      } 

      else{ 

       moveLeft(); 
      } 

     } 


    } 




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

    } 

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

    } 

public void moveRight(){ 

     play=true; 
     baseX+=10; 
    } 

    public void moveLeft(){ 

     play=true; 
     baseX-=10; 
    } 
} 

이미지 :

Image from the game

+0

방금 ​​코드를 테스트했고, rect를 움직이는 것은 완벽하게 작동합니다. 스크린 샷 프로그램 때문일 수는 있지만 이미지에는 창에 포커스가 없습니다. keylistener가 작동하도록 집중해야합니다. 창을 클릭하십시오. 또한 Rect를 움직이는데 타이머가 필요하지 않습니다. 단지 20ms마다 윈도우를 다시 그립니다. 키를 누른 후에 다시 그리기를 호출 할 수도 있지만 애니메이션을 만들려고 할 때 유용합니다 공. – Gumbo

답변

0

당신이 다루고 인해 스레드 안전의 부족에 예상치 못한 스윙 동작입니다. 문서에 따르면 "Swing 구성 요소를 만들거나 상호 작용하는 모든 코드는 이벤트 발송 스레드에서 실행해야합니다." 당신이 그렇게처럼 GUI 생성을 다시 작성해야 달성하기 위해 :

public class Real_Main { 
    public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 

    private static void createAndShowGUI() { 
    JFrame jf = new JFrame(); 
    Real_Create panel = new Real_Create(); 
    jf.setSize(500, 500); 
    jf.setVisible(true); 
    jf.setResizable(false); 
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jf.add(panel); 
    } 
} 

을 당신은 주제 here에 대한 자세한 내용을보실 수 있습니다.

관련 문제