So I spent quite a bit of time today working on laying the groundwork for Splatterfield. And by that I mean that I spent most of the day wrestling with doing simple tasks like creating new classes, populating multidimensional arrays, and drawing squares on the screen. How else would one want to spend their Sunday?
One thing that I am trying to keep in mind is that there are (currently) two major structures that I am trying to wrap my head around:
- The Render Tree – Panda3D’s tree of objects to be rendered in the game world. These are the blocks that should be visible to the player at any particular time. It gets updated every frame.
- The Block Grid – This is a custom three-dimensional array of objects of type Block that stores information about that Block.
The Block Grid is important as it allows me to store and manipulate information about blocks without necessarily displaying them. The blocks will store information about their current state (e.g., what kind of block is it, whether it has been damaged, and so forth). Then if I ever need to access information about that block, I can just pass in the X, Y, Z coordinates and the appropriate property:
One thing that I’m still working with is how to render each of the blocks in the world. Currently, there is a single block type: Block. This makes rendering the entire map quite easy, since I can just copy the one type (instancing) over and over again. I’m not sure if this is something that I will be able to do when I have multiple types; I may have to add in some additional placeholders for each type of block when I do the instancing. Also, I’ll have to investigate how different from the original item instances can be; whether I can apply different textures and so forth. I tested this with sizing and it seemed to work, but I’m not sure what other properties can be added.
Today I was able to get a basic grid system going. Right now it just populates every single space in a 32 x 32 x 16 grid with a generic Block. I’d like to include some of the map generation and loading functionality that my brother and I used in Quadril, so that you can save maps that you have been working on in game. It is one of those tasks that I know I’m going to have to do at some point, but for the time being I’d rather work on something else.
So about that size…
In my earliest iteration of the program I ran into a little hiccup: I was trying to render 262,144 blocks onto the screen at once! It didn’t occur to me that 128 x 128 x 32 = 262,144.
Needless to say, performance was an issue.
So I scaled down the size a bit (to the current levels) but it still suffered. I decided on a quick and dirty solution: if a block had all six of its sides occupied with adjacent blocks, I wouldn’t put it into the render tree.
Actor or a Piece of Cardboard?
When I first started working on actually outputting a simple cube to the screen, I started with one of the Panda3D examples and stole most of it. I had to adjust a few variables and tweak it slightly.
The way that the sample worked was quite literally drawing individual 2D squares onto the canvas.
I wasn’t sure that this would be the best way to go about building a block-based world, especially if I ever wanted to animate the blocks. I decided to try using the Actor class on a very basic model instead. Luckily, Panda3D came with a “block” model that I was able to use. After re-texturing it a bit, I was able to get fairly good results that seemed to perform better than the geometric solution.
At least for the time being, I’ll stick with the Actor class.
Onward and Upward
I think that the next step in the development will be getting some super-basic mouse interaction going. Panda3D starts with the ability to look around a bit, so that’s a nice place to start. I’m going to take a look at some of the samples that are included with the engine and see if I can implement some basic mouse interaction with the blocks themselves. Perhaps selecting a surface of a block would be a good start or clicking on a block to delete it would be a good start.