A Game Yet?
25 October 2019
Phew, that was tough!
I knew getting the mouse input to work well was going to be tricky, but I hadn’t realised it was going to be that tricky!
Using GetCursorPos/SetCursorPos turned out to be just the start of it. The ‘easy’ part - hiding and showing the cursor - turned out to be the hardest part of all. Simply hiding the cursor worked, until I violently wiggled the mouse, then the cursor would flicker back into existence. I tried all sorts of things to get this to stop happening. Capturing the mouse did not improve things, but it did prevent Alt+F4 from working. Using Win32 to hide/show the cursor directly made no difference whatsoever. Ultimately the only thing that improved the flicker was to set the Cursor Clipping to the boundary of the window. Now the cursor never flickers, but with vigorous mouse movements, I can get it to hit the side of the window. Hitting the side of the window will limit the maximum movement the player can make. I’m accepting this for now because such actions probably won’t make sense in real play anyway… time will tell on that one.
I did stumble across another API called ‘RawInput’, which looks like it might be a cleaner way to go. I’ll come back to that later as what I have works enough for now - something to keep in mind, though.
I also ran into an issue with uneven movement, almost UI flicker. It seemed like I was already hitting performance issues, which would be a disaster - I’m only animating a single visual after all. After putting in lots of profiling and investigating, I pinned the issue down to the UI timer. The timer was taking inconsistent and rather long periods to tick. It turns out the DispatcherTimer has a priority setting, by default timer messages are pushed aside in favour of rendering operations. Since this timer is now in control of my input, that assumption doesn’t hold. By merely bumping the priority to be equal to rendering, the issue was resolved.
To test the click handling, I made the blob change colour through a cycled palette. Left-clicking goes one way through the palette; right-clicking goes the other.
Where are we now? We can fling the blob about the screen freely; we can click to change its colour; we can press escape (or change to another window) to pause the game, and there is a working menu.
Not a game
Despite all that, this still isn’t a game of any sort. You can’t win; you can’t lose. And there is no objective. Yeesh, how dull.
There is also a growing list of technical tasks to attend to. I’ve just added ‘Full Screen’ running as an item on my todo list, and that brings with it a requirement for an ‘Options’ menu, and probably some command-line argument handling too. Not to mention I hooked up the mouse as a direct control over the blob, and didn’t use the core ‘thrust and inertia’ mechanic yet.
Still, I can only build one thing at once, and progress is steady.
But first
It is hyper tempting to jump ahead and start implementing proper game mechanics - win, lose, thrust, etc. But really, I know this would be a mistake and cause me to have to redo lots of stuff.
My vision for this game doesn’t have all the activity confined to the size of the window. The window should be a viewport onto a broader universe in which all the action happens.
Viewport like behaviour seems to me to be the next major thing I need to have in place; it also allows me to define the game levels at a fixed size regardless of the window dimensions.
Implementing a partially invisible feature is going to make debugging tricky. So I think a pre-requisite step ought to be to add a logging system. I’ve done enough with logging in the past not to want to mess with writing my own. So I’m just going to plump for an existing library and accept a dependency. I did a quick review of the various .Net logging frameworks and concluded that Serilog was the one I want to try. It seems straightforward, easy to set up, and most importantly allows for sending logs to a central server over HTTP - something that I think is going to be very handy in the future.
Waffle time is over, time to get those logs working.