/*
This write-up contains code that implements the game Pong in C using the cross-platform Allegro library. (I wrote the game in all of an hour on a dare to see who could get Pong done first, me using C and Allegro or Josh using Visual Basic and WinAPI.) Player 1's controls are W and S; player 2's are the arrow keys. (It's not an entirely authentic experience; there is no support for PC game port paddles, and the screen is colored.) To build it:
- If you do not have a supported GCC compiler (MinGW or GNU/Linux GCC), get DJGPP (a DOS GCC) from http://www.delorie.com/djgpp/ and install it according to README.1ST.
- Get the Allegro library (version 3.9.33 or later is best) from http://www.talula.demon.co.uk/allegro/ and install it, following the instructions in the appropriate readme file. (It's not a wasted effort; there are scores of Allegro games at http://www.allegro.cc)
- Paste this source code into a file called pong.c
- DJGPP or MinGW: gcc -Wall -O2 pong.c -lalleg -o pong.exe
Linux: gcc -Wall -O2 pong.c `allegro-config --libs` -o pong
*/
/**************************************\
* pong.c *
* a simple air hockey game *
* ********************************\
* Copyright 2000 Damian Yerrick *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* Or view the License online at http://www.gnu.org/copyleft/gpl.html *
* *
* Damian Yerrick's World Wide Web pages are located at *
* http://www.pineight.com/ *
* *
\**********************************************************************/
#include <allegro.h>
#define PDL_HEIGHT 40
/* set up initial positions for the players ********
* y[i] is how far from the top is paddle
* x[i] is how far from the left to draw paddle
* dy[i] is how fast the paddle is moving
* upkey[i] is the key that moves the paddle up
* downkey[i] is the key that moves the paddle down
*/
int y[2] = {80, 80};
const int x[2] = {0, 310};
int dy[2] = {0, 0};
const int upkey[2] = {KEY_W, KEY_UP};
const int downkey[2] = {KEY_S, KEY_DOWN};
int score[2] = {0, 0};
/* DrawPlayer() ************************
* Draw player p's paddle in color c.
*/
void DrawPlayer(int p, int c)
{
rectfill(screen, x[p], y[p] + 3, x[p] + 9, y[p] + PDL_HEIGHT - 4, c);
}
void DrawBall(int x, int y, int c)
{
ellipsefill(screen, x, y, 6, 5, c);
}
int main()
{
int lastWinner = 1;
int lastClock = 0;
allegro_init();
install_timer();
install_keyboard();
if(set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) < 0)
{
allegro_message("could not shift to gfx mode\n");
exit(1);
}
while(score[0] < 7 && score[1] < 7)
{
int balldone, ballx = 0, bally = 0, balldx, balldy;
/* setup ball */
ballx = lastWinner ? 40 : 280;
bally = 100;
balldx = lastWinner ? 3 : -3;
balldy = rand() % 8 - 4;
if(balldy >= 0)
balldy += 4;
balldone = 0;
while(!balldone)
{
int oldx, oldy, i;
while(lastClock == retrace_count)
yield_timeslice();
lastClock = retrace_count;
/* players */
for(i = 0; i < 2; i++)
{
dy[i] = dy[i] * 15/16;
if(key[upkey[i]])
dy[i] -= 4;
if(key[downkey[i]])
dy[i] += 4;
DrawPlayer(i, 0);
y[i] += dy[i] / 4;
if(y[i] < 0)
{
y[i] = 0;
dy[i] = -dy[i] / 2;
}
if(y[i] > 200 - PDL_HEIGHT)
{
y[i] = 200 - PDL_HEIGHT;
dy[i] = -dy[i] / 2;
}
DrawPlayer(i, i ? 1 : 4);
}
/* the ball */
oldx = ballx;
oldy = bally;
bally += balldy;
if(bally < 5) /* bounce off top */
{
bally = 10 - bally;
balldy = -balldy;
}
else if(bally > 195) /* bounce off bottom */
{
bally = 390 - bally;
balldy = -balldy;
}
ballx += balldx;
if(balldx > 0)
{
if(ballx > 305 && bally >= y[1] &&
bally < y[1] + PDL_HEIGHT)
{
balldx = -balldx;
balldy = (bally - y[1] - PDL_HEIGHT / 2) / 4;
if(balldy >= 0)
balldy++;
}
else if(ballx >= 316)
{
score[0]++;
rest(1000);
lastWinner = 0;
balldone = 1;
}
}
else
{
if(ballx < 15 && bally >= y[0] &&
bally < y[0] + PDL_HEIGHT)
{
balldx = -balldx;
balldy = (bally - y[0] - PDL_HEIGHT / 2) / 4;
if(balldy >= 0)
balldy++;
}
else if(ballx < 5)
{
score[1]++;
rest(1000);
lastWinner = 1;
balldone = 1;
}
}
DrawBall(oldx, oldy, 0);
if(!balldone)
DrawBall(ballx, bally, 10);
textprintf(screen, font, 140, 0, 15, "%d - %d",
score[0], score[1]);
while(keypressed())
{
switch(readkey() >> 8)
{
case KEY_ESC:
score[1] = score[2] = 7;
balldone = 1;
break;
default:
break;
}
}
}
}
return 0;
} END_OF_MAIN();