2013-06-28 2 views
3

나는 여기에 새로운 있습니다. 당신이 도울 수 있기를 바랍니다.자바 게임 개발 : 그래픽

문제점 : JFrame에 애니메이션을 표시하는 데 문제가 있습니다. Java 그래픽이 어떻게 작동하는지 충분히 이해하지 못한다.

글로벌 아이디어 : 게임/영화/클립을 만들고 싶다고합니다. 이것을 위해서 나는 (단순하지 않은) 간단한 애니메이션이 필요하다.

이 질문에 대한 예 : 나는 그것의 구성 (크기, 닫기 작업 등)을 설정하고 다음 클래스 상자의 개체를 창조하는 JFrame의의 화면 stuff- 선언을 가지고 클래스 화면을 가지고, 프레임에 표시됩니다. 이 이미지/클래스 다이어그램을 확인하십시오 (올바르게 작성했으면 좋겠 음). ClassesDiagram

이제 클래스 상자가 JPanel을 확장합니다. JPanel에서 Paint() 메서드를 상속하고 상자를 페인트하는 대신 재정의합니다.

Screen 클래스에서 두 개의 Box를 만든 후 JFrame에 추가 (i .add)합니다. 그런 다음 루프를 시작하면서 (true) 스레드가 해당 양을 잠자 게함으로써 200 밀리 초마다 상자의 위치를 ​​업데이트합니다. (이 경우, 단순한 x ++ 또는 y ++는 box1 또는 box2의 어느 상자에 종속되어 있는가).

주요 문제 1) :이 프로그램은 실행하고 JFrame의 표시되지만 JFrame의에이 마지막으로 추가 된 객체/컴포넌트 - 상자 보여줍니다. 다른 하나는 보여주지 않습니다. 왜?

주제가 How to add multiple components to a JFrame? 인 것을 발견했으며 가장 투표가 많은 게시물을 jjnguy11 월 15, 2010 17:02에으로 작성했습니다. 이상한 이유로 첫 번째 팁이 아니고 두 번째 팁도 저에게 효과적이었습니다.

주된 문제 2) : 내가 아는 한, 나는 레이아웃 매니저가 필요하다. 프레임의 특정 X, Y에 페인트를하고 싶다면 왜 필요합니까?

다른 게시물 (다시 발견 할 수 없음) + 레이아웃에 대한 오라클의 지침을 찾았다면 setLayout (null) 사용을 고려해야한다고 제안했습니다. 나는 그렇게하려하지만, 다시 한 번 문제가있다.

주요 문제 3) : JFrame이 나타나면 1 개의 상자 만 표시됩니다 (녹색이 표시되지 않습니다. 이유는 모르겠 음). 이동하면 지워집니다. 반대편. 여기에 : Box Movement

도움, 팁 및 설명을 미리 감사드립니다! 희망, 게시물을 명확하고, 조직, 그리고 좋은 찾고 있습니다.


public class Screen { 

public static void main(String[] args) { 
    new Screen(); 
} 

private JFrame window; 

public Screen() { 
    window = new JFrame("Multiply components panel"); 
    //window.setLayout(null); 
    window.setSize(200, 200); 

    window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

    Box b1 = new Box(10,10, "box1"); 
    //b1.setBounds(10, 10, 50, 50); 

    Box b2 = new Box(100,100, "box2"); 
    //b2.setBounds(100, 100, 50, 50); 


    window.add(b1); 
    //window.add(b2); 


    window.setVisible(true); 

    while (true){ 

     b1.update(); 
     b2.update(); 

     try { 
      Thread.sleep(200); 
     } catch (Exception e) { 
      // TODO: handle exception 
     } 
    } 

} 
} 

public class Box extends JPanel{ 

int x, y, w, h; 
private String name; 

public Box(int x, int y, String name) { 
    this.x = x; 
    this.y = y; 
    this.w = 100; 
    this.h = 100; 
    this.name=name; 
} 


public void paint(Graphics g){ 
    System.out.println(this.name.equalsIgnoreCase("box1")); 
    if(this.name.equalsIgnoreCase("box1")){ 
     g.setColor(Color.BLACK); 
     g.fillRect(x, y, w, h); 
    }else{ 
     g.setColor(Color.GREEN); 
     g.fillRect(x, y, w, h); 
    } 


} 


public void update() { 
    if(this.name.equalsIgnoreCase("box1")) 
     x++; 
    else 
     y++; 
    //this.setBounds(x, y, w, h); 
    System.out.println("Current "+name+": X: "+x+", Y: "+y+", W: "+w+", H: "+h); 
    repaint(); 
} 

} 
+2

1 년 동안 피드를 제공하지만, [Concurrency in Swing] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)을 먼저 살펴본 후 SO를 찾아보십시오. 스윙과 애니메이션 – MadProgrammer

+0

@DavidKroukamp 유용한 링크를 제공해 주셔서 감사합니다. 나는 그것을 조사해보고 거기에서 물건을 어떻게 만들 었는지보십시오. 그래도 내가 빠진 것을 이해하고 싶습니다. 단지 2 개의 객체를 만드는 것은 너무 복잡하지 않아야합니다. 나는 그 배후의 아이디어를 이해하고 싶다. – Daniel

+0

@MadProgrammer 그럼 네가 그걸로 살아야 해, 아빠. 링크를 가져 주셔서 감사합니다. 얼마나 유용한 지 확신 할 수 없습니다. 깊이있는 스레드가 작동하는 것처럼 보입니다. 필요한 것은 아닙니다. 적어도 지금은. – Daniel

답변

3

주요 문제 1) :이 프로그램은 실행하고 JFrame의 표시되지만 이 JFrame의에 그것은 단지 마지막에 추가 객체/컴포넌트 - 상자를 보여줍니다 . 다른 하나를 표시하지 않습니다. 왜?

당신은 기본적 JFrame으로 window.add(b1); window.add(b2);, 당신이 add(..)을 수행 할 때 BorderLayout 따라서 마지막에 추가 상자를 대체하고있다 않습니다.

주요 문제 2) : 내가 이해하는 한, 레이아웃 관리자가 필요합니다. 왜 그래야합니까 프레임의 특정 X, Y에 페인트를하고 싶다면 (?) 필요합니까?

이 우리가 JPanel의 배치를 완벽하게 제어 할 원하는 setLayout(null)를 사용하는 유일한 시간이 될 것보다는 게임의 객체로 JPanel의를 사용하는 경우.

주요 문제 3). JFrame에 그것은 단지 1 상자 (당신이 할 것입니다 무엇이든 늘 녹색 한 표시를 보여줍니다 나타 왜 몰라)과 는 도착은 Move 않는 경우 다른 쪽에서 지워졌습니다. 여기 : 상자 운동

당신 때문에 당신이 g.fillRect(x,y,w,h), 그것은 g.fillRect(0,0,w,h)

다른 문제해야합니까 :

1) 나는 당신이 주요 문제는 여기 생각 :

public class Box extends JPanel{ 

    ... 

    public void paint(Graphics g){ 

     ... 
    } 

} 

paintComponentJPanel으로 대체하고 super.paintComponent(g) 재정의 된 메서드의 첫 번째 호출입니다.

3)) JPanelgetPreferredSize을 무시하고 JPanel

4의 이미지 나 내용과 일치 정확한 치수를 반환해야는 JFrame 사용에 setSize를 호출 올바른 Layoutmanager 및/또는 단순히 전화보다 필요한 용기의 getPreferredSize을 무시하지 말아 pack()JFrame으로 설정 한 다음 표시되도록 설정하십시오.

5) @MadProgrammer가 말한대로 Concurrency in Swing에 대한 읽기가 있지만 기본적으로 모든 스윙 구성 요소는 SwingUtilities.inokeXXX 블록을 통해 EDT에서 생성/조작되어야합니다. 이 일을

6)의 definetly 나쁜 :

만 연속 루프를 만들뿐만 아니라 당신에게 GUI를 생성 한 스레드에 Thread.sleep를 호출하지 않는 한
while (true){ 

    b1.update(); 
    b2.update(); 

    try { 
     Thread.sleep(200); 
    } catch (Exception e) { 
     // TODO: handle exception 
    } 
} 

, 따라서 동결하는 것 것입니다. How to use Swing Timers을보고, 위 질문에 대한 답변도 this와 같이보십시오.

enter image description here

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class Screen { 

    private JFrame window; 

    public static void main(String[] args) { 

     //creat UI on EDT 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Screen(); 
      } 
     }); 
    } 

    public Screen() { 
     window = new JFrame("Multiply components panel") { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(600, 400); 
      } 
     }; 

     window.setLayout(null);//only reason this is warrented is because its a gmae using JPanels as game objects thus we need full control over its placing 
     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//changed from DISPOSE to EXIT so Timers will be exited too 

     final Box b1 = new Box(10, 10, 50, 50, "box1"); 

     final Box b2 = new Box(100, 100, 50, 50, "box2"); 

     window.add(b1); 
     window.add(b2); 

     window.pack(); 
     window.setVisible(true); 

     Timer timer = new Timer(200, new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       b1.update(); 
       b2.update(); 
      } 
     }); 
     timer.setInitialDelay(0); 
     timer.start(); 

    } 
} 

class Box extends JPanel { 

    int x, y, w, h; 
    private String name; 

    public Box(int x, int y, int w, int h, String name) { 
     this.x = x; 
     this.y = y; 
     this.w = w; 
     this.h = h; 
     this.name = name; 
     setBounds(x, y, w, h);//let the Box class handle setting the bounds more elegant OOP 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     System.out.println(this.name.equalsIgnoreCase("box1")); 
     if (this.name.equalsIgnoreCase("box1")) { 
      g.setColor(Color.BLACK); 
      g.fillRect(0, 0, w, h); 
     } else { 
      g.setColor(Color.GREEN); 
      g.fillRect(0, 0, w, h); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(w, h); 
    } 

    public void update() { 
     if (this.name.equalsIgnoreCase("box1")) { 
      x++; 
     } else { 
      y++; 
     } 
     this.setBounds(x, y, w, h);//set the new bounds so box may be updated 
     System.out.println("Current " + name + ": X: " + x + ", Y: " + y + ", W: " + w + ", H: " + h); 
     revalidate(); 
     repaint(); 
    } 
} 

가 마지막으로 Game Development Loop, Logic and Collision detection Java Swing 2D을 니펫을 내 튜토리얼/코드를 살펴있다 : 여기

구현 위의 수정과 코드입니다.

게임 루프, 로직, 픽셀 충돌 감지, 애니메이션 (즉, 여러 스프라이트를 스와핑하여 스프라이트 세트의 애니메이션을 만드는 등)과 같은 간단한 2D 게임을 시작하는 데 필요한 모든 것이 있습니다. 근본적인 차이점은 그것은 객체를 게임 엔티티로 사용합니다. 즉, 클래스가 객체를 그리는 데 필요한 모든 정보를 보유 할 것입니다. IMO는 게임이 어떻게 수행되어야하는지, 그래픽이 강렬 해지고 많은 JPanels가 화면이 전반적으로 떨어지게 될지 궁금합니다. FPS

+0

답변 해 주셔서 감사합니다. 나는 그것을 조심스럽게 점검하고 그것을 배우고 이해하려고 노력할 것이다. 질문이 있으면 쓰겠습니다. 한 가지를 통해 - 다른 Box를 추가하려고 시도했는데, 첫 번째 사라진 동안 나타났습니다. : \ – Daniel

+1

@DanielBenshtein 내 업데이트 된 게시물을 참조하십시오. 귀하의 모든 질문에 답하기 위해 최선을 다했으며, 단지 1 대신에 두 개의 상자를 모두 표시했습니다. –

+0

인내심과 우수하고 완전한 대답을 해주셔서 대단히 감사합니다! 이제 남은 일은 코드를 확인하고 배우는 것, 그리고 당신과 다른 사람들이 준 링크와 함께하는 것입니다 (하지만 지금은 내 작업입니다). 감사합니다! – Daniel