运行时切换全屏/窗口大小

JME3没有直接提供改变屏幕大小的接口,我们可以通过settings来修改参数,然后调用Application的restart()方法来使这些参数生效。restart()方法源码是这么说的:
    /**
     * Restarts the context, applying any changed settings.
     * <p>
     * Changes to the {@link AppSettings} of this Application are not
     * applied immediately; calling this method forces the context
     * to restart, applying the new settings.
     */
    public void restart(){
        context.setSettings(settings);
        context.restart();
    }


我们对AppSettings的修改并不会立即生效,调用restart方法会强制应用程序重启,并迫使新的配置生效。

我写了一个简单的屏幕切换测试代码,可以正常运行:
package org.pstale.client.gui;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector2f;
import com.jme3.system.AppSettings;

public class TestChangeScreen extends SimpleApplication {

	boolean fullscreen;
	
	@Override
	public void simpleInitApp() {
		fullscreen = settings.isFullscreen();
		
		inputManager.addMapping("r", new KeyTrigger(KeyInput.KEY_R));
		inputManager.addMapping("f", new KeyTrigger(KeyInput.KEY_F));
		inputManager.addListener(listener, "r", "f");
	}

	ActionListener listener = new ActionListener() {
		@Override
		public void onAction(String name, boolean isPressed, float tpf) {
			if (isPressed == false)
				return;

			// R键改变屏幕大小
			if ("r".equals(name)) {
				changeScreen();
			}

			// F键切换全屏
			if ("f".equals(name)) {
				fullScreen();
			}
		}

	};

	Vector2f[] dimension = new Vector2f[] { new Vector2f(800, 600), new Vector2f(1024, 768), new Vector2f(1280, 720) };
	int dCnt = 0;
	private void changeScreen() {
		Vector2f d = dimension[dCnt];
		dCnt++;
		if (dCnt >= dimension.length)
			dCnt = 0;
		
		changeSize(d.x, d.y);
	}
	
	/**
	 * 切换Screen Size
	 */
	private void changeSize(float x, float y) {
		settings.setWidth((int) x);
		settings.setHeight((int) y);
		restart();
	}

	/**
	 * 切换全屏
	 */
	private void fullScreen() {
		fullscreen = !fullscreen;
		settings.setFullscreen(fullscreen);
		restart();
	}

	public static void main(String[] args) {
		// 默认设置
		AppSettings settings = new AppSettings(true);
		settings.setWidth(1024);
		settings.setHeight(768);
		settings.setFullscreen(false);

		// 启动
		SimpleApplication app = new TestChangeScreen();
		app.setShowSettings(false);
		app.setSettings(settings);
		app.start();
	}

}


注意,上述代码在下面条件下会失效:使用JME3自带的配置窗口来初始化应用程序,并且没有勾选上FullScreen。
按F切换全屏的时候,会报下面的异常。原因是JME3在通过LWJGL创建应用程序时,没有生成全屏模式,结果无法切换。
严重: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.RuntimeException: Unable to find fullscreen display mode matching settings
	at com.jme3.system.lwjgl.LwjglDisplay.createContext(LwjglDisplay.java:79)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:177)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
	at java.lang.Thread.run(Unknown Source)

真是太奇怪了,我勾选了FullScreen就没这个问题,不用JME3的默认窗口来设置全屏也没问题,就是在这唯一一种情况下有问题,这算是JME3的一个bug吗?

猜你喜欢

转载自windybell.iteye.com/blog/2241727