나는 간단한 2D 게임을하고있다. 각 틱, 특정 효과 (페이드 전환, 오디오 페이드 인/아웃 등)에 대한 스레드를 시작하는 효과 대기열을 확인하고 싶습니다. 예를 들어, 메뉴 화면에서 "재생"을 누르면이 큐에 "FadeOut"메시지가 추가되고 처리되고 스레드가 시작되어 GamePanel에서 알파 값이 증가하는 검은 색 사각형이 그려집니다.PaintComponent() 외부의 JPanel에 그려진 BufferedImage를 getGraphics()로 덮어 쓰는 법
paintComponent()를 재정의하고 Graphics 객체를 현재 상태 인 draw()에 전달하는 GameStateManager에 내 Graphics 객체를 보내는 중입니다. 현재 paintComponent() 그래픽 객체를 라우트하는 효과 상태 (어쩌면해야 할 것 같은)가 없지만 getGraphics()를 사용하여 내 게임 스레드를 내 효과 스레드에 전달합니다. gameloop은 여전히 게임을 렌더링하므로 GamePanel에 직사각형을 직접 그리면 깜박임이 발생합니다.
나는 BufferedImage에 알파를 증가시키면서 검은 사각형을 그릴 수 있고, AlphaComposite.Src (새로운 그리기가 이전을 대체하게 함)로 컴포지트를 설정 한 다음 게임 패널에 BufferedImage를 그립니다. 문제는 게임 패널에 그린 BufferedImages가 각 그리기를 오버라이드하지 않기 때문에 다양한 알파의 검은 BufferedImages가 서로 겹치기 때문에 페이드 아웃이 실제로 빠르게 발생한다는 것입니다.
이 짧은 프로그램을 작성하여 컴포지트 설정을 테스트하고 무엇이 오버라이드되는지 확인하십시오. 모든 드로잉은 draw()에서 수행됩니다.이 드로잉은 effect 스레드에서 내 run()이됩니다. 흥미로운 무엇
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ScratchPad extends JPanel implements Runnable
{
private JFrame oFrame = null;
private Thread oGameThread = null;
private Graphics2D oPanelGraphics = null;
private Graphics2D oImageGraphics = null;
private BufferedImage oImage = null;
public static void main(String args[]) throws Exception
{
new ScratchPad();
}
public ScratchPad()
{
createFrame();
initPanel();
addAndShowComponents();
oGameThread = new Thread(this, "Game_Loop");
oGameThread.start();
}
private void addAndShowComponents()
{
oFrame.add(this);
oFrame.setVisible(true);
}
private void initPanel()
{
this.setOpaque(true);
this.setBackground(Color.cyan);
}
private void createFrame()
{
oFrame = new JFrame("Fade");
oFrame.setSize(700, 300);
oFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
oFrame.setLocationRelativeTo(null);
}
public void run()
{
oImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
while(true)
{
try
{
draw();
Thread.sleep(100);
}
catch(InterruptedException e)
{
}
}
}
private void draw()
{
oPanelGraphics = (Graphics2D)this.getGraphics();
oImageGraphics = oImage.createGraphics();
oImageGraphics.setComposite(AlphaComposite.Src);
oImageGraphics.setColor(new Color(0,0,0,90));
oImageGraphics.fillRect(0, 0, oImage.getWidth(), oImage.getHeight());
oPanelGraphics.drawImage(oImage, 10, 10, null);
oImageGraphics.setColor(new Color(0,0,0,60));
oImageGraphics.fillRect(0, 0, oImage.getWidth(), oImage.getHeight());
oPanelGraphics.drawImage(oImage, 220, 10, null);
oImageGraphics.setColor(new Color(0,0,0,30));
oImageGraphics.fillRect(0, 0, oImage.getWidth(), oImage.getHeight());
oPanelGraphics.drawImage(oImage, 430, 10, null);
// Drawing this image over location of first image, should overwrite first
// after setting composite to 'Src'
oPanelGraphics.setComposite(AlphaComposite.Src);
oImageGraphics.setColor(new Color(0,0,0,10));
oImageGraphics.fillRect(0, 0, oImage.getWidth(), oImage.getHeight());
oPanelGraphics.drawImage(oImage, 10, 10, null);
oImageGraphics.dispose();
oPanelGraphics.dispose();
}
} // end class
은 'oPanelGraphics'의 복합을 설정하면 이전에 있던 이미지 위에 그려지는 완전히 불투명 한 검정색 이미지의 결과로, 멀리 이동합니다 BufferedImage의 어떤 알파 원인입니다. 검은 색이 아닌 다른 색으로 설정하는 것조차도 효과가 없습니다.
oImageGraphics.setComposite(AlphaComposite.SrcIn);
을 표시 할 아무 것도 발생하지 않습니다 : 흥미 무엇
는에 BufferedImage에 대한 복합을 설정합니다. Java2D에서 그래픽을 합성하는 Oracle 설명서는 'SrcIn'에 대해 다음과 같이 설명합니다.
"소스와 대상의 픽셀이 겹치면 겹치는 영역의 소스 픽셀 만 렌더링됩니다."
그래서, 나는 이것이 AlphaComposite.Src에서 얻은 것과 같은 행동을 할 것으로 기대합니다.
어쩌면 누군가가 이러한 합성물의 진행 상황에 대해 밝힐 수 있으며 원하는 효과를 얻는 방법을 알 수 있습니다.
이 draw() 메서드 대신 패널에서 onDraw (Graphics g2d)를 재정의 할 수 있습니까? –
@MarcosVasconcelos 네, 그게 제가 현재하고있는 일입니다. 그러나 내 게임 (전환, 화면 및 오디오 페이드 인 및 페이드 아웃)에서 효과를 처리하는 방법은 동작을 수행하는 것이 었습니다 (메뉴에서 "재생"을 클릭하거나 특정 타일을 걷는 문자)하면 대기열에 메시지가 추가됩니다 각 게임 틱. 이러한 효과는 스레드에서 실행되어 처리되고 게임 루프는 계속 진행될 수 있습니다. 현재 paintComponent()에서 Graphics 객체를 내 Effects 클래스로 라우팅하지 않습니다. 이것이 효과 스레드에서 getGraphics를 사용하는 이유입니다. – WhitJackman
코드에 따라, 당신은 'paintComponent'를 전혀 무시하지 않고, getGraphics를 사용하고 있습니다. 권장하지는 않습니다. UI 외부에서 UI를 업데이트하려고 시도하고 있습니다. Swing이 정의한 페인트 사이클의 컨텍스트 또한 생성하지 않은'Graphics' 문맥을 처리해서는 안됩니다. 나는 또한 BufferedImage의 요점을 보지 못했다. 또한 애니메이션이 Swing에서 작동하는 방법에 대한 개념이없는 것처럼 보입니다. – MadProgrammer