1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Basic Pong in BGI

Discussion in 'C' started by rai_gandalf, May 31, 2007.

  1. rai_gandalf

    rai_gandalf New Member

    Joined:
    Nov 4, 2005
    Messages:
    46
    Likes Received:
    1
    Trophy Points:
    0
    Occupation:
    Final Year Comp Engg
    Location:
    Mumbai
    Home Page:
    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 :D , 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:
    /* 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 for 2D Basic Tennis using BGI (Non-OOP):
    Code:
    /* 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();
    }
     

    Attached Files:

    Last edited: Jun 2, 2007
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
    Re: Basic 2D Tennis in BGI

    I really like and appreciate your code snippets
     
  3. rai_gandalf

    rai_gandalf New Member

    Joined:
    Nov 4, 2005
    Messages:
    46
    Likes Received:
    1
    Trophy Points:
    0
    Occupation:
    Final Year Comp Engg
    Location:
    Mumbai
    Home Page:
    Re: Basic 2D Tennis in BGI

    Hey thanks a lot Shabbir! .... Its really not that big a deal, as this has been a standardized & done game from sometime in the early 90's .... but as I told you, it was pure love for logic & programming that drives me & no doubt even you & others to give it a try!

    NJOY CODING!

    Regards,
    Rajiv

    PS: Any Queries about any code-segment that is not clear (sorry I didnt comment extensively on this one as I usually do) are welcome
     
  4. tailhook123

    tailhook123 New Member

    Joined:
    May 23, 2007
    Messages:
    30
    Likes Received:
    0
    Trophy Points:
    0
    Re: Basic 2D Tennis in BGI

    Aye.. good coding.. but this is Pong isn't it?

    http://en.wikipedia.org/wiki/Pong
     
  5. rai_gandalf

    rai_gandalf New Member

    Joined:
    Nov 4, 2005
    Messages:
    46
    Likes Received:
    1
    Trophy Points:
    0
    Occupation:
    Final Year Comp Engg
    Location:
    Mumbai
    Home Page:
    Re: Basic 2D Tennis in BGI

    Hey Tailhook,
    Thanks for the link .... I didnt know the name of the game, but just knew that it was & still is a heck of a game .... and anyways, when I set out to code, I was plannin to code Tennis along with the court markings & stuff, but halfway I decided to revert to this "PONG" as the world calls it .... thx 4 the link - made an interesting read - especially Roddick playing Pong .... So, Pong it is .... will rename the thread if I can.

    NJOY CODING

    Regards,
    Rajiv


    PS: To use Shakespeare's quotation slightly distorted to suit the situation : "A Game by any other name would be just as enjoyable" :D
     
  6. keith12125

    keith12125 New Member

    Joined:
    Jul 4, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    ok... I know I'm doing something wrong. I am using Visual C++ to compile this and I don't have a graphics.h file. Do i need to download it?
     
  7. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,283
    Likes Received:
    364
    Trophy Points:
    83
    MS VC compiler does not support BGI graphics and so it does not have the graphics.h file.

    You need to use the old days Turbo C++ 3.0 compiler for the BGI graphics program to compile
     
  8. seeguna

    seeguna New Member

    Joined:
    Jun 20, 2007
    Messages:
    31
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    Technical Consultant
    Location:
    Chennai
    Good one................ Hats up..............
     
  9. rai_gandalf

    rai_gandalf New Member

    Joined:
    Nov 4, 2005
    Messages:
    46
    Likes Received:
    1
    Trophy Points:
    0
    Occupation:
    Final Year Comp Engg
    Location:
    Mumbai
    Home Page:

    Hey thanks a lot. I am glad you liked it.
     

Share This Page