4

背景
私はゲーム開発を高速化するためにゲーム ライブラリを構築していますが、これまでのところ順調に進んでいます。

私は次のものを持っています:

  • 主なエントリークラスpublic static void main(String[] args)
    • このクラスは、ライブラリから呼び出されたクラスを開始しますGame
    • 次に、ウィンドウ サイズを設定Roomし、JFrame
  • 拡張可能Room(ルームはゲーム レベル) クラスが作成されると、ルームからスレッドが開始され、追加されたすべてのオブジェクトが描画されます。
    • オブジェクトにはイベントを追加できます(私が立ち往生している部分)

以上が主なアイデアに含まれるものです。

これがエントリークラスです(非常に単純です)。

package test;

import JGame.Game.Game;
import JGame.Room.Room;
import javax.swing.JFrame;
import test.Rooms.Room1;

public class Main extends JFrame{

    public static void main(String[] args){
        Game game = new Game("Test Game"); // This sets the window title
        game.start(800, 600); // This sets the size of the window

        Room room1 = new Room1();
        game.setRoom(room1);  // adds the JPanel to the main frame
    }
}

Room1伸びRoomます。Room1そのルームに関連付けられているすべてのゲーム オブジェクト内で、ルームに追加されます。

public class Room extends JPanel implements Runnable{
    ArrayList<GameObject> gameObjects = new ArrayList<>();
    @Override
    public void run(){
        try{
            while(true){
                this.repaint();
                Thread.sleep(5);
            }
        }
    }
    public void addGameObjectAt(GameObject gameObject, int x, int y){
        // Sets private variables in GameObject
        // These are then grabbed in the paintComponent to draw at that location
        gameObject.setX(x); 
        gameObject.setY(y);
        gameObjects.add(gameObject);
    }
    @Override
    public void paintComponent(Graphics g){
        g.drawImage(bg, 0, 0, this);
        for(int i = 0; i < gameObjects.size(); i++){
            GameObject go = gameObjects.get(i);
            g.drawImage(go.getSprite(), go.getX(), go.getY(), this);
        }
    }
}

それでは、部屋を作成するとしましょう:

public class Room1 extends Room{
    public Room1(){
        this.createShip();
    }
    public void createShip(){
        Ship = new Ship();
        // Add an object to a list setting its x,y to 10,10
        this.addGameObjectAt(ship, 10, 10);
    }
}

注:これらのオブジェクトはウィンドウに追加されずaddGameObjectAt、単に に追加されArrayList、ルームのスレッドで画面にペイントされます。

部屋に追加Shipしたので、 を使用して画面に描画できますpaintComponent()。これはすべてうまくいきます!

ここで、物事が機能しなくなり始めます。クラスが追加されたのでShip、いくつかの重要なイベントを追加したいと思います。現在Main、それらを機能させるために追加する必要がありますが、面倒なので追加したくありません。Ship、それがイベントが最終的に影響するものだからです。

このコードはキーリスナーをアタッチしません

// GameObject extends JPanel
public class Ship extends GameObject{
    public Ship(){
        this.addKeyListener(new AL());
    }

    public class AL extends KeyAdapter{

        @Override
        public void keyPressed(KeyEvent evt){
            System.out.println("here");
        }

        @Override
        public void keyReleased(KeyEvent evt){
        }
    }
}

これは機能しません。キーを押してもhereALが出力されませんが、クラスとクラスを移動すると機能しますがaddKeyListener()、クラスに入れたくGameありませんGameクラスに入れたいですShip

// This class just sets up the size of the application window
// It also holds an int list of all the game rooms
public class Game extends JFrame{

}

私はこれを少なくとも1週間理解しようとしてきましたが、どうすればこれをShipクラスで機能させることができるのかわかりませんか?

4

2 に答える 2

5

JPanelはフォーカス可能なコンポーネントではないため、 と対話できませんKeyEvents

Swing では、推奨されるアプローチはKey Bindingsを使用することです。コンポーネントにフォーカスがない場合でも、Action を KeyStroke にマップできます。

この例を参照してください

于 2012-12-21T18:51:01.673 に答える
0

JPanel をフォーカス可能にする必要があると思います。ship.setFocusable(true); を試してください。

于 2012-12-21T18:51:06.650 に答える