Primarily, I use the XNA framework for my shooters - so you'll have to hunt for the relevant voodoo in your own framework/language of choice. I'm also going to go over why creating assets for games designed with 3:4 in mind requires some special considerations compared to games that use a more end-user typical landscape resolution.
Also, enthusiasts will refer to a rotated 640x480 display as 480x640. For the sake of this article, any time I reference a display resolution I will always be talking in landscape terms. This makes it easier to talk about scaling from 640x480 to 1280x720 and so on - especially important because the aim of this is to get people thinking about how to design their games to run with scaling viewports that do not care about the actual resolution.
Step 1 - Knowing how damned big your game is going to be!
First, you need to decide on your target resolution for the game. For a clean low-res look that really pops on arcade monitors, you'll probably want to speak to Fagin. But seriously, if low res is your thing - you're going to want to design your assets at 320x240 if it's to be played on a 4:3 monitor. Why 320x240? Because of wonderful devices like Fagin's favourite SLG3000, it becomes possible to scale up a 320x240 image and output at another resolution while generating scanlines on top to keep things looking rather authentic. If you're in to that sort of thing, go and ask one of the hardware guys. I'm no expart!
Another option is of course to design at 640x480. But really, you can design at any resolution you like. I had long conversations with Fagin about this sort of thing via Youtube when making Chronoblast, hence the reason for him doing a video on the game - because I lack the physical equipment or the space for it - I can't really see how the game looks on a good monitor.
It's worth keeping in mind that if you're going to do a 3:4 vertical shooter, people are going to expect to be able to play it on their equipment. We haven't yet gotten to the point where we can all comfortably play fullscreen on rotated 16:9 displays without kicking off a global conflict - so for now, 3:4 is probably your best bet to keep the enthusiasts happy.
Why would you not want to design your game at a higher resolution? Well, the answer is simple. Although it doesn't look terrible, to a trained eye - downscaled graphics end up looking a bit poop to. Case in point:-
Chronoblast running on Fagin's setup
http://www.youtube.com/watch?v=kw4jx8wQeh8
That said, not everyone is in to Tate. Gus runs on the most ghetto SD TV setup you've ever seen, Geist plays (afaik) on a regular monitor with an xbox pad... so, there is an argument for keeping things as presentable as possible for those guys.
Anyway, enough of that rubbish - on with the actual tech.
STOP RAMBLING AND TELL ME ABOUT THE DAMNED SIZE!
Well, it's quite simple. Let's assume a 1280x720 monitor for a moment. This is the idiots way of finding your playfield.
1. Open up MS paint! Yes, paint!
2. Create an image that is 640x480
3. Rotate this image 90 degrees!
4. Go to the resize option, maintain aspect ratio and change the vertical size to match your target res.
For 720p - this gives you a 540x720 space to work with. 370 pixels each side for border art.
For 1080p - this gives you a 810x1080 space to work with. 555 pixels each side for border art.
Great, so how do I bloody well make use of this?!
RENDER TARGETS ARE YOUR FRIENDS
Now, a decent Framework will either provide you with a means to do this - or give you the tools so that you can write one yourself. I believe that GameMaker is quite special in the sense that it will just magically support a rotated monitor and scale everything nicely to maintain aspect ratio. Go GameMakers, you cheating bastards. But for the rest of us...
I wont use the words Render target or backbuffer to explain what they are. Instead, I'll put it in laymans terms. Essentially what we do is say to our program, "Hey, give me a 1280x720 texture that I can write to please". Then all we do is tell the GPU to draw everything to that. Simple.
No, it really is that simple. Here's some Pseudo Code:-
Code: Select all
RenderTarget2D mTexture = new RenderTarget(1280,720,DepthFormat.Blah, ColorFormat.Blah);
////////////////////
// Point GPU at the backbuffer
GraphicsDevice.SetRenderTarget(mTexture);
///////////////////
// Draw the whole game to it!
GameDraw();
///////////////////
// Point back at the screen
GraphicsDevice.SetRenderTarget(null);
//////////////////
// Draw the relevant area from that texture to the damned screen!
Vector2 ScreenCenter = Vector2(screen.width/2,screen.height/2);
Rectangle RelevantSection = Rectangle(370,0,540,720);
Vector2 Origin = Vector2(RelevantSection.width/2,RelevantSection.height/2);
float fRotation = Math.pi/2;
sprite.Draw(mTexture, ScreenCenter, RelevantSection, Color.White, fRotation, Origin);
The aim of this is to help people separate what's rendered from what actually happens in game logic. It's a bit of a big step but once it clicks, it sticks
With this method, you can basically design your game like this:-
http://www.n0rty.com/tateexample.png
Image linked instead of placed in post as it was actually larger than YGW's boner when implementing rank mechanics
In some respects, it's a little inefficient - but it means if you've designed your game to work entirely with screen space collisions and alignment, then you can tate it all with no problem at all.