2

これは、stackoverflow に関する私の最初の投稿であり、私がここで抱えている問題について誰かが私を助けてくれることを願っています。

私が対処している問題はrepaint()問題であり、問​​題を解決するためにこれらのフォーラムを十分に検索していないと考える人もいるでしょうが、私は広範囲に調べましたが、何も機能していません. 以下のコードでは、for ループで drawB を呼び出そうとしていますが、このコードは適切に機能します。for ループは drawB を 20 回ほど呼び出します。drawB では、画像を設定し (配列内の数値によって異なります)、それをサブクラスの GameCanvas でrepaint()呼び出しますpaintComponent()

問題は、この初期化で paintComponant がまったく実行されていないことです。ただし、repaint()DOES は私が作成したループで動作しますが、gameLoop()この初期化を の前に行う必要がありますgameLoop()

誰が何が起こっているのか、またはそれを修正する方法について手がかりを持っていますか?

package engine;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class GameMain extends JFrame // main class for the game as a Swing application
{     

    // Define constants for the game
    static final int CANVAS_WIDTH = 800;    // width and height of the game screen
    static final int CANVAS_HEIGHT = 600;
    static final int UPDATE_RATE = 4;    // number of game update per second
    static final long UPDATE_PERIOD = 1000000000L / UPDATE_RATE;  // nanoseconds

    String path;
    BufferedImage image;

    private GameCanvas canvas;

    // Constructor to initialize the UI components and game objects
    public GameMain() 
    {
        gameInit();

        image = null;
        canvas = new GameCanvas();
        canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
        this.setContentPane(canvas);


        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
        this.setTitle("Blockcraft!");
        this.setVisible(true);
    }

    public void gameInit() 
    {
        dispArray();
        gameStart();
    }

    public void dispArray() 
    {
        int tempLevel[][] = new int[][] {{1,1,1,1},{6,2,2,2},{3,3,3,3},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4}};
        int widthTemp = tempLevel[0].length;
        int heightTemp = tempLevel.length;

        for(int i = 0; i < heightTemp; i++)
        {
            for(int j = 0; j < widthTemp; j++)
            {
                try
                {
                    image = ImageIO.read(getFile());
                }
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
                drawB(image);
            }
        }
    }

    public File getFile() 
    {
        path = "images//1.jpg";
        File file = new File(path);
        return file;
    }

    public void drawB(BufferedImage imgTemp) 
    {
        image = imgTemp;
        repaint();
    }

    private void gameLoop() 
    {
        long beginTime, timeTaken, timeLeft;
        while (true) 
        {
            repaint();

            beginTime = System.nanoTime();

            timeTaken = System.nanoTime() - beginTime;
            timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000L;  // in milliseconds
            if (timeLeft < 10) timeLeft = 10;   // set a minimum
            try 
            {
                Thread.sleep(timeLeft);
            }    
            catch (InterruptedException ex)
            { 
                //
            }
        }
    }

    // Refresh the display. Called back via repaint(), which invoke the paintComponent().
    private void gameDraw(Graphics2D g2d) 
    {
        g2d.drawImage(image, 0, 0, 15, 15, this);
    }

    public void gameKeyPressed(int keyCode)
    {
        //
    }

    public void gameKeyReleased(int keyCode) 
    {
       //
    }

    public void gameKeyTyped(char keyChar) 
    {
       //
    }

    class GameCanvas extends JPanel implements KeyListener
    {
        boolean paintAll;
        int xPos, yPos;
        Image img;

        public GameCanvas() 
        {
            setFocusable(true);  
            requestFocus();
            addKeyListener(this);
        }

        // Override paintComponent to do custom drawing.
        // Called back by repaint()... sometimes?
        @Override
        public void paintComponent(Graphics g) 
        {
            System.out.println("repainting");
            Graphics2D g2d = (Graphics2D)g;

            // Draw the game objects
            gameDraw(g2d);
        }


        // KeyEvent handlers
        @Override
        public void keyPressed(KeyEvent e) 
        {
            gameKeyPressed(e.getKeyCode());
        }

        @Override
        public void keyReleased(KeyEvent e) 
        {
            gameKeyReleased(e.getKeyCode());
        }

        @Override
        public void keyTyped(KeyEvent e) 
        {
            gameKeyTyped(e.getKeyChar());
        }
    }

    // To start and re-start the game.
    public void gameStart() 
    { 
        // Create a new thread
        Thread gameThread =  new Thread() 
        {
            // Override run() to provide the running behavior of this thread.
            @Override
            public void run() 
            {
                gameLoop();
            }
        };
        // Start the thread. start() calls run(), which in turn calls gameLoop().
        gameThread.start();
    }

    // main
    public static void main(String[] args) 
    {
        // Use the event dispatch thread to build the UI for thread-safety.
        SwingUtilities.invokeLater(new Runnable() 
        {
            @Override
            public void run() 
            {
                new GameMain();
            }
        });
    }
}
4

1 に答える 1

3

初期化コード以降、初期化中に応答しないのは理にかなっています。

public void dispArray() {
  int tempLevel[][] = new int[][] { { 1, 1, 1, 1 }, { 6, 2, 2, 2 },
        { 3, 3, 3, 3 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 },
        { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 } };
  int widthTemp = tempLevel[0].length;
  int heightTemp = tempLevel.length;
  for (int i = 0; i < heightTemp; i++) {
     for (int j = 0; j < widthTemp; j++) {
           try {
              image = ImageIO.read(getFile());
           } catch (Exception e) {
              e.printStackTrace();
           }
        drawB(image);
     }
  }
}

public File getFile() {
  path = "images//1.jpg";
  File file = new File(path);
  return file;
}

public void drawB(BufferedImage imgTemp) {
  image = imgTemp;
  repaint();
}

イメージ ファイルの読み込みを含め、すべて Swing イベント スレッドで行われます。

解決策: そうしないでください。代わりに、SwingWorker で利用できるようなバックグラウンド スレッドを使用してください。詳細については、Swing での同時実行を参照してください。

于 2012-12-25T05:57:57.927 に答える