문제

게임의 일부로 10ms마다 실행되는 다음 코드가 있습니다.

private void gameRender()
{
    if(dbImage == null)
    {
        //createImage() returns null if GraphicsEnvironment.isHeadless()
        //returns true. (java.awt.GraphicsEnvironment)
        dbImage = createImage(PWIDTH, PHEIGHT);
        if(dbImage == null)
        {
            System.out.println("dbImage is null"); //Error recieved
            return;
        }
        else
        dbg = dbImage.getGraphics();
    }

    //clear the background
    dbg.setColor(Color.white);
    dbg.fillRect(0, 0, PWIDTH, PHEIGHT);

    //draw game elements...

    if(gameOver)
    {
        gameOverMessage(dbg);
    }
}

문제는 이미지를 정의하려고 시도한 후에도 이미지가 null인지 확인하는 if 문을 입력한다는 것입니다. 나는 주위를 둘러 보았고 GraphicsEnvironment.isheadless ()가 true를 반환하면 createImage ()가 null을 반환 할 것 같습니다.

나는 isheadless () 메소드의 목적이 무엇인지 정확히 이해하지 못하지만 컴파일러 나 IDE와 관련이 있다고 생각했기 때문에 두 가지를 시도했는데 둘 다 동일한 오류 (Eclipse 및 BlueJ)를 얻었습니다. 누구든지 오류의 원인이 무엇인지, 어떻게 고칠 수 있습니까?

미리 감사드립니다

홍옥

...................................................................

편집 : java.awt.component.createimage (int width, int height)를 사용하고 있습니다. 이 방법의 목적은 게임 플레이어의 모습을 포함하는 이미지를 작성하고 편집하는 것입니다. 이것이 전혀 도움이된다면 더 많은 코드가 있습니다.

public class Sim2D extends JPanel implements Runnable
{

private static final int PWIDTH = 500;
private static final int PHEIGHT = 400;
private volatile boolean running = true;
private volatile boolean gameOver = false;

private Thread animator;

//gameRender()
private Graphics dbg;
private Image dbImage = null;


public Sim2D()
{   
    setBackground(Color.white);
    setPreferredSize(new Dimension(PWIDTH, PHEIGHT));

    setFocusable(true);
    requestFocus(); //Sim2D now recieves key events
    readyForTermination();

    addMouseListener( new MouseAdapter() {
        public void mousePressed(MouseEvent e)
        { testPress(e.getX(), e.getY()); }
    });
} //end of constructor

private void testPress(int x, int y)
{
    if(!gameOver)
    {
        gameOver = true; //end game at mousepress
    }
} //end of testPress()


private void readyForTermination()
{
    addKeyListener( new KeyAdapter() {
        public void keyPressed(KeyEvent e)
        { int keyCode = e.getKeyCode();
            if((keyCode == KeyEvent.VK_ESCAPE) ||
               (keyCode == KeyEvent.VK_Q) ||
               (keyCode == KeyEvent.VK_END) ||
               ((keyCode == KeyEvent.VK_C) && e.isControlDown()) )
            {
                running = false; //end process on above list of keypresses
            }
        }
    });
} //end of readyForTermination()

public void addNotify()
{
    super.addNotify(); //creates the peer
    startGame();       //start the thread
} //end of addNotify()

public void startGame()
{
    if(animator == null || !running)
    {
        animator = new Thread(this);
        animator.start();
    }
} //end of startGame()


//run method for world
public void run()
{
    while(running)
    {
        long beforeTime, timeDiff, sleepTime;

        beforeTime = System.nanoTime();

        gameUpdate(); //updates objects in game (step event in game)
        gameRender(); //renders image
        paintScreen(); //paints rendered image to screen

        timeDiff = (System.nanoTime() - beforeTime) / 1000000;
        sleepTime = 10 - timeDiff;

        if(sleepTime <= 0) //if took longer than 10ms
        {
            sleepTime = 5; //sleep a bit anyways
        }

        try{
            Thread.sleep(sleepTime); //sleep by allotted time (attempts to keep this loop to about 10ms)
        }
        catch(InterruptedException ex){}

        beforeTime = System.nanoTime();
    }

    System.exit(0);
} //end of run()

private void gameRender()
{
    if(dbImage == null)
    {
        dbImage = createImage(PWIDTH, PHEIGHT);
        if(dbImage == null)
        {
            System.out.println("dbImage is null");
            return;
        }
        else
        dbg = dbImage.getGraphics();
    }

    //clear the background
    dbg.setColor(Color.white);
    dbg.fillRect(0, 0, PWIDTH, PHEIGHT);

    //draw game elements...

    if(gameOver)
    {
        gameOverMessage(dbg);
    }
} //end of gameRender()

} //end of class Sim2D

이것이 조금 분리하는 데 도움이되기를 바랍니다. Jonathan

도움이 되었습니까?

해결책

CreateImage (...) 대신 보통 BufferedImage를 사용합니다.

다른 팁

프랙탈 생성기를 위해 더블 버퍼링을 구현하려고 시도한 후에는 정확히 같은 문제가있었습니다. 내 해결책 : 나는 책에서 예제를 가져 왔지만 생성자 내부에서 CreateImage를 실행하는 방식으로 결과를 알지 못했습니다. 이것은 nullpointer를 생성했습니다. 그런 다음 나는 이것을 넣었다

if (_dbImage == null) {
_dbImage = createImage(getSize().width, getSize().height);
_dbGraphics = (Graphics2D)_dbImage.getGraphics();
}

업데이트 방법 내부에서 작동했습니다 !! 객체가 구성된 후 업데이트가 호출되기 때문입니다.

java.awt.component의 문서에 따르면, 구성 요소를 표시 할 수없는 경우 CreateImage는 NULL을 반환 할 수 있습니다.

당신이하려는 일을 위해, 당신은 구성 요소에 묶이지 않기 때문에 bufferedimage 클래스를보아야합니다.

확장중인 jpanel에서 addnotify () 메소드를 재정의 해보십시오. 예를 들어 생성자와 같은 애니메이션을 '시작'하기에 좋은 장소입니다. super.addnotify ()를 포함하십시오.

public void addnotify () {super.addnotify (); 게임을 시작하다(); }

행운을 빌어 요

구성 요소가 실제로 화면에 표시되는 것보다 스레드가 일찍 시작되는 것처럼 보입니다. 이런 일이 발생하지 않도록 jpanel의 페인트 (그래픽 g) 메소드를 무시하고 페인트 메소드 내부의 스레드의 run () 메소드에 코드를 넣을 수 있습니다. 스레드의 run () 메소드에서 Repaint ()을 호출하십시오.

예 :

public void paint(Graphics g){
        **gameUpdate(); //updates objects in game (step event in game)
        gameRender(); //renders image
        paintScreen(); //paints rendered image to screen**
}

그리고 당신의 run () 메소드에서 :

public void run(){
 while(running)
    {
        long beforeTime, timeDiff, sleepTime;

        beforeTime = System.nanoTime();

        **repaint();**

        timeDiff = (System.nanoTime() - beforeTime) / 1000000;
        sleepTime = 10 - timeDiff;

        if(sleepTime <= 0) //if took longer than 10ms
        {
            sleepTime = 5; //sleep a bit anyways
        }

        try{
            Thread.sleep(sleepTime); //sleep by allotted time (attempts to keep this loop to about 10ms)
        }
        catch(InterruptedException ex){}

        beforeTime = System.nanoTime();
    }
}

iSheadless는 비 GUI 환경 (예 : 서버 또는 서블릿 컨테이너 내)에서 실행중인 경우에만 TRUE를 반환합니다.

나는 당신의 문제가 당신의 CreateImage 메소드 자체 내에 있다고 생각합니다. 우리에게 더 많은 맥락을 줄 수 있습니까? 어떤 CreateImage 메소드가 호출되고 있으며 그 구현은 무엇입니까?

package javagame;

import java.awt.BorderLayout;
import javax.swing.JFrame;

/**
 *
 * @author stuart
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        JFrame frame= new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 500, 400);

        frame.add(new GamePanel(), BorderLayout.CENTER);
        frame.setVisible(true);
    }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top