【Java】ゲーム用フルスクリーンの実装

2018年6月25日

本稿はゲーム制作で実装したくなるであろう機能の一つである、フルスクリーンを実装する方法を紹介します。(ディスプレイ解像度の変更も含みます。)



ゲーム用フルスクリーン実装に使用する主なクラス

AWT、Swingでのフルスクリーン実装は下記のようなクラスを使用します。

GraphicsDevice

皆さんが見ているモニターの情報にアクセスできるクラスです。

setFullScreenWindowメソッドで指定ウィンドウをフルスクリーン化できます。

setDisplayModeメソッドで解像度の変更ができます。

DisplayMode

解像度の情報などを保持します。

フルスクリーンへ移行

フルスクリーンモードの実装にはGraphicsDeviceオブジェクトを取得する必要があります。

次にGraphicsDeviceのsetFullScreenWindowを呼び出します。フルスクリーンはこれだけ。

GraphicsDeviceの取得は下記のようなコードで取得できます。

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(フルスクリーンにしたいウィンドウオブジェクト);

フルスクリーンは下記のようにsetFullScreenWindow(null)を設定するとフルスクリーンモードを解除できます。次に説明する解像度変更についてもsetFullScreenWindow(null)で解除できます。

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setFullScreenWindow(null);

解像度の変更

解像度の変更ですが、こちらはGraphicsDeviceのsetDisplayModeを呼び出します。下記のような感じで設定しましょう。

GraphicsDevice gd = ge.getDefaultScreenDevice();
gd.setDisplayMode(ディスプレイ情報オブジェクト);

設定できるディスプレイモードは環境に依存すると思うので下記のメソッドで設定できるモードの一覧を取得して実装するのが良いでしょう。

GraphicsDevice gd = ge.getDefaultScreenDevice();
DisplayMode[] modeList = gd.getDisplayModes();
gd.setDisplayMode(ディスプレイ情報オブジェクト(例えばmodeList[0]など・・・));

サンプルコード

フルスクリーン+解像度変更のサンプルです。

例えばゲームを800×600の大きさで作成した場合は下記のようにフルスクリーンモードへ移行後に800×600で解像度設定するといい感じに実装できると思います。

import java.awt.DisplayMode;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;


public class Test{
	public static void main(String[] args) throws InterruptedException {
		JFrame f = new JFrame();

		//サイズ指定
		f.setSize(800,600);

		//ウィンドウ枠を削除
		f.setUndecorated(true);

		//画面表示
		f.setVisible(true);

		//レイアウト指定
		f.setLayout(new FlowLayout());

		//文字列表示
		JLabel label = new JLabel("ゲームタイトルだよ!!\n(何かキーを押すとプログラム終了!!)");
		label.setFont(new Font(Font.MONOSPACED,Font.BOLD, 20));
		f.add(label);

		//何かキーを押すと終了
		f.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				System.exit(0);
			}
		});

		//一応閉じるで終了も入れとく
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		//画面デバイスを取得
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice gd = ge.getDefaultScreenDevice();

		//JFrameをフルスクリーンに
		gd.setFullScreenWindow(f);

		//設定できる解像度オブジェクトを全取得
		DisplayMode[] modeList = gd.getDisplayModes();

		//ウィンドウサイズと同じ解像度モードを取得
		DisplayMode activeMode = null;
		for ( DisplayMode mode : modeList ) {
			System.out.println(mode);
			if ( mode.getWidth() == 800 && mode.getHeight() == 600 &&
					((activeMode == null)
					|| activeMode.getBitDepth() < mode.getBitDepth()
					|| activeMode.getBitDepth() == mode.getBitDepth() && activeMode.getRefreshRate() <= mode.getRefreshRate())) {
				activeMode = mode;
			}
		}

		//解像度の変更
		if ( activeMode!=null ) {
			gd.setDisplayMode(activeMode);
		} else {
			System.out.println("解像度変更に失敗しました。。。\n他のサイズなら成功するかもしれません。");
		}
	}
}
実行結果

解像度は設定変更できないサイズもありますので、ゲーム制作時には一般的な解像度設定可能サイズで制作しておくと良いかもしれません。もちろんフルスクリーンは不要であるならば、適当でいいと思います。

フルスクリーン実装時に、ハマりやすい罠

・setUndecoratedの利用タイミングに注意
フルスクリーンとは関係ないですが、ゲーム実装時にウィンドウの装飾を削除したい場合がありますよね。装飾の削除はsetUndecorated(true)で、できますが、これはウィンドウが表示されている時は利用できません。もし、ウィンドウ(装飾あり)モードから、フルスクリーン(装飾なし)モードへ移動したい場合等は、一旦ウィンドウをcloseしてからsetUndecorated(true)を呼び出しましょう。そのあとsetVisible(true)で表示すれば、反映されます。

・解像度の変更はいろいろ制限があり、どんな時でも利用できるわけではない
解像度の変更はsetFullScreenWindowメソッドで特定のウィンドウオブジェクトを設定して置かなければならない。つまり、コンソールアプリで解像度変更は簡単にはできない。
自由に変えられるようにならないかな~(・・願望)

・解像度変更時、元に戻す手段をしっかり用意しておこう
解像度変更により、PCの操作がやりにくくなってしまう場合があります。特に最低まで落とすと詰みそうになる・・・。Javaでの解像度変更はアプリケーション終了時に、解像度も元の状態に戻されるようになっていますので、確実にプログラムが終了されるようにしておくか、自力で解像度を元に戻す処理を実装しておいてください。解像度を戻す場合は、先ほども説明したとおり、setFullScreenWindow(null)を設定するのが手っ取り早いです。

Java

Posted by nompor