i've starting building a 2d rpg, and i want to have view top down, but tilted so you're not look only at everyone's head.. not an isometric view, because its not at an angle - think final fantasy... i'd say ultima 7, but that's done so it's tilted to the left as well - i just want it tilted back. you know what i mean?(some pics from ultima 7 for reference: http://www.mobygames.com/game/ultima-vii-the-black-gate/screenshots)

so anyway, i have a map now where i can draw my grass and sand, etc.. but i'm wondering how to implement buildings. again, modeling this after ultima 7, i want to just be able to walk into a building, and have the roof disapear so i can see inside. also, i'm pretty sure ultima 7 let you go up to the second floor of a building.

i'm curious how this can be done. at first i was thinking of having a map layer that had things like the roof on it, and when i go in a building, hide that layer. but the problems i'm seeing with that is that i don't want to have another full map layer, when it's largely going to be empty (except for when near a town, where there will be several buildings).

so anyway.. my question is if anyone can give me some ideas on how i can accomplish having buildings, with possible second (or more) floors on my 2d map.

I'm not an expert, but I'd say that's a pretty good example of an isometric view That means you could probably store your map as a set of tiles. If you want roofs and seconds floors, you'll need more "levels" in your tiles, as well.The tile with a staircase painted on it, would have to work like some sort of teleport towards a map with only the second floor on it. If I remember correctly, most of these games showed you the second floor with just "black" around it.

well the reason i don't say that it's isometric is because it looks as if the tiles aren't aligned at an angle - the bottom is parallel with the bottom of the screen. but anyway, i guess it could be isometric too then..

if i have more levels on my map, won't that waste space in memory, or spend more time drawing, even when i'm not in a town, for example?

as for showing black.. i think when you went upstairs, you could still see what was outside.. but was black when you when below the ground level.. (i know for sure thats how it was in ultima 8 at least)

I'm guessing the ultima engines only use tiles, so they didn't need to do any 3D calculation. You could go the same route (displaying a little bitmap of a building on each square. OpenGL will take care of the overlapping bitmaps for you), or you could try to emulate the weird perspective.

If I understand you correctly, you'd like to have the exact same kind of not-quite-perspective projection, not something that comes closer to real 3D projection ? I'm sure you can do it, theoretically, if you fiddle around with your modelview matrix. But you'll need some experience with matrix multiplication. If you're not afraid of math, I think this might give you a start:http://en.wikipedia.org/wiki/3D_projection

In your case, you'll need to replace the third step (perspective transform) with something simpler.Warning: the following comes with no guarantees whatsoever! I'm making this up as I go.

i keep seeing people talk about using opengl for 2d stuff.. it's scaring me, because i'm really unfamiliar with it, and i'm unsure if i'm going about this properly now... i was planning on doing this with java2d.

but anyway, those fears aside. to achieve some kind of overlap, i was planning on having my character spites inserted in the correct cells of the map - when the screen gets drawn, the player will be drawn in at the correct location, so if something overlaps from the cell below, it'll get drawn over where it needs to.

i'm not really sure that perspective transforms would be required for what i want to do, unless i go the opengl route i guess. if i do that, wouldn't i still need to worry about how to store a second floor and when and how to remove it from view so i can see inside a building?

Using plain sprites should be fine (since thats what U7 P1 and P2) did. One way to achieve this if you really don't want to have the extra layer is to have two states for each of your building sprites. One with and one without the roof. When the player walks onto a tile that has more than one state you change it and draw the tile without the roof - also floodfilling to find any other tiles that are inside of the target building and changing their state.

This way the extra information becomes part of the tile rather than an extra map layer. However, you'll probably find other reasons to want multiple map layers so it might be just aswell to add it now.

but if i do need map layers, wouldn't it waste time while drawing to loop through all my layers looking for tiles to draw, even when i'm nowhere near any buildings or other places that would require the second (or greater) map layers?

and that's good that i should still be doing this with java2d.. 3d stuff would complicate things too much for me.

OpenGL doesn't imply 3D - you can do 2D with it - most people end up going that way for performance reasons.

The cost in drawing maps is mostly the actual sprite drawing. If you have a loop that drew the tiles to the screen and you simply checked whether a tile was there or not before drawing then the cost would be very small. I've found better performance with a NullSprite implementation that when asked to draw does nothing - but that might not fit you model.

Extra layers that arn't drawn alot of the time cost very little and give you a huge amout of flexibility that you wouldn't have otherwise. Obviously your call, and as you see there are other ways to get round these things - but most rpgs end up needing extra layers just for things like items.

Presumably you'd only be drawing a small section of your map to the screen anyway?

The reason I mentioned separate layers, has a slightly better reason. If you keep the extra floor and the roof tile as part of one square, you'll need some way to determine how many of the surrounding tiles are part of your building (and will also have a roof tile or second floor tile). Why bother, if you could just switch to another layer of your map? The second floor will contain items and/or NPC's as well, and those are different from the first floor, obviously.

how then can i do just 2d with opengl? i'm an opengl n00b, in case you couldn't tell by now..

i know what you mean by seperate layers bahuman, but i also want to show them all at the same time - like i want the building to show the outside of all its floors, not just the bottom floor, which is why i'm concerned about having them all visible together..

tell me about this NullSprite thing, kevglass.. right now, i have a Tile class, which i use to keep track of all the tiles i'll have on my map. when i call the draw method of that, it'll check if the BufferedImage in that tile object is not null, and draw it if it isn't.. is that sort of like what you're talking about?

Regarding that article though: another option is the keep the DepthTest in OpenGL and use the Z coordinates to manage sprite layers. Under an orthogonal project, "far away" things are drawn the same scale as "close" things (cf. perspective projection). I have found this to be useful when I have layers of sprites, such as a player layer, an enemies layer, a bullets layer, etc.

In fact, you could make two (or more) layers for tiles and put the 2nd floor tiles "above" the ground floor tiles. Simply disable the drawing of the upper layer when the player is on the ground, and enable it when he climbs the stairs. OpenGL will hide the lower level under the upper level. This is probably not the most efficient implementation, but it sure would be easy. Of course, this also assumes that you're doing flat overhead, since otherwise you'll have to skew your projection to handle the leaning of the buildings a la U7, but now I'm just thinking out loud ... through my fingers.

what you said about using the height to handle layers and then look 'through' the ones i don't want, and showing them when i need to go higher is what i starting thinking about after i read that link..

it sounds like a good idea.. though how wouldn't it be efficient? if it's going to not be visible, wouldn't the rendering of it be skipped?

if i wanted to have things tilted, couldn'ti stil do it hte same way, and just draw my tiles so they're at the correct angle?

which sort of brings me to another question, that's probably pulling this thread off topic.. but lets say i want to use some 3d.. would i *have* to use a 3d modeling tool to then draw everything and create models for my buildings, or would i still be able to do it all in my tile map, and then draw cubes or rectangles (or whatever) for my walls where i want them? would that be less efficient than creating a model of the building?

It's definitely less efficient to use 3D tiles to build a scene. However, that doesn't mean it's not right for what you're doing It depends how many tiles you are likely to display in the scene and how much time you want to spend designing your world.

If we can be thinking out loud ... through our fingers ... I just wonder why you would "dumb down" the openGL interface to 2D first, and then come up with tricks to make it look 3D, and layering, and occlusion, etc etc?

I'm sure there's an affine transformation that lets you create the weird perspective à la Ultima 7. That means you can keep your 3rd coordinate and use it as height, inside your map! For example, assuming x and y are the longitude and lattitude in the map:

a wall on the ground, running from (1,1) to (2,1) would be defined as a quad with vertices (1,1,0), (1,1,1),(2,1,1),(2,1,0)Since z ranges from 0 to 1, the wall will reach the ceiling.

a wall on the second floor, running from the same coordinates (1,1) to (2,1), would be a quad with the following coordinates: (1,1,1), (1,1,2),(2,1,2),(2,1,1) and as you can see, it would be stacked right on top of our first wall!

And as you suggested, drawing or hiding the second floor would be simply a matter of changing the frustrum. I wouldn't worry about performance until the FPS actually starts dropping

@DavidBoDavid: you don't have to specify your entire level in a single model. You can model separate walls, doors, tables, objects, coffins, swords ... and your level file would decide what object is placed where. And if your "models" are very simple (like walls), you don't need a modeler at all, I guess.

what bahuman is saying about defining a wall with a set of verticies makes alot of sense to me, if the buildings are fairly rectangular. how would it be less efficient if you're telling it to just draw simple boxes, rather than load a model?

now that i got that whole 3d/2d idea in my head, i'm starting to begrudgingly like it more and more.. this was supposed to be a cheesy simple game.. but then again, i've never been known to take the easy route..

the fps is something that would bother me though, because i would hate to look at it when it suddenly has become an issue, and realize that my fundimental idea of how i went about doing everything was wrong (or at least, inefficient).. so i'd rather think about all the annoying issues first..

i know i'd be able to seperate my building models from my map, or what have you.. it's just that i have almost no experience with 3d modeling tools.. which is part of the reason i was trying to avoid it in the first place..

i know i'd be able to seperate my building models from my map, or what have you.. it's just that i have almost no experience with 3d modeling tools.. which is part of the reason i was trying to avoid it in the first place..

so.. any good books i should be looking at?

LOL! The 2 steps backward is the main reason why most of us don't finish a game, I think

I'm curious... how did you define your map? I'm guessing it's a 2-dimensional array of a structure somewhat like this:

and depending on the groundType and the buildingType, you would draw a different tile. You could do exactly the same with 3D models! The buildingType could simply be an index into an array of small 3D models, for example.

EDIT: on performance, I'm no expert, but I'll hazard a guess, here:

The reason this is less efficient than other techniques (like BSP, or heightmap, or whatever), is because it'll be harder to implement some sort of "level-of-detail" for your map. If you're not careful, you might be forced to draw your entire map, every frame again, even though you may only see a small part of it.

Also, you'll be dealing with many small objects. Like, a 1000 items on the screen, each less than 100 polygons. OpenGL is more capable of drawing 100 items, each with 1000 polygons. This is because a single model with 1000 polygons can be stored in a display list, and stored permanently on your graphics card's memory.

But personally, this is the part of performance I wouldn't care too much about. If your game is capable of overloading the OpenGL engine, that means you've already constructed sophisticated maps with lots of items, and your "engine" will already be capable of playing a game. In the worst-case scenario, you might have to simplify your maps a little because of performance. I wish any of my games were in that stadium

LOL! The 2 steps backward is the main reason why most of us don't finish a game, I think

yeah, probably.. though last night i started to talk myself out of going 3d again.. so i don't know anymore.. *thows up hands*.

right now, i have my map defined as a set of layers,and each layer has tiles on it.. so i was starting to put together my base tile layer, which will have the ground tiles.. then an object layer, that was to have trees, buildings, etc. and then i guess more object layers for extra floors, or things like that.

so i have a set of tiles for the map, and the map just points at each tile where it's supposed to show up.. i did it this way ,so for large areas, i wouldn't be repeating tiles that are the same - like grass.. or trees, or whatever. i don't know.. i've just started working on this, so nothing is totally set in stone yet.

as for how defining the building geometry on the map.. i'm still sort of unsure how it might cause me to draw the whole map. wouldn't i still be looking for an area of my map, and then looking for the objects that are shown within that area only?

the nice thing about opengl is that it's so versatile and powerful. The bad thing about opengl is that it's too versatile and powerful

In a naive implementation, you would send everything to opengl, and opengl will figure out what's visible and what is not. If you have a free-floating camera, your visible area might not be so calculate. If you restrict the camera, you can do what you're thinking of: draw only the part of the map that is visible.

so let's say i want to keep it still 2d-ish, or maybe a bit isometric, with the camera fixed (but maybe it will allow zooming a bit)..

can i still define my map as a set of tiles, and then when i draw the ground, create squares and put my tile as a texture on those squares? is that proper, or some kind of freaky assbackwards way of using opengl?

can i still define my map as a set of tiles, and then when i draw the ground, create squares and put my tile as a texture on those squares? is that proper, or some kind of freaky assbackwards way of using opengl?

This kind of freaky assbackwards way of using opengl involves a technique called billboarding.

lol.. but from what i do know of 3d programming, aren't billboards things that are 'standing up'.. like trees, or that nature.. or does it work the same if i want to make a floor? wouldn't i make a grid of squares and just texture them? or agian, is that pretty much the same thing?

It sounds like you want to call gluOrtho2d() to make the perspective flat -- after calling that draw everything with a z coordinate of 0, giving you true 2d. Then, the equivalent of blitting a sprite is easy - draw a GL_QUAD with your texture activated. Billboarding is something else used to simplify 3d scenes.

To make it like blitting an image with transparency, you should turn blending on so the transparent parts show up transparent. There are some other built in things, like lighting, scaling and depth testing, which might be useful/interesting (but probably not).

Opengl would do some things for you like transparency and scaling, but it will be much harder to play with individual pixels (which might be fun/educational) as you would otherwise. You don't really need opengl and your users would need the right libraries if you use opengl.. but maybe opengl is easier?

Just use your tile approach and draw a tile as texture on a quad, theres nothing bad about it.

Instead of multiple map layers you could use layered tiles, e.g. make a single map, but define your tile class to have multiple layers itself. Assign a "real" height to every layer and fiddle with glOrtho() or some twisted projection matrix to get the desired look. Make the walls simple quads, too, just standing upright. You could define the "wall-spec" as a part of a tile-layer.

If you enable depth testing while drawing, your character can move below ceilings and is always clipped correctly, if it is partly visible.

After all you only have to work through the basic tutorials (2-6) at nehe and maybe the tutorial for masking (20). Setting up the right projection might be challenging, but maybe theres something at google...

yeah blank_axolotl, i think that's the sort of thing i was wondering about..but if opengl can do it like that, i'll look into it.

cylab, that's another thing i was thinking of, if i decide to go a more 3d/2d style. i know bahuman said that it's probably better if i have a model that i can store in the video memory, but i'm thinking there won't ever be too many things on the screen at anyone time anyway.. and if they're all boxes, wouldn't that be easy enough for it to render quickly?

well... i got the jogl chapters from the killer games programming in java website.. and i'll work through those this weekend, and see if any of it makes sense to me..

eitherway.. i'll get back to you guys and let you know how it turns out.. lol.

With my 2D RPG I utilized multiple layers, and did not notice any performance hit whatsoever.

Basically I have a 3D array of Collidable's (my root object, contains x,y,width,height, and drawing methods). The first dimension is every layer, the second and third dimensions are the pieces that you see within that layer. My map editor that I made to create the levels can make as many layers as you want and can traverse them however you want. However, only in the middle layer (level.length/2) can the character interact directly. Therefore to add a foreground layer a matching background layer needs to be added as well – but if you don't want this it's easy to change. The advantage to this, however, is that I have nothing visible within the middle layer. Instead I have all the walls, doors, portals, characters, monsters, chests, etc. etc. within that middle layer, and their graphic representations in the other layers. This allows for passwalls (looks like every other wall but has no matching block in the middle layer), invisible walls (no foreground/background), overhanging houses like in most RPGs (the top half of the house is in foreground so you can walk behind it, the front is in the background so you can walk in front, and only a small section is impassable). This method allowed for me to make absolutely any graphic representation. I put clouds and weather in a super high layer and grass in a very low layer. The big downside to this method? It can be a pain to match up collision blocks with the right places for each of their sprites, especially when the sprites span across multiple layers. The solution? I created an object called a TileSet that is basically a miniaturized version of the main 3D array. Instead it is very small and only holds the information for one "object." Thus you can create a house TileSet that has all foreground, background, block, and door elements, then click once and have them all pasted into each layer for you.

I don't know if this method appeals to you, but with BufferedImage or OpenGL you can split one image into multiple ones, allowing for automatic splits into foreground/background/whatever, making it very easy.

that sounds like a really interesting solution. thanks for sharing that.

i've been rethinking a number of things this weekend, but i was still stuck on how to get several layers working correctly. i was thinking of putting all my objects into one layer, like the floor (could be grass if outside) and objects, trees, rocks, walls, etc into that layer as well. but then when i want to move up a layer, if it's above ground, it would be largely empty to see the ground below, but for the places on that layer, it would be the same thing. so each layer would be independant of each other, and i'd only have to worry about colliding with objects on the layer my player is on.

so how do you manage moving between layers? like if you have a house with 2 floors?

Yeah, that's exactly what I did. The player only every interacts with objects in his layer (the middle layer). If you wanted, you could even use this method to include a house with multiple floors and so have a dynamic way of moving the player between layers (which mine does not, I just use a faux 2D-3D looking system). In addition, only objects in the player's layer have their act() method called, meaning that all Actable's, or performing objects, are in that middle layer as well. Which of course means monsters, scripted walls, NPCs, and the like.

If you wanted to make it so that every layer was interactable if the player moved onto it, then you could have the same 3D array layout but instead of making the other layers merely sprites (which mine are) you can make them just the same as the other layers, but the player can only interact with the layer he is on. If you want to have some layers that have only sprites and other layers that have people, etc. you could have two 3D arrays, one for sprites and one for objects, then have both layers "move up" when the player goes up stairs or whatnot.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org