Making a hexagonal battlefield

I’m making a battlefield composed of hex tiles that units can move around on, kill each other, that sort of thing. I’ve got three issues so far.

1: I’m using librocket for the 2d GUI in conjunction with a ray collision system for clicking on the 3d tiles. Is there a way to check if a click landed on a document so I can stop it being sent to the collision system below?

2: How do I display GUI elements on the tiles? As in, how do I highlight a 3d tile with an arbitrary texture according to the state of the tile? There are about 6 unique textures. I tried swapping texture slots between the highlight texture and a clear one, but this was way too slow.

Right now the individual tiles are hidden because for large fields having all of them drawn at once is too slow. It’s possible that every tile could be highlit, so I don’t think a system where every tile is responsible for drawing its own highlights would work.

3: I’m not sure how to go about setting up a thing like “wait until unit stops moving” in Panda3d. My usual tactic is to write a method that does something and only releases control when it’s finished, but Panda3d seems to be based more around a “give instructions and see it play out in real-time” system. E.g. when I move a unit with a sequence, the Python code continues and starts altering things I don’t want to alter until the unit’s stopped moving.

Hi,

1: I haven’t digged into this yet, but you could probably do some magic from librocket in that it tells panda to ignore events rocket gathered for itself. Still no special idea bout this one - I’m actually pretty interested in this solution, too, now.

2: If all tiles are static (don’t move), I’d use flattenStrong on them first. For highlighting I’d set up a second model with only one tile and put it on top of the not-highlighted and scale it up by a factor of 0.0001 or so. This way all your tiles are tied together which makes a huge performance benefit and you can still switch (overlap) individual tiles. If that doesn’t work for you and the amount of geoms makes your FPS drop, consider clustering the tiles, so that you can flatten at least a few groups.

3: For this taska are usually used. A task is a function that is running every frame (e.g. 30 times a second). So if you need something more complex than simple sequences and intervals, use tasks. A task could typically look like this:

def moveActor(self, task):
    self.actor.lookAt(self.destination)
    self.actor.setY(self.speed * globalClock.getDt()) # this means self.speed units per second
    return task.cont

For doing something else after the actor has reached its destination you could put an if statement into that task and check the distance. For more complex behaviors I suggest using an FSM. Check the manual on those things - they’re described pretty well there.

Hey Nemesis, I called flattenStrong on the node containing the tile models, and that works really well. I avoided doing this because I thought calling flattenStrong would mean I couldn’t manipulate each tile individually.

With the idea of making a separate model for the highlight: I have more than one state I want to represent on the tiles (there’s one for moving, and a different one for attacking, and one for “can move/attack here”, and one for “this is the unit whose turn it is” and one for “this has already been selected”. More than one can be displayed at the same time to show that e.g. you can attack yourself if you want to). Wouldn’t I have to make a separate model for each, each slightly larger than the previous?

Perhaps a different way would be to write a custom shader that has access to all of the textures, and setShaderInput booleans of whether to draw or skip each state’s texture. Could this work in theory?

–edit: typo

How exactly do you imagine the highlighting of the single tiles? Does the model change, only the texture or is it something on top of the texture? And do you want to eventually show multiple states at once?
Depending on your idea other techniques come into scope.

I think like Nemesis#13, too. The simplest way I can imagine is a texture in a second texture stage blended over the texture of the hex-tile.

I have a system that works reasonably well right now using a model for each tile. I’m using a custom shader and calling setShaderInput(texturename,value) on the model. The shader only draws that texture if the value is 1.


For posterity, I’ll try and explain what I wanted to do.

-There are many tiles. A tile does not necessarily have to have a visible geometry representing it, I can just use a single model of the right size to represent the ground.

-Each tile does, however, need to be able to show textures on its face. Whether it’s showing a texture or not should come down to a simple boolean value in the game’s tile object.

-Each tile has around 6 textures that it could be required to show. Each texture is controlled by a separate value in the code.

-Each tile may have more than one texture showing at once. I don’t think any more than 2 at once are actually required in-game.

-The game may require that all tiles are showing a texture simultaneously.

So does anyone have an answer to the first question yet? That was actually the more important one.