1
1
Fork 0
mirror of https://github.com/boxgaming/qbjs.git synced 2024-09-20 04:24:45 +00:00
qbjs/samples/games/trfbird.bas

798 lines
146 KiB
QBasic
Raw Normal View History

2022-04-15 19:47:03 +00:00
' -----------------------------------------------
' QB64 FlappyBird Clone by Terry Ritchie 02/28/14
'
' This program was created to accompany the QB64
' Game Programming course located at:
' http://www.qb64sourcecode.com
'
' You may not sell or distribute this game! It
' was made for instructional purposes only.
'
' Update: 04/29/20
'
' Added EXE icon support in lines 18 and 19
' Any key press now starts game in line 274
' Any key press now flaps bird in line 196
'
' -----------------------------------------------
'$ExeIcon:'.\fbird.ico'
'_Icon
'--------------------------------
'- Variable declaration section -
'--------------------------------
Const FALSE = 0 ' boolean: truth 0
Const TRUE = Not FALSE ' boolean: truth -1
Const LARGE = 0 ' large numbers
Const SMALL = 1 ' small numbers (not used in current version of game)
Const GOLD = 0 ' gold medal
Const SILVER = 1 ' silver medal
Const LIGHT = 0 ' light colored gold/silver medal
Const DARK = 1 ' dark colored gold/silver medal
Type PARALLAX ' parallax scenery settings
image As Long ' scene image
x As Integer ' scene image x location
y As Integer ' scene image y location
frame As Integer ' current parallax frame
fmax As Integer ' maximum parallax frames allowed
End Type
Type INFLIGHT ' flappy bird inflight characterisitcs
y As Single ' flappy bird y location
yvel As Single ' flappy bird y velocity
flap As Integer ' wing flap position
flapframe As Integer ' wing flap frame counter
angle As Integer ' angle of flappy bird
End Type
Type PIPE ' pipe characteristics
x As Integer ' pipe x location
y As Integer ' pipe y location
End Type
Dim Shared Pipes(3) As PIPE ' define 3 moving sets of pipes
Dim Shared Pipe&(1) ' pipe images 0=top 1=bottom
Dim Shared PipeImage& ' all three pipes drawn image
Dim Shared Birdie As INFLIGHT ' bird flight characteristics
Dim Shared Scenery(4) As PARALLAX ' define 4 moving scenes in parallax
Dim Shared Fbird&(8, 3) ' flapping bird images
Dim Shared Num&(9, 1) ' big and small numeral images
Dim Shared Plaque& ' medal/score plaque
Dim Shared FlappyBird& ' Flappy Bird title image
Dim Shared GameOver& ' Game Over image
Dim Shared GetReady& ' Get Ready image
Dim Shared Medal&(1, 1) ' gold/silver medal images
Dim Shared Finger& ' tap finger image
Dim Shared ScoreButton& ' score button image
Dim Shared ShareButton& ' share button image
Dim Shared StartButton& ' start button image
Dim Shared OKButton& ' OK button image
Dim Shared RateButton& ' RATE button image
Dim Shared MenuButton& ' MENU button image
Dim Shared PlayButton& ' PLAY [|>] button image
Dim Shared PauseButton& ' PAUSE [||] button image
Dim Shared HazardBar& ' Hazard bar parallax image
Dim Shared Clouds& ' Clouds parallax image
Dim Shared City& ' Cityscape parallax image
Dim Shared Bushes& ' Bushes parallax image
Dim Shared New& ' red NEW image
Dim Shared Clean& ' clean playing screen image
Dim Shared HitBird% ' boolean: TRUE if bird hits something
Dim Shared HighScore% ' high score
Dim Shared Score% ' current score
Dim Shared Paused% ' boolean: TRUE if game paused
Dim Shared Ding& ' ding sound
Dim Shared Flap& ' flapping sound
Dim Shared Smack& ' bird smack sound
Dim Shared Latch% ' boolean: TRUE if mouse button held down
Dim WinX% ' stops player from exiting program at will
'------------------------
'- Main Program Section -
'------------------------
Screen _NewImage(432, 768, 32) ' create 432x768 game screen
_Title "FlappyBird" ' give window a title
Cls ' clear the screen
_Delay .5 ' slight delay before moving screen to middle
'_ScreenMove _Middle ' move window to center of desktop
'WinX% = _Exit ' program will handle all window close requests
LOADASSETS ' set/load game graphics/sounds/settings
Birdie.flap = 1 ' set initial wing position of bird
Do ' BEGIN MAIN GAME LOOP
_Limit 60 ' 60 frames per second
UPDATESCENERY ' update parallaxing scenery
_PutImage (40, 265), FlappyBird& ' place game title on screen
_PutImage (350, 265), Fbird&(2, FLAPTHEBIRD%) ' place flapping bird on screen
If BUTTON%(64, 535, StartButton&) Then PLAYGAME ' if start button pressed play game
If BUTTON%(248, 535, ScoreButton&) Then SHOWSCORE ' if score button pressed show scores
If BUTTON%(248, 480, RateButton&) Then RATEGAME ' if rate button pressed bring up browser
_Display ' update screen with changes
Loop Until _KeyDown(27) 'Or _Exit ' END MAIN GAME LOOP when ESC pressed or window closed
CLEANUP ' clean the computer's RAM before leaving
System ' return to Windows desktop
'-------------------------------------
'- Subroutines and Functions section -
'-------------------------------------
'----------------------------------------------------------------------------------------------------------------------
Function FLAPTHEBIRD% ()
'*
'* Returns the next index value used in Fbird&() to animate the bird's
'* flapping wings.
'*
'Shared Birdie As INFLIGHT
Birdie.flapframe = Birdie.flapframe + 1 ' increment frame counter
If Birdie.flapframe = 4 Then ' hit limit?
Birdie.flapframe = 0 ' yes, reset frame counter
Birdie.flap = Birdie.flap + 1 ' increment flap counter
If Birdie.flap = 4 Then Birdie.flap = 1 ' reset flap counter when limit hit
End If
FLAPTHEBIRD% = Birdie.flap ' return next index value
End Function
'----------------------------------------------------------------------------------------------------------------------
Sub MOVEPIPES ()
'*
'* Creates and moves the pipe images across the screen.
'*
'Shared Pipes() As PIPE , Pipe&(), PipeImage&, Paused%, Score%, Ding&
Dim p% ' counter indicating which pipe being worked on
_Dest PipeImage& ' work on this image
Cls , _RGBA32(0, 0, 0, 0) ' clear image with transparent black
_Dest 0 ' back to work on screen
Do ' BEGIN PIPE LOOP
p% = p% + 1 ' increment pipe counter
If Not Paused% Then ' is game paused?
Pipes(p%).x = Pipes(p%).x - 3 ' no, move pipe to the left
If Pipes(p%).x < -250 Then ' hit lower limit?
Pipes(p%).x = 500 ' yes, move pipe all the way right
Pipes(p%).y = -(Int(Rnd(1) * 384) + 12) ' generate random pipe height position
End If
If Pipes(p%).x = 101 Then ' is pipe crossing bird location?
_SndPlay Ding& ' play ding sound
Score% = Score% + 1 ' increment player score
End If
End If
If Pipes(p%).x > -78 And Pipes(p%).x < 432 Then ' is pipe currently seen on screen?
_PutImage (Pipes(p%).x, Pipes(p%).y), Pipe&(0), PipeImage& ' place top pipe
_PutImage (Pipes(p%).x, Pipes(p%).y + 576), Pipe&(1), PipeImage& ' place bottom pipe
End If
Loop Until p% = 3 ' END PIPE LOOP when all pipes moved
_PutImage (0, 0), PipeImage& ' place pipe image on screen
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub FLYBIRDIE ()
'*
'* Controls the flight of bird on screen.
'*
'Shared Birdie As INFLIGHT, Fbird&(), Paused%, Flap&, HitBird%, Latch%, Smack&
Dim b% ' boolean: TRUE if left mouse button pressed
Dim Angle% ' angle of bird in flight
If Not Paused% Then ' is game paused?
While _MouseInput: Wend ' no, get latest mouse information
b% = _MouseButton(1) ' get left mouse button status
If _KeyHit > 0 Then b% = -1 ' any key will also make bird flap (added 04/29/20)
If Not b% Then Latch% = FALSE ' release latch if button let go
If Not HitBird% Then ' has bird hit something?
If Not Latch% Then ' no, has left button been release?
If b% Then ' yes, was left button pressed?
Birdie.yvel = -8 ' yes, reset bird y velocity
_SndPlay Flap& ' play flap sound
Latch% = TRUE ' remember mouse button pressed
End If
End If
End If
Birdie.yvel = Birdie.yvel + .5 ' bleed off some bird y velocity
Birdie.y = Birdie.y + Birdie.yvel ' add velocity to bird's y direction
If Not HitBird% Then ' has bird hit something?
If Birdie.y < -6 Or Birdie.y > 549 Then ' no, has bird hit top/bottom of screen?
HitBird% = TRUE ' yes, remeber bird hit something
_SndPlay Smack& ' play smack sound
End If
End If
If Birdie.yvel < 0 Then ' is bird heading upward?
Birdie.angle = 1 ' yes, set angle of bird accordingly
Else
Angle% = Int(Birdie.yvel * .5) + 1 ' calculate angle according to bird velocity
If Angle% > 8 Then Angle% = 8 ' keep angle within limits
Birdie.angle = Angle% ' set bird angle
End If
End If
_PutImage (100, Birdie.y), Fbird&(Birdie.angle, FLAPTHEBIRD%) ' place bird on screen
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub UPDATESCORE ()
'*
'* Displays player's score on screen.
'*
'Shared Num&(), Score%
Dim s$ ' score in string format
Dim w% ' width of score string
Dim x% ' x location of score digits
Dim p% ' position counter
s$ = LTrim$(RTrim$(Str$(Score%))) ' convert score to string
w% = Len(s$) * 23 ' calculate width of score
x% = (432 - w%) / 2 ' calculate x position of score
For p% = 1 To Len(s$) ' cycle through each position in score string
_PutImage (x%, 100), Num&(Asc(Mid$(s$, p%, 1)) - 48, LARGE) ' place score digit on screen
x% = x% + 23 ' move to next digit position
Next p%
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub READY ()
'*
'* displays instructions to the player and waits for player to start game.
'*
'Shared Fbird&(), Finger&, GetReady&
Dim b% ' boolean: TRUE if left mouse button pressed
Do ' BEGIN READY LOOP
_Limit 60 ' 60 frames per second
UPDATESCENERY ' move parallax scenery
_PutImage (180, 350), Finger& ' place finger instructions on screen
_PutImage (85, 225), GetReady& ' place get ready image on screen
_PutImage (100, 375), Fbird&(2, FLAPTHEBIRD%) ' place bird on screen
UPDATESCORE ' place score on screen
_Display ' update screen with changes
While _MouseInput: Wend ' get latest mouse information
b% = _MouseButton(1) ' get status of left mouse button
If _KeyHit > 0 Then b% = -1 ' any key press will also begin game (added 04/29/20)
'If _Exit Then CLEANUP: System ' leave game if user closes game window
Loop Until b% ' END READY LOOP when left button pressed
_Delay .2 ' slight delay to allow mouse button release
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub PLAYGAME ()
'*
'* Allows player to play the game.
'*
'Shared Pipes() As PIPE, Birdie As INFLIGHT, PauseButton&, PlayButton&, Paused%, HitBird%, Score%
'Randomize Timer ' seed random number generator
Score% = 0 ' reset player score
Birdie.y = 0 ' reset bird y location
Birdie.yvel = 0 ' reset bird y velocity
Birdie.flap = 1 ' reset bird wing flap index
Pipes(1).x = 500 ' reset position of first pipe
Pipes(2).x = 749 ' reset position of second pipe
Pipes(3).x = 998 ' reset position of third pipe
Pipes(1).y = -(Int(Rnd(1) * 384) + 12) ' calculate random y position of pipe 1
Pipes(2).y = -(Int(Rnd(1) * 384) + 12) ' calculate random y position of pipe 2
Pipes(3).y = -(Int(Rnd(1) * 384) + 12) ' calculate random y position of pipe 3
READY ' display instructions to player
Do ' BEGIN GAME PLAY LOOP
_Limit 60 ' 60 frames per second
UPDATESCENERY ' move parallax scenery
MOVEPIPES ' move pipes
UPDATESCORE ' display player score
FLYBIRDIE ' move and display bird
CHECKFORHIT ' check for bird hits
If Not Paused% Then ' is game paused?
If BUTTON%(30, 100, PauseButton&) Then ' no, was pause button pressed?
Paused% = TRUE ' yes, place game in pause state
End If
Else ' no, game is not paused
If BUTTON%(30, 100, PlayButton&) Then ' was play button pressed?
Paused% = FALSE ' yes, take game out of pause state
End If
End If
_Display ' update screen with changes
'If _Exit Then CLEANUP: System ' leave game if user closes game window
Loop Until HitBird% ' END GAME PLAY LOOP if bird hits something
Do ' BEGIN BIRD DROPPING LOOP
_Limit 60 ' 60 frames per second
Paused% = TRUE ' place game in paused state
UPDATESCENERY ' draw parallax scenery
MOVEPIPES ' draw pipes
Paused% = FALSE ' take game out of pause state
FLYBIRDIE ' move bird on screen
_Display ' update screen with changes
'If _Exit Then CLEANUP: System ' leave game if user closes game window
Loop Until Birdie.y >= 546 ' END BIRD DROPPING LOOP when bird hits ground
SHOWSCORE ' display player's score plaque
HitBird% = FALSE ' reset bird hit indicator
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub CHECKFORHIT ()
'*
'* Detects if bird hits a pipe.
'*
'Shared Pipes() As PIPE, Birdie As INFLIGHT, HitBird%, Smack&
Dim p% ' pipe counter
For p% = 1 To 3 ' cycle through all pipe positions
If Pipes(p%).x <= 153 And Pipes(p%).x >= 22 Then ' is pipe in bird territory?
If BOXCOLLISION(105, Birdie.y + 6, 43, 41, Pipes(p%).x, Pipes(p%).y, 78, 432) Then ' collision?
HitBird% = TRUE ' yes, remember bird hit pipe
End If
If BOXCOLLISION(105, Birdie.y + 6, 43, 41, Pipes(p%).x, Pipes(p%).y + 576, 78, 432) Then ' collision?
HitBird% = TRUE ' yes, remember bird hit pipe
End If
End If
Next p%
If HitBird% Then _SndPlay Smack& ' play smack sound if bird hit pipe
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub RATEGAME ()
'*
'* Allows player to rate game.
'*
'Shell "https://www.qb64.org/forum/index.php?topic=437.0" ' go to QB64 web site forum area for flappy bird
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub SHOWSCORE ()
'*
'* Display's current and high scores on score plaque
'*
'Shared Fbird&(), Num&(), Medal&(), FlappyBird&, GameOver&, Plaque&, OKButton&, ShareButton&
'Shared HitBird%, HighScore%, Score%, New&
Dim Ok% ' boolean: TRUE if OK button pressed
Dim Scores%(1) ' current and high scores
Dim sc% ' current score being drawn
Dim x% ' x location of score digits
Dim p% ' digit position counter
Dim ShowNew% ' boolean: TRUE if score is a new high score
Dim s$ ' score in string format
If Score% > HighScore% Then ' is this a new high score?
'Open "fbird.sco" For Output As #1 ' yes, open score file
'Print #1, Score% ' save new high score
'Close #1 ' close score file
HighScore% = Score% ' remember new high score
ShowNew% = TRUE ' remember this is a new high score
End If
Scores%(0) = Score% ' place score in array
Scores%(1) = HighScore% ' place high score in array
Ok% = FALSE ' reset OK button status indicator
Do ' BEGIN SCORE LOOP
_Limit 60 ' 60 frames per second
If HitBird% Then ' did bird hit something?
_PutImage (75, 200), GameOver& ' yes, place game over image on screen
Else ' no, bird did not hit anything
UPDATESCENERY ' move parallax scenery
_PutImage (40, 200), FlappyBird& ' place flappy bird title on screen
_PutImage (350, 200), Fbird&(2, FLAPTHEBIRD%) ' place flapping bird on screen
End If
_PutImage (46, 295), Plaque& ' place plaque on screen
'Select Case HighScore% ' what is range of high score?
' Case 25 TO 49 ' from 25 to 49
' _PutImage (85, 360), Medal&(SILVER, LIGHT) ' display a light silver medal
' Case 50 TO 99 ' from 50 to 99
' _PutImage (85, 360), Medal&(SILVER, DARK) ' display a dark silver medal
' Case 100 TO 199 ' from 100 to 199
' _PutImage (85, 360), Medal&(GOLD, LIGHT) ' display a light gold medal
' Case Is > 199 ' from 200 and beyond
' _PutImage (85, 360), Medal&(GOLD, DARK) ' display a dark gold medal
'End Select
For sc% = 0 To 1 ' cycle through both scores
s$ = LTrim$(RTrim$(Str$(Scores%(sc%)))) ' convert score to string
x% = 354 - Len(s$) * 23 ' calculate position of score digit
For p% = 1 To Len(s$) ' cycle through score string
_PutImage (x%, 346 + sc% * 64), Num&(Asc(Mid$(s$, p%, 1)) - 48, LARGE) ' place digit on plaque
x% = x% + 23 ' increment digit position
Next p%
Next sc%
If ShowNew% Then _PutImage (250, 382), New& ' display red new image if new high score
If BUTTON%(64, 535, OKButton&) Then Ok% = TRUE ' remember if OK button was pressed
If BUTTON%(248, 535, ShareButton&) Then ' was share button pressed?
SHAREPROGRAM ' yes, share program with others
UPDATESCENERY ' draw parallax scenery
MOVEPIPES ' draw pipes
End If
_Display ' update screen with changes
'If _Exit Then CLEANUP: System ' leave game if user closes game window
Loop Until Ok% ' END SCORE LOOP when OK button pressed
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub SHAREPROGRAM ()
'*
'* Allows player to share program with others
'*
'Shared Fbird&(), FlappyBird&, OKButton&
Dim Message& ' composed message to player's friend(s)
Dim Ok% ' boolean: TRUE if OK button pressed
Message& = _NewImage(339, 174, 32) ' create image to hold message to player
'_Clipboard$ = "I just discovered a great game! You can download it here: http:\\www.qb64sourcecode.com\fbird.exe"
'_PrintMode _KeepBackground ' printed text will save background
Line (58, 307)-(372, 453), _RGB32(219, 218, 150), BF ' clear plaque image
Color _RGB32(210, 170, 79) ' compose message to player on plaque
_PrintString (66, 316), "The following message has been copied"
Color _RGB32(82, 55, 71)
_PrintString (65, 315), "The following message has been copied"
Color _RGB32(210, 170, 79)
_PrintString (66, 331), "to your computer's clipboard:"
Color _RGB32(82, 55, 71)
_PrintString (65, 330), "to your computer's clipboard:"
Color _RGB32(210, 170, 79)
_PrintString (66, 351), "'I just discovered a great game! You"
Color _RGB32(82, 55, 71)
_PrintString (65, 350), "'I just discovered a great game! You"
Color _RGB32(210, 170, 79)
_PrintString (66, 366), "can download it here:"
Color _RGB32(82, 55, 71)
_PrintString (65, 365), "can download it here:"
Color _RGB32(210, 170, 79)
_PrintString (66, 381), "www.qb64sourcecode.com\fbird.exe'"
Color _RGB32(82, 55, 71)
_PrintString (65, 380), "www.qb64sourcecode.com\fbird.exe'"
Color _RGB32(210, 170, 79)
_PrintString (66, 401), "Create an email for your friends and"
Color _RGB32(82, 55, 71)
_PrintString (65, 400), "Create an email for your friends and"
Color _RGB32(210, 170, 79)
_PrintString (66, 416), "paste this message into it! Go ahead,"
Color _RGB32(82, 55, 71)
_PrintString (65, 415), "paste this message into it! Go ahead,"
Color _RGB32(210, 170, 79)
_PrintString (66, 431), "do it now before you change your mind!"
Color _RGB32(82, 55, 71)
_PrintString (65, 430), "do it now before you change your mind!"
_PutImage , _Dest, Message&, (46, 295)-(384, 468) ' place message in image
Do ' BEGIN SHARE LOOP
_Limit 60 ' 60 frames per second
UPDATESCENERY ' move parallax scenery
_PutImage (40, 200), FlappyBird& ' place flappy bird title on screen
_PutImage (350, 200), Fbird&(2, FLAPTHEBIRD%) ' place flapping bird on screen
_PutImage (46, 295), Message& ' place message on plaque
If BUTTON%(156, 535, OKButton&) Then Ok% = TRUE ' remeber if OK button pressed
_Display ' update screen with changes
'If _Exit Then CLEANUP: System ' leave game if user closes game window
Loop Until Ok% ' END SHRE LOOP when OK button pressed
_FreeImage Message& ' message image no longer needed
End Sub
'----------------------------------------------------------------------------------------------------------------------
Function BUTTON% (xpos As Integer, ypos As Integer, Img As Long)
'*
'* Creates a button on the screen the player can click with the mouse button.
'*
'* xpos% - x coordinate position of button on screen
'* ypos% - y coordinate position of button on screen
'* Image& - button image
'*
'* Returns: boolean: TRUE if button pressed
'* FALSE if button not pressed
'*
Dim x% ' current mouse x coordinate
Dim y% ' current mouse y coordinate
Dim b% ' boolean: TRUE if left mouse button pressed
_PutImage (xpos, ypos), Img ' place button image on the screen
While _MouseInput: Wend ' get latest mouse information
x% = _MouseX ' get current mouse x coordinate
y% = _MouseY ' get current mouse y coordinate
b% = _MouseButton(1)
If b% Then ' is left mouse button pressed?
If x% >= xpos Then ' yes, is mouse x within lower limit of button?
If x% <= xpos + _Width(Img) Then ' yes, is mouse x within upper limit of button?
If y% >= ypos Then ' yes, is mouse y within lower limit of button?
If y% <= ypos + _Height(Img) Then ' yes, is mouse y within upper limit of button?
BUTTON% = TRUE ' yes, remember that button was clicked on
_Delay .2 ' slight delay to allow button to release
End If
End If
End If
End If
End If
End Function
'----------------------------------------------------------------------------------------------------------------------
Sub UPDATESCENERY ()
'*
'* Updates the moving parallax scenery
'*
'Shared Scenery() As PARALLAX, Clean&, HazardBar&, Paused%
Dim c% ' scenery index indicator
_PutImage , Clean& ' clear screen with clean image
Do ' BEGIN SCENERY LOOP
c% = c% + 1 ' increment index value
If Not Paused% Then ' is game in paused state?
Scenery(c%).frame = Scenery(c%).frame + 1 ' no, update frame counter of current scenery
If Scenery(c%).frame = Scenery(c%).fmax Then ' frame counter hit limit?
Scenery(c%).frame = 0 ' yes, reset frame counter
Scenery(c%).x = Scenery(c%).x - 1 ' move scenery 1 pixel to left
If Scenery(c%).x = -432 Then ' scenery hit lower limit?
Scenery(c%).x = 0 ' yes, reset scenery to start position
End If
End If
End If
_PutImage (Scenery(c%).x, Scenery(c%).y), Scenery(c%).image ' place current scenery on screen
Loop Until c% = 3 ' END SCENERY LOOP when all scenery updated
If Not Paused% Then ' is game in paused state?
Scenery(4).x = Scenery(4).x - 3 ' no, move hazard bar 3 pixels to left
If Scenery(4).x = -21 Then Scenery(4).x = 0 ' reset to start position if lower limit hit
End If
_PutImage (Scenery(4).x, Scenery(4).y), HazardBar& ' place hazard bar on screen
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub LOADASSETS ()
'*
'* Loads game graphics, sounds and initial settings.
'*
'Shared Scenery() As PARALLAX, Birdie As INFLIGHT, Pipes() As PIPE, Pipe&(), Fbird&()
'Shared Num&(), Medal&(), Plaque&, FlappyBird&, GameOver&, GetReady&, Finger&
'Shared ScoreButton&, ShareButton&, StartButton&, OKButton&, RateButton&, MenuButton&
'Shared PlayButton&, PauseButton&, HazardBar&, Clouds&, City&, Bushes&, New&, Clean&
'Shared HighScore%, PipeImage&, Ding&, Flap&, Smack&
Dim Sheet& ' sprite sheet image
Dim x% ' generic counter
Dim y% ' generic counter
Dim PipeTop& ' temporary top of pipe image
Dim PipeTube& ' temporary pipe tube image
Ding& = _SndOpen("data:audio/ogg;base64,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
Flap& = _SndOpen("data:audio/ogg;base64,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QikppdZaCCGEUEopJaXWYuwghFBCKaWk1FqMIYQQSiklpdRaizGEEEIppaTUUmsxllJKSSml1FprMdZSSikppdRSa7HFmFJKqbXWWosxxlpTSim11lprscVYa2qttdZijDHGWmtNrbXWWowx1lhrrQUAABw4AAAEGEEnGVUWYaMJFx6AQkNWBABRAACAMYgxxBiCjknIJEQOMigZlAZCSKmjlFEqJZYaM0olphJrBKGjFFLKKJUaS6sZpRJjiaUAALADBwCwAwuh0JCVAEAeAACBkFKMOeccQogxxpxzDiHFGGPOOacYY8w555xTjDHmnHPOMcaccw5CCBljzjkHIYTOOecghBBC55xzEEIIoXPOOQghhNA55xyEEEIoAACowAEAIMBGkc0JRoIKDVkJAKQCAADGMOaccxBKaZRyDkIIpbTUKOUchBBKSS1zDkIppbQWW+YchFJKSa21DkIpKaXUWowdhFJSSqnFGDsIpaTUWoy1dhBKSam1GGsNpaQWW6y11hpKSa3FGGuttaTUWoy15pxzSam1GGutNecCAMATHACACmxYHeGkaCyw0JCVAEAGAABhDEIIIYQQQgghhJRCCCklAABgwAEAIMCEMlBoyEoAIBUAADCGMcacg1BKoxSEEEIoJaVGKQchhFBSS5mDUkpJJbUWMwillFJKajFm0ElJKbUWY80glJJSajHG2EEoKbXWYoyxg1BSSq3FWGsopaUWY6wxxlBKSq3FGmONJaUWa6251lpLSq3FGGutuRYAgNDgAAB2YMPqCCdFY4GFhqwEAPIAABCElGKMMcaQUowxxphzSCmlGGPMOaUYY44555xijDHGnHOOMcaYc845xxhjzjnnnGOMOeecc84xxpxzzjnnmHPOOeecc8w555xzzjkBAEAFDgAAATaKbE4wElRoyEoAIBwAAECIMecYc05CSo1SzkkIHYRSWm0UcxBK6CCU1lLmnJRSQiglxdgy5yClEkIqLaXaQUglpVJSiq22DkJqKZXSUmutZs5BKKWklmKsLXMQQikppdZqrZ2EklJKtbVYawwhlJRSa622GmsppaWWaqyx1lhDKaml2GKstcZaYmwttRprrK3GklJLrdVaY621FgBg8uAAAJVg4wwrSWeFo8GFhqwEAHIDAAiEGHPOOQgllBBCKaVESjHmHIQQSiillFJSiZRizDkHoZRSSimllJIx5hx0EEoopZRSUkklY8w5ByGUUEoppZRSSucchBBKKKWUUkoqJZXOOQchhFJKKaWUklIpHYQQQiillFJSSSWVVDoIIYRSSimllFJSKqWEEkIpJZVSSimlpJRSCiGUUEoppaSSSkoplRJKKKWUVEopJZVUUikplFJKKaWUVEpKJaWUUgillFJSKamUVEpKKaVQSimllFRSSSWllFJJpZRSSiklpZRSSimVlEoppaRSSioppVRaSqmUUkpJpZSUWkoppZRSKqWkklJKKaWUUkoppVRKSSWVklJKKaWUUkqllFJKSamkVFIqKaWSUgEAQAcOAAABRlRaiJ1mXHkEjihkmIAKDVkJAIQDAABSSimllFJKiYyUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJ
Smack& = _SndOpen("data:audio/ogg;base64,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
Sheet& = _LoadImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2YAAAHLCAYAAACjyIvnAAAACXBIWXMAAC4jAAAuIwF4pT92AAAgAElEQVR4nOyd6VcTSRvF/a+G0XHGGSSC65hqlgFBNpVVZRFBZFMEFAGDiiAiCgLiAIrIIoKIgKigjooIjOKK+zouWd4P9/0QqaqGBEJMSMA6de450vZSt6o79fy6lp6DOSKJJJJI05PInkKQpF2wdT6smaTaZpDsApDQzZCKK2e1V2sn6cIVCAkJCVlaru1MbhevUrl3Mvlc6qEK7GZaa0T8Pvyx/Dn5a/F5sHV5CFle5rZ7Nm94RRJJpNmfpJJqEJ9QKB0UUDooIJWdBN2epprR8CI1d4IcKAGJToZypQ/1qHRQgMSmzmhvo4n3ZEzWuK6tG1YhIaHZKQFmQtaWue2ezRp6kUQSSZ9IzDaQ4Bj6EJOsfCiVqyGdbpnxQb1Ufx4kImFcEL8qeJNsu3TkxIzzSoqOg3iumxhYXP0h1beB5BaBxG6fcR5HkwAzISGh2SQBZkLWlrntns0aepFEEkkPZbR3JTgGJCufBbsG4ExquzxjgnuyPRvK35aNC+CLcg7g44eP2BXLeV8VPGN8UX9FFQYBhcx1RlJYDE4cLkP/P7fh6+zKALSidsb5xJyZCWZ80OPafpWKD4zcOoxIFjzxEoGU0OzXbHp2TAGwgO4eqvCrvVR3Pg1QDX5luqceNCh+H/5Y/pz8tQSwzW6Z2+7ZrKEXSaQfPfFQpnRQQJW8E611Z+UBLwdnUksXiE8ISGEZ612LSgJJzbGrYF86cWbckD6lgwLpm5Lwb/8gdDoddDodhgfvyYEmu8CufJiSlPMXQ+mgQJS7K4qzc3G1oxtfv3yhHnU6HTK3bGce7ayuJvTG1Y22X0XFe+NlDUizVEA204NLIaHp1Gx6dgSYCdlK5rZ7Nm/8RRLJWolkFxjtoZBqz9k0QDYEZaMBrkE4O9kEsipI//c8F5DCMpCoJLsM+KW2y1C6uNG8bfTwRmdLu8Fg/kjuQeZzsbseQCtqQQI2guzcZzeexnk82QSSmYfi7Bi87N6lB5Y3Nw16bKw6zerJL9xuPY1NAszsJ7gUEppOzaZnR4CZkK1kbrs37Y29VHYSZFuWfiGAXxZDaumaMYHKbE/S8dN2XxckPg0kJgVSc8e4vJL9R+h2qbKOBcNj9peO/G1w+7R5mADKjMLZmCGBNaoIJAV4ynucODiTSqpAIhNtVp8kKx+evy1GdfYGfTD/+aXBYP7zp88IWOLBfLgHsn87EUjnOiE1d4DEpNgNfJKULDYsMymIQcvjeoMeHz94xDzNX2IXHkxJMwXMxFwRISHzNJ3PjkfnVSr3i0zWgDf+nPy1/Lp7qHhYGvg8QHVfPUj1WMP0RMc0oh0yKH4f/lj+nPy1+DzweTNWPra+X4SmJnPbPas37lKN/s0yCYqG0kk5fj5GQemMCVRmc5Iqar8Fw0qQoGiQzDxINU02rxuyNQMkY68etqoa2L2zcCXdjjmYIx2rkW0nayLk9xq3P1kVbPQ8VvdjApQZhbNvOqXaCG2/Cl9v5xiEM6mkCso/Vuj/Dou1SR2SjL3oKN86KbSM7VEaq9jkLVAuXKn/e8FySA1ttr8n80tp/iLdJL2/wUJoR1qMegx19WN1dPg4pLKTIClZIEUVNvdjrOxNgTEBZgLMhGauBJgJMBOynsxt9yzeyEtN7SD7ivUrri33mnTCuH9CBkiaCiRgA0h4nM2DlLFpsvybKlv7GE0kPE5f1mkqSJV1bK5Sao7hvC/3AolIANlXDKmpfVp9UFh0UEDpFoCIxIzx+XMLADlYBuIbRrftCPJGX10yUgLH33/bYtcb3D56Hqv6qWuF0pkN8dsT5Q/d+38nDHbHwlmgy3K8uLSTBsxj4WyzlzsOJIXIYW0a4Uw6XgulWwCUDgps8fFgwf3DGug0n4z6jFuzUZbn5EAv9NUlQ9uvwgZCmBcb9gJSj+e64PaLM7at8UJ19gZ8fTtxHep0OhzI2MP8/brUJnVjLAkwE2Am9GNKgJkAMyHrydx2zyKNJzl8HCQ+TT4MyRiILfFAdkIazp6sx8jjJxjsu8v+30lp8yBlbJptYDau19LFHSQsFlu3RMJ/0fgV9MbJPRAkPg3k8HGreyIBLFhPWR8LnU6H8/XNCJF8J8zjQOM2GlCePxyDkBUr6f89aU83uJ0GykGbIFU1WM2bVFkHpbMb9kT5s6B3inAW6SYZhLPNXu5427Mb2n4VDiXKl3GfLgCQ9Wo6KNB+LAW6t3cmDeqvXboqO6737wTq72JJrOz/pGM1rKf0zPnpg87SapCkTJBVwbhWxfKne9s3qb+LzecN368u7nToLUnPhS1W3ZwpYCbmivw4mk1znOxB9vDsbLjaS7Wuu4fKUi8++LrmITCou4eKzw8PS080TCM6phf/GzKol0ZkbH/+nPy1+DzweVvT3UMlhzRTykE8O/Yic9s98xvM4koQv3DZ29+JtHqRhMG+uwYbdH9ujolHYbl+6OO6aNnqc7ZKMx3MSGGZviwz8+BxsNRo/j79kw1tvwoDjdtQnb0B29asgvsvzhP7+nUpiF+4fvichZcBJ/uPyK5158Yt2T1zvLAE0tzx+YvxdIO6b48sqNT2q1CxMwzlGaEGt0tzF40HtPg0qwXJPjtzMNKRwfJxvxw6rXpKcFaRSKC9zcHZtSR8uBQn82YrOCPxaZDmLkLFzjBohw5N6m1Ue5JYj2ict7vMy44gb+bDNwxS22X9yyAHBaTiSqv5IgfLQNZGQvnHn7KyLEkNYfl7enZSb+/evJUd77doGbI3+uFsQTRCvVczb4Xl01JHfF6Gk3+ishSYWeq3z96CSwFm0yMRXFqvPAWYCTATz870yNx2z+wGk59nYSg4LtkegmtVCfBcsJhuf3jvgcEGvba8CmcqT+LBv/dRrCpgQUp00rQBjSlvjY2J33863ybL6mPvYdnQRLo9mq3cV5wShOHWHajbF4mMUB94/7EESgcFEnz/MuhLc0eFa1UJKNkeghhPN6P1TbXIFdJhywTJ/HLrBzL2GCzTkcdPoUrZNS4f65auQHPhJrmfW+lQNy+D5mr0OJ9PL2ZAFeU/3o+LG0hWvmWB89t3yjYQooez++XQqT+YFPiOwtneECeoGxyhblHq4exGMtRNLlA3OkFzbavN4UzafQC36livpfZ5h0n+nj58LMvrjcpIeo6BRjY3TxXlj9RI5ot4BVkPzNJUBu/1zV4cOA4dNsnf5oD19PiOUgbRBfFrmZfYVAFm/L1kZ8GlALPpkQgurVeeAswEmIlnZ3pkbrtnfoPZ0kUb3tAVK5EXuwbtR2Px5mqmrEFPC2ZvuutPnJq0ce/p6GaN+p8+kE63gOQctPrckpkMZlJTuxwmwmJBcg5COt0C5Z8McK5Wbh2X99unk3HzeCg01xMm9Hi3ngXGfy1YLlvMgJdU0/jd/sj2bHo+z9+X4/XLVxPeMzcu9yJ+XaQsH+uXOUFz3h3a64l6yLzoq4eZBkfZdl7XqxNl85n4wN8SvTLSySbZeTM3BEDz8alJQe+oTuzPpD7UDY5Qn1sBdZMz+9uGcCYVV4J4BVF4kgX2RlZlHKvygiPY4u6E3ryFUJ9dAu2dbHqO0znBuF6tr7fh1h1yTxYGaOqJW93Tb8FC2TVHh43q/b2Y1Fvp/kP02Pwta+ixncfi2Hld/QWYcUnMFZnd+pHnB1o7gLa3Z2dYzTT0dYBqyi8+jJQDD2Mh3b1Ug58HqB6qB6m+B8CmKlOA7YGaiS8Tvr547+LZsR/4NJYfc9s9sw6S6ttAcotwaPcmPGpLmzCgr82NQMSqdSjKzsPg7f5JG/ePHz4gNSIeNaWVGLpzF2uWs4UNpNJqqwUtMw3MpMo6SNV6CCL7i433Yo0Grj8vwofrWQbzr251/RbUK6C54AnN5fXQ/rNdts/fWextf05iOnQ6HR4PP0RDVS0yt2zH6kUSlMu8vh9e6s/LloavOVJiMrQ01ZxB4DL9/dK+eyEDsba/5DAzur3DH5+u75T5jP7L1XgZ
For y% = 0 To 2 ' cycle through bird image rows
For x% = 0 To 7 ' cycle through bird image columns
Fbird&(x% + 1, y% + 1) = _NewImage(53, 53, 32) ' create image holder then get image
_PutImage , Sheet&, Fbird&(x% + 1, y% + 1), (x% * 53, y% * 53)-(x% * 53 + 52, y% * 53 + 52)
Next x%
Next y%
For x% = 0 To 9 ' cycle trough 9 numeral images
Num&(x%, 0) = _NewImage(21, 30, 32) ' create image holder for big
Num&(x%, 1) = _NewImage(18, 21, 32) ' create image holder for small
_PutImage , Sheet&, Num&(x%, 0), (x% * 21, 159)-(x% * 21 + 20, 188) ' get images
_PutImage , Sheet&, Num&(x%, 1), (x% * 18 + 210, 159)-(x% * 18 + 227, 179)
Next x%
Plaque& = _NewImage(339, 174, 32) ' define remaining image sizes
FlappyBird& = _NewImage(288, 66, 32)
GameOver& = _NewImage(282, 57, 32)
GetReady& = _NewImage(261, 66, 32)
PipeTop& = _NewImage(78, 36, 32)
PipeTube& = _NewImage(78, 36, 32)
Pipe&(0) = _NewImage(78, 432, 32)
Pipe&(1) = _NewImage(78, 432, 32)
PipeImage& = _NewImage(432, 596, 32)
Medal&(0, 0) = _NewImage(66, 66, 32)
Medal&(0, 1) = _NewImage(66, 66, 32)
Medal&(1, 0) = _NewImage(66, 66, 32)
Medal&(1, 1) = _NewImage(66, 66, 32)
Finger& = _NewImage(117, 147, 32)
ScoreButton& = _NewImage(120, 42, 32)
ShareButton& = _NewImage(120, 42, 32)
StartButton& = _NewImage(120, 42, 32)
OKButton& = _NewImage(120, 42, 32)
RateButton& = _NewImage(120, 42, 32)
MenuButton& = _NewImage(120, 42, 32)
PlayButton& = _NewImage(39, 42, 32)
PauseButton& = _NewImage(39, 42, 32)
HazardBar& = _NewImage(462, 24, 32)
Clouds& = _NewImage(864, 120, 32)
City& = _NewImage(864, 57, 32)
Bushes& = _NewImage(864, 27, 32)
New& = _NewImage(48, 21, 32)
_PutImage , Sheet&, Plaque&, (0, 189)-(338, 362) ' grab images from sprite sheet
_PutImage , Sheet&, FlappyBird&, (0, 363)-(287, 428)
_PutImage , Sheet&, GameOver&, (588, 246)-(869, 302)
_PutImage , Sheet&, GetReady&, (588, 303)-(847, 368)
_PutImage , Sheet&, Medal&(0, 0), (339, 327)-(404, 392)
_PutImage , Sheet&, Medal&(0, 1), (405, 327)-(470, 392)
_PutImage , Sheet&, Medal&(1, 0), (339, 261)-(404, 326)
_PutImage , Sheet&, Medal&(1, 1), (405, 261)-(470, 326)
_PutImage , Sheet&, Finger&, (471, 246)-(587, 392)
_PutImage , Sheet&, ScoreButton&, (288, 417)-(407, 458)
_PutImage , Sheet&, ShareButton&, (408, 417)-(527, 458)
_PutImage , Sheet&, StartButton&, (528, 417)-(647, 458)
_PutImage , Sheet&, OKButton&, (424, 204)-(543, 245)
_PutImage , Sheet&, RateButton&, (544, 204)-(663, 245)
_PutImage , Sheet&, MenuButton&, (664, 204)-(783, 245)
_PutImage , Sheet&, PlayButton&, (784, 204)-(822, 245)
_PutImage , Sheet&, PauseButton&, (823, 204)-(861, 245)
_PutImage , Sheet&, HazardBar&, (288, 393)-(749, 416)
_PutImage (0, 0)-(431, 119), Sheet&, Clouds&, (424, 0)-(855, 119)
_PutImage (432, 0)-(863, 119), Sheet&, Clouds&, (424, 0)-(855, 119)
_PutImage (0, 0)-(431, 56), Sheet&, City&, (424, 120)-(855, 176)
_PutImage (432, 0)-(863, 56), Sheet&, City&, (424, 120)-(855, 176)
_PutImage (0, 0)-(431, 26), Sheet&, Bushes&, (424, 177)-(855, 203)
_PutImage (432, 0)-(863, 26), Sheet&, Bushes&, (424, 177)-(855, 203)
_PutImage , Sheet&, New&, (289, 363)-(336, 383)
_PutImage , Sheet&, PipeTop&, (339, 189)-(416, 224)
_PutImage , Sheet&, PipeTube&, (339, 225)-(416, 260)
_PutImage (0, 431)-(77, 395), PipeTop&, Pipe&(0) ' create bottom of upper tube image
_PutImage (0, 0), PipeTop&, Pipe&(1) ' create top of lower tube image
For y% = 0 To 395 Step 36 ' cycle through tube body of pipes
_PutImage (0, y% + 35)-(77, y%), PipeTube&, Pipe&(0) ' draw tube on upper pipe image
_PutImage (0, 36 + y%), PipeTube&, Pipe&(1) ' draw tube on lower pipe image
Next y%
_FreeImage PipeTop& ' temporary image no longer needed
_FreeImage PipeTube& ' temporary image no longer needed
_FreeImage Sheet& ' sprite sheet no longer needed
Clean& = _NewImage(432, 768, 32) ' create clean image holder
_Dest Clean& ' work on clean image
Cls , _RGB32(84, 192, 201) ' clear image with sky blue color
Line (0, 620)-(431, 767), _RGB32(219, 218, 150), BF ' create brown ground portion of image
Line (0, 577)-(431, 595), _RGB32(100, 224, 117), BF ' create green grass portion of image
_Dest 0 ' back to work on screen
Scenery(1).image = Clouds& ' set scenery parallax information
Scenery(1).y = 457
Scenery(1).fmax = 8
Scenery(2).image = City&
Scenery(2).y = 510
Scenery(2).fmax = 4
Scenery(3).image = Bushes&
Scenery(3).y = 550
Scenery(3).fmax = 2
Scenery(4).image = HazardBar&
Scenery(4).y = 596
'If _FileExists("fbird.sco") Then ' does high score file exist?
' Open "fbird.sco" For Input As #1 ' yes, open high score file
' Input #1, HighScore% ' get high score from file
' Close #1 ' close high score file
'End If
End Sub
'----------------------------------------------------------------------------------------------------------------------
Function BOXCOLLISION% (Box1X As Integer, Box1Y As Integer, Box1Width As Integer, Box1Height As Integer, Box2X As Integer, Box2Y As Integer, Box2Width As Integer, Box2Height As Integer)
'**
'** Detects if two bounding box areas are in collision
'**
'** INPUT : Box1X% - upper left corner X location of bounding box 1
'** Box1Y% - upper left corner Y location of bounding box 1
'** Box1Width% - the width of bounding box 1
'** Box1Height% - the height of bounding box 1
'** Box2X% - upper left corner X location of bounding box 2
'** Box2Y% - upper left corner Y location of bounding box 2
'** Box2Width% - the width of bounding box 2
'** Box2Height% - the height of bounding box 2
'**
'** OUTPUT: BOXCOLLISION - 0 (FALSE) for no collision, -1 (TRUE) for collision
'**
If Box1X <= Box2X + Box2Width - 1 Then ' is box1 x within lower limit of box2 x?
If Box1X + Box1Width - 1 >= Box2X Then ' yes, is box1 x within upper limit of box2 x?
If Box1Y <= Box2Y + Box2Height - 1 Then ' yes, is box1 y within lower limit of box2 y?
If Box1Y + Box1Height - 1 >= Box2Y Then ' yes, is box1 y within upper limit of box2 y?
BOXCOLLISION = TRUE ' yes, then a collision occured, return result
End If
End If
End If
End If
End Function
'----------------------------------------------------------------------------------------------------------------------
Sub CLEANUP ()
'*
'* Removes all game assets from the computer's RAM.
'*
'Shared Fbird&(), Pipe&(), Num&(), Medal&(), Plaque&, FlappyBird&, GameOver&, GetReady&
'Shared Finger&, ScoreButton&, ShareButton&, StartButton&, OKButton&, RateButton&
'Shared MenuButton&, PlayButton&, PauseButton&, HazardBar&, Clouds&, City&, Bushes&
'Shared New&, Clean&, PipeImage&, Ding&, Flap&, Smack&
Dim x% ' generic counter
Dim y% ' generic counter
_SndClose Ding& ' remove game sounds from RAM
_SndClose Flap&
_SndClose Smack&
For y% = 0 To 2 ' cycle through bird image rows
For x% = 0 To 7 ' cycle through bird image columns
_FreeImage Fbird&(x% + 1, y% + 1) ' remove bird image from RAM
Next x%
Next y%
For x% = 0 To 9 ' cycle trough 9 numeral images
_FreeImage Num&(x%, 0) ' remove large numeral image from RAM
_FreeImage Num&(x%, 1) ' remove small numeral image from RAM
Next x%
_FreeImage Plaque& ' remove all remaining images from RAM
_FreeImage FlappyBird&
_FreeImage GameOver&
_FreeImage GetReady&
_FreeImage Pipe&(0)
_FreeImage Pipe&(1)
_FreeImage PipeImage&
_FreeImage Medal&(0, 0)
_FreeImage Medal&(0, 1)
_FreeImage Medal&(1, 0)
_FreeImage Medal&(1, 1)
_FreeImage Finger&
_FreeImage ScoreButton&
_FreeImage ShareButton&
_FreeImage StartButton&
_FreeImage OKButton&
_FreeImage RateButton&
_FreeImage MenuButton&
_FreeImage PlayButton&
_FreeImage PauseButton&
_FreeImage HazardBar&
_FreeImage Clouds&
_FreeImage City&
_FreeImage Bushes&
_FreeImage New&
_FreeImage Clean&
End Sub
'----------------------------------------------------------------------------------------------------------------------