Our UI is obviously very crude at the moment as it should be, but as I started to put in the Tower placement stuff I found some areas it might be better to clean up now.
HUD Overlay
Currently, the general style of the UI we are using is a BorderPane where the GameControlPanel is docked to the right. Having played around with Bloons I really like their Head Up Display (HUD) style approach where all the controls are overlayed over the Level.
This will work much better on a small screen (mobile, tablet, pi, whatever) but I think it also looks better in general (I recommend trying out Bloons TD on your mobile if you get the chance) and is more game-like.
proposal #1: overlay game controls on main scene: make SimpleGameScene internally use a StackPane instead of a BorderPane. Add the LevelPanel to the bottom of the stack. Add the GameControlPanel to the top of the stack (probably in an an AnchorPane with pickOnBounds set to false).
SimpleGameScene vs Game
In most places we haven't separated View from Model from Control, e.g. LevelPanel is the level model, the level view and the level control; Enemy is MVC all in one; Tower, Projectile; etc.
Then at the top level we suddenly have Game (MC) and SimpleGameScene (V). It's a bit odd and pattern wise which one do we reference, where. We pass around a reference to the Game, but what if I want to show something in the SimpleGameScene (like a dialog to start a new Game). Should the Game have a reference to the Scene and we trigger displays indirectly or should we pass around references to the SimpleGameScene, etc?
I feel like we should either separate out everything into MVC or at least into V vs M+C (or we should merge SimpleGameScene and Game into one? I could be convinced of the split (?) but the latter is the current dominant approach we have and easiest would be to stick with it.
proposal #2: merge Game and SimpleGameScene into one class called Game. At the same time rename LevelPanel to Level to be more consistent with Game/Enemy/Tower/Wave/Projectile.
FXML Best Practices
I also struggled with the FXML that has been generated from SceneBuilder. The GridPane thing is not a real dynamic approach and all the funny constraints make it hard to edit by hand. Maybe using SB it would be ok, but as soon as we start adding in dynamic elements that link in with code I'd tend to start working with the FXML directly (maybe I'm just old school though?).
I'd actually suggest that FXML is not really helping us for the HUD as it is pretty specific and we should just code up this part of the UI in Java. If we do want the FXML then the way we are using it is not all that great. It's strange to load it and embed it like is done now and then look up elements by ID. The "controller" concept exists to avoid all that.
If we stick with FXML, I'd expect not to have a GameControlPanel and instead have a GameControlControlller (at which point the names need reconsidering) that is referenced by the GameControl FXML. It would be then be the SimpleGameScene that does the FXML load and then passes the "Game" object to the controller and adds the fxml loaded view to the scene.
(As an aside to Richard, your attempt to use FXML to basically "make a self defined view" is one of the patterns I pushed for early and making the FXML just bind to an arbitrary class passed in, instead of the whole fxml-creates-the-controller concept would have allowed for this and much more. Greg wasn't strongly against it though. The cludgy controller injection that was added helps, but still hasn't made it overly convenient to do this pattern and many others).
So proposal #3 would be to either just code up the game control elements in Java or switch to use the Controller way of dong things. If switching, I'd also be keen to rewrite the FXML to be clean and simple since the generated stuff is pretty nasty and I like to work with it by hand for dynamic elements.
Dialogs and Screen Flow
I like the way Bloons does it's dialogs - basically a floating Node that pops up as an overlay over the rest of the screen (exactly what I did for dialogs in jfxflow). These also tend to animate in/out. I'd be keen to replicate this and if we're gong to
So proposal #4 include a "dialog" layer in Game. Add methods to Game (aka SimpleGameScene) that allow showing of the dialogs and general workflow of screens (i.e. choose level, choose difficulty, game over, etc).
Zooming and Panning
I kind of like the idea that our level should be zoomable and possibly pannable. Either this would be manually controlled by the user or it would be more just a case of the level being scaled to the size of the screen. If we're thinking about small screen devices then this seems pretty necessary.
If we're going to do zooming and panning then it might be easiest to do a bit of this work up front as things like Tower placement coordinates, etc, will likely change when zoom changes.
This one is more a question than a proposal. What do you guys think about this? Should we zoom, and if so how to do it cleanly? Can we just use the inbuilt FX scale and translate to do zooming and panning? I've had some feedback on this sort of stuff from my forum post on it but I need to dig through what the guys have given me for more details.
I'm probably thinking that next coding chance I get, I'll look at implementing the above proposals before doing anything more on Tower placement. Let me know thoughts when you have a chance - I might get a little bit of coding time tomorrow night my time but can hold off if you need more time to review.