Setting resolution for your game?

I like to write old style arcade games but always picked a 800 x 600 resolution as they suited the style. I would try changing the resolution on screen via the program and then playing the game. My own PC copes with this resolution perfectly, my old laptop would lose the bottom part of the screen while my new fancy laptop just lowers the resolution a little and then shows your game in a corner of the screen. I’ve spent the last two days altering the game graphics and mechanics to work at 1080 but the problem hasn’t gone away - it says it’s in 1920 x 1080 but is actually only showing 1450 x 900. If I say getWidth and getHeight then it shows 1920 x 1080 still. I’m baffled.

Is there a simple way of finding out what screen res are actually supported and then picking one that works. The ideal solution for me would be able to set the players screen to 800 x 600 in full screen mode but this seems hellishly difficult. Ideas?

Here’s the code I use :


	public static void main(String[] args) {
		Frame f = new Frame(device.getDefaultConfiguration());

		// get display mode
		OldDisplayMode = device.getDisplayMode();
		DisplayMode bsf_dm = device.getDisplayMode();
		int bsf_scr = -100;
		
		System.out.println("best width="+BestScreenWidth+" height="+BestScreenHeight );

		/*
		 * other stuff
		 */
		neptune w = new neptune();
		f = new Frame("Neptune");

		f.setUndecorated(true);
		f.setResizable(false);

		f.add(w);
		Window win = new Window(f);
		f.addWindowListener(new FrameListener());

		for( DisplayMode dm : device.getDisplayModes() ) {
			int scr = 0;
			if ( dm.getWidth() == BestScreenWidth ) { scr += 1000; }
			if ( dm.getWidth() > BestScreenWidth ) { scr += 40 + (BestScreenWidth-dm.getWidth())/10; }
			if ( dm.getHeight() == BestScreenHeight ) { scr += 1400; }
			if ( dm.getHeight() > BestScreenHeight ) { scr += 40 + (BestScreenHeight-dm.getHeight())/10; }
			scr += dm.getRefreshRate();
			if ( dm.getBitDepth() >= 32 ) { 
				scr += 50; 
			} else if ( dm.getBitDepth() >= 16 ) { 
				scr += 25;
			}

			if ( scr > bsf_scr ) {
				System.out.println("Current best width="+dm.getWidth()+" height="+dm.getHeight()+
				 		" dep="+dm.getBitDepth() +" refresh="+dm.getRefreshRate()+
				 		" bitdepth="+dm.getBitDepth()+" scr="+scr );
				bsf_scr = scr;
				bsf_dm = dm;

				if ( dm.getWidth() == ScreenWidth && dm.getHeight() == ScreenHeight ) { break; }
			}
		}

		/*
		 * try it out
		 */
		try {
			if ( device.isFullScreenSupported() ) {
				device.setFullScreenWindow(f);
				if ( device.isDisplayChangeSupported() ) {
					device.setDisplayMode( bsf_dm );
				}
			}
		} catch ( Exception e ) {
			device.setDisplayMode(OldDisplayMode);
			device.setFullScreenWindow(win);
		}

		
		ScreenWidth = bsf_dm.getWidth();
		ScreenHeight = bsf_dm.getHeight();
		System.out.println("Chosen width="+ScreenWidth+" height="+ScreenHeight );
		w.init();

                Thread t2 = new Thread(new WebIO(), "My Thread");
	} 

The output looks reasonable but the screen res is 1600 x 900:

C:\Users\Mike\Dropbox\Projects\neptune>java -cp ".;neptune.jar;tinysound-1.1.1.jar" -Dsun.java2d.noddraw=true neptune
best width=1920 height=1080
Current best width=320 height=200 dep=32 refresh=40 bitdepth=32 scr=90
Current best width=320 height=200 dep=32 refresh=60 bitdepth=32 scr=110
Current best width=1920 height=1080 dep=32 refresh=40 bitdepth=32 scr=2490
Current best width=1920 height=1080 dep=32 refresh=60 bitdepth=32 scr=2510
Chosen width=1920 height=1080
Aug 11, 2017 11:33:10 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

The short answer to this is sorta braindead but… use the user’s desktop resolution and don’t change anything. Scale your game to fit. (Easier using OpenGL obviously)

Cas :slight_smile:

Sorry for the delay, I was hoping someone would say you’re wrong and all I have to do is blah blah blah. Sadly that doesn’t appear to be the case. It just struck me as odd that the getWidth call etc would return something that was wrong. Hey ho.

I’ve had a look at OpenGL and suspect it’s too difficult for my feeble mind to get round. However, all my games are 2D games so I began looking at 2D variants like Slick2D. This looks a little easier to understand but will it allow me to scale a game (preferably one that’s already in 800 x 600) to any screen size? will it also be possible to release via something like steam? android?

Mike

There is at least a 3:1 spread in the pixel density of commonly available displays. There’s
no sensible way to design a game that doesn’t take this into account. Something that looks
nice on a 72dpi display will be a tiny unusable feature on a 300ppi display.

You also should take into account that a lot of screens are touch only (even windows pc screens)
and on such screens there is no mouse tracking, no mouse rollovers, and a minimum feature size
of around 1/3 inch if the user is intended to click on it.

I would try the following:
Find out which axis of the screen is smaller than the other one and then calculate the new dimensions for the game so that the game is “maximized” on one axis and then leave some black stripes on the bigger axis (center the game)
That also means that your game could keep its aspect ratio (e.g. 4:3).
At least thats what I did when I had similiar problems.

Cheers

I had to use this line too when I was using Java2D in 2012 on Mac.


getRootPane().setWindowDecorationStyle(JRootPane.NONE);

Otherwise, I got the menubar still visible in the past. By the way, I too prefer OpenGL, that makes graphics really easy and gives good performance too.

This works well. A slightly more complex solution is to allow a bit of leeway by allowing elements of the game to move around a bit clamped to the edges - stuff like score and lives and things like that - and if you can, don’t fill the empty background with black, but instead use a nice bit of “fading texture” or something that your main game section goes nicely with.

Cas :slight_smile:

Altering the screen size manually : I recently spent a few days altering everything in my game (graphics, movement, text size etc etc) to go from 800 x 600 to 1920 x 1080. I had the intention of then scaling everything myself to fit the users screen size. The biggest problem was I’d try to set a screen size (a valid java command) and it would return success and tell me the screen dimensions were n x n but it turned out these values were wrong and not to be trusted.

It must be a common problem to all games writers so there must be an easy to use solution out there. I had a look at OpenGL but it’s too complex for me. Slick2D seems better for me but before I install eclipse and start trying to learn Slick2D, I wanted to know whether I’d be wasting my time. Can it rescale the playing area (graphics, text etc) so I can still use the existing 800 x 600 logic? Would it work on any screen whether PC or laptop?

My games are just simple arcade games so it’s just key controls (WASD & fire) so touch isn’t an issue. If the device doesn’t have a keyboard then I’ll deal with that later on down the line - maybe add tilt movement and tap anywhere to fire for phones etc. Actually this is miles down the line as I haven’t released anything yet but I’d like my hobby to pay for itself.

There is no simple solution unfortunately. Believe it or not the days of widely disparate screen resolutions and aspect ratios (and even input devices) is actually a “new problem” facing the industry which hasn’t actually had time to really adapt and work out best practices.

I’ve spent quite a lot of time making a state-of-the-art solution (using OpenGL). It is entirely aspect-ratio independent - as UI elements (including the game) are anchored to various screen edges and positions and each other - it is also resolution independent, as it is rendered at any arbitrary logical resolution (which can be finely adjusted by the user), but I always render the final display out at physical desktop resolution (or window size). It is fiddly and complex but it’s the only real way to do it right.

I think at a minimum you will need to come up with a system of anchoring so that you can place and resize your game “areas” according to the physical bounds of its full rendering area. This will allow it at least to not break on fairly arbitrary aspect ratios.

The resolution though is a different kettle of fish. It is possible to do in Java2D without a huge amount of hassle - render everything to a VolatileImage of the same aspect ratio as the target display. I would potentially use a VolatileImage that is twice the resolution of the target display. Then render the VolatileImage to the target, rescaling it to the target’s physical resolution, every frame. It’s perfectly fast enough.

Cas :slight_smile: