#include "fbgfx.bi" ' Our subroutine declarations will go here! DECLARE SUB MainMenu ' Sub that runs our main menu loop. DECLARE SUB MainLoop ' Sub that runs our main game loop. DECLARE SUB LoadGraphics ' Sub that loads all the program's graphics. DECLARE SUB InitVariables ' Sub that initiates the game variables ' (should be called before every new game). DECLARE SUB MoveDrawSheep ' A sub that moves, draws and controls the ' sheep. DECLARE SUB MoveDrawPlayer ' A sub that moves the warrior(according ' to the key pressed) and draws it. DECLARE SUB PrintScore ' Particle subs. First initiates particles, second draws them. DECLARE SUB InitiateParticle (xpos!, ypos!, parttype, partdirec) DECLARE SUB ParticleLayer ' Useful constants(makes your code easier to read and write). const FALSE = 0 const TRUE = 1 DIM SHARED background1(64004) AS INTEGER ' An array that will hold the ' background image DIM SHARED WarriorSprite(12, 404) AS INTEGER ' An array that will hold ' the warior sprites. DIM SHARED ExtraSprite(18, 900) AS INTEGER ' An array that will hold ' the additional sprites. SCREEN 13,8,2,0 ' 13 means 320*200 graphics resolution; 8 means ' 8bit color depth; 2 means two work pages and ' 0 means window mode(1 would be full screen mode). ' When your program is running you can toggle ' between full screen/window mode with ALT+ENTER. SETMOUSE 0,0,0 ' Hides the mouse cursor. ' Our user defined type containing 10 variables. TYPE ObjectType X AS SINGLE Y AS SINGLE Speed AS SINGLE Frame AS INTEGER Direction AS INTEGER Move AS INTEGER Attack AS INTEGER Alive AS INTEGER Typ AS INTEGER Duration AS INTEGER END TYPE DIM SHARED Player AS ObjectType ' Our player. DIM SHARED Sheep(10) AS ObjectType ' Our sheep. DIM SHARED Particle(100) AS ObjectType ' Our particles for the ' particle layer. 100 of ' them maximum on the screen. DIM SHARED Frame1, KeyPressed DIM SHARED seconds, milsec DIM SHARED starttime AS DOUBLE LoadGraphics ' Load the program's graphics. MainMenu ' Initiate main menu. END ' End program. ' MAIN MODULE ENDS HERE! ' ********************** SUB LoadGraphics ' Let's hide the work page since we are ' going to load program's graphics directly ' onto the screen. Page 1 is set as the ' work page and page 0 as the visible ' page. Everything you paste will be ' pasted on the work page(if you don't ' specify otherwise) and won't be ' visible(copied to the visible page) ' until you use SCREENCOPY. SCREENSET 1, 0 ' Load the background image and store ' it in an array. BLOAD "backgrnd.bmp", 0 GET (0,0)-(319,199), background1(0) CLS ' Clear our screen since we ' are loading a new image(not ' neccesary but wise). ' Load the warrior sprites onto the screen and ' store them into an array. BLOAD "sprites.bmp", 0 FOR imagepos = 1 TO 12 GET (0+(imagepos-1)*24,0)-(19+(imagepos-1)*24,19), WarriorSprite(imagepos, 0) NEXT imagepos ' The 12 warrior sprites are saved as follows: ' WarriorSprite(1, 0) - warrior moving down image #1 ' WarriorSprite(2, 0) - warrior moving down image #2 ' WarriorSprite(3, 0) - warrior moving up image #1 ' WarriorSprite(4, 0) - warrior moving up image #2 ' WarriorSprite(5, 0) - warrior moving left image #1 ' WarriorSprite(6, 0) - warrior moving left image #2 ' WarriorSprite(7, 0) - warrior moving right image #1 ' WarriorSprite(8, 0) - warrior moving right image #2 ' WarriorSprite(9, 0) - warrior swinging up ' WarriorSprite(10, 0) - warrior swinging down ' WarriorSprite(11, 0) - warrior swinging left ' WarriorSprite(12, 0) - warrior swinging right ' Load the image holding the additional sprites and store ' them into the "ExtraSprite" array on specific positions. BLOAD "EXTRASPR.BMP", 0 ' Load the sheep sprites. FOR imagepos = 1 TO 8 GET (0+(imagepos-1)*24,0)-(19+(imagepos-1)*24,19), ExtraSprite(imagepos, 0) NEXT imagepos ' Load the bloody sheep meat. FOR meatpos = 1 TO 7 GET (6+(meatpos-1)*13,25)-(17+(meatpos-1)*13,34), ExtraSprite(meatpos + 8, 0) NEXT meatpos ' Load the fireball. GET (11, 42)-(23, 53), ExtraSprite(16, 0) ' Load the mouse cursor. GET (108, 24)-(121, 40), ExtraSprite(17, 0) ' Load the menu pointer. GET (127, 25)-(139, 37), ExtraSprite(18, 0) ' The sprites are saved in the "ExtraSprite" array as follows: ' ExtraSprite(1, 0) - sheep moving down image #1 ' ExtraSprite(2, 0) - sheep moving down image #2 ' ExtraSprite(3, 0) - sheep moving up image #1 ' ExtraSprite(4, 0) - sheep moving up image #2 ' ExtraSprite(5, 0) - sheep moving left image #1 ' ExtraSprite(6, 0) - sheep moving left image #2 ' ExtraSprite(7, 0) - sheep moving right image #1 ' ExtraSprite(8, 0) - sheep moving right image #2 ' ExtraSprite(9, 0) - ExtraSprite(15, 0) - 7 bloody meat pieces ' ExtraSprite(16, 0) - the fireball sprite ' ExtraSprite(17, 0) - the mouse cursor ' ExtraSprite(18, 0) - the menu pointer END SUB SUB MainLoop DO ' Our timer(millisecond precise). ' starttime variable checks if ' a millisecond has passed ' using the TIMER statement. ' & is used with variables ' you want to return DOUBLE ' PRECISION values. When 10 ' milliseconds has passed ' add one seconds and return ' the milliseconds to 0. IF starttime + 0.1 <= TIMER& THEN milsec = milsec + 1 IF milsec > 9 THEN seconds = seconds + 1 milsec = 0 END IF starttime = TIMER& END IF ' Frame1 changes from 1 to 2 or vice versa every ' 16 cycles(set with Frame2 variable). Frame2 = (Frame2 MOD 16) + 1 IF Frame2 = 10 THEN Frame1 = (Frame1 MOD 2) + 1 IF Player.Move = FALSE OR Frame1 = 0 THEN Frame1 = 1 ' Pastes the background. PUT (0, 0), background1(0), PSET ParticleLayer ' Paste the particles. MoveDrawSheep ' Paste the sheep and move them. MoveDrawPlayer ' Paste and control the player. ' Print playtime in the top-left corner of the ' screen. LOCATE 1, 1 PRINT "Playtime: "+STR$(seconds)+"."+STR$(milsec) ' Copy the work page(page 1) to the visible page(page 0). SCREENCOPY SCREENSYNC ' Wait for vertical blank(use always in all the game ' game loops to get 85 FPS). SLEEP 2 ' Statement used to prevent 100% CPU usage(prevents ' the program to use up all the computer cycles - useful ' and recommended). ' A round is over by deafult. GameEnd = TRUE ' Check all the sheep. If any of them is alive the ' game should not end(round not completed). FOR checksheep = 1 TO 10 IF Sheep(checksheep).Alive = TRUE THEN GameEnd = FALSE NEXT checksheep LOOP UNTIL MULTIKEY(SC_Q) OR MULTIKEY(SC_ESCAPE) OR GameEnd = TRUE ' Execute the loop until the user presses Q or ESCAPE or the game ends. END SUB SUB MainMenu ' Will add code here later that calls ' the main loop after the player clicks ' on an option in the menu. For now ' the main loop is called right away. ' Load initial variables(player's position, etc.). InitVariables ' Call the main game loop. MainLoop ' Show the score screen if all sheep are killed. PrintScore END SUB SUB InitVariables RANDOMIZE TIMER ' Warrior's(player's) initial ' position, speed(constant) ' and direction(1 = right). Player.X = 150 Player.Y = 90 Player.Speed = 1 Player.Direction = 1 ' Initiate all the sheep(their positions, etc.). FOR countsheep = 1 TO 10 ' Randomize a number 1 to 300(sheep's X position). Sheep(countsheep).X = INT(RND * 300) + 1 ' Randomize a number 1 to 180(sheep's Y position). Sheep(countsheep).Y = INT(RND * 180) + 1 ' Randomize a number 1 to 4. Sheep(countsheep).Direction = INT(RND * 4) + 1 ' New game -> all sheep alive by deafult. Sheep(countsheep).Alive = TRUE ' Speed of all sheep. Sheep(countsheep).Speed = 0.6 NEXT countsheep ' Set all particles as INACTIVE/LOCKED. FOR countparticle = 1 TO 100 Particle(countparticle).Alive = FALSE NEXT countparticle ' Resest the custom timer. milsec = 0 seconds = 0 END SUB SUB MoveDrawSheep ' Loop through all the sheep. FOR countsheep = 1 TO 10 ' The current sheep is not moving by default. Sheep(countsheep).Move = FALSE ' Sheep(countsheep).Direction = 1 -> sheep moving right ' Sheep(countsheep).Direction = 2 -> sheep moving left ' Sheep(countsheep).Direction = 3 -> sheep moving down ' Sheep(countsheep).Direction = 4 -> sheep moving up ' The next 4 IF clauses is the AI. In more demanding projects ' your AI will most likely be more complex so you will probably ' place it in a separate sub. ' Each IF checks if the player is less than 50 pixels away from ' the sheep in both directions(scope of detection - change all 50 to ' higher or less number to get a different scope of detection/reaction). ' The first condition in each IF checks where's the player according ' to sheep(in X or Y direction) and then we flag the sheep's direction ' if this condtition is met. The last two IFs have another condition ' inside them which is just nitpicking and gives a better feeling. IF Player.Y < Sheep(countsheep).Y AND ABS(Player.Y-Sheep(countsheep).Y) < 50 AND ABS(Player.X-Sheep(countsheep).X) < 50 THEN Sheep(countsheep).Move = TRUE Sheep(countsheep).Direction = 3 END IF IF Player.Y > Sheep(countsheep).Y AND ABS(Player.Y-Sheep(countsheep).Y) < 50 AND ABS(Player.X-Sheep(countsheep).X) < 50 THEN Sheep(countsheep).Move = TRUE Sheep(countsheep).Direction = 4 END IF IF Player.X > Sheep(countsheep).X AND ABS(Player.X-Sheep(countsheep).X) < 50 AND ABS(Player.Y-Sheep(countsheep).Y) < 50 THEN Sheep(countsheep).Move = TRUE IF ABS(Player.X-Sheep(countsheep).X) > 20 THEN Sheep(countsheep).Direction = 2 END IF IF Player.X < Sheep(countsheep).X AND ABS(Player.X-Sheep(countsheep).X) < 50 AND ABS(Player.Y-Sheep(countsheep).Y) < 50 THEN Sheep(countsheep).Move = TRUE IF ABS(Player.X-Sheep(countsheep).X) > 20 THEN Sheep(countsheep).Direction = 1 END IF ' If the current sheep is moving change its position ' according to its direction(flagged with the AI code). ' If the current sheep is out of bounds prevent it to ' walk off the screen. Note how the SELECT CASE statement ' works. IF Sheep(countsheep).Move = TRUE THEN SELECT CASE Sheep(countsheep).Direction CASE 1 Sheep(countsheep).X = Sheep(countsheep).X + Sheep(countsheep).Speed IF Sheep(countsheep).X > 300 THEN Sheep(countsheep).X = 300 CASE 2 Sheep(countsheep).X = Sheep(countsheep).X - Sheep(countsheep).Speed IF Sheep(countsheep).X < 0 THEN Sheep(countsheep).X = 0 CASE 3 Sheep(countsheep).Y = Sheep(countsheep).Y + Sheep(countsheep).Speed IF Sheep(countsheep).Y > 180 THEN Sheep(countsheep).Y = 180 CASE 4 Sheep(countsheep).Y = Sheep(countsheep).Y - Sheep(countsheep).Speed IF Sheep(countsheep).Y < 0 THEN Sheep(countsheep).Y = 0 END SELECT END IF ' The current sheep frame(sprite) by default(sheep not moving). IF Sheep(countsheep).Direction = 1 THEN Sheep(countsheep).Frame = 7 IF Sheep(countsheep).Direction = 2 THEN Sheep(countsheep).Frame = 5 IF Sheep(countsheep).Direction = 3 THEN Sheep(countsheep).Frame = 1 IF Sheep(countsheep).Direction = 4 THEN Sheep(countsheep).Frame = 3 ' If the current sheep is moving flag the proper sprite according ' to its direction. IF Sheep(countsheep).Move = TRUE THEN IF Sheep(countsheep).Direction = 1 THEN Sheep(countsheep).Frame = 6 + Frame1 IF Sheep(countsheep).Direction = 2 THEN Sheep(countsheep).Frame = 4 + Frame1 IF Sheep(countsheep).Direction = 3 THEN Sheep(countsheep).Frame = 0 + Frame1 IF Sheep(countsheep).Direction = 4 THEN Sheep(countsheep).Frame = 2 + Frame1 END IF ' If the current sheep is ALIVE draw it! IF Sheep(countsheep).Alive = TRUE THEN PUT (Sheep(countsheep).X, Sheep(countsheep).Y), ExtraSprite(Sheep(countsheep).Frame, 0), TRANS NEXT countsheep END SUB SUB MoveDrawPlayer ' Player.Direction = 1 -> warrior moving right ' Player.Direction = 2 -> warrior moving left ' Player.Direction = 3 -> warrior moving down ' Player.Direction = 4 -> warrior moving up Player.Move = FALSE ' By deafult player is not ' moving. ' According to pushed key move the ' player and flag the proper direction. IF MULTIKEY(SC_RIGHT) THEN Player.X = Player.X + Player.Speed Player.Direction = 1 Player.Move = TRUE END IF IF MULTIKEY(SC_LEFT) THEN Player.X = Player.X - Player.Speed Player.Direction = 2 Player.Move = TRUE END IF IF MULTIKEY(SC_DOWN) THEN Player.Y = Player.Y + Player.Speed Player.Direction = 3 Player.Move = TRUE END IF IF MULTIKEY(SC_UP) THEN Player.Y = Player.Y - Player.Speed Player.Direction = 4 Player.Move = TRUE END IF ' The following 4 conditions prevent ' the warrior to walk off the screen. IF Player.X < 0 THEN Player.Move = FALSE Player.X = 0 END IF IF Player.X > 300 THEN Player.Move = FALSE Player.X = 300 END IF IF Player.Y < 0 THEN Player.Move = FALSE Player.Y = 0 END IF IF Player.Y > 180 THEN Player.Move = FALSE Player.Y = 180 END IF ' Attack variable needs to reduce to 0 by 1 in ' each cycle since we want for the attack to ' "time out" once we initiate it(swing with the ' sword). Player.Attack = Player.Attack - 1 IF Player.Attack < 0 THEN Player.Attack = 0 ' When the player presses SPACE and the SPACE ' key is released from the last time you ' swung the sword(KeyPressed = FALSE) ' initiate new attack(Player.Attack = 10) and ' flag that SPACE is pressed(KeyPressed = TRUE). ' KeyPressed variable is used to prevent the ' player to be able to hold the SWING. This can ' be done on more ways like prevent the player ' to swing until Player.Attack = 0(replace ' KeyPressed = FALSE with this condition). IF MULTIKEY(SC_SPACE) AND KeyPressed = FALSE THEN KeyPressed = TRUE Player.Attack = 10 END IF ' According to player's direction flag the ' proper sprite. IF Player.Direction = 1 THEN Player.Frame = 6 + Frame1 IF Player.Direction = 2 THEN Player.Frame = 4 + Frame1 IF Player.Direction = 3 THEN Player.Frame = 0 + Frame1 IF Player.Direction = 4 THEN Player.Frame = 2 + Frame1 ' If the player is attacking... IF Player.Attack >0 THEN ' If the player is swinging check for collision with the sheep. ' In our specific range detector we have 3 main conditions. ' First, the sheep must be alive for us to check collision with ' it. Second, the warrior and the sheep must be less that 15 pixels ' apart in horizontal direction. Third, the warrior and the sheep ' must be less than 15 pixels apart in vertical direction. ' You can tweak the pixel distances if you want and can get a ' better result. The secondary condition depends on the direction. ' For example, if the warrior is facing right(Direction = 1) sheep ' must be at least one pixel to the right from the warrior. ' Anyway, if all conditions are met the sheep is killed(Alive = FALSE). FOR checksheep = 1 TO 10 IF Sheep(checksheep).Alive = TRUE AND ABS(Player.X-Sheep(checksheep).X) < 15 AND ABS(Player.Y-Sheep(checksheep).Y) < 15 THEN IF Player.Direction = 1 AND Sheep(checksheep).X > Player.X THEN Sheep(checksheep).Alive = FALSE IF Player.Direction = 2 AND Sheep(checksheep).X < Player.X THEN Sheep(checksheep).Alive = FALSE IF Player.Direction = 3 AND Sheep(checksheep).Y > Player.Y THEN Sheep(checksheep).Alive = FALSE IF Player.Direction = 4 AND Sheep(checksheep).Y < Player.Y THEN Sheep(checksheep).Alive = FALSE IF Sheep(checksheep).Alive = FALSE THEN ' If the sheep is killed spawn 7 bloody meat pieces(particle type 1 ' -> third parameter). InitiateParticle Sheep(checksheep).X+10, Sheep(checksheep).Y+10, 1, 0 InitiateParticle Sheep(checksheep).X+13, Sheep(checksheep).Y+10, 1, 0 InitiateParticle Sheep(checksheep).X+9, Sheep(checksheep).Y+13, 1, 0 InitiateParticle Sheep(checksheep).X+8, Sheep(checksheep).Y+11, 1, 0 InitiateParticle Sheep(checksheep).X+12, Sheep(checksheep).Y+8, 1, 0 InitiateParticle Sheep(checksheep).X+11, Sheep(checksheep).Y+9, 1, 0 InitiateParticle Sheep(checksheep).X+11, Sheep(checksheep).Y+9, 1, 0 END IF END IF NEXT checksheep ' If the player is attacking flag the proper attack ' sprite according to player's direction. IF Player.Direction = 1 THEN Player.Frame = 12 IF Player.Direction = 2 THEN Player.Frame = 11 IF Player.Direction = 3 THEN Player.Frame = 10 IF Player.Direction = 4 THEN Player.Frame = 9 END IF ' If the player pushes ENTER initiate a fireball but only ' if another one is NOT ACTIVE(flagged with the FireBFree variable). IF MULTIKEY(SC_ENTER) THEN FireBFree = TRUE ' By deafult the fireball is free. ' Go through all the particles and check if an active one is ' the fireball. FOR countparticle = 1 TO 100 IF Particle(countparticle).Alive = TRUE AND Particle(countparticle).Typ = 2 THEN FireBFree = FALSE NEXT countparticle ' Note how player's direction is passed into the sub(4th parameter). IF FireBFree = TRUE THEN InitiateParticle Player.X+4, Player.Y+5, 2, Player.Direction END IF ' Pastes the warrior on Player.X and Player.Y coordinates, ' using sprite number Player.Frame and skips background color(TRANS). PUT (Player.X, Player.Y), WarriorSprite(Player.Frame, 0), TRANS ' Flag KeyPressed as FALSE(pressing is not locked!) only when ' the player releases SPACE or ENTER. IF MULTIKEY(SC_ENTER) OR MULTIKEY(SC_SPACE) THEN GOTO skipkeyrestore: KeyPressed = FALSE skipkeyrestore: END SUB SUB InitiateParticle (xpos!, ypos!, parttype, partdirec) ' Check the particles for a free one. FOR countparticle = 1 TO 100 ' If the current one is free(Alive = FALSE) activate ' it and pass certain values to it. IF Particle(countparticle).Alive = FALSE THEN Particle(countparticle).Alive = TRUE Particle(countparticle).Typ = parttype ' Pass the particle type ' from parttype. Particle(countparticle).X = xpos! ' Pass the particle's position Particle(countparticle).Y = ypos! ' from xpos! and ypos! ' If the particle is type 1(bloody meat pieces) ' randomize its DIRECTION(from 1 to 8), set ' its DURATION(with bloody meat pieces it flags ' how much the piece will move once it's spawned), ' set its speed(from 0.1 to 1) and its FRAME(sprite ' from ExtraSprite array -> from 9 to 15, check ' LoadGraphics sub). IF Particle(countparticle).Typ = 1 THEN Particle(countparticle).Direction = INT(RND * 8) + 1 Particle(countparticle).Duration = 10 Particle(countparticle).Speed = (INT(RND * 10) + 1) / 10 Particle(countparticle).Frame = INT(RND * 6) + 9 END IF ' If the particle is type 2(fireball) flag ' its direction according to partdirec, its ' duration and speed(modify this for faster ' or slower fireball) and sprite(only one ' image of fireball in the ExtraSprite array ' placed on position 16). IF Particle(countparticle).Typ = 2 THEN Particle(countparticle).Direction = partdirec Particle(countparticle).Duration = 100 Particle(countparticle).Speed = 2 Particle(countparticle).Frame = 16 END IF EXIT SUB ' Once the particle is initiated exit this sub. END IF NEXT countparticle ' If a particle is not free in this slot ' seek in the next. END SUB SUB ParticleLayer ' Go through all the particles... FOR countparticle = 1 TO 100 ' If the current particle is activated(Alive = TRUE) ' manage and draw it. IF Particle(countparticle).Alive = TRUE THEN ' If the current particle is type 1(bloody meat piece) ' reduce its duration from 10 to 0. While duration is ' above 0 the particle it moved according to its ' direction. IF Particle(countparticle).Typ = 1 THEN Particle(countparticle).Duration = Particle(countparticle).Duration - 1 IF Particle(countparticle).Duration < 0 THEN Particle(countparticle).Duration = 0 ' While duration is above 0 move the particle ' according to its direction with preset speed. ' Directions span from up(1), up-right(2), right(3), all ' the way to up-left(8). IF Particle(countparticle).Duration > 0 THEN SELECT CASE Particle(countparticle).Direction CASE 1 Particle(countparticle).Y = Particle(countparticle).Y - Particle(countparticle).Speed CASE 2 Particle(countparticle).Y = Particle(countparticle).Y - Particle(countparticle).Speed Particle(countparticle).X = Particle(countparticle).X + Particle(countparticle).Speed CASE 3 Particle(countparticle).X = Particle(countparticle).X + Particle(countparticle).Speed CASE 4 Particle(countparticle).Y = Particle(countparticle).Y + Particle(countparticle).Speed Particle(countparticle).X = Particle(countparticle).X + Particle(countparticle).Speed CASE 5 Particle(countparticle).Y = Particle(countparticle).Y + Particle(countparticle).Speed CASE 6 Particle(countparticle).Y = Particle(countparticle).Y + Particle(countparticle).Speed Particle(countparticle).X = Particle(countparticle).X - Particle(countparticle).Speed CASE 7 Particle(countparticle).X = Particle(countparticle).X - Particle(countparticle).Speed CASE 8 Particle(countparticle).Y = Particle(countparticle).Y - Particle(countparticle).Speed Particle(countparticle).X = Particle(countparticle).X - Particle(countparticle).Speed END SELECT END IF ' End if duration is above 0. END IF ' End if particle is type 1. ' If particle type is 2(fireball)... IF Particle(countparticle).Typ = 2 THEN ' If the particle's life has expired(duration = 0) kill it(Alive = FALSE). Particle(countparticle).Duration = Particle(countparticle).Duration - 1 IF Particle(countparticle).Duration < 0 THEN Particle(countparticle).Alive = FALSE ' According to particle's direction move it(right, left, down, up) ' with preset speed. SELECT CASE Particle(countparticle).Direction CASE 1 Particle(countparticle).X = Particle(countparticle).X + Particle(countparticle).Speed CASE 2 Particle(countparticle).X = Particle(countparticle).X - Particle(countparticle).Speed CASE 3 Particle(countparticle).Y = Particle(countparticle).Y + Particle(countparticle).Speed CASE 4 Particle(countparticle).Y = Particle(countparticle).Y - Particle(countparticle).Speed END SELECT ' If the fireball is off the screen kill it. IF Particle(countparticle).Y < -12 OR Particle(countparticle).Y > 200 OR Particle(countparticle).X < -12 OR Particle(countparticle).X > 320 THEN Particle(countparticle).Alive = FALSE ' Check all sheep if the fireball is in collision with any of them. ' The collision is check from the centers of the sheep and the ' fireball and they need to be less than 11 pixel apart. FOR checksheep = 1 TO 10 ' If the fireball is active(not destroyed upon collision with ' the previous sheep), the current sheep is alive and they are ' in collision kill the fireball and the sheep. IF Particle(countparticle).Alive = TRUE AND Sheep(checksheep).Alive = TRUE AND ABS(Particle(countparticle).X+5-Sheep(checksheep).X-10) < 11 AND ABS(Particle(countparticle).Y+5-Sheep(checksheep).Y-10) < 11 THEN Sheep(checksheep).Alive = FALSE ' Kill the fireball. Particle(countparticle).Alive = FALSE ' Kill the sheep. ' If the sheep is killed spawn 7 bloody meat pieces(particle type 1 ' -> third parameter). InitiateParticle Sheep(checksheep).X+10, Sheep(checksheep).Y+10, 1, 0 InitiateParticle Sheep(checksheep).X+13, Sheep(checksheep).Y+10, 1, 0 InitiateParticle Sheep(checksheep).X+9, Sheep(checksheep).Y+13, 1, 0 InitiateParticle Sheep(checksheep).X+8, Sheep(checksheep).Y+11, 1, 0 InitiateParticle Sheep(checksheep).X+12, Sheep(checksheep).Y+8, 1, 0 InitiateParticle Sheep(checksheep).X+11, Sheep(checksheep).Y+9, 1, 0 InitiateParticle Sheep(checksheep).X+11, Sheep(checksheep).Y+9, 1, 0 END IF NEXT checksheep ' Check next sheep for collision. END IF ' End if particle is type 2. ' Draw the current particle on its position with its frame. PUT (Particle(countparticle).X, Particle(countparticle).Y), ExtraSprite(Particle(countparticle).Frame, 0), TRANS END IF ' End if particle is activated(Alive = TRUE). NEXT countparticle ' Check next particle. END SUB SUB PrintScore ' This sub is executed when a game round ' is completed. CLS ' Clear the screen. ' If any of the sheep is alive EXIT this sub since ' the user aborted the game and no sense in ' printing the score. FOR checksheep = 1 TO 10 IF Sheep(checksheep).Alive = TRUE THEN EXIT SUB NEXT checksheep ' Play a loop which ends until the use ' pushes escape. DO ' Print the number of seconds the round took ' to complete. LOCATE 2, 1 PRINT "You needed " + STR$(seconds) + "." + STR$(milsec)+" seconds" LOCATE 3, 1 PRINT "to kill all the sheep." ' According to this time print a different ' message. More time it took the player ' to finish a round print a less ' complimenting message. message$ = "An ok score...for a granny!" IF seconds < 16 THEN message$ = "Not bad!" IF seconds < 11 THEN message$ = "Good job!" IF seconds < 8 THEN message$ = "Excellent job!" LOCATE 5, 1 PRINT message$ LOCATE 7, 1 PRINT "Press ESCAPE to return to main menu." ' Standard statements in every loop. SCREENCOPY SCREENSYNC SLEEP 2 ' End loop when ESCAPE is pushed. LOOP UNTIL MULTIKEY(SC_ESCAPE) END SUB