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.
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.
I'm going to compile it in 5.2.4 version.
It never gets to see KEY_W if it sees KEY_UP, because you break; out before it gets there...:P
I switched them but the output is still same.
You can't "switch" them, you have to stop breaking!! Think about it logically...
IF KEY_W THEN BREAK
IF KEY_UP THEN BREAK <--NEVER GETS REACHED IF KEY_W!
IF KEY_UP THEN BREAK
IF KEY_W THEN BREAK <--NEVER GETS REACHED IF KEY_UP!
You can't break and expect more code in the switch/case to run!!
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.
You might find al_get_keyboard_state is an easier API to use.
Also:
case ALLEGRO_KEY_R :main(); break;
I hope that doesn't mean that pressing 'R' will recursively call main()!
This else is what prevents pad1 from moving when pad2 is moving. Remove it
Nice one!
Ah! Ingenious of you Audric.
That got perfectly well.
I was focusing on the switch case part and was thinking that how can it possibly be stopping paddle 1 to move, and there you got it.
I have attached the executable.
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".
Do the paddles go faster if you hit random keys ?
If you are using a timer event to give the tempo of the game logic, the block should rather be here:
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 }
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:
Thanks Audric, I was doing it indeed badly, now its much better, there is still some flickering but ball isn't going off just on every event passed to game.
I have attached the main program file, please look at it and tell me my mistakes and where I should I improve.
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.
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.
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) :
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.
thanks for the link I'll correct all the mistakes right away and learn what is necessary.
How did you made the image to display?
<img src="http:///blah.com/img.jpg" />
What website were you looking at? I'd like to see the code.
No, I was talking about the images in attachments.
How to show images from attachments.
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.
Like this :
{"name":"611875","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6d4e65f5083f5b765ab638f267b70e02.png","w":814,"h":639,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/d\/6d4e65f5083f5b765ab638f267b70e02"}
Thanks!
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.
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.
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.
It's almost done, maybe I'll be able to upload my entry today. Kudos!
I'll come to the tail part tomorrow.