0

2Dゲームを作成したいのですが、BufferStrategyを使用して2Dサーフェス/キャンバスに描画するための最良かつ最も効率的な方法を見つけるのに苦労しています。メインウィンドウとしてJFrameを使用し、その表面に描画したいと思います。これがどのように行われるか(これが良い方法である場合)のサンプルコードと他の例を見てみたいと思います。誰かがそうすることのいくつかの長所と短所も説明できれば素晴らしいでしょう。

現在、'frame.add(new Painter());'を使用して描画クラスをJFrameに追加しています。次に、paintComponentメソッドをオーバーライドします。これに関して私が見つけた唯一の問題は、このメソッドを1回だけ呼び出すように見えることです。

これは私のPainterクラスです:

public class Painter extends JPanel{

    public static Player player;

    public Painter() {
        player = new Player(300, 300);

    }

    public void paint(Graphics g) {
        player.x++;
        g.setColor(Color.white);
        g.fillRect(player.x, player.y, 32, 32);
    }

}
4

2 に答える 2

3

最も単純なケースでは、ゲームがユーザーアクションのみに基づいて画面を更新する必要がある場合、repaint()何かを更新するときに(たとえば、JFrameで)呼び出す必要があります。

その他の場合は、ゲームの状態を更新し、更新されたゲームの状態をタイムリーにレンダリングする、いわゆるゲームループを構築する必要があります。Javaコードを使用した単純なゲームループに関する優れたチュートリアルは、http://obviam.net/index.php/the-android-game-loop/にあります。

シリアスゲームを開発する場合は、ゲームループやその他の日常的なゲーム開発の側面を管理するためのゲームエンジンを使用する必要があります。優れたJavaゲームエンジンはここにあります:http ://code.google.com/p/playn/

于 2012-06-10T07:50:26.817 に答える
3

ゲームループと、ゲームオブジェクトなど(画像、爆発など)を画面に印刷する効率的な方法を得るには、タイミングメカニズムと、何度も何度も印刷すると同時に更新を取得するJFrameが必要です。プレイヤーとゲームの状態自体から。

まず、mainメソッドが必要です。これは、Javaのこのタイプのフィールドにかなり慣れていないことを推測するため、可能な限り迅速かつ明確に分類します。

public static main(String[] args)
{
  yourClassName game = new yourClassName();
  game.run();
  System.exit(0);
}

このメインメソッドは、最初に2つのことを実行します。実行メソッドへのオブジェクトを作成し(ゲームループでは静的参照は推奨されないため)、次に新しく作成したオブジェクトでそのメソッドを呼び出します。そのrunメソッドが完了すると、システムはプログラムを終了します。

ここでは詳しく説明しませんが、runメソッドを実行すると、1回だけ実行されるinitメソッドが必要になります。このメソッドでは、レンダリング先のJFrameを作成します。これは非常に簡単なので、JFrameクラスの作成についてはこれ以上説明しません。ただし、Runメソッドは次のようになります...

void Run()
{
   init();
   while(isRunning)
   {
     update();
     draw();

     time = (1000 / fps) - (System.currentTimeMillis() - time);

            if (time > 0) 
            {
                try 
                { 
                        Thread.sleep(time); 
                } 
                catch(Exception e){} 
            }

   }
}

この方法では、計算速度が必要な特定のfpsに低下します(この場合、fps変数はshowの場合はfpsという名前になります)。

これで、updateメソッドに、キーボードまたはマウス(そして私の場合は現在サーバー)で変更を探すためのkeyBindingやその他のものがあります。ほとんどの人は、Repaintメソッドに必要なパラメータを使用せずにJFrameに印刷または描画する方法を知らないため、ダブルバッファリングを追加してこれをオーバーライドします。

BufferedImage backBuffer;

initializeメソッドで追加します

backBuffer = new BufferedImage(getWidth(),getHeight(),
                            BufferedImage.TYPE_INT_RGB)

ドローメソッドでは、次のようになります...

Graphics g = getGraphics();

Graphics bbg = backBuffer.getGraphics();

そして、それらを使用すると、initクラスによって作成されたJFrameに描画することができます(また、これを行うことにより、任意のクラスまたはスレッドから描画して処理負荷を減らすことができます)。

それが機能するかどうかを確認するには、先に進んで、bbg.fillRect(updateX,updateY,5,5)

updateXとupdateYは、長方形の位置を更新するために使用する変数を表します。それらをグローバル変数または文字クラスに保存されたパブリック変数として保存します。

そして、他のすべてが失敗した場合、これは私が自分のゲームエンジンを作成するために使用したサンプルコードです...

import input.InputHandler; 

import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 
import javax.swing.JFrame; 

/** 
 * Main class for the game 
 */ 
public class GameTutorial extends JFrame 
{        
    boolean isRunning = true; 
    int fps = 30; 
    int windowWidth = 500; 
    int windowHeight = 500; 

    BufferedImage backBuffer; 
    Insets insets; 
    InputHandler input; 

    int x = 0; 

    public static void main(String[] args) 
    { 
            GameTutorial game = new GameTutorial(); 
            game.run(); 
            System.exit(0); 
    } 

    /** 
     * This method starts the game and runs it in a loop 
     */ 
    public void run() 
    { 
            initialize(); 

            while(isRunning) 
            { 
                    long time = System.currentTimeMillis(); 

                    update(); 
                    draw(); 

                    //  delay for each frame  -   time it took for one frame 
                    time = (1000 / fps) - (System.currentTimeMillis()-          time); 

                    if (time > 0) 
                    { 
                            try 
                            { 
                                    Thread.sleep(time); 
                            } 
                            catch(Exception e){} 
                    } 
            } 

            setVisible(false); 
    } 

    /** 
     * This method will set up everything need for the game to run 
     */ 
    void initialize() 
    { 
            setTitle("Game Tutorial"); 
            setSize(windowWidth, windowHeight); 
            setResizable(false); 
            setDefaultCloseOperation(EXIT_ON_CLOSE); 
            setVisible(true); 

            insets = getInsets(); 
            setSize(insets.left + windowWidth + insets.right, 
                            insets.top + windowHeight + insets.bottom); 

        backBuffer = new BufferedImage(windowWidth, windowHeight,   BufferedImage.TYPE_INT_RGB); 
            input = new InputHandler(this); 
    } 

    /** 
     * This method will check for input, move things 
     * around and check for win conditions, etc 
     */ 
    void update() 
    { 
            if (input.isKeyDown(KeyEvent.VK_RIGHT)) 
            { 
                    x += 5; 
            } 
            if (input.isKeyDown(KeyEvent.VK_LEFT)) 
            { 
                    x -= 5; 
            } 
    } 

    /** 
     * This method will draw everything 
     */ 
    void draw() 
    {               
            Graphics g = getGraphics(); 

            Graphics bbg = backBuffer.getGraphics(); 

            bbg.setColor(Color.WHITE); 
            bbg.fillRect(0, 0, windowWidth, windowHeight); 

            bbg.setColor(Color.BLACK); 
            bbg.drawOval(x, 10, 20, 20); 

            g.drawImage(backBuffer, insets.left, insets.top, this); 
    } 
} 

これがお役に立てば幸いです。これは非常に遅い答えかもしれませんが、理解しやすく、使いやすく、操作が楽しい、まともなJavaゲームエンジンをまだ見たことがありません。あなたがそれと幸せなプログラミングにとどまることを願っています!!!

于 2015-07-05T00:49:55.953 に答える