|
When I tried Multiplayer in my Pong game, priority got to only one player. |
Doctor Cop
Member #16,833
April 2018
|
I am making a PONG game for the compensation of Krampus hack 2018 and while implementing the AI part I got bored so I thought of making it multiplayer. I'm currently making my game with MinGW compiler but I thought of making my multiplayer prototype in my old Code Blocks. Allegro's 5.0.10 was already configured in it so I thought it will be quick to prototype but when I changed the lines of AI part with the following code the output was unexpected. 1 if(event.type == ALLEGRO_EVENT_KEY_DOWN)
2 {
3 switch(event.keyboard.keycode)
4 {
5 case ALLEGRO_KEY_R
6 :main();
7 break;
8 case ALLEGRO_KEY_ESCAPE:
9 done = true;
10 break;
11 case ALLEGRO_KEY_UP:
12
13 keys[UP] = true;
14 break;
15 case ALLEGRO_KEY_DOWN:
16
17 keys[DOWN] = true;
18 break;
19 case ALLEGRO_KEY_W:
20
21 keys[W] = true;
22 break;
23 case ALLEGRO_KEY_S:
24
25 keys[S] = true;
26 break;
27 }
28 }
29
30 if(event.type == ALLEGRO_EVENT_KEY_UP)
31 {
32 switch(event.keyboard.keycode)
33 {
34 case ALLEGRO_KEY_UP:
35 keys[UP] = false;
36 break;
37 case ALLEGRO_KEY_DOWN:
38 keys[DOWN] = false;
39 break;
40 case ALLEGRO_KEY_W:
41 keys[W] = false;
42 break;
43 case ALLEGRO_KEY_S:
44 keys[S] = false;
45 break;
46 }
47 }
48
49 if(keys[UP])
50 {
51 MovePaddleUp(&pad2);
52 }
53 else if(keys[DOWN])
54 {
55 MovePaddleDown(&pad2);
56 }
57 else if(keys[W])
58 {
59 MovePaddleUp(&pad1);
60 }
61 else if(keys[S])
62 {
63 MovePaddleDown(&pad1);
64 }
When Arrow keys are pressed then W, S are not working. The Pad1 is getting priority instead of doing simultaneous movement. Is it because I used an older version of Allegro? Do I have to configure my MinGW compiler in Code Blocks to run it correctly or is there something wrong with my code? Edit: Now I have attached the game, its for Windows.
|
Dizzy Egg
Member #10,824
March 2009
|
It never gets to see KEY_W if it sees KEY_UP, because you break; out before it gets there...:P
---------------------------------------------------- |
Doctor Cop
Member #16,833
April 2018
|
I switched them but the output is still same.
|
Dizzy Egg
Member #10,824
March 2009
|
You can't "switch" them, you have to stop breaking!! Think about it logically... IF KEY_W THEN BREAK IF KEY_UP THEN BREAK You can't break and expect more code in the switch/case to run!!
---------------------------------------------------- |
Peter Hull
Member #1,136
March 2001
|
One event only contains info about one key state change. If you press 2 keys you have 2 events. Make sure you're processing all events each cycle of the main loop. Also: case ALLEGRO_KEY_R :main(); break; I hope that doesn't mean that pressing 'R' will recursively call main()!
|
Audric
Member #907
January 2001
|
1 if(keys[UP])
2 {
3 MovePaddleUp(&pad2);
4 }
5 else if(keys[DOWN])
6 {
7 MovePaddleDown(&pad2);
8 }
9 //
10 // This else is what prevents pad1 from moving when pad2 is moving. Remove it
11 //
12 /**/else/**/ if(keys[W])
13 {
14 MovePaddleUp(&pad1);
15 }
16 else if(keys[S])
17 {
18 MovePaddleDown(&pad1);
19 }
|
Peter Hull
Member #1,136
March 2001
|
Audric said: This else is what prevents pad1 from moving when pad2 is moving. Remove it Nice one!
|
Doctor Cop
Member #16,833
April 2018
|
Ah! Ingenious of you Audric. That got perfectly well. I have attached the executable.
|
Audric
Member #907
January 2001
|
There is still probably an issue that this entire block of if(keys[]) gets executed "every time an event is received, no matter the kind of event". if(event.type == ALLEGRO_EVENT_KEY_UP) ... else if(event.type == ALLEGRO_EVENT_KEY_DOWN) ... else if(event.type == ALLEGRO_EVENT_TIMER) { // here // move paddles according to controllers // apply ball physics }
|
Doctor Cop
Member #16,833
April 2018
|
Thanks Audric, I tried it but the ball still moves faster even when I move mouse over screen. I must be doing it badly. I'm going to refactor it and look for possible blind spots. Edit: I have attached the main program file, please look at it and tell me my mistakes and where I should I improve.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Think about it, what happens when you move the mouse? It generates an event, and if your logic runs once for every event, then your game will update faster when the mouse moves. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Doctor Cop
Member #16,833
April 2018
|
Yes Edgar, now i totally get it. Please look at my main C file and tell me where I can improve. Everybody is welcome for positive criticism.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Okay, well, there are some problems. I used Code::Blocks code folding feature to illustrate my point : {"name":"611873","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/d\/fd014ca5d6760439816334c0211343ad.png","w":1920,"h":1080,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/d\/fd014ca5d6760439816334c0211343ad"} You can clearly see how you're using your ALLEGRO_EVENT before it is valid. The line : ALLEGRO_EVENT event; Only allocates space on the stack for your object. Because in C object's don't have constructors, the memory held by event is uninitialized. So when you ask on the following line, if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {/*...*/}; You're accessing type, which is uninitialized. In fact, you don't even have a valid value for your event until the end of your loop when you call al_wait_for_event and then you just ignore it!. You've got to learn scoping rules. Another questionable thing is mixing event handling and logic. Peter Hull started a thread on the event loop, you should follow along there and take a look at the different kinds of loops there are. The basic game loop is like this (Object Oriented and in C, for your viewing pleasure) : 1typedef struct Game {/*...blah...*/} *game;
2
3Game* CreateGame(/** parameters */) {/** make a game object */}
4void DestroyGame(Game** g) {/** destroy game */}
5
6void UpdateGame(Game* g , double dt) {/** ... */}
7
8int HandleEvent(Game* g , ALLEGRO_EVENT ev) {
9 if (ev.type == ALLEGRO_EVENT_TIMER) {
10 UpdateGame(g , al_get_timer_speed(ev.timer.source));
11 }
12 /** Handle other events here */
13}
14void Redraw(Game* g) {/**...*/}
15
16
17
18int main(int argc , char** argv) {
19 (void)argc;
20 (void)argv;
21
22 Game* game = CreateGame();
23 if (!game) {return 1;}
24
25 while (!game->quit) {
26 if (game->redraw) {
27 Redraw(game);
28 game->redraw = false;
29 }
30 do {
31 ALLEGRO_EVENT ev;
32 al_wait_for_event(queue , &ev);
33 /// We're now guaranteed a valid event. al_get_next_event makes no such guarantee
34 HandleEvent(game , ev);
35 } while (!al_is_event_queue_empty(queue));
36 }
37
38 /// Clean up
39 DestroyGame(&game);
40
41 return 0;
42}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Doctor Cop
Member #16,833
April 2018
|
Thanks for all this. I got this wrong way from a website I was learning so I thought that it was somehow OK. Right now I'm listening "Pray for me" and i'm all fired up to correct my mistakes. How did you made the image to display?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
<img src="http:///blah.com/img.jpg" /> What website were you looking at? I'd like to see the code. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Doctor Cop
Member #16,833
April 2018
|
No, I was talking about the images in attachments.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Just use the URL of the attachment as the URL of the img tag, like so : <img src="https://d1cxvcw9gjxu2x.cloudfront.net/attachments/611874" /> Gives you : {"name":"611874","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/5\/f5b9d682a1f3459e1b61a8fdf8162116.png","w":1920,"h":1080,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/5\/f5b9d682a1f3459e1b61a8fdf8162116"} Protip : When you upload attachments, they turn blue and become a link. Right click on them and select "copy link location" and then paste it into your src tag. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Doctor Cop
Member #16,833
April 2018
|
Like this : Thanks!
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Nice, clean looking Pong. Now try to draw tails behind the ball as it travels. This will require you to think a little bit. Consider it a personal challenge. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
princeofspace
Member #11,874
April 2010
|
Continuing on Edgar's suggestion: while (!game->quit) { if (game->redraw) { Redraw(game); game->redraw = false; } Most games separate the logic from the draw code. In a nice, small pong game like this one, that probably isn't necessary, but in bigger projects, you'll want to have an update function prior to the Redraw. while (!game->quit) { if (game->redraw) { Update(game); Redraw(game); game->redraw = false; } The update function handles the "business logic" of the game --- moving paddles and the ball, for instance. This gives you a number of advantages; one is that you can now pause the game, simply by omitting the update call whilst the game state is paused. while (!game->quit) { if (game->redraw) { if (!game->paused) { Update(game); } Redraw(game); game->redraw = false; } Note that the main game loop will still call Redraw whether the game is paused or not. Because you've separated the event loop from the game logic, you can now manipulate the game pause state with an input event. |
Doctor Cop
Member #16,833
April 2018
|
Edgar Reynaldo said: Now try to draw tails behind the ball as it travels
I already have a challenge of completing the AI part and now completing the menu. I'll come to the tail part tomorrow.
|
|