Thursday, March 29, 2012

Now You're Editting With Power

Hey Readers!

What a busy week it's been, I've gotten a ton accomplished. The focus for this week was all on the tools, in particular the tools associated with editing a voxel sprite.

First up was some bug fixes I needed to get out of the way, I cleaned up the grid rendering for each layer in the voxel sprite, it was rendering a couple more lines than it should have been. The other bug fix was to do with the mouse drag selection in tile placing mode, it only worked for a single layer, so I extended the selection box to select all 4 layers. It could still use some improvements though, it only really works for selecting tiles when looking at the level head on.

Next up was figuring out what tools I wanted to add for edit mode. The tools I decided on were as follows:
    Draw Point
    Draw Line
    Draw Circle
    Extrude Layer
    Load From Image
    Extrude Layer by Color
    Switch Grid Axis
    Slide Layer Up
    Slider Layer Down
    Toggle Draw/Erase

Once I had an idea of the tools I wanted to build, the next step was to set up a window and some icons for selecting the different tools. So I set about to create a bunch of first pass icons to use. The first batch are sort of monotone, not a lot of detail but they get the job done. I'll have to get a UI artist down the road to clean these up.

Once I had my icons I went to add them to buttons. I ran into a bit of a roadblock here though because I realized that I hadn't set up my buttons so that I could have an image rendered on them. This wasn't a big deal I just added another asset to render on top of the buttons, but I realized that my UISprite object was only set up for scalable UI images where it separates the image into a grid of 9 images so that everything scales nicely. This was overkill for a little button image so I set up a non-scalable render mode for the UISprite that just renders the image as a simple quad.

I also started to hook up the UICopyPastable object I had created the previous week. I hooked it up to the UIEditbox for the trial run, it worked like a charm. It's nice to have copy and paste working now, makes using the edit boxes a little nicer, they still need cursors though.

Alright, that was the first day, on Tuesday I ran into a problem from setting up the copy and paste. I needed to separate out key commands that work for UI elements from Key commands set up for different edit modes. I had been meaning to do this for quite a while, my gameplan was to create groups for keyinput so that I could disable key commands based on group whenever I needed to. This took me the majority of Tuesday, testing included.

The first thing I wanted to get working was the grid axis toggle. This changed the grid within the voxel sprite between the x,y, and z axis. Next I hooked up the point drawing and line drawing I already had in place to the buttons I had set up in the edit toolbox. The first tool I really started working on was the fill tool. This is like the classic paint tool that does a flood fill across a layer. Then I added erase mode toggle which just flips the tools between placing a voxel and erasing a voxel, I made this a toggle so that erase works with all the tools, point, line, circle. Once I had finished the fill tool I figured it'd be a good time to hook all these tools up to mouse clicks, that was a fairly quick change. I also made a note that layer up and layer down weren't going to be that useful so I'm going to combine them and make a layer move tool. The next thing I realized was that I was going to need a file dialog. I came to a crossroads on this one, I knew that it was quite easy to bring up the standard windows dialog, so I had to weigh whether or not it would be worth all the extra time of implementing all the features for my own file dialog. In the end I decided that it was in my best interest to use the standard win32 dialog for now.

Thursday, since I was adding the file dialog I figured it would be a good time to switch tracks and spend some time hooking up the file dialog to things I already had in place. The first one was the main menu so that I could save and load different levels. This led me to realize that I didn't have a clean way to destroy a level. So I had to invest some time into making sure all the memory was properly freed so that I had a clean shutdown, flushing out everything properly. I'm still not 100% I got all the memory cleaned up but at least for now everything is flushing out properly. Since I had a clean shutdown now, I figured I'd add a New Level option to the main menu which just starts you out with a clean slate for building up a level.
Friday, with the Tile Edit State code starting to grow I figured it was a good time to separate out some of this code. I moved the code for the Tile Edit State and the Tile Placing State out of the main Editor Game State. All the code had already been in separate classes but it had all been living in the same cpp/h files. This was leading to some compile time issues on my little computer, plus the separation makes everything a lot cleaner. I also added a FileDialogInfo to the creation of the file dialog so I could adjust things like the default file extension and what not when I'm popping up the dialog. I also got to the bottom of a non fatal memory stomp, seems that it was caused by my group changes to the Input Watcher. I still need to dig into that one a bit deeper but it has a band-aid on it for now.

It's amazing sometimes how much you can get completed in one week!

Showing off the new file menu
First look at the new edit toolbox
Toggling the grid axis
Drawing with the line tool
Making a closed box so I can demo the fill tool
Bam, fill tool!
Showing off the erase toggle with the draw point tool
This last one is showing off the palette edit, change the color in the palette and it updates the sprite.

Sunday, March 18, 2012

More Cleanup

Hey Readers,

Sorry for the lack of updates, my wife and I just had a baby so I've been off work and therefore not doing any programming on the bus. Lots to update on though!

I added in context objects for all the major systems. This made all of the parameters I was passing into various objects a lot cleaner. Now an object just takes in the necessary contexts and has all the information it needs for construction.

I also cleaned up the movement code in the physics. After all the refactoring I was finding that the collision didn't quite work right. The character would get stuck all the time inside of walls. The trick was to separate out the collision into vertical and horizontal steps and also separate the collision response. Now everything's working great.

After that I decided it was time to start cleaning up all the bus in the editor and refine some of the features that I had stubbed in. The first thing I added was that if an object is selected and the user presses Ctrl-E it switches into the voxel editor mode with that objects voxel sprite.

Then I made some tweaks to the color palette. I set it up so that when the user enters voxel edit mode it loads all of the colors for that voxel sprite into the palette. I also fixed up the rgb sliders, now when the user selects a color the sliders auto adjust to the current color. Previously while they would adjust the color, the positions of the sliders didn't update to the current color.

I also changed the behaviour of saving for voxel sprites. Before when the user would press Ctrl-S it would save the currently edited voxel sprite as Sprite.spark in the base directory. Now it uses the metadata associated with the asset to get the proper filename so that it saves back to the right file. I should have done this ages ago, makes it a lot easier to iterate on art.

Another update was to the mouse raycast code. Before when selecting an object I would just iterate over the entire list of objects and as soon as I came across the first object that intersected with the mouse raycast I would break and make that object the currently selected. The problem with this is that the first object is not necessarily the closest object! So I changed it so that I build up a vector of selected object and then make the closest object to the camera the currently selected object.

The last thing I started putting in is functionality for copy and paste from the windows clipboard. I hooked up the platform specific code and now I'm starting to hook into the frontend code. I've stubbed in a UICopyPastable sprocket which any object that wants copy paste behaviour can use it.