buildings like in ultima 7

hi,

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.

any help with be grealy appreciated!

I’m not an expert, but I’d say that’s a pretty good example of an isometric view ;D
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.

hi bahuman,

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)

Huh, you’re right, I missed that :o

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.

  • X2D=X3D - Z3D
  • Y2D=Y3D + Z3D

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.

Java2D for this is fine - especially now its getting so much faster.

Kev (the avatar) Glass :wink:

hey kevglass,

that’s a really interesting idea. :slight_smile:

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.

thanks,
david

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?

Kev

The reason I mentioned OpenGL is simply because I’m so fond of it. ;D

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… :stuck_out_tongue:

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?

Why would you be forced to use the third coordinate? Just use 0 for all z-coordinates, or use the methods that only accept two coordinates 8)

http://basic4gl.wikispaces.com/2D+Drawing+in+OpenGL

duh! i guess that makes sense… :-[

hmm… but that also gives me ideas for making something better than just 2d… something like paper mario, where all the sprites are 2d and flat, but its got a 3d sort of look and feel to it… HMMMM…

i’ll have to look into this some more… thanks! :smiley:

That’s a nice concise article. Thanks for the link – I’ll be sharing it!

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.

hey purpleguitar,

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 :slight_smile: It depends how many tiles you are likely to display in the scene and how much time you want to spend designing your world.

Decisions Decisions :slight_smile:

Kev

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? ::slight_smile:

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 8)

@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.

That’s 99% of the fun, isn’t it ? ;D

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… :stuck_out_tongue:

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… :slight_smile:

oh boy… now i’m starting to rethink how i defined my map and all that… sigh… 1 step forward, 2 steps backward… :stuck_out_tongue:

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? :stuck_out_tongue:

thanks again, btw.

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

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


public class TileInformation {
  public int groundType;
  public int buildingType;
  public List items;
}

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 :stuck_out_tongue:

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.

my map and layer classs (in a nutshell) is something like this:


public class Map {
  private ArrayList mapLayers;
}

public class Layer {
  private Tiles[ ] [ ] tilemap;
  private Tiles[ ] tileset;
}

and i have a class for tiles


public class Tiles {
  private BufferedImage base;
}

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? ???

this is making me feel like such a noob… :’(