/* ============================================================================== WordUp Graphics Toolkit Version 5.0 Demonstration Program 60 This program demonstrates use of the sprite library to create a simple BREAKOUT game. The user moves a "paddle" with the mouse and hits the ball around the screen, trying to knock out the bricks. *** PROJECT *** This program requires the WGT5_WC.LIB and WSPR_WC.LIB files to be linked. *** DATA FILES *** BREAK.SPR WATCOM C++ VERSION ============================================================================== */ #include #include #include #include #include #include #include color palette[256]; /* Our palette */ block sprites[31]; /* Sprites to be loaded */ short x, y, i; /* Counters and position variables */ short chk1, chk2, chk3, chk4; /* Result of pixel checks */ short blk[10][28] = { /* Our wall of bricks is defined here */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 0,3,4,3,3,3,4,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,3, 0,3,4,3,3,3,4,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3, 0,3,4,3,3,3,4,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3, 0,3,4,3,4,3,4,3,3,3,3,3,4,3,4,4,4,3,3,3,3,3,3,3,4,3,3,3, 0,3,4,3,4,3,4,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,4,3,3,3, 0,3,4,3,4,3,4,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,4,3,3,3, 0,3,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,3, 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }; void dobounce(void); /* Makes a sound when the ball bounces */ float sbx, sby, sp, lx, ly; /* Speed of ball and position of ball */ float xsp, ysp; /* More motion variables */ void looper(); /* Main program loop is in this routine */ void hit(short, short); /* Performs update when ball hits brick */ short hits; /* Number of bricks hit */ void main (void) { i = minit (); /* Initialize mouse handler */ if (i == 0) { printf ("Mouse not detected. You need a mouse for this example program\n"); printf ("Press any key\n"); getch (); exit (1); } else printf ("Mouse with %i buttons detected.\n", i); if (!vgadetected ()) { printf ("VGA is required to run this program..."); exit (1); } printf ("WGT Example #60\n\n"); printf ("This program demonstrates use of the sprite library to create a simple\n"); printf ("BREAKOUT game. The user moves a paddle with the mouse and hits the ball\n"); printf ("around the screen, trying to knock out the bricks.\n"); printf ("Clicking the right mouse button will quit.\n"); printf ("\nPress any key\n"); getch (); /* Now start VGA mode, load the sprites and set the palette */ vga256 (); wloadsprites (palette, "break.spr", sprites, 0, 30); wsetpalette (0, 255, palette); /* Initialize the sprite system and tell it we've got 2 sprites to use */ initialize_sprites (sprites); maxsprite = 2; wsetscreen (spritescreen); /* Draw our game screen on the sprite screen */ for (y = 0; y < 200; y++) /* Background is a series of gray lines */ { wsetcolor ((y / 8) + 1); wline (0, y, 319, y); } wsetcolor (0); /* Make black playing area */ wbar (50, 10, 270, 189); wsetcolor (16); /* Outline it */ wrectangle (49, 9, 271, 190); for (x = 1; x < 28; x++) /* Now draw the bricks */ for (y = 1; y < 10; y++) { wputblock (x * 7 + 57, y * 5 + 20, sprites[blk[y][x]], 0); } /* After it has been drawn, show it on the visual screen too */ wcopyscreen (0, 0, 319, 199, spritescreen, 0, 0, NULL); wcopyscreen (0, 0, 319, 199, spritescreen, 0, 0, backgroundscreen); wnormscreen (); spriteon (0, 160, 100, 1); /* Turn on our sprites */ spriteon (1, 160, 100, 2); msetbounds (50, 129, 245, 179); /* Limit mouse movement */ xsp = 1.1; /* Set initial ball speeds */ ysp = 1.3; sbx = xsp; sby = ysp; lx = 160; /* And the initial position */ ly = 100; msetxy (160, 150); do { /* Now play the game */ looper (); } while (mouse.but != 2); /* Until the right mouse button is clicked */ deinitialize_sprites (); /* Deinit the sprite system */ mdeinit (); /* And the mouse handler */ wsetmode (3); /* Return to text mode */ } void looper(void) { wretrace (); /* Time our updates to the vertical retrace */ erase_sprites (); /* Clear sprites from sprite screen */ s[0].x = mouse.mx; /* Set paddle position to mouse position */ s[0].y = mouse.my; if (lx > 267) /* Is ball bouncing off right wall? */ { dobounce (); lx = 267; sbx = -sbx; /* Change direction */ } if (lx < 49) /* Is ball bouncing off left wall? */ { dobounce (); lx = 49; sbx = -sbx; /* Change direction */ } if (ly < 9) /* Is ball bouncing off top wall? */ { dobounce (); ly = 9; sby = -sby; /* Change direction */ } lx += sbx; /* Update ball positions */ ly += sby; s[1].x = (float)lx; s[1].y = (float)ly; if (s[1].y > 186) /* Did it get by the user and go off the bottom? */ { for (i = 2000; i >= 200; i--) sound (i); nosound (); lx = 160; /* Reset it to the starting position */ ly = 100; } if (overlap (0, 1)) /* Hit the ball with paddle? */ { sound (900); sby = -ysp; /* Change speed and direction based on part of paddle hit */ if (s[1].x > s[0].x + 21) sbx = xsp * 4; else if (s[1].x > s[0].x + 18) sbx = xsp * 2; else if (s[1].x > s[0].x + 12) sbx = xsp; else if (s[1].x > s[0].x + 6) sbx = -xsp; else if (s[1].x > s[0].x + 3) sbx = -xsp * 2; else sbx = -xsp * 4; } /* Now check edges of ball for brick contact */ chk1 = wgetpixel (s[1].x + 3, s[1].y - 1); /* Upper edge */ chk2 = wgetpixel (s[1].x + 3, s[1].y + 6); /* Lower edge */ chk3 = wgetpixel (s[1].x - 1, s[1].y + 3); /* Left edge */ chk4 = wgetpixel (s[1].x + 6, s[1].y + 3); /* Right edge */ if (chk1 > 28) { hit (3, -1); sby = ysp; } else if (chk2 > 28) { hit (3, 6); sby = -ysp; } if (chk3 > 28) { hit (-1, 3); sbx = -sbx; lx += 2; } else if (chk4 > 28) { hit (6, 3); sbx = -sbx; lx -= 2; } nosound (); /* Turn off all sound */ draw_sprites (1); /* Draw the sprites again */ } void hit (short ix, short iy) { short x1, x2; short y1, y2; sound (600); /* Beep because we hit something */ wsetcolor (0); /* Loop through all the bricks to see what we hit */ for (x = 1; x < 28; x++) { x1 = x * 7 + 57; x2 = x1 + 6; for (y = 1; y < 10; y++) { y1 = y * 5 + 20; y2 = y1 + 4; if ((s[1].x + ix >= x1) && (s[1].x + ix <= x2) && (s[1].y + iy >= y1) && (s[1].y + iy <= y2) && (blk[y][x] != 0)) { wsetscreen (spritescreen); wbar (x1, y1, x2, y2); /* Erase brick */ wsetscreen (backgroundscreen); wbar (x1, y1, x2, y2); /* Erase brick */ wnormscreen (); /* And update visual screen */ wcopyscreen (x1, y1, x2, y2, spritescreen, x1, y1, NULL); blk[y][x] = 0; /* Disable brick in array */ hits++; if ((hits % 15) == 0) /* Increase speed after every 15 hits */ { xsp += .1; ysp += .1; } } } } } void dobounce (void) { sound (200); /* Beep when bouncing */ nosound (); }