AppTitle = "PEARL6" ; Created by Philipp Lenssen Include "header.bb" Include "cache.bb" Include "sprite.bb" Include "init_sprite.bb" Include "init_bricks.bb" Include "misc.bb" Include "quotes.bb" Global game.typeGame Global event.typeEvent main End Function main() setGraphics screenWidth, screenHeight intro game.typeGame = New typeGame background.typeBackground = New typeBackground initGameStart game playGame background Delete background Delete game End Function Function playGame(background.typeBackground) doPlayGame = True While doPlayGame initGame game initSprites sprite.typeSprite initBackgroundColor background, game gameLoop sprite, game, background deleteSprites sprite doPlayGame = handleGameExit() Wend End Function Function intro() SetBuffer BackBuffer() DrawBlock LoadImage("file/back.bmp"), screenLeft, screenTop Flip waitContinue End Function Function gameLoop(sprite.typeSprite, game.typeGame, background.typeBackground) timer = CreateTimer(timerFrequency) While Not game\over handleMusic handleSprites sprite handleGame game, sprite handleInput handleEvent sprite, background, game handleBackground background SetBuffer BackBuffer() drawBackground background drawSprites sprite handleDisplay game, sprite Flip WaitTimer timer Wend End Function Function drawSprites(sprite.typeSprite) For layer = layerDeepBack To layerFront For sprite.typeSprite = Each typeSprite If (sprite\layer = layer) Then drawSprite sprite EndIf Next Next End Function Function handleDisplay(game.typeGame, sprite.typeSprite) handleChanceDisplay game, sprite handleExtraDisplay game, sprite End Function Function handleChanceDisplay(game.typeGame, sprite.typeSprite) y = getChanceDisplayOffset(sprite) For chance = 1 To game\chances - 1 x = (chance -1) * 13 Color 0, 20, 50 ; dark blue outline Oval x + 10, y, 10, 10, False Color 80, 120, 200 ; medium blue fill Oval x + 11, y + 1, 8, 8, True Color 100, 180, 240 ; light blue glow Rect x + 13, y + 2, 2, 2, False Next End Function Function getChanceDisplayOffset(sprite.typeSprite) y = 10 For sprite.typeSprite = Each typeSprite If sprite\class = classBall If sprite\subEnergy > 0 y = y + 10 EndIf EndIf Next Return y End Function Function handleExtraDisplay(game.typeGame, sprite.typeSprite) ballY = 0 For sprite.typeSprite = Each typeSprite If sprite\class = classPlayer Or sprite\class = classBall If sprite\subEnergy > 0 If sprite\class = classPlayer x = screenWidth - 110 drawSubEnergyStatus x, 10, sprite\subEnergy Else ; if sprite\class = classBall x = screenLeft + 10 ballY = ballY + 10 drawSubEnergyStatus x, ballY, sprite\subEnergy EndIf EndIf EndIf Next End Function Function drawSubEnergyStatus(x, y, energy) Color 0, 20, 50 ; dark blue outline Rect x, screenTop + y, 100, 8, False Color 250 - energy / 5, 120, 200 ; medium blue fill Rect x + 1, screenTop + y + 1, energy / 10 - 2, 6, True End Function Function handleSprites(sprite.typeSprite) handleCollision sprite For sprite.typeSprite = Each typeSprite handleMorph sprite handleSpriteDefault sprite handleSpriteClass sprite Next For sprite.typeSprite = Each typeSprite emptyCollision sprite Next For sprite.typeSprite = Each typeSprite If sprite\dying Then Delete sprite Next handleSpritesLevel sprite checkIfAllBricksGone sprite checkIfPearlLeft sprite End Function Function checkIfPearlLeft(sprite.typeSprite) pearlFound = False For sprite.typeSprite = Each typeSprite If sprite\class = classBall If sprite\dying = False pearlFound = True ; exit for EndIf EndIf Next If Not pearlFound Then setEvent eventNoBallLeft End Function Function handleSpritesLevel(sprite.typeSprite) Select game\level Case 6 If Rnd(100) >= 99.6 If Rnd(100) >= 50 leftOfScreen = True Else leftOfScreen = False EndIf For i = 1 To 4 initSpriteAttacker sprite, i, leftOfScreen Next EndIf End Select End Function Function checkIfAllBricksGone(sprite.typeSprite) brickFound = False For sprite.typeSprite = Each typeSprite If sprite\class = classBrick And sprite\subClass <> subClassStatic brickFound = True EndIf Next If Not brickFound setEvent eventAllBricksGone EndIf End Function Function initGame(game.typeGame) game\counter = 60 game\direction = 0 game\over = False game\won = False game\chances = gameDefaultChances End Function Function handleGame(game.typeGame, sprite.typeSprite) game\counter = game\counter + game\direction game\over = game\counter = 0 If game\extraPause > 0 Then game\extraPause = game\extraPause - 1 End Function Function initGameStart(game.typeGame) game\speed# = 0.4 game\level = 1 game\rank = 0 game\music = True game\sound = True game\chances = gameDefaultChances End Function Function initBackgroundColor(background.typeBackground, game.typeGame) background\redMin = paletteMin background\greenMin = paletteMin background\blueMin = paletteMin background\redMax = paletteMax background\greenMax = paletteMax background\blueMax = paletteMax background\redSpeed = nothing background\greenSpeed = nothing background\blueSpeed = nothing Select game\level Case 1 background\redSpeed = .1 background\redMax = 140 background\blue = 200 Case 2 background\greenSpeed = .15 background\blueSpeed = .05 background\greenMin = 160 background\green = 160 background\blue = 200 background\blueMax = paletteMax background\blueMin = 190 Case 3 background\redMin = 50 background\redMax = 200 background\redSpeed = .1 background\greenMax = 50 background\greenMax = 200 background\greenSpeed = .1 Case 4 background\redMin = 200 background\redMax = 250 background\redSpeed = .2 background\greenMin = 200 background\greenMax = 250 background\greenSpeed = .2 background\blueMin = 200 background\blueMax = 250 background\blueSpeed = .2 Case 5 background\greenSpeed = .1 background\greenMax = 140 background\blue = 100 Case 6 background\red = 225 background\green = 221 background\blue = 130 End Select End Function Function handleBackground(background.typeBackground) If background\redSpeed <> nothing background\red = background\red + background\redSpeed If background\red < background\redMin background\red = background\redMin background\redSpeed = background\redSpeed * -1 ElseIf background\red > background\redMax background\red = background\redMax background\redSpeed = background\redSpeed * -1 EndIf EndIf If background\greenSpeed <> nothing background\green = background\green + background\greenSpeed If background\green < background\greenMin background\green = background\greenMin background\greenSpeed = background\greenSpeed * -1 ElseIf background\green > background\greenMax background\green = background\greenMax background\greenSpeed = background\greenSpeed * -1 EndIf EndIf If background\blueSpeed <> nothing background\blue = background\blue + background\blueSpeed If background\blue < background\blueMin background\blue = background\blueMin background\blueSpeed = background\blueSpeed * -1 ElseIf background\blue > background\blueMax background\blue = background\blueMax background\blueSpeed = background\blueSpeed * -1 EndIf EndIf End Function Function drawBackground(background.typeBackground) Cls size = 9 For y = screenTop To screenHeight / size off = -(y * 7) safeColor background\red + off, background\green + off, background\blue + off Rect screenLeft, y * size, screenWidth, size Next End Function Function deleteSprites(sprite.typeSprite) For sprite.typeSprite = Each typeSprite Delete sprite Next End Function Function handleInput() If KeyDown(keyEscape) setEvent eventEscapePressed ElseIf KeyDown(keyPause) setEvent eventPausePressed ElseIf KeyDown(keyMusic) game\music = Not game\music Delay 400 If Not game\music Then StopChannel game\musicChannel End If ElseIf KeyDown(keySound) game\sound = Not game\sound Delay 400 EndIf End Function Function setEvent(number) event.typeEvent = New typeEvent event\number = number End Function Function handleEvent(sprite.typeSprite, background.typeBackground, game.typeGame) For event.typeEvent = Each typeEvent Select event\number Case eventEscapePressed game\over = True ;Case eventNextLevelWarp ; removeRandomBrick sprite Case eventPlayerShoots For spriteB.typeSprite = Each typeSprite If spriteB\class = classPlayer spriteBCenter = spriteB\x + spriteB\width / 2 sprite.typeSprite = New typeSprite initSpriteBullet sprite, spriteB\x, spriteB\y sprite\targetX = spriteBCenter - sprite\width sprite.typeSprite = New typeSprite initSpriteBullet sprite, spriteB\x + spriteB\width, spriteB\y sprite\x = sprite\x - sprite\width sprite\targetX = spriteBCenter If spriteB\subClass = subClassExtraFirepower Or spriteB\subClass = subClassExtraSuperfirepower sprite.typeSprite = New typeSprite initSpriteBulletExtra spriteB, sprite If spriteB\subClass = subClassExtraSuperfirepower initSpriteBulletExtraSuper spriteB EndIf triggerSound "missile_extra", defaultValue Else triggerSound "missile", defaultValue EndIf EndIf Next Case eventAllBricksGone game\direction = -1 game\won = True Case eventNoBallLeft game\chances = game\chances - 1 If game\chances > 0 spriteB.typeSprite = New typeSprite initSpriteBall spriteB spriteB\y = spriteB\y - 100 Else killPlayerSprite sprite EndIf Case eventPlayerDies game\direction = -1 Case eventAlienLeftScreen, eventFallingBrickLeftScreen, eventBoggleBrickLeftScreen, eventAttackerLeftScreen killPlayerSprite sprite Case eventHitSide For sprite.typeSprite = Each typeSprite If sprite\subClass = subClassOrder If sprite\x + sprite\width / 2 > screenWidth / 2 sprite\targetX = screenWidth - sprite\width * 2 Else sprite\targetX = screenLeft + sprite\width EndIf sprite\targetY = sprite\y + sprite\height * 4 sprite\layer = layerFront sprite\subClass = 0 EndIf Next Case eventPausePressed handlePause Case eventExtraSlowpearl, eventExtraBallshield For sprite.typeSprite = Each typeSprite If sprite\class = classBall If sprite\subClass = 0 If event\number = eventExtraSlowpearl sprite\speedLimit = ballSpeedLimit / 2 sprite\subClass = subClassExtraSlowpearl ElseIf event\number = eventExtraBallShield sprite\subClass = subClassExtraBallShield EndIf sprite\subEnergy = ballExtraMax EndIf EndIf Next Case eventExtraWidth For sprite.typeSprite = Each typeSprite If sprite\class = classPlayer If sprite\subClass = 0 sprite\targetWidth = sprite\width * 2 sprite\subEnergy = playerExtraMax sprite\subClass = subClassExtraWidth EndIf EndIf Next Case eventExtraChance If game\chances < 10 game\chances = game\chances + 1 EndIf Case eventExtraFirepower, eventExtraSuperfirepower, eventExtraInverted For sprite.typeSprite = Each typeSprite If sprite\class = classPlayer If sprite\subClass = 0 If event\number = eventExtraFirepower sprite\subClass = subClassExtraFirepower ElseIf event\number = eventExtraSuperfirepower sprite\subClass = subClassExtraSuperfirepower ElseIf event\number = eventExtraInverted sprite\subClass = subClassExtraInverted EndIf sprite\subEnergy = playerExtraMax EndIf EndIf Next Case eventExtraBomb For sprite.typeSprite = Each typeSprite If sprite\class = classAlien initSparklesExplosion sprite, False sprite\dying = True EndIf Next triggerSound "explosion", 1 Case eventExtraBrickbomb For sprite.typeSprite = Each typeSprite If sprite\class = classBrick If Rnd(100) > 90 initSparklesExplosion sprite, False sprite\dying = True EndIf EndIf Next triggerSound "explosion", 1 Case eventExtraSecondpearl spriteB.typeSprite = New typeSprite initSpriteBall spriteB Case eventExtraMultipearl For y = 1 To 3 spriteB.typeSprite = New typeSprite initSpriteBall spriteB spriteB\y = spriteB\y - y * 50 Next End Select Delete event Next End Function Function killPlayerSprite(sprite.typeSprite) For sprite.typeSprite = Each typeSprite If sprite\class = classPlayer sprite\targetRed = paletteMax sprite\targetGreen = paletteMin sprite\targetBlue = paletteMin sprite\energyDirection = -1 ; exit for EndIf Next End Function Function removeRandomBrick(sprite.typeSprite) For spriteB.typeSprite = Each typeSprite If spriteB\class = classBrick And (Not killedBrick) spriteB\dying = True killedBrick = True End If Next End Function Function triggerSound(soundName$, loudness#) If game\sound If loudness# = defaultValue loudness# = defaultLoudness# EndIf PlaySound getSoundFromCache("file/" + soundName$ + ".wav", loudness#) EndIf End Function Function handlePause() timeOut = 400 SetBuffer BackBuffer() shadePrint screenHeight / 2, "GAME PAUSED", False, 28, 200 Flip PauseChannel game\musicChannel Delay timeOut While Not KeyDown(keyPause) Wend Delay timeOut ResumeChannel game\musicChannel End Function Function handleSpriteClass(sprite.typeSprite) Select sprite\class Case classPlayer handleSpritePlayer sprite Case classExtra handleSpriteExtra sprite Case classBall handleSpriteBall sprite Case classAlien handleSpriteAlien sprite Case classStar If sprite\y > screenHeight sprite\y = screenTop - sprite\height sprite\x = Rnd(screenWidth) EndIf Case classBullet, classAlienBullet dieOutsideY sprite If sprite\pushedBy <> 0 Then sprite\dying = True Case classBrick handleSpriteBrick sprite Case classFallingBrick handleSpriteFallingBrick sprite Case classAttacker handleSpriteAttacker sprite Case classBoggleBrick handleSpriteBoggleBrick sprite End Select End Function Function handleSpriteBrick(sprite.typeSprite) If sprite\subClass = subClassStatic spriteShiftX sprite EndIf If sprite\pushedBy = classBall If sprite\subPushedBy <> subClassStartBall handleSpriteBrickCollision sprite EndIf EndIf End Function Function handleSpriteExtra(sprite.typeSprite) dieOutside sprite If sprite\pushedBy = classPlayer If sprite\subClass <> 0 sprite\speedX = 20 If Rnd(10) > 5 Then sprite\speedX = sprite\speedX * -1 sprite\image = getImageFromCache("file\extra_" + getExtraImage(sprite\subClass) + ".bmp") ; if it was "surprise" sprite\subClass = 0 EndIf EndIf End Function Function handleSpriteAttacker(sprite.typeSprite) If headingOutsideScreen(sprite) setEvent eventAttackerLeftScreen sprite\dying = True EndIf If sprite\pushedBy = classBullet sprite\dying = True initSparklesAttacker sprite triggerSound "explosion", defaultValue EndIf End Function Function handleSpriteBoggleBrick(sprite.typeSprite) If sprite\pushedBy = classBullet initSpriteBoggle sprite EndIf If sprite\y + sprite\height < screenTop sprite\dying = True ElseIf sprite\y > screenHeight sprite\dying = True initSparklesFromSprite sprite setEvent eventBoggleBrickLeftScreen triggerSound "explosion", defaultValue EndIf If sprite\counter = counterTurn initSpriteSparkleBehindNegative sprite EndIf End Function Function handleSpriteFallingBrick(sprite.typeSprite) If sprite\pushedBy = classBullet initSparklesFromSprite sprite sprite\energy = sprite\energy - 1 If sprite\energy = 0 triggerSound "explosion", defaultValue EndIf EndIf If sprite\y + sprite\height > screenHeight sprite\dying = True setEvent eventFallingBrickLeftScreen triggerSound "explosion", defaultValue EndIf If sprite\counter = counterTurn initSpriteSparkleBehindNegative sprite EndIf End Function Function handleSpriteAlien(sprite.typeSprite) bounceSoftX sprite, 100 If sprite\y > screenHeight sprite\dying = True initSparklesExplosion sprite, False setEvent eventAlienLeftScreen triggerSound "explosion", defaultValue ElseIf sprite\pushedBy = classBullet If sprite\subClass <> subClassSmall spriteB.typeSprite = New typeSprite initSpriteAlienSmall spriteB.typeSprite, sprite\x, sprite\y, -Abs(sprite\speedX), sprite\speedY * 2 spriteB.typeSprite = New typeSprite initSpriteAlienSmall spriteB.typeSprite, sprite\x + sprite\width, sprite\y, Abs(sprite\speedX), sprite\speedY * 2 initSparklesExplosion sprite, False triggerSound "explosion", 1 Else initColoredSparkles sprite\x, sprite\y, 10, sprite\red, sprite\green, sprite\blue triggerSound "explosion", .7 EndIf sprite\dying = True ElseIf Rnd(100) >= 99.6 And sprite\subClass <> subClassSmall spriteNew.typeSprite = New typeSprite initSpriteAlienBullet sprite, spriteNew triggerSound "short_laser", .8 EndIf End Function Function handleSpritePlayer(sprite.typeSprite) If sprite\subClass = subClassExtraInverted sprite\x = screenWidth - MouseX() Else sprite\x = MouseX() EndIf If sprite\counter = counterTurn If MouseDown(leftMouseButton) setEvent eventPlayerShoots sprite\counterMax = 10 EndIf ;If MouseDown(rightMouseButton) ; setEvent eventNextLevelWarp ;EndIf EndIf sprite\y = (screenHeight - 76) + MouseY() / 8 spritePushInScreenX sprite If sprite\pushedBy = classBall Then sprite\targetGreen = 170 sprite\targetBlue = 170 ElseIf sprite\blue = 170 sprite\targetBlue = 255 sprite\targetGreen = 220 EndIf If sprite\pushedBy = classAlienBullet sprite\energy = 1 sprite\energyDirection = -1 ElseIf sprite\pushedBy = classExtra If sprite\subPushedBy <> 0 If playerAcceptExtra(sprite\subClass, sprite\subPushedBy) If reachedTargets(sprite) triggerSound "extra", defaultValue activateExtra sprite\subPushedBy EndIf EndIf EndIf EndIf handlePlayerSubClass sprite If sprite\counter = counterTurn initSpritePlayerShade sprite EndIf If sprite\energy = 1 setEvent eventPlayerDies initSparklesExplosion sprite, True triggerSound "explosion_player", defaultValue EndIf End Function Function playerAcceptExtra(subClass, subPushedBy) acceptExtra = True If isPlayerExtra(subClass) And isPlayerExtra(subPushedBy) acceptExtra = False EndIf Return acceptExtra End Function Function isPlayerExtra(extra) isWidth = extra = subClassExtraWidth isFirepower = extra = subClassExtraFirepower isSuperfirepower = extra = subClassExtraSuperfirepower isInverted = extra = subClassExtraInverted Return False; isWidth Or isFirepower Or isSuperfirepower Or isInverted End Function Function handlePlayerSubClass(sprite.typeSprite) If sprite\handleSubEnergyGone Select sprite\subClass Case subClassExtraWidth If reachedTargets(sprite) sprite\handleSubEnergyGone = False sprite\targetWidth = playerDefaultWidth sprite\subClass = 0 EndIf Default sprite\handleSubEnergyGone = False sprite\subClass = 0 End Select EndIf End Function Function activateExtra(extraNumber) Select extraNumber Case subClassExtraWidth setEvent eventExtraWidth Case subClassExtraBomb setEvent eventExtraBomb Case subClassExtraBrickbomb setEvent eventExtraBrickbomb Case subClassExtraSlowpearl setEvent eventExtraSlowpearl Case subClassExtraSecondpearl setEvent eventExtraSecondpearl Case subClassExtraMultipearl setEvent eventExtraMultipearl Case subClassExtraFirepower setEvent eventExtraFirepower Case subClassExtraSuperfirepower setEvent eventExtraSuperfirepower Case subClassExtraInverted setEvent eventExtraInverted Case subClassExtraChance setEvent eventExtraChance Case subClassExtraBallshield setEvent eventExtraBallshield End Select End Function Function handleSpriteBall(sprite.typeSprite) borderBounceSpecific sprite, True, True, True, False If sprite\pushedBy = classBullet If sprite\subClass <> subClassExtraBallshield sprite\dying = True setEvent eventBallDied initSparklesExplosion sprite, True triggerSound "explosion_pearl", defaultValue EndIf ElseIf sprite\subClass = subClassStartBall If sprite\y > screenHeight / 2 sprite\subClass = 0 If Rnd(100) >= 50 sprite\targetSpeedX = 6 Else sprite\targetSpeedX = -6 EndIf EndIf Else If sprite\y > screenHeight + 10 sprite\dying = True setEvent eventBallDied EndIf If sprite\pushedBy = classPlayer Or sprite\pushedBy = classBrick sprite\speedX = sprite\pushedX * sprite\speedLimit sprite\speedY = sprite\pushedY * sprite\speedLimit sprite\red = 250 If sprite\pushedBy = classBrick initSparkles sprite\x + sprite\width / 2, sprite\y + sprite\height / 2, 6 + Rnd(4) Else ; if sprite\pushedBy = classPlayer triggerSound "ping", defaultValue EndIf ; ball went straight? If sprite\speedX = 0 sprite\targetSpeedX = sprite\speedLimit ElseIf sprite\speedY = 0 sprite\targetSpeedY = sprite\speedLimit EndIf EndIf EndIf If sprite\counter = counterTurn initSpriteSparkleBehind sprite EndIf If sprite\handleSubEnergyGone sprite\handleSubEnergyGone = False If sprite\subClass = subClassExtraSlowpearl sprite\speedLimit = ballSpeedLimit EndIf sprite\subClass = 0 EndIf End Function Function gameGiveExtra() giveExtra = False If game\extraPause = 0 If Rnd(10) > 7.5 giveExtra = True game\extraPause = gameExtraPause EndIf EndIf Return giveExtra End Function Function handleSpriteBrickCollision(sprite.typeSprite) If gameGiveExtra() If Not (sprite\subClass = subClassOrder Or sprite\dying = True Or sprite\energyDirection < 0 Or sprite\subClass = subClassStatic) If reachedTargets(sprite) triggerSound "bonus", defaultValue morphToSpriteExtra sprite choseExtra = True EndIf EndIf EndIf If Not choseExtra Select sprite\subClass Case subClassStatic triggerSound "ping", defaultValue - .3 sprite\targetRed = 30 sprite\red = paletteMax sprite\colorSpeed = 2 sprite\targetY = sprite\y sprite\y = sprite\y + sprite\pushedY * 4 Case subClassBonus, subClassSpecialBonus triggerSound "bonus", defaultValue sprite\class = classFallingBrick sprite\energy = 6 sprite\targetRed = paletteMax sprite\targetGreen = 150 sprite\targetBlue = 20 sprite\targetWidth = brickWidth sprite\speedY = sprite\speedLimit sprite\counterMax = 10 If sprite\subClass = subClassSpecialBonus If Rnd(100) >= 50 sprite\targetSpeedX = -2 Else sprite\targetSpeedX = 2 EndIf EndIf Case subClassShield triggerSound "bump", 1 sprite\subClass = 0 sprite\speedY = 3 sprite\speedLimit = 3 sprite\targetSpeedY = 0 sprite\targetRed = 100 sprite\targetGreen = 150 sprite\targetBlue = 200 Case subClassMove If reachedTargets(sprite) triggerSound "bump", 1 sprite\energy = sprite\energy -1 If sprite\energy = 2 sprite\targetRed = paletteMax sprite\targetY = sprite\y + sprite\height * 5 sprite\targetWidth = sprite\height setEvent eventHitSide ElseIf sprite\energy = 1 If sprite\x < screenWidth / 2 sprite\targetX = sprite\x - sprite\width Else sprite\targetX = sprite\x + sprite\width EndIf sprite\targetGreen = 0 sprite\targetBlue = 0 ElseIf sprite\energy = 0 sprite\energy = 15 sprite\energyDirection = -1 sprite\targetBlue = paletteMax sprite\targetGreen = paletteMax EndIf EndIf Case subClassBoggle initSpriteBoggle sprite Default If reachedTargets(sprite) triggerSound "ping", defaultValue sprite\class = classDying sprite\energyDirection = -1 sprite\targetSpeedY = nothing sprite\targetSpeedX = nothing spriteSetTargetColorToBack sprite spriteB.typeSprite = New typeSprite initSpriteAlien spriteB EndIf End Select EndIf End Function Function morphToSpriteExtra(sprite.typeSprite) Repeat sprite\subClass = getRandomExtra() If sprite\subClass = 0 Then surpriseExtra = True Until sprite\subClass <> 0 If surpriseExtra imageSubName$ = "surprise" Else imageSubName$ = getExtraImage(sprite\subClass) EndIf sprite\speedY = 2.6 sprite\class = classExtra sprite\width = 32 sprite\height = sprite\width sprite\image = getImageFromCache("file\extra_" + imageSubName$ + ".bmp") sprite\layer = layerFront sprite\speedLimit = 20 End Function Function getRandomExtra() randomI = Rnd(120) If randomI > 110 subClass = subClassExtraBallshield ElseIf randomI > 100 subClass = subClassExtraChance ElseIf randomI > 90 subClass = subClassExtraMultipearl ElseIf randomI > 80 subClass = subClassExtraInverted ElseIf randomI > 70 subClass = subClassExtraSuperfirepower ElseIf randomI > 60 subClass = subClassExtraFirepower ElseIf randomI > 50 subClass = subClassExtraSecondpearl ElseIf randomI > 40 subClass = subClassExtraBomb ElseIf randomI > 30 subClass = subClassExtraSlowpearl ElseIf randomI > 20 subClass = subClassExtraBrickbomb ElseIf randomI > 10 subClass = subClassExtraWidth Else subClass = 0 EndIf Return subClass End Function Function getExtraImage$(subClass) Select subClass Case subClassExtraMultipearl imageSubName$ = "multipearl" Case subClassExtraInverted imageSubName$ = "inverted" Case subClassExtraSuperfirepower imageSubName$ = "superfirepower" Case subClassExtraFirepower imageSubName$ = "firepower" Case subClassExtraSecondPearl imageSubName$ = "secondpearl" Case subClassExtraBomb imageSubName$ = "bomb" Case subClassExtraSlowpearl imageSubName$ = "slowpearl" Case subClassExtraBrickBomb imageSubName$ = "brickbomb" Case subClassExtraWidth imageSubName$ = "width" Case subClassExtraChance imageSubName$ = "chance" Case subClassExtraBallshield imageSubName$ = "ballshield" End Select Return imageSubName$ End Function Function handleMusic() If game\music If Not ChannelPlaying(game\musicChannel) game\musicChannel = PlayMusic("file/music" + Int(Rnd(5)) + ".mid") EndIf EndIf End Function Function handleGameExit() If game\won SetBuffer BackBuffer() triggerSound "heavy_explosion", 1 If game\level < gameLevelMax game\level = game\level + 1 shadePrint screenHeight / 2, "W E L L D O N E", True, 28, 200 shadePrint screenHeight / 2 + 26, "ENTER LEVEL " + game\level, False, 16, 160 Else game\rank = game\rank + 1 shadePrint screenHeight / 2, "Y O U W I N", True, 28, 200 shadePrint screenHeight / 2 + 26, "ALL LEVELS CLEARED! CONGRATULATIONS", False, 16, 160 shadePrint screenHeight / 2 + 64, "YOUR RANK IS " + verboseRank$(game\rank), False, 16, 160 If game\rank = gameRankMax shadePrint screenHeight / 2 + 100, "GAME OVER", False, 16, 160 EndIf game\speed# = game\speed# + .2 game\level = 1 EndIf Flip waitContinue game\chances = gameDefaultChances doPlayGame = game\rank <> gameRankMax game\won = False Else doPlayGame = askWithQuote("Play again?") game\over = False EndIf Return doPlayGame End Function Function waitContinue() While Not KeyHit(keyContinue) Wend End Function Function verboseRank$(rank) Select rank Case 1 verbose$ = "COMMANDER" Case 2 verbose$ = "MASTER" Case 3 verbose$ = "GENIUS" Case 4 verbose$ = "BUDDHA" Case 5 verbose$ = "GOD" End Select Return "PEARL " + verbose$ End Function Function handleCollision(sprite.typeSprite) For sprite.typeSprite = Each typeSprite If sprite\class = classPlayer For spriteB.typeSprite = Each typeSprite If spriteB\class = classAlienBullet Or spriteB\class = classExtra checkCollision spriteB, sprite EndIf Next ElseIf sprite\class = classBall For spriteB.typeSprite = Each typeSprite If spriteB\class <> classBall If spriteB\class = classPlayer Or spriteB\class = classBrick Or spriteB\class = classBullet checkCollision sprite, spriteB EndIf EndIf Next ElseIf sprite\class = classBullet For spriteB.typeSprite = Each typeSprite If spriteB\class = classAlien Or spriteB\class = classFallingBrick Or spriteB\class = classBoggleBrick Or spriteB\class = classAttacker checkCollision sprite, spriteB EndIf Next EndIf Next End Function Function drawSprite(sprite.typeSprite) If sprite\image <> 0 If sprite\frameMax > 0 DrawImage sprite\image, sprite\x, sprite\y, sprite\frame Else DrawImage sprite\image, sprite\x, sprite\y EndIf ElseIf sprite\class = classBall Or sprite\subClass = subClassPearl If sprite\subClass = subClassExtraBallshield colorFromSprite sprite, -80 Oval sprite\x - sprite\width / 2, sprite\y - sprite\height / 2, sprite\width * 2, sprite\height * 2 EndIf colorFromSprite sprite, 0 Oval sprite\x, sprite\y, sprite\width, sprite\height If sprite\subClass <> subClassPearl colorFromSprite sprite, 70 Oval sprite\x + sprite\width / 4, sprite\y + sprite\height / 4, sprite\height / 4, sprite\width / 4 EndIf Else If sprite\width = 1 And sprite\height = 1 colorFromSprite sprite, 0 Plot sprite\x, sprite\y ElseIf sprite\class = classPlayer Or sprite\class = classBrick Or sprite\class = classFallingBrick Or sprite\class = classBoggleBrick colorFromSprite sprite, -160 Rect sprite\x + brickBorder, sprite\y + brickBorder, sprite\width - brickBorder, sprite\height - brickBorder colorFromSprite sprite, 90 Rect sprite\x, sprite\y, sprite\width - brickBorder, sprite\height - brickBorder colorFromSprite sprite, 0 Rect sprite\x + brickBorder, sprite\y + brickBorder, sprite\width - brickBorder * 2, sprite\height - brickBorder * 2 ElseIf sprite\class = classShade colorFromSprite sprite, 0 Rect sprite\x + brickBorder, sprite\y + brickBorder, sprite\width - brickBorder * 2, sprite\height - brickBorder * 2 Else colorFromSprite sprite, 0 Rect sprite\x, sprite\y, sprite\width, sprite\height EndIf EndIf End Function