Can you explain how did you made so your console input text box stay active after pressing enter?
Check out imgui_demo.cpp and how Console example is implemented there, it's pretty complex and I just copy-pasted
this code.
The work on the game continues! And the biggest change I've made since the dev log is GUI implementation.
Previously I did GUI manually. Storing various sprites and GUI's state in GameStates, etc. But this causes the following problems:
1) Some GUI code was very repetitive
2) GUI was hard coded, I've manually set positions to each sprite and text string
3) GUI callbacks were in C++ which I don't like, because with most of the logic, game state and wrappers being in Lua, it's much easier to do things on Lua side.
4) I've managed to remove almost all GameState's, but GUIs were pretty hard to do in Lua, so I couldn't move GUI states there. (main menu, inventory screen, game UI, dialogue GUI, etc.)
My first idea was not the easiest one: I wanted to expose some of SFML's interface to Lua to draw GUI stuff from Lua and handle all the logic there too. Looking back at it now, it just looks like a really bad idea which would have cost me tons of hours!
Thankfully, after I've started making C++ GUI classes, I've realized that there's no need for doing drawing or even basic GUI logic in Lua! So, let's look at the current stuff I've got going. Here's how the main menu looks now (it isn't a final look, of course!)
Here's a JSON which defines it:
{
"class" : "Frame",
"tag" : "MAIN_MENU_FRAME",
"children" : [
{
"class" : "Image",
"texture" : "gui/main_menu_bg"
},
{
"class" : "NinePatch",
"position" : [70, 148],
"size" : [108, 54],
"texture" : "gui/nine_patch",
"script" : "gui/main_menu",
"textureCoords" : {
"corner" : [0, 0, 5, 5],
"horizontal" : [5, 0, 1, 5],
"vertical" : [0, 5, 5, 1],
"contents" : [5, 5, 1, 1]
},
"children" : [
{
"tag" : "CONTINUE_BUTTON",
"class" : "TextButton",
"textTag" : "CONTINUE",
"font" : "press2p",
"position" : [ 26, 10 ]
},
{
"tag" : "NEW_GAME_BUTTON",
"class" : "TextButton",
"textTag" : "NEW_GAME",
"font" : "press2p",
"position" : [ 26, 24 ]
},
{
"tag" : "EXIT_BUTTON",
"class" : "TextButton",
"textTag" : "EXIT",
"font" : "press2p",
"position" : [ 26, 38 ]
},
{
"class" : "Cursor",
"texture" : "gui/ghost_cursor",
"moveSound" : "menu_cursor",
"movementType" : "UpDown"
}
]
},
{
"tag" : "CREDITS_TEXT",
"class" : "StaticText",
"textTag" : "CREDITS",
"font" : "munro",
"position" : [ 122, 228 ]
}
]
}
As you can see, GUI has a few basic classes: StaticText, TextButton, Image, NinePatch. I can create children to any element and what's nice is that all positions are kept relative to the parent element, so it's easy to organize stuff! Right now the positions are still kinda hard coded (no automatic placement and aligning), but it's totally fine.
I can also add callbacks to buttons like this:
return {
callbacks = {
{
tag = "CONTINUE_BUTTON",
onPress = function(self)
continueGame()
end
},
{
tag = "NEW_GAME_BUTTON",
onPress = function(self)
print("NEW GAME IS NOT IMPLEMENTED YET")
end
},
{
tag = "EXIT_BUTTON",
onPress = function(self)
exitGame()
end
}
}
}
There's nothing novel about the implementation, just base GuiElement class which inherits from sf::Drawable and sf::Transformable, has some children and virtual load, update and draw functions.
Cursor has pretty nice input: it's kinda like key repeat, when you hold "down", it scrolls down the first time with bigger delay, but then continues scrolling down with less delay between "ticks". I manually keep track of time for delays to make it available to gamepad input and also not to depend on system settings (you can easly change delay of key repeat).
GUI system is already powerful, I've managed to make a Dialogue GUI with it!
It looks and behaves the same way as the old GUI, but now it's much easier to control it, drawing it is just this:
target.draw(gui);
I will also implement main game UI next and also inventory screen. They will be a bit trickier to make, but it'll be so worth it. I'll also do options menu which will require some additional GUI work, but this will be done a bit later.
So, handling GUI is much easier now, but the best thing about it is that now I can have just a bunch of GameStates: MenuState (all the GUI will be there: main menu, dialogue, inventory screen, game UI, etc. and I'll just switch between them), LoadingState, GameState (which just calls updates to entity systems and rendering system draw function), TransitionState (used to in-between areas transitions, very tricky, uses some shaders, so I don't want to do it in Lua) and that's it! Other game states (mini-games, ghost state, etc.) can be easily implemented in Lua now.
They don't contain any of the game logic, all of it is now in Lua and this makes me incredibly happy! Engine and game are almost separate now, which means that it'll be easy for me to reuse my engine for other projects in the future.
I've also started working on AI... and there's so many things I have to do here! Better state machines (or maybe even planning system), better path finding... Path finding aspect is pretty hard to do, because I'll have to implement some algorithm for automatically building a nav-mesh (or maybe I'll be fine with just using grid graphs?) I don't want to create graphs by hand, it'll take lots of time and in the end it doesn't give very good results.
Some games just use steering behaviours for AI (and I've previously used just them too!), but this is only fine as long as your enemies are some monsters or "possesed" people (older Zelda games only use steering algorithms). I want enemies in my game be a just bit smarter and not get stuck in any obstacles on their way.
Enemies in Link to the Past get stuck all the time. They don't get completely stuck, however, because steering algorithm slides them along the wall. But it's still not as good as proper path finding. (Or maybe I'm overthinking it...)Hope implementation of all that stuff won't take long. But I'm a bit glad that I'll finally get the chance to write all this stuff.
But that's not all. I'm also planning to work on combat system and I'll try to make combos, targeting and dodging to feel good. I want combat to feel a bit like it does in Dark Souls or 3d Zeldas. Basically, you approach the enemy, target it and now can circle around it, dodging it's hits and hitting it with combos. Not sure how it would work in 4 directions (it would have been perfect in 8 directions, but I can't draw so many animations!), and so far I haven't seen any 2d action rpgs with complex combat, so it'll be pretty interesting to see what I can do.
The closest to what I want is Bastion (hey, the main character uses hammer too!), but it uses isometric perspective and has 8 directions. If anyone knows good 2d top-down games with good melee combat system, please tell me about it!