2015-01-10 3 views
0

나는 Snake 게임을 만들고 있는데 JLayeredPane을 사용해야하는 문제가 있습니다. 나는 타이머에 따라 끊임없이 다시 칠해야하는 DrawBoard 클래스를 사용하여 보드를 그렸습니다. DrawBoard 클래스에 배치 할 수 없으므로 보드에 배치 할 3 개의 과일에 임의의 색상을 지정해야합니다 (지속적으로 다시 그리기 때문에 임의의 색상이 모든 페인트에 대해 계속 변경됨). 별도의 JPanel, c2. c2는 이것을 컨테이너 (drawBoard 컴포넌트 포함)와 함께 JLayeredFrame에 넣습니다. c2가 컨테이너 상단에 놓일 수 있습니다 - 보드에 과일을 효과적으로 오버레이하여 매번 과일 구성 요소를 수동으로 다시 칠할 수 있습니다. 과일이 수집되어 임의의 색상이 설정됩니다.JPanel은 setOpaque (false) 메소드로 계속 Repainted되고 있습니다.

과일을 보드에 드로잉 할 때, 아래에서 보드를 볼 수 있도록 컴포넌트의 배경과 JPanel을 투명하게 설정해야합니다. 문제점은 c2.setOpaque (false)가 호출 될 때 c2 JPanel이 계속해서 다시 그려 지므로 과일에 대해 계속해서 임의의 색상을 생성한다는 점입니다.

그러면 JLayeredPane이 JFrame에 배치됩니다.

c2 JPanel을 자체 호출없이 투명 배경으로 만들려면 어떻게해야할까요?

보드 클래스 - JFrame에 나는 또한 모든 틱에 대한 해당 작업을 수행하는 actionPerformed 메소드와 타이머가이 클래스에서

public Board() { 
     boardBack(g); 
     startGame(); 
    } 

    public void boardBack(Graphics g) { 
     questionBox = new QuestionBox(); 
     drawBoard = new DrawBoard(); 
     points = new Points(); 
     fruit = new Fruit(); 
     filler = new Filler(); 

     JFrame frame = new JFrame("Snake"); 
     JPanel container = new JPanel(); 
     JPanel c2 = new JPanel(); 
     JLayeredPane pane = new JLayeredPane(); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.addKeyListener(this); 
     container.setLayout(new BorderLayout()); 
     c2.setLayout(new BorderLayout()); 
     frame.setResizable(false); 

     container.add(questionBox, BorderLayout.NORTH); 
     container.add(points, BorderLayout.CENTER); 
     container.add(drawBoard, BorderLayout.SOUTH); 

     c2.add(fruit, BorderLayout.SOUTH); 
     c2.add(filler, BorderLayout.NORTH); 

     filler.setOpaque(false); 
     fruit.setOpaque(false); 
     //This is where the problem exists, 
     //when removed I cannot see the drawBoard component below, 
     //but it no longer repaints. 
     c2.setOpaque(false); 

     container.setBounds(0, 0, 600, 720); 
     c2.setBounds(0, 0, 600, 720); 

     pane.add(c2, new Integer(2)); 
     pane.add(container, new Integer(1)); 

     pane.setPreferredSize(new Dimension(600, 720)); 

     frame.add(pane); 

     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

인 곳이다. 이 안에 과일 구성 요소가 리콜되지 않습니다. 실행 내가 문제를 보여주기 위해 paintComponent() 방법 내에서 System.out.println() 넣을 때

과일 클래스는

package snake; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.util.Random; 

import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class Fruit extends JPanel { 

    public static Color red = new Color(8005929); 
    public static Color brown = new Color(9067566); 
    public static Color purple = new Color(6684774); 

    public static Dimension dim4 = new Dimension(600, 600); 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(dim4.width, dim4.height); 
    } 

     Random rand = new Random(); 
     public int selectColour; 
     //The structure of the array is as follows 
     // [0] - fruit1 colour 
     // [1] - fruit2 colour 
     // [2] - fruit3 colour 
     public int[] colourSelected = new int[3]; 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     //This allows us to select a random colour for the fruit to be assigned. 
     //Where selectColour = 0 refers to the colour red 
     //Where selectColour = 1 refers to the colour brown 
     //Where selectColour = 2 refers to the colour purple 
     int selectColour = rand.nextInt(3); 

     switch (selectColour) { 
     case 0: 
      colourSelected[0] = selectColour; 
      g.setColor(red); 
      break; 
     case 1: 
      colourSelected[0] = selectColour; 
      g.setColor(brown); 
      break; 
     case 2: 
      colourSelected[0] = selectColour; 
      g.setColor(purple); 
      break; 
     } 

     //Draws the fruit at the point of the fruit 
     g.fillRect(Board.fruit1.x * Board.SCALE, Board.fruit1.y * Board.SCALE, 
       Board.SCALE, Board.SCALE); 

     //This draws the second fruit 
     g.setColor(brown); 
     g.fillRect(Board.fruit2.x * Board.SCALE, Board.fruit2.y * Board.SCALE, 
       Board.SCALE, Board.SCALE); 

     //This draws the third fruit 
     g.setColor(purple); 
     g.fillRect(Board.fruit3.x * Board.SCALE, Board.fruit3.y * Board.SCALE, 
       Board.SCALE, Board.SCALE); 

    } 

이 문제를 보여줍니다.

setOpaque (false)의이 (왼쪽 하단 과일 지속적으로 색상을 변경)

enter image description here

이 때 제거 코드에서 여전히 때는 먼저, 당신은 돈

enter image description here

+0

는 [실행 가능한 예 (https://stackoverflow.com/help를 제공하는 것을 고려,이 메소드를 호출 할 때마다 구성 요소를 다시 칠 수있는 방법에 paintComponent의 출력, 컬러 세대/mcve) 문제를 보여줍니다. 이것은 덜 혼란스럽고 더 나은 응답을 가져올 것입니다. – MadProgrammer

답변

2

중요한 일 ' 페인트 작업을 제어하지 마십시오. 페인트 작업은 여러 가지 이유로 발생할 수 있습니다. 많은 이유 중 하나는 제어 할 수 없습니다.

둘째, 페인팅은 구성 요소의 현재 상태를 페인트하고 논리를 포함하지 않아야합니다.

이동 당신이 Timer 대신 전화를하고

+0

하지만 setColour가 어디에 있는지에 관계없이 구성 요소를 지속적으로 다시 칠하기 때문에 결과적으로 차이가 없습니다. 결과적으로이 메서드를 paintComponent로 다시 호출하여 과일의 색을 설정해야합니다. – HyperBlue

+0

또한 말했듯이, c2.setOpaque (false)를 제거하면 더 이상 자체를 다시 칠하지 않습니다. – HyperBlue

+0

문제를 나타내는 실행 가능한 예제를 제공하십시오. 투명한 컴포넌트는 오버랩되는 하나 이상의 컴포넌트가 업데이트 될 때 재 검증되어야하므로 코드의 다른 부분이 업데이트되어 다시 그려 질 수 있습니다. – MadProgrammer