/* Alex Wiggins */ /* November 2006 */ Program SimpleInvaders Method Main() // resize screen SetScreenSize(600, 600) // set co-ordinate system to device; (0, 0) is top-left corner SetDeviceCoordinates() // load sprites Var Count As Int // - user sprite Var UserSpritePosX As Int Var UserSpritePosY As Int = 500 Var UserTimeline As Int [6] For Count = 1 To 6 UserTimeline[Count] = 50 Next LoadSprite("User", "SpaceStation.gif") UserSpritePosX = (ScreenWidth() / 2) - (GetSpriteWidth("User") / 2) MoveSpriteToPoint("User", UserSpritePosX, UserSpritePosY) SetSpriteAnimationTimeline("User", True, UserTimeline) // - CPU sprites Var CPUSpriteLeft As Int [5] Var CPUSpriteTop As Int Var CPUTimeline As Int [6] For Count = 1 To 6 CPUTimeline[Count] = 50 Next For Count = 1 To 5 LoadSprite("CPU" + Count, "UFO.gif") CPUSpriteLeft[Count] = ((ScreenWidth() - 100) / 5 * Count) - (GetSpriteWidth("CPU" + Count) / 2) CPUSpriteTop = 50 MoveSpriteToPoint("CPU" + Count, CPUSpriteLeft[Count], CPUSpriteTop) SetSpriteAnimationTimeline("CPU" + Count, True, CPUTimeline) Next // variables to store left- and right- most CPU sprites Var CPUSpriteLeftNo As Int = 1 Var CPUSpriteRightNo As Int = 5 // variable to store current direction of movement Var CPUSpriteMoveRight As Bool = False // set constant CPU sprite movement speeds Var CPUSpriteSpeeds As Int [5] CPUSpriteSpeeds[1] = 80 CPUSpriteSpeeds[2] = 70 CPUSpriteSpeeds[3] = 60 CPUSpriteSpeeds[4] = 40 CPUSpriteSpeeds[5] = 20 Var CPUSpriteSpeedNo As Int = 1 // - static sprites // - user missile sprite LoadSprite("UserMissile", "Bullet.gif") RotateSprite("UserMissile", 90) Var UserMissileActive As Bool = False Var UserMissilePosX As Int Var UserMissilePosY As Int Var UserMissileCollisions As String [] // - CPU missile sprites // display sprites Var CPUSpriteVisible As Bool [5] ShowSprite("User") For Count = 1 To 5 ShowSprite("CPU" + Count) CPUSpriteVisible[Count] = True Next // load sounds? // time tracking variables Var TimeCurrent As Decimal Var TimeLastInput As Decimal = 0.0 Var TimeLastCPU As Decimal = 0.0 Var TimeLastUserMissile As Decimal = 0.0 Var LevelUp As Bool = False Var GameOver As Bool = False // main loop While Not GameOver // check time passed since input checked TimeCurrent = TickCount() If TimeCurrent - TimeLastInput > 20 Then // check user keyboard input // - left arrow key If IsKeyDown("Left") Then UserSpritePosX = UserSpritePosX - 5 End If // - right arrow key If IsKeyDown("Right") Then UserSpritePosX = UserSpritePosX + 5 End If // - up arrow key or space bar If IsKeyDown("Up") Or IsKeyDown("Space") Then // check if user missile not yet active If Not UserMissileActive Then // set the flag to active UserMissileActive = True // set the starting position UserMissilePosX = UserSpritePosX + (GetSpriteWidth("User") / 2) UserMissilePosY = UserSpritePosY - GetSpriteHeight("UserMissile") // move the sprite MoveSpriteToPoint("UserMissile", UserMissilePosX, UserMissilePosY) // display the sprite ShowSprite("UserMissile") End If End If // check if too far left If UserSpritePosX < 5 Then UserSpritePosX = 5 End If // check if too far right If UserSpritePosX > (ScreenWidth() - GetSpriteWidth("User") - 5) Then UserSpritePosX = ScreenWidth() - GetSpriteWidth("User") - 5 End If // move the user sprite MoveSpriteToPoint("User", UserSpritePosX, UserSpritePosY) // set the time last checked TimeLastInput = TimeCurrent End If // handle input // check time passed since movement checked TimeCurrent = TickCount() If TimeCurrent - TimeLastUserMissile > 5 Then // check user missile If UserMissileActive Then // move the missile UserMissilePosY = UserMissilePosY - 5 MoveSpriteToPoint("UserMissile", UserMissilePosX, UserMissilePosY) // check for collision UserMissileCollisions = GetSpritesThatIntersectWith("UserMissile") If ArrayLength(UserMissileCollisions) > 0 Then // check if CPU sprite collided with If SubStr(UserMissileCollisions[1], 1, 3) = "CPU" Then // set the visibility of the sprite CPUSpriteVisible[ConvertToInt(SubStr(UserMissileCollisions[1], 4, 1))] = False // check if no sprites visible If CPUSpriteLeftNo = CPUSpriteRightNo Then // next level LevelUp = True End If End If // hide sprite collided with HideSprite(UserMissileCollisions[1]) // keep track of left-most CPU sprite Count = CPUSpriteLeftNo While CPUSpriteVisible[Count] = False And Count <= CPUSpriteRightNo // check the next sprite (to the right) Count = Count + 1 End While // set the current left-most CPU sprite CPUSpriteLeftNo = Count // keep track of right-most CPU sprites Count = CPUSpriteRightNo While CPUSpriteVisible[Count] = False And Count >= CPUSpriteLeftNo // check the next sprite (to the left) Count = Count - 1 End While // set the current right-most CPU sprite CPUSpriteRightNo = Count // hide the sprite HideSprite("UserMissile") // set the user missile active flag to false UserMissileActive = False End If // check if off the top of the screen If UserMissilePosY + GetSpriteHeight("UserMissile") <= 0 Then // hide the sprite HideSprite("UserMissile") // set the user missile active flag to false UserMissileActive = False End If End If // set the time last checked TimeLastUserMissile = TimeCurrent End If // handle user missile // check time passed since movement checked TimeCurrent = TickCount() If TimeCurrent - TimeLastCPU > CPUSpriteSpeeds[CPUSpriteSpeedNo] Then // move CPU sprites (horizontally) For Count = CPUSpriteLeftNo To CPUSpriteRightNo If CPUSpriteMoveRight Then CPUSpriteLeft[Count] = CPUSpriteLeft[Count] + 5 Else CPUSpriteLeft[Count] = CPUSpriteLeft[Count] - 5 End If MoveSpriteToPoint("CPU" + Count, CPUSpriteLeft[Count], CPUSpriteTop) Next // check direction of movement // check for left- or right-most sprites at edge of screen If CPUSpriteLeft[CPUSpriteLeftNo] <= 5 Or CPUSpriteLeft[CPUSpriteRightNo] >= (ScreenWidth() - GetSpriteWidth("CPU5") - 5) Then // reverse direction CPUSpriteMoveRight = Not CPUSpriteMoveRight // move CPU sprites down CPUSpriteTop = CPUSpriteTop + GetSpriteHeight("CPU1") For Count = CPUSpriteLeftNo To CPUSpriteRightNo MoveSpriteToPoint("CPU" + Count, CPUSpriteLeft[Count], CPUSpriteTop) Next // increase speed (unless already at maximum speed) If Not CPUSpriteSpeedNo = ArrayLength(CPUSpriteSpeeds) Then CPUSpriteSpeedNo = CPUSpriteSpeedNo + 1 End If End If // set the time last checked TimeLastCPU = TimeCurrent End If // handle CPU movement // check CPU missiles // check for game over (collision inloving user sprite or CPU sprites too low) GameOver = (ArrayLength(GetSpritesThatIntersectWith("User")) > 0) Or (CPUSpriteTop + GetSpriteHeight("CPU1") - 10 > GetSpriteTop("User")) // check for next level If LevelUp Then // play sound? Delay(1000) // clear sprites ClearSprites() // display message SetFont("Arial Black", 48, False, False, False) PrintLine("LEVEL UP") // temp PrintLine("(END)") GameOver = True // display initial screen (sprites) End If End While // game over // play sound? Delay(1000) // clear sprites ClearSprites() // display game over SetFont("Arial Black", 48, False, False, False) PrintLine("GAME OVER") // show scores, etc. // ask if high score should be saved // ask if user wants to play again End Method // SubStr function written by Gert on the Phrogram forums: http://phrogram.com/forums/thread/696.aspx // Required as Substring function has a bug in KPL Function SubStr(Text As String, Start As Int, Length As Int) As String Define Result As String Define MaxPosition As Int Define xx As Int MaxPosition = Start + length - 1 If StringLength(Text) < MaxPosition Then MaxPosition = StringLength(Text) End If For xx = Start To MaxPosition Result = Result + Substring(Text, xx, 1) Next Return Result End Function End Program