1

だから私は背景として画像のグリッドを表示する Java でゲームを作ろうとしています。予想どおり 32 枚の画像ですが、約 3 分の 2 の確率で、パネルに何も表示されません!

問題を解決するために多くの機能を削除しました。コードを実行すると、1 秒間に数回再描画しなくても、時々しか機能しません。

メインクラス

import javax.swing.JFrame;


public class Main {



    public static void main(String[] args) {
        //Creating a new frame for the whole game and everything
        JFrame frame = new JFrame("Lawlz this is my game");
        frame.setSize(800,800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setResizable(false);

        //adding the game panel to the main frame
        frame.add(new GameFrame());
    }

}

ゲーム フレーム クラス (パネルが作成される場所) これは、ほぼすべてがコメント アウトされたコードです。アニメーションとプレーヤー クラスでさえ、まだ約半分の時間で何も表示されません。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GameFrame extends JPanel {//implements ActionListener {

    Timer mainTimer;
    Player player;
    Random rand = new Random();
    Grid GameGrid = new Grid(25, 25);

    int enemyCount = 5;

    //Constructer!
    public GameFrame()
    {
        setFocusable(true);
        //player = new Player(100,100);
    }

    //Does all of the drawing for the game
    public void paint(Graphics g)
    {
        //Sends to the JPanel class (super class)
        super.paint(g);

        //gets a graphics 2d object
        Graphics2D g2d = (Graphics2D)g;

        GameGrid.draw(g2d);
    }
}

基本的に多くの「グリッド空間」オブジェクトを保持する GameGrid クラス。それぞれは基本的に単なる画像です。また、この時点で、draw() メソッドで描画されたほとんどすべてを出力する役割も果たします。

import java.awt.Graphics2D;
import java.util.ArrayList;


public class Grid {

    ArrayList<GridSpace> grid = new ArrayList<GridSpace>();
    int width;
    int height;

    public Grid(int w, int h)
    {
        width = w;
        height = h;

        //Temporary for creating the x and y values by using the size of the images
        int gw = new GridSpace(0,0).getGridImg().getWidth(null);
        int gh = new GridSpace(0,0).getGridImg().getHeight(null);

        for(int i = 0; i < h; i++)
        {
            for(int n = 0; n < w; n++)
            {
                grid.add(new GridSpace(n*gw,i*gh));   //GridSpace(n*ImageWidth, i*ImageHeight)
            }
        }
    }

    public void draw(Graphics2D g2d)
    {
        for(int i = 0; i < width; i++)
        {
            for(int n = 0; n < height; n++)
            {
                GridSpace tempSpace = GetGridSpaceByID(GetCoordinates(n,i)); //gets the GridSpace object for this corrdinate
                g2d.drawImage(tempSpace.getGridImg(),tempSpace.x,tempSpace.y,null);
            }
        }
    }

    public void test(Graphics2D g2d)
    {
        GridSpace tempSpace = GetGridSpaceByID(GetCoordinates(0,0));
        g2d.drawImage(tempSpace.getGridImg(),tempSpace.x,tempSpace.y,null);
    }

    public GridSpace GetGridSpaceByID(int n)
    {
        return grid.get(n);
    }

    public int GetCoordinates(int x, int y)
    {
        return x + y * width;
    }


}

最後に、基本的に画像を格納するだけの GridSpace オブジェクト

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.util.Random;

import javax.swing.ImageIcon;


public class GridSpace {
    Random r = new Random();
    ImageIcon ic;
    int x = 0;
    int y = 0;

    public GridSpace(int x,int y)
    {
        this.x = x;
        this.y = y;

        //Stores an image for this grid space
        //ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\pic1.png");
        if(r.nextInt(10) < 9)
        {
            ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\Video Game\\grass1.jpg");
        }
        else
        {
            ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\Video Game\\grass2.jpg");
        }
    }

    public Image getGridImg()
    {
        //Image image = ic.getImage();
        return ic.getImage();
    }
}
4

3 に答える 3

2
  1. GameFrame(より正確には と呼ばれるGamePanel場合があります) をオーバーライドして、ゲーム プレイ エリアに適しgetPreferredSize()たサイズを返す必要があります。フレーム自体に独自の装飾があり、大きくなります。
  2. メインの呼び出しの順序が間違っています。setVisible(true)最後の部分として呼び出します。
  3. また、EDT で GUI を開始するようにというアドバイスにも注意してください。

これは、私の現在の「フレーム デモ」テンプレートのメインであり、最後の 2 つのポイントを示し、その他の優れたヒントを提供します。

public static void main(String[] args) {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            // the GUI as seen by the user (without frame)
            JPanel gui = new JPanel(new BorderLayout());
            gui.setBorder(new EmptyBorder(2,3,2,3));

            // TODO!
            gui.setPreferredSize(new Dimension(400,100));
            gui.setBackground(Color.WHITE);

            JFrame f = new JFrame("Demo");
            f.add(gui);
            // Ensures JVM closes after frame(s) closed and
            // all non-daemon threads are finished
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            // See http://stackoverflow.com/a/7143398/418556 for demo.
            f.setLocationByPlatform(true);

            // ensures the frame is the minimum size it needs to be
            // in order display the components within it
            f.pack();
            // should be done last, to avoid flickering, moving,
            // resizing artifacts.
            f.setVisible(true);
        }
    };
    // Swing GUIs should be created and updated on the EDT
    // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
    SwingUtilities.invokeLater(r);
}
于 2012-12-17T01:35:36.853 に答える
2

GameFrame現在、呼び出し後にパネルを追加しているため

frame.setVisible(true);

サイズ変更などのイベントが実行されるまでペイントされません。メソッドの最後のメソッドsetVisibleとしてこの呼び出しを行う必要があります。また、Swing の最適化されたペイント モデルを利用するのではなく、使用します。mainpaintComponentpaint

必須のリンク: AWT と Swing でペイントする

于 2012-12-16T17:59:43.320 に答える
2

これらの問題の一部は、メイン スレッドで Swing 関連のコードを呼び出している場合にも発生する可能性があります。EDT (Event Dispatch Thread) で実行してみてください。

これを行うには、Mainクラスを次のように変更します。

import javax.swing.JFrame;

public class Main {

    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater (new Runnable ()
        {
            public void run ()
            {
                //Creating a new frame for the whole game and everything
                JFrame frame = new JFrame("Lawlz this is my game");
                frame.setSize(800,800);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
                frame.setResizable(false);

                //adding the game panel to the main frame
                frame.add(new GameFrame());
            }
        });
    }
}

詳しくはこちらをご覧ください。

于 2012-12-16T18:05:17.553 に答える