《Java 2D游戏编程入门》—— 1.6 修改显示模式

    xiaoxiao2024-07-16  106

    本节书摘来异步社区《Java 2D游戏编程入门》一书中的第1章,第1.6节,作者:【美】Timothy Wright(莱特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.6 修改显示模式

    要创建全屏的应用程序,需要修改显示模式。DisplayModeTest如图1.4所示,它使用了Swing组件。这个示例也位于javagames.render包中。如果你还没有编写过任何的Swing程序,一些代码可能会看上去很陌生。有很多相关的图书和教程可供参考,并且如果要详细介绍Swing所提供的所有功能,需要比这本书更大的篇幅。

    这个示例应用程序列出了所有可用的屏幕分辨率,这允许用户在全屏模式之间来回切换,以使用任何可用的显示模式。这个示例不仅展示了使用Swing组件编程,而且这段代码还用来创建一个初始的游戏界面,以供在切换到全屏游戏之前使用。这使得用户可以使用常规的Swing组件来配置系统。

    这个示例还包含了一个名为DisplayModeWrapper的内部类。尽管我并不痴迷于内部类,但这个类使得该示例更容易在单个文件中展示。我宁愿每个文件中只有一个类,在其他类的内部创建类以使它们可以访问私有方法这种做法很有趣,但为了简短起见,我还是另寻它途。包装类使用equals()方法只比较显示模式的宽度和高度,而不包括位深度或刷新速率。根据操作系统的不同,很多显示模式可能只是在位深度或刷新速率上有所差异:

    640×480 32 bit 59 Hz640×480 32 bit 60 Hz640×480 32 bit 75 Hz640×480 16 bit 59 Hz640×480 16 bit 60 Hz

    由于该程序把显示模式创建为32位并且忽略了其他模式,因此16位的模式是不可用的。为了让软件决定使用哪种刷新速率,使用了REFRESH_RATE_UNKNOWN值。通过这种方式,只有640×480的显示模式会被使用,而其他的模式会被略过。

    构造方法包含了保存当前显示模式所需的代码。在软件启动之前,这个模式和用户系统的显示模式进行匹配。当应用程序返回到窗口模式的时候,使用这个显示模式来离开全屏模式。

    public DisplayModeExample() {     GraphicsEnvironment ge =     GraphicsEnvironment.getLocalGraphicsEnvironment();   graphicsDevice = ge.getDefaultScreenDevice();   currentDisplayMode = graphicsDevice.getDisplayMode(); }``` getMainPanel()方法创建了Swing组件。其中列出了可用显示模式的一个下拉列表框,切换到全屏模式的一个按钮,以及切换回窗口模式的另一个按钮。listDisplayModes()方法把显示模式的一个列表,返回到前面所介绍的一个包装器类中。包装器不仅允许搜索列表以找到高度和宽度相匹配的模式,还覆盖了toString()方法以生成在下拉列表框中易于读取的值。 onEnterFullScreen()方法首先检查以确保支持全屏模式,然后切换到全屏模式,并且随后修改显示模式。getSelectedMode()方法真正地创建一个全新的DisplayMode,它带有一个未知的刷新频率,以便能够使用默认的刷新频率。

    // DisplayModeExample.javaprotected void onEnterFullScreen() {  if( graphicsDevice.isFullScreenSupported() ) {    DisplayMode newMode = getSelectedMode();    graphicsDevice.setFullScreenWindow( this );    graphicsDevice.setDisplayMode( newMode );  }}`onExitFullScreen()方法使用所保存的显示模式,将显示返回到窗口模式。这些方法的调用,是按照进入全屏模式时相反的顺序来进行的。由于只有在全屏模式中才可以修改显示模式,因此在更改显示模式之前必须先切换模式,并且在最初的显示模式重置之前,不能设置回窗口模式。

    package javagames.render; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; public class DisplayModeExample extends JFrame {   class DisplayModeWrapper {     private DisplayMode dm;     public DisplayModeWrapper( DisplayMode dm ) {       this.dm = dm;     }     public boolean equals( Object obj ) {       DisplayModeWrapper other = (DisplayModeWrapper)obj;       if( dm.getWidth() != other.dm.getWidth() )         return false;       if( dm.getHeight() != other.dm.getHeight() )         return false;       return true;     }     public String toString() {       return "" + dm.getWidth() + " x " + dm.getHeight();     }   }   private JComboBox displayModes;   private GraphicsDevice graphicsDevice;   private DisplayMode currentDisplayMode;   public DisplayModeExample() {     GraphicsEnvironment ge =       GraphicsEnvironment.getLocalGraphicsEnvironment();     graphicsDevice = ge.getDefaultScreenDevice();     currentDisplayMode = graphicsDevice.getDisplayMode();   }   private JPanel getMainPanel() {     JPanel p = new JPanel();     displayModes = new JComboBox( listDisplayModes() );     p.add( displayModes );     JButton enterButton = new JButton( "Enter Full Screen" );     enterButton.addActionListener( new ActionListener() {       public void actionPerformed( ActionEvent e ) {         onEnterFullScreen();       }     });     p.add( enterButton );     JButton exitButton = new JButton( "Exit Full Screen" );     exitButton.addActionListener( new ActionListener() {       public void actionPerformed( ActionEvent e ) {         onExitFullScreen();       }     });     p.add( exitButton );     return p;   }   private DisplayModeWrapper[] listDisplayModes() {     ArrayList<DisplayModeWrapper> list = new       ArrayList<DisplayModeWrapper>();     for( DisplayMode mode : graphicsDevice.getDisplayModes() ) {       if( mode.getBitDepth() == 32 ) {         DisplayModeWrapper wrap = new DisplayModeWrapper( mode );         if( !list.contains( wrap ) ) {           list.add( wrap );         }       }     }     return list.toArray( new DisplayModeWrapper[0] );   }   protected void createAndShowGUI() {     Container canvas = getContentPane();     canvas.add( getMainPanel() );     canvas.setIgnoreRepaint( true );     setDefaultCloseOperation( EXIT_ON_CLOSE );     setTitle( "Display Mode Test" );     pack();     setVisible( true );   }   protected void onEnterFullScreen() {     if( graphicsDevice.isFullScreenSupported() ) {       DisplayMode newMode = getSelectedMode();       graphicsDevice.setFullScreenWindow( this );       graphicsDevice.setDisplayMode( newMode );     }   }   protected void onExitFullScreen() {     graphicsDevice.setDisplayMode( currentDisplayMode );     graphicsDevice.setFullScreenWindow( null );   }   protected DisplayMode getSelectedMode() {     DisplayModeWrapper wrapper =        (DisplayModeWrapper)displayModes.getSelectedItem();     DisplayMode dm = wrapper.dm;     int width = dm.getWidth();     int height = dm.getHeight();     int bit = 32;     int refresh = DisplayMode.REFRESH_RATE_UNKNOWN;     return new DisplayMode( width, height, bit, refresh );   }   public static void main( String[] args ) {     final DisplayModeExample app = new DisplayModeExample();     SwingUtilities.invokeLater( new Runnable() {       public void run() {         app.createAndShowGUI();       }     });   }
    最新回复(0)