| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506 |
- ' *******************************************************************
- ' Digesteroids - V1.0
- ' --------------------------------------------------------
- ' An evil biscuit corporation are using their army of
- ' sweet snack food to take over the world. Use your ship
- ' to take down the evil invading corporation before
- ' they infest the world with dunkables sweetmeal biscuits.
- ' REQUIRES 1024x768x32! @75Hz
- ' --------------------------------------------------------
- ' Author: Rob Hutchinson 2004
- ' Email: [email protected]
- ' Written entirely in Protean IDE:
- ' WWW: http://www.proteanide.co.uk/
- ' --------------------------------------------------------
- ' Yep, there's stuff in here, I didnt get time to implement
- ' Pickups, Weapons and Vortexes.
- ' *******************************************************************
-
- Strict
- Framework SDL.SDLRenderMax2D
- Import brl.pngloader
- Import brl.wavloader
- Import brl.oggloader
- Import brl.Random
- Import sdl.sdlfreeaudio
- Import Brl.StandardIO 'for debuglog()
- ' Import various utilities.
- Import "simplephysics.bmx"
- Import "dynamicgame.bmx"
- Import "MathUtil.bmx"
- SetAudioDriver("FreeAudio SDL")
- ' Screen settings.
- Const WIDTH = 1024 ' Width of the screen.
- Const HEIGHT = 768 ' Height of the screen.
- Const DEPTH = 0 ' Depth of the screen.
- Const REFRESHRATE = 75 ' How often to update the screen (Per second).
- ' Game Settings
- Const DYNAMICTIMING = True ' If true then the game will try to keep up with
- Const DESIREDFPS = 75 ' The Desired FPS of the game, can be independant of Refresh Rate.
- Function ScreenPan(OffsetX:Float, OffsetY:Float)
- ' Local Width,Height,Depth,Hz
- ' Width=GraphicsWidth()
- ' Height=GraphicsHeight()
- ' Depth=GraphicsDepth()
- ' Hz=GraphicsHertz()
- ' glMatrixMode GL_PROJECTION
- ' glLoadIdentity
- ' glOrtho 0,Width,Height,0,-1,1
- 'glTranslatef OffsetX, OffsetY,0
- 'glMatrixMode GL_MODELVIEW
- EndFunction
- Function QFlushKeys()
- ' Quick implementation of flushkeys as BMX doesnt have one at time of writing, sure it
- ' will be added though.
- For Local Key:Int = 0 To 255
- KeyHit(Key)
- KeyDown(Key)
- Next
- End Function
- '#Region Scene: MainMenu
- ' The main menu scene.
- Type MainMenuScene Extends T2DDynamicGameScene
- '#Region DrawTextCentered
- Function DrawTextCentered:Int(Text:String,Y:Int)
- Local Out:Int = (WIDTH / 2) - (TextWidth(Text) / 2)
- DrawText(Text, Out, Y)
- Return Out
- End Function
- '#End Region
- '#Region Declarations
- Const STARS_PER_SECOND = 6
- Field BackColor:Float
- Field Direction:Float = 0.01
- Field ExitGame:Int = False
- Field Music:TSound
- Field MusicChannel:TChannel
- Field Title:TImage
- Field LowerTitle:TImage
- Field Options:TImage
- Field Craft:TImage
- Field EnteredText:String = ""
- Field LastHighScore:Int
- Field ShowCredits:Int = False
- Field Viewing:Int = VIEW_MENU
- Field HoverOver:Int = VIEW_START
- Const VIEW_MENU = 0
- Const VIEW_START = 0
- Const VIEW_INSTRUCTIONS = 1
- Const VIEW_HIGHSCORES = 2
- Const VIEW_QUIT = 3
- Const VIEW_ENTERHIGH = 4
- Field Stars:TPhysicsProviderCollection = New TPhysicsProviderCollection
- Field World:TWorldPhysicsProvider = TWorldPhysicsProvider.Create(0.0, 0.0, 0.0, True)
- '#End Region
- '#Region Method: FinishScoreEntry
- Method FinishScoreEntry()
- Self.ViewMenu(VIEW_HIGHSCORES)
- Scores.Add(Self.LastHighScore, Self.EnteredText)
- ' Add this to the high scores..
- Self.LastHighScore = 0
- Self.EnteredText = ""
- End Method
- '#End Region
- '#Region Method: ViewMenu
- Method ViewMenu(Menu:Int)
- Self.Viewing = Menu
- Self.HoverOver = Menu
- QFlushKeys()
- End Method
- '#End Region
- '#Region Method: Update
- Method Update()
- Self.Stars.ApplyPhysics()
- ' Add new stars..
- For Local CountStars:Int = 0 To STARS_PER_SECOND
- Local Star:TMenuStar = TMenuStar.Create(World, Self, 10.0)
- Self.Stars.AddLast(Star)
- Next
- ' Do enter key checking..
- Select Self.Viewing
- Case VIEW_MENU
- If KeyHit(KEY_ENTER) Then
- Select Self.HoverOver
- Case VIEW_START
- Self.TerminateMainLoop = True
-
- Case VIEW_INSTRUCTIONS
- Self.ViewMenu(VIEW_INSTRUCTIONS)
-
- Case VIEW_HIGHSCORES
- Self.ViewMenu(VIEW_HIGHSCORES)
-
- Case VIEW_QUIT
- Self.TerminateMainLoop = True
- Self.ExitGame = True
-
- End Select
- EndIf
- If KeyHit(KEY_UP)
- Self.HoverOver :- 1
- If Self.HoverOver < VIEW_START Then Self.HoverOver = VIEW_START
- EndIf
- If KeyHit(KEY_DOWN)
- Self.HoverOver :+ 1
- If Self.HoverOver > VIEW_QUIT Then Self.HoverOver = VIEW_QUIT
- EndIf
- If KeyHit(KEY_ESCAPE) Then
- Self.TerminateMainLoop = True
- Self.ExitGame = True
- Else
- If KeyHit(KEY_C)
- Self.TerminateMainLoop = True
- Self.ShowCredits = True
- EndIf
- EndIf
- Case VIEW_INSTRUCTIONS, VIEW_HIGHSCORES
- If KeyHit(KEY_ENTER) Or KeyHit(KEY_ESCAPE)
- Self.Viewing = VIEW_MENU
- EndIf
- Case VIEW_ENTERHIGH
- ' Check for alpha keys.
- For Local Count:Int = KEY_A To KEY_Z
- If KeyHit(Count) Then Self.EnteredText = Self.EnteredText + Chr(Count)
- Next
- ' Check for number key hits
- For Local Count:Int = KEY_0 To KEY_9
- If KeyHit(Count) Then Self.EnteredText = Self.EnteredText + Chr(Count)
- Next
- ' Special case, check for space bar
- If KeyHit(KEY_SPACE)
- Self.EnteredText = Self.EnteredText + " "
- EndIf
- ' Remove a character when user hits backspace.
- If KeyHit(KEY_BACKSPACE)
- If Len(Self.EnteredText) > 0
- Self.EnteredText = Self.EnteredText[..Len(Self.EnteredText)]
- EndIf
- EndIf
- ' If 5 characters are entered, end high score entry.
- If Len(Self.EnteredText) = 5 Then Self.FinishScoreEntry()
-
- If KeyHit(KEY_ENTER)
- Self.FinishScoreEntry()
- EndIf
- End Select
- End Method
- '#End Region
- '#Region Method: Render
- Method Render()
- Cls
- ScreenPan(0,0)
- SetTransform
- SetAlpha 1.0
- SetBlend(SOLIDBLEND)
- Self.Stars.Draw()
- SetColor 255,255,255
- SetBlend(ALPHABLEND)
- DrawImage(Self.Title,0,40)
- DrawImage(Self.LowerTitle,0,660)
- Local StartPosX:Int = 150
- Local StartPosY:Int = 245
- Select Self.Viewing
- Case VIEW_MENU
- ' Showing main menu
- DrawImage(Self.Options,450,330)
- SetRotation -90
- Select Self.HoverOver
- Case VIEW_START
- DrawImage(Self.Craft,416,352)
-
- Case VIEW_INSTRUCTIONS
- DrawImage(Self.Craft,416,352 + 37)
-
- Case VIEW_HIGHSCORES
- DrawImage(Self.Craft,416,352 + 74)
-
- Case VIEW_QUIT
- DrawImage(Self.Craft,416,352 + 145)
-
- End Select
- Case VIEW_HIGHSCORES
- Scores.Render(385,310)
- Case VIEW_ENTERHIGH
- DrawTextCentered("CONGRATULATIONS!",StartPosY)
- DrawTextCentered("You have a new high score!",StartPosY+50)
- DrawTextCentered("Please enter your name (5 characters)",StartPosY+65)
- Local TextX:Int = DrawTextCentered(Self.EnteredText,StartPosY+250)
- DrawRect(TextX + TextWidth(Self.EnteredText), StartPosY+250, 12, 15)
- Case VIEW_INSTRUCTIONS
- DrawText("Welcome to Digesteroids!",StartPosX,StartPosY)
- DrawText("------------------------",StartPosX,StartPosY+20)
- DrawText("An evil biscuit corporation are using their army of sweet snack food to take over the world.",StartPosX,StartPosY+50)
- DrawText("Fortunately, the ingredients the evil corporation used are vulnerable to big sweaty laser",StartPosX,StartPosY+70)
- DrawText("blasts. Use your ship's cannon to take out the corporation before they infest the world with",StartPosX,StartPosY+90)
- DrawText("sweetmeal dunkables biscuits. But be careful, space is small (just big enough to fit inside",StartPosX,StartPosY+110)
- DrawText("your screen), it is also cyclical, so beware of incoming oval shaped objects.",StartPosX,StartPosY+130)
- DrawText("Keys:",StartPosX,StartPosY+180)
- DrawText(" - UP CURSOR ARROW = Thrust",StartPosX,StartPosY+200)
- DrawText(" - DOWN CURSOR ARROW = Teleport",StartPosX,StartPosY+220)
- DrawText(" - LEFT CURSOR ARROW = Rotate Ship Left",StartPosX,StartPosY+240)
- DrawText(" - RIGHT CURSOR ARROW = Rotate Ship Right",StartPosX,StartPosY+260)
- DrawText(" - ESCAPE = QUIT",StartPosX,StartPosY+280)
- DrawText("Yes, that's right, it's a glorified asteroids game!",StartPosX,StartPosY+320)
- SetColor 255,0,0
- DrawText("Note: Your score is based on the speed at which your ship is travelling when it fired.",StartPosX,StartPosY+340)
- End Select
- End Method
- '#End Region
- '#Region Method: Start
- Method Start()
- Self.MusicChannel = AllocChannel()
- If Self.Music = Null Then Self.Music = LoadSound("sounds\menu.ogg",True)
- PlaySound(Self.Music,Self.MusicChannel)
- SetChannelVolume MusicChannel,1.0
- ' Load GFX..
- If Self.Title = Null Then Self.Title = LoadImage("graphics\title.png")
- If Self.LowerTitle = Null Then Self.LowerTitle = LoadImage("graphics\lower.png")
- If Self.Options = Null Then Self.Options = LoadImage("graphics\options.png")
- If Self.Craft = Null Then Self.Craft = LoadImage("graphics\ship.png")
- ' Add a screen full of stars.
- For Local CountStars:Int = 0 To 1000
- Local Star:TMenuStar = TMenuStar.Create(World, Self, 10.0)
- Star.X = Rnd(WIDTH)
- Self.Stars.AddLast(Star)
- Next
- End Method
- '#End Region
- '#Region Method: Finish
- Method Finish()
- Self.Stars.Clear()
- Self.MusicChannel.Stop()
- Self.MusicChannel = Null
- End Method
- '#End Region
-
- End Type
- '#End Region
- '#Region Scene: MainGame
- ' Main Game scene
- Type MainGameScene Extends T2DDynamicGameScene
- '#Region Declarations
- Const STARS_PER_SECOND = 3
- Const FINISH_AT_LEVEL = 6
- Field Level:Int = 1
- Field Completed:Int = False
-
- Field DigestiveImage:TImage
- Field ShipImage:TImage
- Field StarsImage:TImage
- Field LargeImpactSound:TSound
- Field World:TWorldPhysicsProvider = TWorldPhysicsProvider.Create(0.0, 0.0, 0.0, True)
- Field Digestives:TPhysicsProviderCollection = New TPhysicsProviderCollection
- Field Bullets:TPhysicsProviderCollection = New TPhysicsProviderCollection
- Field Stars:TPhysicsProviderCollection = New TPhysicsProviderCollection
- Field Chunks:TFountain
- Const CHUNK_COUNT = 2
- Field ChunkImages:TImage[CHUNK_COUNT + 1]
- Field Player:TPlayer
- Field Shake:Float
- Field Pickups:TList = New TList
- '#End Region
- '#Region Method: Update
- Method Update()
- If KeyHit(KEY_ESCAPE) Then Self.TerminateMainLoop = True
- CheckEndOfLevel() ' Check if we need to move to the next level (IE, all digestives gone)
- ' Add new stars..
- For Local CountStars:Int = 0 To STARS_PER_SECOND
- Local Speed:Float = Self.Player.Speed()
- If Speed < 1.0 Then Speed = 1.0
- Local Star:TStar = TStar.Create(World, Self, Speed)
- Self.Stars.AddLast(Star)
- Next
- ' Update screenshake...
- Self.Shake :/ 1.02
- If Self.Shake < 0.0 Then Self.Shake = 0.0
- If Self.Shake > 6.0 Then Self.Shake = 6.0
- ' Update all the stars.
- Self.Stars.ApplyPhysics()
- ' Update the chunks
- Self.Chunks.UpdateWithFriction(TPhysicsProvider.AxisX | TPhysicsProvider.AxisY)
- ' Update all the digestives.
- Self.Digestives.ApplyPhysics()
- ' Update all the bullets.
- Self.Bullets.ApplyPhysics()
- ' Update the player.
- Self.Player.Update()
- Self.Player.ApplyFriction(TPhysicsProvider.AxisX | TPhysicsProvider.AxisY)
- Self.Player.ApplyPhysics()
- End Method
- '#End Region
- '#Region Method: Render
- Method Render()
- SetClsColor 0,0,0
- Cls
-
- If Self.Shake > 0.0 Then
- ScreenPan(Float(Rnd(Shake)),Float(Rnd(Shake)))
- EndIf
- ' Draw the spazzy psychodelic effect if it is enabled.
- Self.DrawPsychodelic()
-
- SetAlpha 1
- SetTransform
- ' Draw all the stars.
- Self.Stars.Draw()
- Self.Chunks.Draw()
- ' Draw the digestives.
- SetColor 255,255,255
- SetBlend(ALPHABLEND)
- Digestives.Draw()
- ' Draw the bullets
- SetBlend(LIGHTBLEND)
- Bullets.Draw()
-
- ' Draw the player.
- SetBlend(ALPHABLEND)
- Player.Draw()
- ' Draw the hud
- DrawHUD()
- End Method
- '#End Region
- '#Region Method: Start
- Method Start()
- AutoMidHandle True
- Self.Shake = 0
- Self.Chunks = TFountain.Create(Self.World,TRectangle.Create(0,0,WIDTH,HEIGHT))
- ' Load in the required Images...
- If Self.DigestiveImage = Null Then Self.DigestiveImage = LoadImage("graphics\digestive.png")
- If Self.ShipImage = Null Then Self.ShipImage = LoadImage("graphics\ship.png")
- If Self.StarsImage = Null Then Self.StarsImage = LoadImage("graphics\stars.png")
- For Local LoadCount:Int = 0 To CHUNK_COUNT
- Self.ChunkImages[LoadCount] = LoadImage("graphics\piece" + String(LoadCount + 1) + ".png")
- Next
- ' Set up the player
- Self.Player = TPlayer.Create(Self.World, Self.ShipImage,Self)
- Self.Player.LoadAssets()
- ' Load up the sounds.
- If Self.LargeImpactSound = Null Then Self.LargeImpactSound = LoadSound("sounds\impactlarge.wav")
- ' Reset the game..
- Self.ResetGame()
- ' Create all the weapons..
- Self.Pickups.Clear()
- Local Bullet1Image:TImage = LoadImage("graphics\bullet1.png")
- Local Fire1Sound:TSound = LoadSound("sounds\fire.wav")
- ' Local Blaster:TWeapon = TWeapon.Create(Speed,Graphic,Size,Radius,Veer,FireRate,MainGame,Sound)
- Local Blaster:TWeapon = TWeapon.Create(10, Bullet1Image, 0.65, 4.0, 0,30, Self, Fire1Sound, Bullet1Image, "Blaster")
- Local FastBlaster:TWeapon = TWeapon.Create(9, Bullet1Image, 0.3, 4.0, 0.0, 15, Self, Fire1Sound, Bullet1Image, "Blaster Mk2")
- Local SprayBlaster:TWeapon = TWeapon.Create(8, Bullet1Image, 0.35, 4.0, 5.0, 1, Self, Fire1Sound, Bullet1Image, "Blaster Mk3")
- Local BlasterPickup:TPickup = TPickup.Create(TPickup.MODIFIER_WEAPON,0,0,True,Blaster,Bullet1Image,0.01,Bullet1Image)
- Local FastBlasterPickup:TPickup = TPickup.Create(TPickup.MODIFIER_WEAPON,0,0,True,FastBlaster,Bullet1Image,0.01,Bullet1Image)
- Local SprayBlasterPickup:TPickup = TPickup.Create(TPickup.MODIFIER_WEAPON,0,0,True,SprayBlaster,Bullet1Image,0.008,Bullet1Image)
- Local Score1000Pickup:TPickup = TPickup.Create(TPickup.MODIFIER_SCORE,1000,0,True,Null,Null,0.02,Bullet1Image)
- Local Score500Pickup:TPickup = TPickup.Create(TPickup.MODIFIER_SCORE,500,0,True,Null,Null,0.03,Bullet1Image)
- Local RotationPickup:TPickup = TPickup.Create(TPickup.MODIFIER_ROTATION,1.1,0,True,Null,Null,0.01,Bullet1Image)
- Local PsychodelicPickup:TPickup = TPickup.Create(TPickup.MODIFIER_PSYCHODELIC,0,1000,False,Null,Null,0.04,Bullet1Image)
- Local LivesPickup:TPickup = TPickup.Create(TPickup.MODIFIER_LIVES,1,0,True,Null,Null,0.001,Bullet1Image)
- Self.Player.Weapon = Blaster
- End Method
- '#End Region
- '#Region Method: Finish
- Method Finish()
- Self.Player.ThrusterChannel.Stop
- Self.Player.ThrusterChannel = Null
- End Method
- '#End Region
-
- '#Region Method: CheckEndOfLevel
- Method CheckEndOfLevel()
- If Digestives.IsEmpty() = True
- ' No more digestives..
- Level :+ 1
- If Level = FINISH_AT_LEVEL Then
- ' This was the last level.
- Self.Completed = True
- Self.TerminateMainLoop = True
- Else
- ' Move to the next level
- GotoLevel(Level)
- EndIf
- EndIf
- End Method
- '#End Region
- '#Region Method: DrawHUD
- Method DrawHUD()
- SetColor 255,255,255
- SetAlpha 1.0
- SetRotation 0
- DrawText "Level: " + Level,0,0
- Local Lives:String = "Lives: " + Player.Lives
- Local Score:String = "Score: " + Player.Score
- DrawText Score,(WIDTH / 2) - (TextWidth(Score) / 2) ,0
- DrawText Lives,(WIDTH - TextWidth(Lives)) ,0
-
- Local fr$="000"+Int(Self.Player.Speed()*1000) Mod 1000
- Local sp$=Int(Self.Player.Speed()*1000)/1000+"."+fr[fr.length-3..]
-
- DrawText "Speed: " + sp,0,15
- DrawText "Teleports: " + Self.Player.Teleports,0,30
- End Method
- '#End Region
- '#Region Method: ResetGame
- Method ResetGame()
- Digestives.Clear()
- Bullets.Clear()
- Stars.Clear()
- Chunks.Particles.Clear()
- Player.Lives = 5
- Player.Reset()
- GotoLevel(1)
- End Method
- '#End Region
- '#Region Method: GotoLevel
- Method GotoLevel(ToLevel:Int)
- Level = ToLevel
- For Local Count:Int = 1 To ToLevel
- Local Digestive:TDigestive = TDigestive.Create(World, DigestiveImage,Self)
- Digestive.X = Rnd(0,WIDTH)
- Digestive.Y = Rnd(0,HEIGHT)
- Digestive.Rotation = Rnd(360)
- Digestive.Weight = 5
- Digestive.SetVelocityFromAngle(Rnd(360.0),Rnd(0.5,1.5))
- Digestive.HitSound = Self.LargeImpactSound
- Digestives.AddLast(Digestive)
- Next
- End Method
- '#End Region
- '#Region Method: DrawPsychodelic
- Field PsychoAngle:Float = 0
- Field Psycho:Int = False
-
- Method DrawPsychodelic()
- If Psycho = True
- SetColor Int(Rnd(0.0,255)),Int(Rnd(0.0,255)),Int(Rnd(0.0,255))
- PsychoAngle :+ 8
- SetBlend(SOLIDBLEND)
- TileImage(StarsImage,Float(Sin(PsychoAngle) * 200),Float(Cos(PsychoAngle) * 200))
- Else
- SetColor 255,255,255
- EndIf
- End Method
- '#End Region
- '#Region Method: FindSafeLocation
- Method FindSafeLocation:TPointD(Radius:Float)
- While True
- Local X:Int = Rnd(0,WIDTH)
- Local Y:Int = Rnd(0,HEIGHT)
- If Self.IsLocationSafe(X,Y,Radius)
- Local Out:TPointD = New TPointD
- Out.X = X
- Out.Y = Y
- Return Out
- EndIf
- Wend
- End Method
- '#End Region
- '#Region Method: IsLocationSafe
- Method IsLocationSafe:Int(X:Int,Y:Int,Radius:Float)
- Local TryCircle:TCircle = New TCircle
- TryCircle.X = X
- TryCircle.Y = Y
- TryCircle.Radius = Radius
- For Local Item:TDigestive = EachIn Self.Digestives
- If Item.Circle.CollidesWith(TryCircle)
- Return False
- EndIf
- Next
- Return True
- End Method
- '#End Region
- End Type
- '#End Region
- '#Region Scene: Ending
- ' The ending scene.
- Type EndingScene Extends T2DDynamicGameScene
-
- '#Region Declarations
- Const STARS_PER_SECOND = 0
- Const MAGNET_COUNT = 5
- Field ScrollPoint:Float
- Field Music:TSound
- Field MusicChannel:TChannel
- Field Title:TImage
- Field Time:Int = 1000000
- Field TEXTS_COUNT = 23
- Field Texts:String[TEXTS_COUNT]
- Field Stars:TPhysicsProviderCollection = New TPhysicsProviderCollection
- Field World:TWorldPhysicsProvider = TWorldPhysicsProvider.Create(0.2, 0.0, 0.0, True)
- '#End Region
- '#Region Method: Update
- Method Update()
- Self.Stars.ApplyPhysics()
- If KeyHit(KEY_ESCAPE) Then
- Self.TerminateMainLoop = True
- EndIf
- Self.Time :+ 1
- If Self.Time > 100 Then
- Self.Time = 0
- ' Add a new magnet
- Local ThisMagnet:TEndMagnet = New TEndMagnet
- ThisMagnet.X = Rnd(WIDTH)
- ThisMagnet.Y = Rnd(HEIGHT)
- ThisMagnet.Radius = Rnd(200,500)
- ThisMagnet.Polarity = TMagnet.PositivePolarity
- ThisMagnet.Strength = Rnd(0.1,0.5)
- Self.World.Magnets.AddLast(ThisMagnet)
- Self.World.ApplyMagnets = True
- EndIf
- Local X:Int = WIDTH/2
- Local Y:Int = HEIGHT/2
- For Local Magnet:TEndMagnet = EachIn Self.World.Magnets
- For Local Count:Int = 0 To STARS_PER_SECOND
- Local ThisStar:TEndingStar = TEndingStar.Create(Self.World, Self, Float(Rnd(1.0,5.0)), Int(Magnet.X + (Sin(Rnd(360.0)) * 5.0)), Int(Magnet.Y + (Cos(Rnd(360.0)) * 5.0)))
- ThisStar.SetVelocityFromAngle(Rnd(360),Rnd(1.0,5.0))
- Self.Stars.AddLast(ThisStar)
- Magnet.Stars :+ 1
- Next
- If Magnet.Stars > 500 Then
- Self.World.Magnets.Remove(Magnet)
- EndIf
- Next
- ' Update the scoller
- Self.ScrollPoint :- 0.5
- If Self.Scrollpoint < -((TEXTS_COUNT * 25) + 100)
- Self.ScrollPoint = HEIGHT + 20
- EndIf
-
- End Method
- '#End Region
- '#Region Method: Render
- Method Render()
- Cls
- Self.Stars.Draw()
- SetColor 255,255,255
- For Local Count:Int = 0 To TEXTS_COUNT - 1
- MainMenuScene.DrawTextCentered(Self.Texts[Count],Int(Self.ScrollPoint + (25 * Count)))
- Next
- End Method
- '#End Region
- '#Region Method: Start
- Method Start()
- Self.MusicChannel = AllocChannel()
- If Self.Music = Null Then Self.Music = LoadSound("sounds\ending.ogg",True)
- If Self.MusicChannel <> Null
- PlaySound(Self.Music,Self.MusicChannel)
- EndIf
- Self.Texts[0] = "Cast of Characters"
- Self.Texts[1] = "------------------"
- Self.Texts[2] = ""
- Self.Texts[3] = "Space Craft.......................Intrepid"
- Self.Texts[4] = "Digestive...............Sweet Meal Biscuit"
- Self.Texts[5] = "Star...............................Himself"
- Self.Texts[6] = ""
- Self.Texts[7] = "Written by Rob Hutchinson in roughly 5 days."
- Self.Texts[8] = "Email: [email protected]"
- Self.Texts[9] = "Web: http://www.proteanide.co.uk/"
- Self.Texts[10] = ""
- Self.Texts[11] = "Special Thanks To"
- Self.Texts[12] = "-----------------"
- Self.Texts[13] = "Richard Makepeace.............Inspiration"
- Self.Texts[14] = "James Readman.................Inspiration"
- Self.Texts[15] = ""
- Self.Texts[16] = "Greets"
- Self.Texts[17] = "------"
- Self.Texts[18] = "Pickup, Cabsy, Peters, ZanaX, Compona, Helen, + all other family and friends."
- Self.Texts[19] = ""
- Self.Texts[20] = ""
- Self.Texts[21] = ""
- Self.Texts[22] = "Thank you for playing."
- Self.ScrollPoint = HEIGHT + 20
- End Method
- '#End Region
- '#Region Method: Finish
- Method Finish()
- Self.Stars.Clear()
- If Self.MusicChannel <> Null Then
- Self.MusicChannel.Stop()
- Self.MusicChannel = Null
- EndIf
- End Method
- '#End Region
- End Type
- '#End Region
- Type TCircle
-
- Field X:Int
- Field Y:Int
- Field Radius:Float
-
- Method CollidesWith:Int(Circle:TCircle)
- Local Distance:Double = TPhysicsUtility.DistanceBetweenPoints(Self.X,Self.Y,Circle.X,Circle.Y)
- If Distance < (Self.Radius + Circle.Radius) Then Return True
- Return False
- End Method
- Method Draw()
- SetBlend(ALPHABLEND)
- SetAlpha(0.5)
- SetRotation 0
- DrawCircle(X,Y,Int(Radius))
- End Method
- Function DrawCircle(X,Y,Radius)
- DrawOval(X - Radius,Y - Radius,Radius * 2,Radius * 2)
- End Function
- End Type
- Type TDigestive Extends TPhysicsProvider
- Field Image:TImage
- Field Alpha:Float = 1.0
- Field Rotation:Float = 0
- Field Scale:Float = 1.0
- Field Circle:TCircle = New TCircle
- Field GameScene:MainGameScene
- Const InitialRadius:Float = 70.0
- Field HitSound:TSound
- Method SplitIntoChunks(X:Int,Y:Int,Multiplier:Float)
- GameScene.Digestives.Remove(Self)
- Local Channel:TChannel = AllocChannel()
- If Channel <> Null
- Channel.SetVolume(Self.Scale)
- PlaySound(Self.HitSound, Channel)
- EndIf
- Self.GameScene.Chunks.X = X
- Self.GameScene.Chunks.Y = Y
-
- Self.GameScene.Player.Score :+ Int(((Self.Scale * 100.0) + 4.0) * Multiplier)
- Self.GameScene.Shake :+ (Self.Scale * 3.5)
-
- If Self.Scale > 0.2
- For Local Count:Int = 0 To Int(Self.Scale * 5)
- Local Digestive:TDigestive = TDigestive.Create(Self.World, Self.Image, Self.GameScene)
- Digestive.X = Self.X
- Digestive.Y = Self.Y
- Digestive.Rotation = Rnd(360)
- Digestive.Weight = 5
- Digestive.SetVelocityFromAngle(Rnd(360.0),Rnd(0.5,1.5))
- Digestive.SetDrawScale(Self.Scale / 2)
- Digestive.HitSound = Self.HitSound
- GameScene.Digestives.AddLast(Digestive)
- Next
- For Local ChunkCount:Int = 0 To 4 * (Self.Scale * 10)
- Local Particle:TStaticParticle = Self.GameScene.Chunks.AddStaticParticle(Self.GameScene.ChunkImages[(Int(Rnd(0,MainGameScene.CHUNK_COUNT)))], Float(Rnd(360.0)), Float(Rnd(0.5,10.0)), 0, 0.01, [255,255,255])
- Particle.Friction = 0.97
- Particle.Size = Rnd(0.5,1.0)
- Particle.Rotation = Rnd(-5.0,5.0)
- Next
- Else
- For Local ChunkCount2:Int = 0 To Rnd(3,8)
- Local Particle:TStaticParticle = Self.GameScene.Chunks.AddStaticParticle(Self.GameScene.ChunkImages[(Int(Rnd(0,MainGameScene.CHUNK_COUNT)))], Float(Rnd(360.0)), Float(Rnd(0.5,10.0)), 0, 0.01, [255,255,255])
- Particle.Friction = 0.97
- Particle.Size = Rnd(0.2,0.5)
- Particle.Rotation = Rnd(-5.0,5.0)
- Next
- End If
- End Method
- Method Draw()
- SetAlpha Self.ALPHA
- SetRotation Self.Rotation
- SetScale Self.Scale,Self.Scale
- DrawImage(Self.Image, Float(Self.X), Float(Self.Y))
- SetScale 1,1
- End Method
- Method SetDrawScale(Scale:Float)
- Self.Scale = Scale
- Self.Circle.Radius = Self.InitialRadius * Self.Scale
- End Method
- Method PhysicsApplied()
- Rotation:+2
- Local HalfWidth:Int = ((Image.Width * Self.Scale) / 2)
- Local HalfHeight:Int = ((Image.Height * Self.Scale) / 2)
- If X < -HalfWidth Then X = WIDTH + HalfWidth
- If Y < -HalfHeight Then Y = HEIGHT + HalfHeight
- If X > WIDTH + HalfWidth Then X = -HalfWidth
- If Y > HEIGHT + HalfHeight Then Y = -HalfHeight
- Self.Circle.X = Self.X
- Self.Circle.Y = Self.Y
- End Method
- Function Create:TDigestive(World:TWorldPhysicsProvider,Image:TImage,GameScene:MainGameScene)
- Local Out:TDigestive = New TDigestive
- Out.GameScene = GameScene
- Out.Circle.Radius = InitialRadius
- Out.World = World
- Out.Image = Image
- Return Out
- End Function
- End Type
- Type TPlayer Extends TPhysicsProvider
- Field Lives:Int
- Field Score:Int
- Field Weapon:TWeapon
- Field Dead:Int = True
- Field Teleports:Int = 2
- Field Image:TImage
- Field Rotation:Float
- Field Acceleration:Float
- Field MaxAcceleration:Float = 4.0
- Field Motion:Float = 0.001
- Field AccelerationDropMultiplier:Float = 8
- Field Circle:TCircle = New TCircle
- Field GameScene:MainGameScene
- Field FireRateCount:Float = 0
- Field Thruster:TFountain
- Field Death:TFountain
- Field ThrusterImage:TImage
- Field DeathImage:TImage
- Field SparkleImage:TImage
- Field ThrusterSound:TSound
- Field CrashSound:TSound
- Field ThrusterChannel:TChannel
- Field TeleportSound:TSound
- Method Draw()
- SetTransform
- ' Render the thruster...
- SetBlend LIGHTBLEND
- SetScale 0.6, 0.6
- SetAlpha 1.0
- Self.Thruster.Draw()
- Self.Death.Draw()
- If Not Self.Dead Then
- ' Render the player.
- SetBlend ALPHABLEND
- SetAlpha 1.0
- SetScale 1.0,1.0
- SetColor 255,255,255
- SetRotation 360 - Self.Rotation
- DrawImage(Self.Image, Float(Self.X), Float(Self.Y))
- EndIf
- End Method
- Method PhysicsApplied()
- Local HalfWidth:Int = (Image.Width / 2)
- Local HalfHeight:Int = (Image.Height / 2)
- If X < -HalfWidth Then X = WIDTH + HalfWidth
- If Y < -HalfHeight Then Y = HEIGHT + HalfHeight
- If X > WIDTH + HalfWidth Then X = -HalfWidth
- If Y > HEIGHT + HalfHeight Then Y = -HalfHeight
- Self.Circle.X = Self.X
- Self.Circle.Y = Self.Y
- End Method
- Method Update()
- ' Update thruster and death particles.
- Local Particle:TStaticParticle = Self.Thruster.AddStaticParticle(Self.ThrusterImage, Float(Self.Rotation + 180 + Rnd(-5.0,5.0)), 1.0, 1, 0.04, [255,255,255])
-
- Local ActualRotation:Float = Self.Rotation + 180
- Self.Thruster.X = Self.X + (Sin(ActualRotation) * 10)
- Self.Thruster.Y = Self.Y + (Cos(ActualRotation) * 10)
- Local ThisSpeed:Float = Self.Speed()
-
- If ThisSpeed < 0 Then ThisSpeed = 0
- If ThisSpeed > 10.0 Then ThisSpeed = 10.0
-
- ' Add particles to the thruster..
- Particle.Size = (ThisSpeed / 10)
- Self.ThrusterChannel.SetVolume(ThisSpeed / 10)
- Self.ThrusterChannel.SetPan(Float(Self.X / Float(WIDTH / 2.0) - 1.0))
- Self.GameScene.Shake:+ 0.10 * (ThisSpeed / 10.0)
- Self.Thruster.Update()
- Self.Death.UpdateWithFriction(TPhysicsProvider.AxisX | TPhysicsProvider.AxisY)
-
- If Self.Dead
- ' Player is currently dead, wait for a nice chance to put them back down.
- If Self.Lives < 1 Then
- ' Wait for the death particles to become zeroed.
- If Self.Death.Particles.IsEmpty() Then
- Self.GameScene.TerminateMainLoop = True
- EndIf
- Else
- ' Check to see if the center spot is safe to plop the ship on.
- If Self.GameScene.IsLocationSafe(WIDTH/2, HEIGHT/2, 70)
- Self.Dead = False
- For Local Pops:Int = 0 To 200
- Local Particle:TStaticParticle = Self.Death.AddStaticParticle(Self.SparkleImage, Float(Rnd(360.0)), Float(Rnd(0.5,2.0)), 0, Float(Rnd(0.01, 0.03)), [255,255,255])
- Particle.X = Self.X
- Particle.Y = Self.Y
- Particle.Rotation = Rnd(-1.0,1.0)
- Particle.Friction = 0.97
- Particle.Size = Rnd(0.1,0.2)
- Next
- EndIf
- EndIf
- Else
- ' Update fire rate counter...
- Self.FireRateCount :- 1
-
- If KeyDown(KEY_UP)
- ' Thrust
- Self.Acceleration :+ Self.Motion
- ' Clamp the acceleration
- If Self.Acceleration > Self.MaxAcceleration Then Self.Acceleration = Self.MaxAcceleration
- ' Add acceleration.
- Self.IncreaseVelocityFromAngle(Self.Rotation,Self.Acceleration)
- Else
- Self.Acceleration :- (Self.Motion * Self.AccelerationDropMultiplier)
- If Self.Acceleration < 0.0 Then Self.Acceleration = 0
- EndIf
-
- If KeyDown(KEY_LEFT)
- ' RotateLeft
- Self.Rotation :+ 3
- EndIf
-
- If KeyDown(KEY_RIGHT)
- ' RotateLeft
- Self.Rotation :- 3
- EndIf
-
- If KeyDown(KEY_SPACE)
- ' FIRE!
- If Self.FireRateCount <= 0 Then
- Self.FireRateCount = Self.Weapon.FireRate
- Self.Weapon.Fire(Self)
- End If
- EndIf
-
- If KeyHit(KEY_DOWN)
- ' TELEPORT
- If Self.Teleports > 0 Then
- Self.Teleports :- 1
- Local Location:TPointD = Self.GameScene.FindSafeLocation(20)
- PlaySound(Self.TeleportSound)
- Self.Death.X = Self.X
- Self.Death.Y = Self.Y
- For Local Pops:Int = 0 To 50
- Local Particle:TStaticParticle = Self.Death.AddStaticParticle(Self.SparkleImage, Float(Rnd(360.0)), Float(Rnd(0.5,10.0)), 0, 0.02, [255,255,255])
- Particle.X = Self.X
- Particle.Y = Self.Y
- Particle.Rotation = Rnd(-1.0,1.0)
- Particle.Friction = 0.97
- Particle.Size = Rnd(0.1,0.2)
- Next
- Self.X = Int(Location.X)
- Self.Y = Int(Location.Y)
- Self.Death.X = Self.X
- Self.Death.Y = Self.Y
- For Local Pops:Int = 0 To 20
- Local Particle:TStaticParticle = Self.Death.AddStaticParticle(Self.SparkleImage, Float(Rnd(360.0)), Float(Rnd(0.5,2.0)), 0, 0.02, [255,255,255])
- Particle.X = Self.X
- Particle.Y = Self.Y
- Particle.Rotation = Rnd(-1.0,1.0)
- Particle.Friction = 0.97
- Particle.Size = Rnd(0.1,0.2)
- Next
- EndIf
- EndIf
-
- ' COLLISION DETECT AGAINST DIGESTIVES!
- ' ---------------------------------------------------------
- For Local Item:TDigestive = EachIn Self.GameScene.Digestives
- If Item.Circle.CollidesWith(Self.Circle)
- Self.Lives :- 1
- Self.Dead = True
- PlaySound(Self.CrashSound)
-
- Local PlayerSpeed:Double = Self.Speed()
- Self.GameScene.Shake :+ PlayerSpeed / 1.5
- If PlayerSpeed > 10.0
- Item.SplitIntoChunks(Int(Self.X),Int(Self.Y),Float(Self.Speed()))
- EndIf
- Self.Death.X = Self.X
- Self.Death.Y = Self.Y
- For Local Pops:Int = 0 To 100
- If PlayerSpeed > 10 Then PlayerSpeed = 10
- Local Angle:Double = Self.Angle() + Rnd(-(80 - (8.0 * PlayerSpeed)), 80 - (8.0 * PlayerSpeed))
- Local Particle:TStaticParticle = Self.Death.AddStaticParticle(Self.DeathImage, Float(Angle), Float(Rnd(0.1, Self.Speed())), 0, 0.03, [255,255,255])
- Particle.Friction = 0.98
- Particle.Size = Rnd(0.1,0.7)
- Particle.Color = [Rand(80,255),24,Rand(24,128)]
- Next
- For Local Pops:Int = 0 To 300
- Local Particle:TStaticParticle = Self.Death.AddStaticParticle(Self.DeathImage, Float(Rnd(360.0)), Float(Rnd(0.1, 7.0)), 0, Float(Rnd(0.01,0.04)), [255,255,255])
- Particle.Friction = 0.99
- Particle.Size = Rnd(0.1,0.4)
- Particle.Color = [Rand(80,255),24,Rand(24,200)]
- Next
- Self.Reset()
- EndIf
- Next
- EndIf
- End Method
- Method Reset()
- Self.X = WIDTH / 2
- Self.Y = HEIGHT / 2
- Self.Acceleration = 0
- Self.VelocityX = 0
- Self.VelocityY = 0
- Self.Teleports = 2
- Self.Dead = 2
- End Method
- Method LoadAssets()
- If Self.ThrusterImage = Null Then Self.ThrusterImage = LoadImage("graphics\bullet1.png")
- If Self.DeathImage = Null Then Self.DeathImage = LoadImage("graphics\pop.png")
- If Self.SparkleImage = Null Then Self.SparkleImage = LoadImage("graphics\sparkle.png")
- ' Load in the sounds...
- If Self.ThrusterSound = Null Then Self.ThrusterSound = LoadSound("sounds\thrust.wav",True)
- If Self.CrashSound = Null Then Self.CrashSound = LoadSound("sounds\crash.wav",False)
- If Self.TeleportSound = Null Then Self.TeleportSound = LoadSound("sounds\teleport.wav",False)
-
- Self.ThrusterChannel = AllocChannel()
- Self.ThrusterChannel.SetVolume(0)
- PlaySound(Self.ThrusterSound,Self.ThrusterChannel)
- End Method
- Function Create:TPlayer(World:TWorldPhysicsProvider, Image:TImage, GameScene:MainGameScene)
- Local Out:TPlayer = New TPlayer
- Out.Thruster = TFountain.Create(World, TRectangle.Create(0,0,WIDTH,HEIGHT))
- Out.Death = TFountain.Create(World, TRectangle.Create(0,0,WIDTH,HEIGHT))
- Out.GameScene = GameScene
- Out.Circle.Radius = 10
- Out.World = World
- Out.Image = Image
- Out.Friction = 0.985
- Out.Reset()
- Return Out
- End Function
- End Type
- Type TBullet Extends TPhysicsProvider
- Field Image:TImage
- Field Circle:TCircle = New TCircle
- Field GameScene:MainGameScene
- Field Size:Float = 1.0
- Field ScoreMultiplier:Float = 1
- Field TTL:Int
- Field Fading:Float = 1.0
- Const TIME_TO_LIVE = 100
- Method Draw()
- SetScale(Self.Size,Self.Size)
- SetAlpha(Self.Fading)
- DrawImage(Self.Image, Float(Self.X), Float(Self.Y))
- End Method
- Method PhysicsApplied()
- Local HalfWidth:Int = (Image.Width / 2)
- Local HalfHeight:Int = (Image.Height / 2)
- If X < -HalfWidth Then X = WIDTH + HalfWidth
- If Y < -HalfHeight Then Y = HEIGHT + HalfHeight
- If X > WIDTH + HalfWidth Then X = -HalfWidth
- If Y > HEIGHT + HalfHeight Then Y = -HalfHeight
- ' Shall we kill it off?
- Self.TTL :+ 1
- If Self.TTL > TIME_TO_LIVE Then
- Self.Fading :- 0.015
- If Self.Fading < 0.05
- Self.GameScene.Bullets.Remove(Self)
- EndIf
- EndIf
-
- ' If X < -HalfWidth Or Y < -HalfHeight Or X > WIDTH + HalfWidth Or Y > HEIGHT + HalfHeight Then
- ' ' Bullet went off't screen
- ' Self.GameScene.Bullets.Remove(Self)
- ' EndIf
- Self.Circle.X = Self.X
- Self.Circle.Y = Self.Y
- ' COLLISION DETECT AGAINST DIGESTIVES!
- ' ---------------------------------------------------------
- For Local Item:TDigestive = EachIn Self.GameScene.Digestives
- If Item.Circle.CollidesWith(Self.Circle)
- If Self.Fading > 0.5
- Self.GameScene.Bullets.Remove(Self)
- Item.SplitIntoChunks(Self.Circle.X,Self.Circle.Y,Self.ScoreMultiplier)
- Exit
- EndIf
- EndIf
- Next
- End Method
- Function Create:TBullet(World:TWorldPhysicsProvider, Image:TImage, Player:TPlayer, Speed:Float, GameScene:MainGameScene, Size:Float, Radius:Float, Veer:Float)
- Local Out:TBullet = New TBullet
- Out.GameScene = GameScene
- Out.SetVelocityFromAngle(Player.Rotation + Rnd(-Veer,Veer),Speed)
- Out.Size = Size
- Out.Circle.Radius = Radius * Size
- Out.X = Player.X
- Out.Y = Player.Y
- Out.World = World
- Out.Image = Image
- Return Out
- End Function
- End Type
- Type TStar Extends TPhysicsProvider
- Field Color[]
- Field GameScene:MainGameScene
-
- Method Draw()
- SetColor Self.Color[0],Self.Color[1],Self.Color[2]
- DrawRect(Float(X),Float(Y),1,1)
- End Method
- Method PhysicsApplied()
- Self.VelocityX :* 1.01
- Self.VelocityY :* 1.01
-
- Local HalfWidth:Int = 5
- Local HalfHeight:Int = 5
- If X < -HalfWidth Or Y < -HalfHeight Or X > WIDTH + HalfWidth Or Y > HEIGHT + HalfHeight Then
- ' Bullet went off't screen
- Self.GameScene.Stars.Remove(Self)
- EndIf
- End Method
- Function Create:TStar(World:TWorldPhysicsProvider,GameScene:MainGameScene, Speed:Float)
- Local Out:TStar = New TStar
- Local Pigment = Rand(24,255)
- Out.GameScene = GameScene
- Out.Color = [Pigment,Pigment,Pigment]
- Out.SetVelocityFromAngle(Rnd(360),Rnd(0.2,0.9) * Speed)
- Out.X = WIDTH / 2
- Out.Y = HEIGHT / 2
- Out.World = World
- Return Out
- End Function
- End Type
- Type TMenuStar Extends TPhysicsProvider
- Field Color[]
- Field MenuScene:MainMenuScene
-
- Method Draw()
- SetColor Self.Color[0],Self.Color[1],Self.Color[2]
- DrawRect(Float(X),Float(Y),1,1)
- End Method
- Method PhysicsApplied()
- ' Self.VelocityX :* 1.01
- ' Self.VelocityY :* 1.01
-
- Local HalfWidth:Int = 5
- Local HalfHeight:Int = 5
- If X < -HalfWidth Or Y < -HalfHeight Or X > WIDTH + HalfWidth Or Y > HEIGHT + HalfHeight Then
- ' Bullet went off't screen
- Self.MenuScene.Stars.Remove(Self)
- EndIf
- End Method
- Function Create:TMenuStar(World:TWorldPhysicsProvider,MenuScene:MainMenuScene, Speed:Float)
- Local Out:TMenuStar = New TMenuStar
- Local Pigment = Rand(24,255)
- Out.MenuScene = MenuScene
- Out.Color = [Pigment,Pigment,Pigment]
- Out.SetVelocityFromAngle(90,Rnd(0.2,0.9) * Speed)
- Out.X = 0
- Out.Y = Rnd(HEIGHT)
- Out.World = World
- Return Out
- End Function
- End Type
- Type TEndingStar Extends TPhysicsProvider
- Field Color[]
- Field EndScene:EndingScene
-
- Method Draw()
- SetColor Self.Color[0],Self.Color[1],Self.Color[2]
- DrawRect(Float(X),Float(Y),1,1)
- End Method
- Method PhysicsApplied()
- ' Self.VelocityX :* 1.01
- ' Self.VelocityY :* 1.01
-
- Local HalfWidth:Int = 5
- Local HalfHeight:Int = 5
- If X < -HalfWidth Or Y < -HalfHeight Or X > WIDTH + HalfWidth Or Y > HEIGHT + HalfHeight Then
- ' Bullet went off't screen
- Self.EndScene.Stars.Remove(Self)
- EndIf
- End Method
- Function Create:TEndingStar(World:TWorldPhysicsProvider, EndScene:EndingScene, Speed:Float, X:Int, Y:Int)
- Local Out:TEndingStar = New TEndingStar
- Local Pigment = Rand(24,255)
- Out.EndScene = EndScene
- Out.Color = [Pigment,Pigment,Pigment]
- Out.X = X
- Out.Y = Y
- Out.World = World
- Return Out
- End Function
- End Type
- Type TPickup Extends TLink
- Const MODIFIER_SCORE = 0
- Const MODIFIER_LIVES = 1
- Const MODIFIER_ROTATION = 2
- Const MODIFIER_PSYCHODELIC = 3
- Const MODIFIER_WEAPON = 4
- Field Modifies:Int = MODIFIER_SCORE
- Field ByValue:Float
- Field LastsFor:Int
- Field Time:Int
- Field IsPermanent:Int = False
- Field Weapon:TWeapon
- Field Icon:TImage
- Field Probability:Double
- Field OwnedIcon:TImage
- Method Clone:TPickup()
- Local Out:TPickup = New TPickup
- Out.Modifies = Self.Modifies
- Out.ByValue = Self.ByValue
- Out.LastsFor = Self.LastsFor
- Out.IsPermanent = Self.IsPermanent
- Out.Weapon = Self.Weapon
- Out.Icon = Self.Icon
- Out.Probability = Self.Probability
- Out.OwnedIcon = Out.OwnedIcon
- Return Out
- End Method
- Function Create:TPickup(Modifies:Int,ByValue:Float,LastsFor:Int,IsPermanent:Int,Weapon:TWeapon,Icon:TImage,Probability:Double,OwnedIcon:TImage)
- Local Out:TPickup = New TPickup
- Out.Modifies = Modifies
- Out.ByValue = ByValue
- Out.LastsFor = LastsFor
- Out.IsPermanent = IsPermanent
- Out.Weapon = Weapon
- Out.Icon = Icon
- Out.Probability = Probability
- Out.OwnedIcon = OwnedIcon
- Return Out
- End Function
- End Type
- Type TWeapon Extends TLink
- Field Speed:Float
- Field Graphic:TImage
- Field Size:Float
- Field Radius:Float
- Field Veer:Float
- Field FireRate:Int
- Field MainGame:MainGameScene
- Field Sound:TSound
- Field Name:String
- Field Icon:TImage
- Method Fire(Player:TPlayer)
- Local Shot:TBullet = TBullet.Create(MainGame.World, Self.Graphic, Player, Float(Self.Speed + Player.Speed()), Self.MainGame, Self.Size, Self.Radius, Self.Veer)
- Shot.ScoreMultiplier = (Player.Speed() * 4.0)
- If Shot.ScoreMultiplier < 1.0 Then Shot.ScoreMultiplier = 1.0
- Self.MainGame.Bullets.AddLast(Shot)
- PlaySound(Self.Sound)
- End Method
- Function Create:TWeapon(Speed:Float,Graphic:TImage,Size:Float,Radius:Float,Veer:Float,FireRate:Int,MainGame:MainGameScene,Sound:TSound,Icon:TImage,Name:String)
- Local Out:TWeapon = New TWeapon
- Out.Speed = Speed
- Out.Graphic = Graphic
- Out.Size = Size
- Out.Radius = Radius
- Out.Veer = Veer
- Out.FireRate = FireRate
- Out.MainGame = MainGame
- Out.Sound = Sound
- Out.Icon = Icon
- Out.Name = Name
- Return Out
- End Function
- End Type
- Type TEndMagnet Extends TMagnet
-
- Field Stars:Int
-
- End Type
- Type THighScores
- Const SCORE_COUNT = 10
- Field Scores:Int[SCORE_COUNT]
- Field Names:String[SCORE_COUNT]
- Method Render(X:Int, Y:Int)
- For Local Count:Int = 0 To SCORE_COUNT - 1
- DrawText(Self.Names[Count], X,Y + (Count * 20))
- Next
- For Local Count2:Int = 0 To SCORE_COUNT - 1
- DrawText(Self.Scores[Count2], X + 200,Y + (Count2 * 20))
- Next
- End Method
- Method IsHighScore:Int(Score:Int)
- For Local Count:Int = 0 To SCORE_COUNT - 1
- If Score > Self.Scores[Count] Then
- Return True
- EndIf
- Next
- Return False
- End Method
-
- Method Add(Score:Int,Name:String)
- ' Find out where we should put the score..
- Local PlaceAt:Int = SCORE_COUNT - 1
- For Local Count:Int = SCORE_COUNT - 1 To 0 Step -1
- If Score > Self.Scores[Count] Then
- PlaceAt = Count
- EndIf
- Next
- ' Shuffle them all down..
- For Local Shuffle:Int = SCORE_COUNT - 2 To PlaceAt Step -1
- Self.Scores[Shuffle + 1] = Self.Scores[Shuffle]
- Self.Names[Shuffle + 1] = Self.Names[Shuffle]
- Next
- Self.Scores[PlaceAt] = Score
- Self.Names[PlaceAt] = Name
- End Method
- Method Save(File:String)
- Local Out:TStream = OpenStream(File,False,True)
- If Out <> Null
- For Local Count:Int = 0 To SCORE_COUNT - 1
- WriteInt(Out,Self.Scores[Count])
- WriteLine(Out,Self.Names[Count])
- Next
- CloseStream(Out)
- EndIf
- End Method
- Function Load:THighScores(File:String)
- Local In:TStream = OpenStream(File,True,False)
- Local Out:THighScores = New THighScores
- If In = Null
- ' Fill it full of high scores..
- Out.Names[0] = "Loki"
- Out.Names[1] = "Booty"
- Out.Names[2] = "Rix"
- Out.Names[3] = "Jamez"
- Out.Names[4] = "Pies"
- Out.Names[5] = "Bobny"
- Out.Names[6] = "Berty"
- Out.Names[7] = "Billy"
- Out.Names[8] = "Bonny"
- Out.Names[9] = "Boxer"
- Out.Scores[0] = 100000
- Out.Scores[1] = 80000
- Out.Scores[2] = 50000
- Out.Scores[3] = 40000
- Out.Scores[4] = 30000
- Out.Scores[5] = 20000
- Out.Scores[6] = 10000
- Out.Scores[7] = 5000
- Out.Scores[8] = 4000
- Out.Scores[9] = 1000
- Else
- For Local Count:Int = 0 To SCORE_COUNT - 1
- Out.Scores[Count] = ReadInt(In)
- Out.Names[Count] = ReadLine(In)
- Next
- CloseStream(In)
- EndIf
- Return Out
- End Function
- End Type
- ' Main game setup.
- ' ------------------------
- Local Game:T2DDynamicGame = T2DDynamicGame.Create(WIDTH, HEIGHT, DEPTH, REFRESHRATE)
- Global Scores:THighScores = THighScores.Load("hi.dat")
- Game.DynamicTiming = DYNAMICTIMING
- Game.DesiredFPS = DESIREDFPS
- Game.Initialize() ' Go into graphics mode.
- HideMouse
- ' Create the main game scene.
- Local MenuScene:MainMenuScene = New MainMenuScene
- Local GameScene:MainGameScene = New MainGameScene
- Local EndScene:EndingScene = New EndingScene
- Local QuitFlag:Int = False
- While Not QuitFlag
- ' Attach The Game Scene To The Dynamic Game.
- Game.Setscene(Menuscene)
-
- ' Start The Main Loop.
- Game.Mainloop()
- If Not MenuScene.Exitgame
- If MenuScene.ShowCredits
- MenuScene.ShowCredits = False
- Game.SetScene(EndScene)
- Game.Mainloop()
- Else
- Game.Setscene(GameScene)
- Game.Mainloop()
- QFlushKeys()
- If GameScene.Completed
- GameScene.Completed = False
- Game.SetScene(EndScene)
- Game.Mainloop()
- EndIf
- QFlushKeys()
- ' Check for high score.
- If Scores.IsHighScore(GameScene.Player.Score) Then
- ' We got a high score.
- MenuScene.ViewMenu(MenuScene.VIEW_ENTERHIGH)
- MenuScene.LastHighScore = GameScene.Player.Score
- MenuScene.EnteredText = ""
- EndIf
- EndIf
- Else
- QuitFlag = True
- EndIf
- Wend
- Scores.Save("hi.dat")
- ' Clean up after we shut down.
- Game.ShutDown()
- ' Fin
- Const DEBUG = True
- Function DebugLog(Text:String)
- If DEBUG Then Print Text
- End Function
|