buildings like in ultima 7

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

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.

:stuck_out_tongue:

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?

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

that’s so freaky… and assbackwards! :o

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?

thanks for still replying to all of this… :slight_smile:

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…

And if you have not idea of OpenGL at all, heres a very brief description, or see the OpenGL page at Wikipedia.
For a more complete understanding of OpenGL, you can view the redbook and the bluebook online.

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

thanks again! ;D

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.

Good luck, hope that maybe helped a little bit.

hey demonpants,

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

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?

thanks

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.

So maybe like this:


Object[][][] sprites;
Object[][][] obects;
int currentLayer = 2;
int playerX, playerY;

onKeyUp()
{
     if (objects[currentLayer][playerX][playerY+1] == null)
          movePlayer(currentLayer,playerX,playerY+1);
}
//etc.

movePlayer(int floor, int x, int y)
{
     //methods for changing your player's position on the map
}

draw()
{
     for (int i = 0; i < currentLayer; i++)
     {
          drawAllObjectsInThisLayer(i);
          drawAllSpritesInThisLayer(i);
     }

     //Draw the player in between the layers under and over him
     drawPlayer();

     for (int i = currentLayer; i < objects.length; i++)
     {
          drawAllObjectsInThisLayer(i);
          drawAllSpritesInThisLayer(i);
     }
}

Not any actual code there, really, but you get the idea I think.

Good luck, hope that helped.

Hmm…interesting.

do you have any sprites that are larger than one tile, though? i’m wondering how you handle the player bring infront of the back wall of a room (for example) when the room walls are drawn the layer above the player… if the player sprite is say one tile wide and 2 tiles tall… i’m trying to do something (graphically) like chrono trigger, instead of doing it like final fantasy 3 (not that i’m implying one is bad or anything).

the way i started thinking about it, is that the current layer would be composed of tiles, and each tile would have the base grownd texture, and whatever other additional things that the player could still walk on (like a sprig of grass, or a flower), and then the tile would have a list of object, orderd by increasing x-coordinate. so that stuff will appear infront of the players feet, for example. so then my player movement consists of small shifts on a given tile, or moving him between tiles. all the collision checking is based on what is on the tiles around him only. if he goes up a level, then it will be the same situation.

i think i understand how your method is working though (and it giving something more ff3-style), and i was thinking of doing something similar to that until i started worrying about things partially overlapping each other (ct-style). if i’m thinking of how yours is supposed to work completely wrong, please correct me. :slight_smile:

Well the key is the invisible walls. Essentially, everything you see you can’t actually interact with. The real physical walls are not drawn and are only used for moving logic. That way I can in fact make humungous gigantic pictures with only one single block that you can’t walk through. Imagine this:

Say we have the sprite for a big house. It might look like this, with ^'s being the roof (foreground), @@ being the middle (midground), and ++ being the part you can walk on top of “in front of” (background).


^^^^^
@@@@@
@@@@@
+++++

That actual sprite, although drawn with different characters, is two sprites placed in the top left corner, one in the foreground drawn above the player and one in the background, like this:


+0000
+0000
00000
00000

Where the + is the single block where the sprite is saved in the 3D array, but can be seen across the whole thing. The +0000 is just the roof saved in some layer higher than the player so it is drawn on top of him, then the rest is drawn in a layer under the player.

Now with just that, I would have a large image taking up several blocks you could just walk all over. What now becomes neccesary is to include spaces in the midground so, logically speaking, part of the house obstructs walking. an O is an empty space, and a + is where a wall is placed in the moddle layer. Note these walls are invisible.


OOOOO
+++++
+++++
OOOOO

The character can walk anywhere where there are O’s, so if you want on the top you would be unobstructed but a roof would still be drawn on top of you, while the bottom O’s can be walked upon even though you are walking on top of a sprite. Try walking through the entire house, however, and you will be stopped by invisible blocks.

In this way, although the collision is in fact entirely grid based like FF3, it appears as if you are interacting with a 3D house – a house which is one sprite (in fact I allow for the stretching/shrinking of any sprite to any size). Chrono Trigger probably did something on this level, so even though you may believe that FF3 and CT drawing methods are so different, they in fact probably use the same walking engine – CT just has a few layers slapped on to create the pretty (but fake) 3D effect.

ohhh… very interesting! i understand what you’re doing now. (after spelling it out for me…lol). your example makes alot of sense.

so if i understand this correctly, when i’m inside of a building, then the front wall would be the layer on top of the player, and the rest would be behind him. i think that would still give the effect i want. but what about buildings with walls or rooms inside?

something like:


_________
|         |
|___      |
|         |
|___   __ |

that’s how the layout would look from a straight top-down view, but the walls would be drawn so they look like they’re on an angle. so in my little house there’s a wall on the inside making 2 rooms. when i’m in the front room, i’d be drawn infront of it, but if i go into the back room, that wall would need to be drawn on top of me. if i put that middle wall on the top layer, it’ll still be drawn on top of me, even if i’m infront of it. :-S

Ah, that’s an issue that I never had to worry about because for multiple rooms I simply created multiple level files (half second level loading made that okay).

I’d imagine if you wanted it to work that way then you could have the player’s position “vertically” (in the array) to be dynamic rather than always in the center. Therefore they could move up or down within the array of objects, changing what appears over and under them. The only problem with this is that your collidable pieces (rather than ones that are just drawn and you can’t touch) might move out of sync you may end up colliding with your simple drawn objects. Perhaps a good solution for this would be to maybe reserve 3 to 5 layers for collidable objects, then ones outside of that would be the background pictures. This way you could actually have multiple floors worth of collision, and you could have multiple floors of drawn parts.

Either way it really comes down to your array management. I think probably the best solution for you (if you are continuing to do it my way) would be to create two totally separate 2D arrays – one for invisible touchable objects, and one for their drawn representations. Scroll them both simultaneously (make sure to have graphics refresh after both have drawn, not in between) and have the same interaction/drawing level for (say you are interacting with layer 3, draw layers 0-2 under the player and 4-5 on top) both, creating your pseudo-3D look and allowing for walls that are drawn over the player in multi-room houses.