Hi guys. I've been making a console game with the ncurses library. I've set up a couple of windows and pads and they seem to be working all right and everything I display on the screen works ok. Now the problem is movement. I can move each individual thing at a time but If I trigger something like a for loop(enemy attack) or a while loop(shoot bullet) nothing else can be moved at the same time. I've tried every timout, nodelay etc function I can find in ncurses and nothing seems to fix this. In every source code I've looked at that uses curses they always seem to deal with this problem with either a) setting up some sort of time interval to update and redraw game loops at FPS or b)splitting the process into threads.
Now man did I hope it would not come to the second choice but I see no other option at this point. I'm quite the beginner in c++ but hey I guess there is first time for everything. I've been looking at boost thread library which to me seems them most easiest way to go about this. The problem is I have no idea how to implement these threads and how I can correctly connect them to the processes I want.
I will post few lines of codes where I would like to split the process up with threads. My question is also? would it be enough to have just main and then one thread that handles input?
I just skimmed this over, but if you are trying to do a multi-threaded game, my only advice is don't. Even if you are a beginner at C++, creating a multi-threaded game is a completely different concept. You can't be modifying and reading data at the same time otherwise you get unwanted results. Unless you are creating a complex physics engine that has hundreds of objects that need to be calculated each tick, you don't really need to use more than one thread.
Multithreading isn't really an issue of knowing C++, the concept can be applied in any language, the trouble is using it accordingly.
ok yeah I thought I might be over-complicating things, do you know any other way to go about this?
I'm thinking if my problem has something to do with all the windows and pads I use and having to refresh them with each move. One source code I looked at used very similar technique to mine but no curses windows but in this game he was drawing the map with arrays and making the game elements move inside it.
It's just that I find creating pads and windows is quite a comfortable way to order elements in the game and display them properly but if I can't make two animated elements move at the same time the game logic is quite f'ed!
You can apply this same logic to a console. It's easiest if you are completely redrawing the entire screen every frame (which is how it's typically done in games). If you have to keep track of what needs updating and what doesn't, it ends up being more difficult.
As for how to do any of this in ncurses, I have absolutly no clue as I've never used that lib.
man do I agree with this one right now
Thank you. It's a shame so many people are so intimidated by graphic libs. They can be very simple.
Ok I got some progress now and It does not include threading. I created a game loop that redraws and update's everything every some milliseconds. Now I can display enemies and move player + shoot at the same time but the time is very strange, when enemy is moving the player's movement are very laggy, I think player is picking up on the time given to the enemy. Any ideas on how to seperate this, so player's movement won't get affected by enemies time loop?
OK I think I will finally surrender. I will not make a console game. This is bullshit!. I'm heading over to some nice graphics library, maybe the one you recommended Disch. Thanks for your input guys!
I think player is picking up on the time given to the enemy. Any ideas on how to seperate this, so player's movement won't get affected by enemies time loop?
The easiest way to handle time is to operate in simple "steps". This can be accomplished by having a "frame" being a single step. If you can update at a fixed framerate, this means that updating something by X every frame will produce an animated or gradual movement effect.
For a simple example, at 60 FPS, an enemy that moves 2 pixels per frame will be moving pretty slowly. If you are using tiles and not individual pixels (as you would be forced to in a console environment), you would probably have to something like move it 0.1 tiles per frame instead (so that it moves 1 tile every 10 frames).
Doing this will have no impact on the speed of any other objects in the game world, including the player.
A simple example of how this might be accomplished:
class GameObject
{
public:
virtualvoid DoFrame() = 0;
virtualvoid Draw() = 0;
};
class Enemy : public GameObject
{
public:
virtualvoid DoFrame()
{
// this function is called once per frame to update the object's status
// so here, the enemy would move a little bit, and maybe his graphic
// would animate.
}
virtualvoid Draw()
{
// here you simply draw this object to the screen
}
};
class Player : public GameObject
{
// ... write the same functions for the player. Same idea for DoFrame, only
// you might use user input to determine the action rather than AI
};
int main()
{
// your 'World' class or something similar would probably own a list of all
// objects in the game world. It would add new objects to that list as they're spawned
// and remove objects as they're destroyed.
// for simplicity I'll just throw this list in main for this example:
std::list<GameObject*> objects;
Player the_player; // some objects to put in that list
Enemy an_enemy; // the player and a single opponent
objects.push_back( &the_player );
objects.push_back( &an_enemy );
while( game_is_running )
{
ProcessUserInput(); // see if the player wants to quit, maybe get his movement input, etc
// Move and animate objects:
for(auto i = objects.begin(); i != objects.end(); ++i)
{
(*i)->DoFrame(); // update the objects
}
// Loop again to draw everything... also probably draw a background or something
for(auto i = objects.begin(); i != objects.end(); ++i)
{
(*i)->Draw();
}
PresentToScreen(); // finalize drawing and actually put what you just drew on the display
// (this is an additional step in most graphic libs, as drawing is typically double-buffered)
WaitForNextFrame(); // wait until 1/60th of a second or so has passed so that we
// have a fixed framerate.
// Note that Sleep(1000 / 60) is a poor way to do this, as it will cause your framerate
// to slow down if the above updating/drawing code took some time to process (ie, the
// more that needs to be done, the slower your game will run)
// Smarter ways would be to check the time at the start of this loop and then
// wait until 1/60th of a second has passed from that timestamp.
//
// On the other hand, some libs (such as SFML) do this for you, and all you have to do
// is set the framerate at startup and it will automatically wait after you finish drawing
}
}
What you should not be doing is looping on a single object and animating it, while disregarding all other objects. That could cause what you were seeing, where the speed of one object was affecting the others.
Wow thank you Disch this is a very good documentation you did. And yes this is excactly what I was doing wrong, triggering animation of different objects and expecting them to sync, not very clever. I dunno, maybe I clear up few things and reconstruct how the game is built.