Hello to one & all, I did a little bit of programming this weekend (I got myself a new Xbox 360!) .... but not satisfied with the Gaming monolith, I decided to do some game programming myself. So, I implemented that very famous game played by everyone who had access to a computer in the early 90's .... And the result is here .... Now, its no big deal as its already a standardized game which has been done & played & now occupies a place only in computer museums
, but nonetheless here it is .... its still incomplete in some ways - User Interfaces need to be strengthened & more options need to be provided, but the basic math & functionality is all there .... Am currently working on a Object Oriented Version of this in C++ with more options.
Hope you enjoy this!
HAPPY CODING!
CODE for a Ball Bouncing off the boundaries of the Screen in Graphics Mode (Non-OOP)
CODE for 2D Basic Tennis using BGI (Non-OOP):
, but nonetheless here it is .... its still incomplete in some ways - User Interfaces need to be strengthened & more options need to be provided, but the basic math & functionality is all there .... Am currently working on a Object Oriented Version of this in C++ with more options.Hope you enjoy this!
HAPPY CODING!
CODE for a Ball Bouncing off the boundaries of the Screen in Graphics Mode (Non-OOP)
Code: C
/* Program to Produce a continuously moving ball, which bounces on striking a wall */
/* SOURCE CODE */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <time.h>
#include <math.h>
#include <dos.h>
#define DEFDELAY 5
/* Global Variables */
// Symbolic Constants
const int xincr=1,yincr=1;
const int TRUE=1,FALSE=0;
const int FWD=0,BCK=1,UP=0,DWN=1;
const int LEFT=1,RIGHT=2,TOP=3,BOTTOM=4;
// Other Variables
int gd,gm,MAXX,MAXY;
int xstart,ystart,ballrad;
int xinst,yinst;
int xdir,ydir,cuttingbound;
int bounce=TRUE,linecol,fillcol;
/* Function Prototypes */
void initgraphics(void);
void testresolution(void);
void moveball(void);
int testboundary(void);
void rebound(void);
void drawball(void);
void showimpact(void);
void main()
{
testresolution();
printf("Please Enter XY Co-Ordinates of Starting Point : ");
scanf("%d%d",&xstart,&ystart);
printf("\n\nEnter the Size of Ball (Radius) : ");
scanf("%d",&ballrad);
printf("\n\n\nPress Any Key to Enter Graphics Mode ..... ");
getch();
moveball();
}
void initgraphics(void)
{
int error;
initgraph(&gd,&gm,"\\TC\\BGI");
error=graphresult();
if(error!=grOk)
{
printf("\n\n\aGRAPHICS ERROR! Error Code : %d",error);
getch();exit(1);
}
}
void testresolution(void)
{
clrscr();
printf("Testing System Resolution! Press Any Key to enter Graphics Mode ....");
getch();
initgraphics();
MAXX=getmaxx();
MAXY=getmaxy();
closegraph();
printf("System Resolution Detected!\n");
printf("\nHORIZONTAL PIXEL SPAN : %d (0 to %d)",MAXX+1,MAXX);
printf("\nVERTICAL PIXEL SPAN : %d (0 to %d)",MAXY+1,MAXY);
getch();
clrscr();
}
void moveball(void)
{
// Seeding Random Number Generator
randomize();
// Initializing the Graphics Mode
initgraphics();
// Initializing the Position of the Ball
xinst=xstart;
yinst=ystart;
// Iterating Till User Hits a Key
xdir=random(2);
ydir=random(2);
while(!kbhit())
{
if(testboundary())
{
// Drawing the Ball
cleardevice();
drawball();
delay(DEFDELAY);
// Making Changes
if(xdir==FWD)
xinst+=xincr;
else
xinst-=xincr;
if(ydir==UP)
yinst-=yincr;
else
yinst+=yincr;
}
else
rebound();
}
closegraph();
}
int testboundary(void)
{
if(bounce==TRUE)
return TRUE;
else
{
if((xinst+ballrad)>=MAXX || (xinst-ballrad)<=0 ||
(yinst+ballrad)>=MAXY || (yinst-ballrad)<=0)
{
if((xinst+ballrad)>=MAXX)
cuttingbound=RIGHT;
else if((xinst-ballrad)<=0)
cuttingbound=LEFT;
else if((yinst+ballrad)>=MAXY)
cuttingbound=BOTTOM;
else
cuttingbound=TOP;
return FALSE;
}
else
return TRUE;
}
}
void rebound(void)
{
bounce=TRUE;
switch(cuttingbound)
{
case LEFT:xdir=FWD;break;
case RIGHT:xdir=BCK;break;
case TOP:ydir=DWN;break;
case BOTTOM:ydir=UP;break;
}
}
void drawball(void)
{
if(bounce==TRUE)
{
bounce=FALSE;
do{
linecol=random(15);
fillcol=random(15);
}while(linecol==BLACK || fillcol==BLACK || linecol==fillcol);
}
setcolor(linecol);
circle(xinst,yinst,ballrad);
setfillstyle(1,fillcol);
floodfill(xinst,yinst,linecol);
}
Code: C
/* Program for a basic 2 player Pong match with no specialized shot/bounce physics */
/*
Programmed By:
Rajiv Iyer,
T.E. Computers,
SIES GST, Nerul
*/
/* SOURCE CODE */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <time.h>
#include <math.h>
#include <dos.h>
#define BARSIZE 4
#define DEFRAD 10
#define DEFDELAY 10
#define LONGDELAY 500
#define HFSND 70000
#define DEFPENALTY 50
#define DEFREWARD 25
/* Global Variables */
// Symbolic Constants
const int BARYCH=10;
const int DXCH=3,DYCH=3;
const int TRUE=1,FALSE=0;
const int FWD=0,BCK=1,UP=0,DWN=1;
const int LEFT=1,RIGHT=2,TOP=3,BOTTOM=4;
// Other Variables
int gd,gm,MAXX,MAXY;
int bounce=TRUE,cuttingbound;
int linecol,fillcol;
/* Structure Declaration */
struct Player
{
int num;
int bar[BARSIZE];
int points;
int returned,missed;
}P1,P2;
struct Sphere
{
int xinst,yinst;
int xdir,ydir;
int radius;
}Ball;
/* Function Prototypes */
void instructions(void);
void initGraphics(void);
void testResolution(void);
void moveBall(void);
int testBoundary(void);
int keyhit(void);
void rebound(void);
void drawBall(void);
void drawUserBars(void);
void pauseMenu(void);
void displayStats(void);
void main()
{
testResolution();
instructions();
moveBall();
}
void instructions(void)
{
clrscr();
printf("Welcome to the Basic 2D Tennis Program!");
printf("\n\nKeys for User I :-\n");
printf("MOVE BAR UP : 'W' or 'w'\n");
printf("MOVE BAR DOWN : 'S' or 's'\n");
printf("\n\nKeys for User II :-\n");
printf("MOVE BAR UP : 'P' or 'p'\n");
printf("MOVE BAR DOWN : 'L' or 'l'\n");
printf("\n\nCommon Keys:\n");
printf("Terminate Game : 'T' or 't'\n");
printf("Halt/Pause Game : 'H' or 'h'\n");
printf("\n\nAll Keys are Case Insensitive!");
printf("\n\n\nPress Any Key to Enter Graphics Mode & PLAY ! ..... ");
getch();
}
void initGraphics(void)
{
int error;
initgraph(&gd,&gm,"\\TC\\BGI");
error=graphresult();
if(error!=grOk)
{
printf("\n\n\aGRAPHICS ERROR! Error Code : %d",error);
getch();exit(1);
}
}
void testResolution(void)
{
clrscr();
printf("Testing System Resolution! Press Any Key to enter Graphics Mode ....");
getch();
initGraphics();
MAXX=getmaxx();
MAXY=getmaxy();
closegraph();
printf("System Resolution Detected!\n");
printf("\nHORIZONTAL PIXEL SPAN : %d (0 to %d)",MAXX+1,MAXX);
printf("\nVERTICAL PIXEL SPAN : %d (0 to %d)",MAXY+1,MAXY);
getch();
clrscr();
}
void moveBall(void)
{
// Seeding Random Number Generator
randomize();
// Initializing the Graphics Mode
initGraphics();
// Initializing the Position of the Two Player Bars
P1.bar[0]=20 ; P1.bar[1]=200; P1.bar[2]=30 ; P1.bar[3]=280;
P2.bar[0]=610; P2.bar[1]=200; P2.bar[2]=620; P2.bar[3]=280;
// Initializing the Marks Tally of Both Players to Zero
P1.points=P2.points=0;
P1.returned=P2.returned=0;
P1.missed=P2.missed=0;
// Initializing the Position of the Ball
Ball.xinst=MAXX/2;
Ball.yinst=MAXY/2;
Ball.radius=DEFRAD;
// Randomizing the Initial Direction of Travel of Ball
Ball.xdir=random(2);
Ball.ydir=random(2);
// Iterating Till Either User Hits TERMINATE(T) Key
while(!keyhit())
{
if(testBoundary())
{
// Drawing the Ball
cleardevice();
drawBall();
drawUserBars();
delay(DEFDELAY);
// Making Changes
if(Ball.xdir==FWD)
Ball.xinst+=DXCH;
else
Ball.xinst-=DXCH;
if(Ball.ydir==UP)
Ball.yinst-=DYCH;
else
Ball.yinst+=DYCH;
}
else
rebound();
}
closegraph();
displayStats();
}
int keyhit(void)
{
int i;
char uch,tempch;
if(kbhit())
{
uch=getch();
switch(uch)
{
case 't':
case 'T':
// The TERMINATE (T) Key was hit - so Returning True
return TRUE;
case 'w':
case 'W':
// The UP-Direction Key for Player I has been pressed
// Testing Whether Player Bar goes out of window with such a move
if(P1.bar[1]-BARYCH<0)
{
sound(HFSND);
nosound();
}
else
{
for(i=1;i<BARSIZE;i+=2)
P1.bar[i]-=BARYCH;
}
return FALSE;
case 's':
case 'S':
// The DOWN-Direction Key for Player I has been pressed
// Testing Whether Player Bar goes out of window with such a move
if(P1.bar[3]+BARYCH>MAXY)
{
sound(HFSND);
nosound();
}
else
{
for(i=1;i<BARSIZE;i+=2)
P1.bar[i]+=BARYCH;
}
return FALSE;
case 'p':
case 'P':
// The UP-Direction Key for Player II has been pressed
// Testing Whether Player Bar goes out of window with such a move
if(P2.bar[1]-BARYCH<0)
{
sound(HFSND);
nosound();
}
else
{
for(i=1;i<BARSIZE;i+=2)
P2.bar[i]-=BARYCH;
}
return FALSE;
case 'l':
case 'L':
// The DOWN-Direction Key for Player II has been pressed
// Testing Whether Player Bar goes out of window with such a move
if(P2.bar[3]+BARYCH>MAXY)
{
sound(HFSND);
nosound();
}
else
{
for(i=1;i<BARSIZE;i+=2)
P2.bar[i]+=BARYCH;
}
return FALSE;
case 'h':
case 'H':
//do{
pauseMenu();
//tempch=getch();
//}while(tempch!='h' && tempch!='H');
return FALSE;
default:
return FALSE;
}
}
else
return FALSE;
}
int testBoundary(void)
{
if(bounce==TRUE)
return TRUE;
else
{
if((Ball.xinst+Ball.radius)>=MAXX || (Ball.xinst-Ball.radius)<=0)
{
if((Ball.xinst+Ball.radius)>=MAXX)
{
cuttingbound=RIGHT;
// Player 2 misses Shot => Hence Deducting Points
P2.points-=DEFPENALTY;
P2.missed++;
}
else if((Ball.xinst-Ball.radius)<=0)
{
cuttingbound=LEFT;
// Player 1 misses Shot => Hence Deducting Points
P1.points-=DEFPENALTY;
P1.missed++;
}
// Resetting Ball to Center of Screen
Ball.xinst=MAXX/2;
Ball.yinst=MAXY/2;
// Randomizing the Initial Direction of Travel
Ball.xdir=random(2);
Ball.ydir=random(2);
// Delaying for Short Period before Graphically Resetting
delay(LONGDELAY);
return TRUE;
}
else if((Ball.yinst+Ball.radius)>=MAXY || (Ball.yinst-Ball.radius)<=0)
{
if((Ball.yinst+Ball.radius)>=MAXY)
cuttingbound=BOTTOM;
else if((Ball.yinst-Ball.radius)<=0)
cuttingbound=TOP;
return FALSE;
}
else if((Ball.xinst+Ball.radius)>=P2.bar[0] && (Ball.yinst>P2.bar[1] && Ball.yinst<P2.bar[3]) && Ball.xdir==FWD)
{
cuttingbound=RIGHT;
// Player 2 Returns Shot Successfully => Hence Rewarding Points
P2.points+=DEFREWARD;
P2.returned++;
return FALSE;
}
else if((Ball.xinst-Ball.radius)<=P1.bar[2] && (Ball.yinst>P1.bar[1] && Ball.yinst<P1.bar[3]) && Ball.xdir==BCK)
{
cuttingbound=LEFT;
// Player 1 Returns Shot Successfully => Hence Rewarding Points
P1.points+=DEFREWARD;
P1.returned++;
return FALSE;
}
else
return TRUE;
}
}
void rebound(void)
{
bounce=TRUE;
switch(cuttingbound)
{
case LEFT:Ball.xdir=FWD;break;
case RIGHT:Ball.xdir=BCK;break;
case TOP:Ball.ydir=DWN;break;
case BOTTOM:Ball.ydir=UP;break;
}
}
void drawBall(void)
{
if(bounce==TRUE)
{
bounce=FALSE;
do{
linecol=random(15);
fillcol=random(15);
}while(linecol==BLACK || fillcol==BLACK || linecol==fillcol);
}
setcolor(linecol);
circle(Ball.xinst,Ball.yinst,Ball.radius);
setfillstyle(1,fillcol);
floodfill(Ball.xinst,Ball.yinst,linecol);
}
void drawUserBars(void)
{
// Drawing Player I Bar
setcolor(linecol);
rectangle(P1.bar[0],P1.bar[1],P1.bar[2],P1.bar[3]);
setfillstyle(1,fillcol);
floodfill(P1.bar[0]+5,P1.bar[1]+5,linecol);
// Drawing Player I Bar
setcolor(linecol);
rectangle(P2.bar[0],P2.bar[1],P2.bar[2],P2.bar[3]);
setfillstyle(1,fillcol);
floodfill(P2.bar[0]+5,P2.bar[1]+5,linecol);
}
void pauseMenu(void)
{
char pch;
do{
settextstyle(TRIPLEX_FONT,HORIZ_DIR,3);
outtextxy(150,100,"1. Resume Game");
outtextxy(150,200,"2. Display Statistics");
outtextxy(150,300,"3. Controls");
pch=getch();
switch(pch)
{
case '1':
break;
case '2':
closegraph();
displayStats();
initGraphics();
break;
case '3':
closegraph();
instructions();
initGraphics();
break;
default:
printf("\n\n\aInvalid Choice!\n\n\a");
}
}while(pch!='1');
}
void displayStats(void)
{
// Printing All Collected Statistics
printf("Statistics Score-Card :\n");
printf("\n\nFor User I :\nShots Taken : %d\nShots Missed : %d\nTotal Score : %d",P1.returned,P1.missed,P1.points);
printf("\n\nFor User II :\nShots Taken : %d\nShots Missed : %d\nTotal Score : %d",P2.returned,P2.missed,P2.points);
printf("\n\n\nWINNER : ");
if(P1.points>P2.points)
printf("Player I !!");
else if(P1.points<P2.points)
printf("Player II !!");
else
printf("Undeterminable !!");
getch();
}


