よくわかってにゃい猫がじゃばじゃばしてみた

ゲームにゃを管理する部分にゃをうにゃうにゃとですにゃ。
ついでにゃに、描画にゃの部分にゃを別にゃににゃ。
 
にゃんだか、描画がいやにゃ感じにゃにゴタゴタしてるっぽいにゃけど……気にしにゃい。
 

class Game {
  /**
   * ゲームモード切替。
   * @param newGame 切り替えるゲーム nullで終了
   */
  public static void changeGame( Game newGame ) {
    Game.newGame = newGame;
    if(newGame != null) {
      newGame.initialize();
    }
  }

  /**
   * ゲーム遷移処理。
   */
  public static Game transitGame( Game game ) {
    if(game == Game.newGame) {
      return game;
    }
    if((Game.newGame == null) || !Game.newGame.isLoading()) {
      if(game != null) { game.terminate(); }
      game = Game.newGame;
    }
    return game;
  }

  /**
   * ゲーム終了かどうか。
   */
  public static boolean isEndOfGame() {
    return newGame != null;
  }

  /**
   * 初期化処理。
   */
  public void initialize() {}

  /**
   * 終了処理。
   */
  public void terminate() {}

  /**
   * 準備中かどうか。
   */
  public boolean isLoading() { return false; }

  /**
   * ゲーム更新。
   */
  public void update( InputDevice id ) {}

  /**
   * ゲーム描画。
   */
  public void render( GraphicDevice gd ) {}

  /** ゲーム */
  private static Game newGame;
}
class GameTest extends Game {
  /**
   * 初期化処理。
   */
  public void initialize() {
  }

  /**
   * ゲーム更新。
   */
  public void update( InputDevice id ) {
    if(id.getPressed( 0 ) != 0) {
      changeGame( null ); // 何か入力されたら終了
    }
  }

  /**
   * ゲーム描画。
   */
  public void render( GraphicDevice gd ) {
  }
}
public interface GraphicDevice {
  /**
   * シーンの描画を開始する。
   */
  public abstract void beginScene();

  /**
   * シーンの描画を終了する。
   */
  public abstract void endScene();

  /**
   * シーンを描画する。
   */
  public abstract void render( Game game );

  /**
   * シーンを表示する。
   */
  public abstract void present();
}
import javax.swing.*;
import javax.media.opengl.*;
import com.sun.opengl.util.GLUT;

public class GraphicDeviceJOGL implements GraphicDevice {

  class EventListener implements GLEventListener {

    EventListener( GraphicDevice gd, GLJPanel panel ) {
      this.gd = gd;
      this.panel = panel;
    }

    /**
     * OpenGL context が初期化された後に呼び出される。
     */
    public void init( GLAutoDrawable drawable ) {
      if(drawable == null) {
        return;
      }
      gl = drawable.getGL();
      glut = new GLUT();
    }

    /**
     * 画面モードが変わったときに呼び出される。
     */
    public void displayChanged( GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged ) {
    }

    /**
     * 画面サイズが変わったときに呼び出される。
     */
    public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
      if(drawable == null) {
        return;
      }
      final float ratio = (float)height / (float)width;
      gl = drawable.getGL();
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL.GL_PROJECTION );
      gl.glLoadIdentity();
      gl.glFrustum( -1.0f, 1.0f, -ratio, ratio, 5.0f, 40.0f );
      gl.glMatrixMode( GL.GL_MODELVIEW );
      gl.glLoadIdentity();
      gl.glTranslatef( 0.0f, 0.0f, -20.0f );
    }

    /**
     * 描画が必要なときに呼び出される。
     */
    public void display( GLAutoDrawable drawable ) {
      if((game == null) || (drawable == null)) {
        return;
      }
      gl = drawable.getGL();
      game.render( gd ); // ゲーム描画
    }

    public void render( Game game ) {
      this.game = game;
      panel.display();
    }

    /** グラフィックデバイス */
    private GraphicDevice gd;

    /** ゲーム */
    private Game game;

    /** パネル */
    private GLJPanel panel;
  }

  GraphicDeviceJOGL( GLJPanel panel ) {
    super();
    panel.addGLEventListener( el = new EventListener( this, panel ) );
  }

  /**
   * シーンの描画を開始する。
   */
  public void beginScene() {
  }

  /**
   * シーンの描画を終了する。
   */
  public void endScene() {
  }

  /**
   * シーンを描画する。
   */
  public void render( Game game ) {
    el.render( game );
  }

  /**
   * シーンを表示する。
   */
  public void present() {
  }

  /** イベント */
  private EventListener el;
  /** gl */
  protected GL gl;
  /** glut */
  protected GLUT glut;
}
import java.awt.*;
import javax.swing.*;
import javax.media.opengl.*;

class infcat_jogl extends GLJPanel implements Runnable {

  infcat_jogl() {
    // グラフィック初期化
    gd = new GraphicDeviceJOGL( this );
    // 入力の初期化
    id = new InputDeviceKeyboard( this );
  }

  public void run() {
    // アイコン設定
    frame.setIconImage( (new ImageIcon( getClass().getClassLoader().getResource( "images/icon/icon.jpg" ) )).getImage() );
    // ウィンドウのサイズと表示位置を設定
    setPreferredSize( new Dimension( 320, 240 ) ); // パネルサイズ設定
    frame.pack();                        // サイズを再計算
    frame.setLocationRelativeTo( null ); // ウィンドウを中央にする
    frame.setVisible( true );            // フレームウィンドウ表示

    try {
      Game.changeGame( game = new GameTest() );
      // メインループ
      while(Game.isEndOfGame()) {
        game = Game.transitGame( game ); // ゲーム遷移
        id.update();                     // 入力を更新
        game.update( id );               // ゲーム更新
        gd.beginScene(); {               // 描画開始
          gd.render( game );             // 描画
        } gd.endScene();                 // 描画終了
        gd.present();                    // 画面更新
      }
      game.terminate();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.exit(0);
    }
  }

  public static void main(String [] args) {
    // フレーム作成
    frame = new JFrame( "InfinityCat Zero" );
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.setResizable( false );  // リサイズ不可
    // ゲーム作成
    infcat_jogl game_main = new infcat_jogl();
    frame.getContentPane().add( game_main );
    // ゲームスレッド開始
    (new Thread( game_main )).start();
  }

  /** フレームウィンドウ */
  private static JFrame frame;
  /** ゲーム */
  private Game game;
  /** 入力 */
  private InputDevice id;
  /** グラフィック */
  private GraphicDevice gd;
}