I'll try to be more specific, and yes most likely I will have a loading screen(I also tried to load the maps using the loading screen state but that doesn't allow my collision to work). So after level 1 is finished, I would like to then load level 2 but because the setup already calls level 1 to begin with I cant set the next level as its not updating, wouldn't I need to handle the level changing in the update rather than the setup function? However doing this method in the Update function lags my game as it is constantly loading the LoadFromFile(std::string filename) function over and over.
I was under the impression you were trying to load on the fly. Since it's at an obvious stopping point, I don't understand why you can't move to a loading state, throw up a "loading level" screen and load everything you need right then. When the level is loaded, you can go back to the playing state and start on the new level. Multi-threading is definitely not needed in this situation.
Without more information on what kind of game it is, and how the level data is used, it's hard to answer, but I'll take a stab.
If you have to load levels on the fly (ie, you can't have a "loading" screen) where you're still actively controlling your character, then you can look at loading them in a separate worker thread. However, you have to do this well before the user will need the new level data to ensure you don't try and display the level before it's completed loading (ie, the user is a screen away from needing the level data). Once you've loaded the level, you'll want to notify the main thread it's completed loading and it can be used.
Thanks for helping me rethink this, at first I was definitely thinking of having a separate thread handle the second player's requests.
In the pseudocode it looks like local requests are serially processed before remote requests.
To have requests processed in the order they are spontaneously generated, would one sort the requests by a time stamp? (after serially retrieving the local and remote requests as above)
You could just have a general command queue, where all commands received (either from a remote player, or form a local player) are put into a single FIFO queue. Then, when you process all the commands in that queue, you'll automatically process them in the order they are received.
However, since this should happen every game loop, in practice, there really won't be any difference in what order you handle them. If you execute your game loop once every 1/60 second (for example), then that would be the largest possible difference in time between when a local play sent you something, and when a remote player sent you something, if processed in order. And, even then, network delay would probably be larger than that.
I'm sure you have the indices memorized right now, but, if you stop working on this for a bit, then come back later, will you remember what 6 and 7 and 10 are? Probably not, so, you still need to replace these magic numbers with constants. Something as simple as this:
v= # empty list ( temp / local )
v.append([item[VY],-item[VX]]) # add alternate vectors. use y,-x and -y,x
u=random.randint(0,len(v)-1) # pick one at random
item[VX]=v[u] # update the x and y vector
item[X]=item[SAFE_X] # rewind item's x and y position to last know good value (pre collision)
Also, you don't need to comment every line. Only comment where it makes sense.
For example, it's obvious, if you rewind x, you're doing the same thing for y. So you could say rewind item's x and y position to last know good value (pre collision)
Thanks for all the good answers. I realize that the better approach would be to use the same data structure in both threads, while having different classes.
What I am actually trying to do is:
The main thread handles the game logic and works on the resources (reading/writing them). The auxiliary thread handles the display only, reading only from the resources.
I want at a later point to be able to either have the render thread:
1. either read from the original data while the game logic thread waits (thus avoiding copying the resources at all).
2. either read from a copy of the original data, while the game logic continues its work.
In case 2 above, copying the resources will be done as a light copy first (i.e. actually sharing the resource until the point where the main thread modifies it: in that case, the main thread will first deep-copy the resource before modifying it, while the render thread will still read from the old, unmodified resource, thus avoiding a crash).
Why do you have a separate thread for Rendering? Is the Rendering phase a bottleneck in your program? What happens if you simply render all your object within the main game loop?
Basically, are you sure what you're doing is worth the trouble? Multithreaded programming can be difficult to do correctly, and if you miss 1 thing, you'll start having odd bugs that are very hard to debug. Be sure you really need to do it before trying to do it.
If it's as an exercise, then disregard, but if it's a solution to a bigger problem (like making a game), then I'd re-evaluate and ensure it's really needed.
FWIW, in my hobby games I've written, I've never seen the need for more than 1 thread. Some big games will need more, but they have to have good reasons for them.
Maybe, instead of having an index stored in the power up, you have the actual type stored and duration, and there's no need for an if in your loop. You can also update before checking collision to also condense it. Something Like this:
for(int i = 0; i < PowerUpses.Count; i++)
Also this whole peer-to-peer architecture would at most take me one day to write up, so it's really not that big of a deal.
MAYBE the initial structure you think will work will take a day. Then, when you start to use it, you'll run into an issue. then, when you get more users, you'll get more issues. Then, when you have a lot of players, you'll be running into different issues all the time, all related to trying to use peer-to-peer, and you're time will be dedicated 100% to trying to find a solution for all the problems. You'll fix one problem, and another will arise, all the while, you'll be hearing about cheaters doing this or that.
Obviously, with any networking solution you select you're going to have some amount of debugging you're going to run into, but, if you're trying to do peer-to-peer with any sort of game that requires sub-second communications amongst all the players, it's going to be 1000x worse.
With that said, if you're still going to write this peer-to-peer framework, I truly hope it does well, and you can come back with a synopsis of it and we can all learn from it.
Wow, you're doing all this extra complex work just to
benefit of not having to purchase a dedicated server.
And, this is for a game with 50-100 players. I think this is like a case of cutting off your nose to spite your face. IMO, you're going to go through so much heart-ache, you'll be wishing you had spent a little money for that dedicated server.
Now I just need to make it so that the bullet fires from the player and not from the left side of the screen.
You'll want to set the bullet's rectangle X to the player's X position on initial creation.
I'd also suggest removing the X, Y, Width, and Height variables in the Bullet struct since all of those values are repeated in the Rect Variable.
Also, you might want to look into creating a vector of bullets, so you can have more than 1 bullet at a time, but that's obviously gameplay specific. And, instead of using a timer to kill the bullet, remove it when it either leaves the view-able screen, or it has collided with an enemy.
The only difficulty that could be faced by a "whole forum of mentors" is each mentor might have a slightly different perspective on things, and everyone of them could be a good way to do things, but they are different.That could often be confusing for a begineer.
Whereas, with a single mentor, he will lead him down one specific path. Hopefully it is a good path, but it will be a single path that he believes in, and without the confusion of the specific direction to take.