Author Topic: Flappy Bird Clone by Terry Ritchie  (Read 458 times)

Offline Qwerkey

  • Moderator
  • Forum Resident
  • Posts: 736
Flappy Bird Clone by Terry Ritchie
« on: April 30, 2020, 04:24:10 AM »
Flappy Bird

Author: @TerryRitchie
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=437.0
Version: 1
Tags: [Graphics], [2D], [Game], [Side-scroller]

Description:
Here's an oldie, my QB64 version of FlappyBird. I used this program as an introduction to game programming in the course I used to teach.

Source Code:
Note the source code is given here for reference.  You will need all the files from the .zip
Code: QB64: [Select]
  1.     ' -----------------------------------------------
  2.     ' QB64 FlappyBird Clone by Terry Ritchie 02/28/14
  3.     '
  4.     ' This program was created to accompany the QB64
  5.     ' Game Programming course located at:
  6.     ' http://www.qb64sourcecode.com
  7.     '
  8.     ' You may not sell or distribute this game! It
  9.     ' was made for instructional purposes only.
  10.     '
  11.     ' Update: 04/29/20
  12.     '
  13.     ' Added EXE icon support in lines 18 and 19
  14.     ' Any key press now starts game in line 274
  15.     ' Any key press now flaps bird in line 196
  16.     '
  17.     ' -----------------------------------------------
  18.      
  19.     $EXEICON:'.\fbird.ico'
  20.     _ICON
  21.      
  22.     '--------------------------------
  23.     '- Variable declaration section -
  24.     '--------------------------------
  25.      
  26.     CONST FALSE = 0 '            boolean: truth  0
  27.     CONST TRUE = NOT FALSE '     boolean: truth -1
  28.     CONST LARGE = 0 '            large numbers
  29.     CONST SMALL = 1 '            small numbers (not used in current version of game)
  30.     CONST GOLD = 0 '             gold medal
  31.     CONST SILVER = 1 '           silver medal
  32.     CONST LIGHT = 0 '            light colored gold/silver medal
  33.     CONST DARK = 1 '             dark colored gold/silver medal
  34.      
  35.     TYPE PARALLAX '              parallax scenery settings
  36.         image AS LONG '          scene image
  37.         x AS INTEGER '           scene image x location
  38.         y AS INTEGER '           scene image y location
  39.         frame AS INTEGER '       current parallax frame
  40.         fmax AS INTEGER '        maximum parallax frames allowed
  41.     END TYPE
  42.      
  43.     TYPE INFLIGHT '              flappy bird inflight characterisitcs
  44.         y AS SINGLE '            flappy bird y location
  45.         yvel AS SINGLE '         flappy bird y velocity
  46.         flap AS INTEGER '        wing flap position
  47.         flapframe AS INTEGER '   wing flap frame counter
  48.         angle AS INTEGER '       angle of flappy bird
  49.     END TYPE
  50.      
  51.     TYPE PIPE '                  pipe characteristics
  52.         x AS INTEGER '           pipe x location
  53.         y AS INTEGER '           pipe y location
  54.     END TYPE
  55.      
  56.     DIM Pipes(3) AS PIPE '       define 3 moving sets of pipes
  57.     DIM Pipe&(1) '               pipe images 0=top 1=bottom
  58.     DIM PipeImage& '             all three pipes drawn image
  59.     DIM Birdie AS INFLIGHT '     bird flight characteristics
  60.     DIM Scenery(4) AS PARALLAX ' define 4 moving scenes in parallax
  61.     DIM Fbird&(8, 3) '           flapping bird images
  62.     DIM Num&(9, 1) '             big and small numeral images
  63.     DIM Plaque& '                medal/score plaque
  64.     DIM FlappyBird& '            Flappy Bird title image
  65.     DIM GameOver& '              Game Over image
  66.     DIM GetReady& '              Get Ready image
  67.     DIM Medal&(1, 1) '           gold/silver medal images
  68.     DIM Finger& '                tap finger image
  69.     DIM ScoreButton& '           score button image
  70.     DIM ShareButton& '           share button image
  71.     DIM StartButton& '           start button image
  72.     DIM OKButton& '              OK button image
  73.     DIM RateButton& '            RATE button image
  74.     DIM MenuButton& '            MENU button image
  75.     DIM PlayButton& '            PLAY [|>] button image
  76.     DIM PauseButton& '           PAUSE [||] button image
  77.     DIM HazardBar& '             Hazard bar parallax image
  78.     DIM Clouds& '                Clouds parallax image
  79.     DIM City& '                  Cityscape parallax image
  80.     DIM Bushes& '                Bushes parallax image
  81.     DIM New& '                   red NEW image
  82.     DIM Clean& '                 clean playing screen image
  83.     DIM HitBird% '               boolean: TRUE if bird hits something
  84.     DIM HighScore% '             high score
  85.     DIM Score% '                 current score
  86.     DIM Paused% '                boolean: TRUE if game paused
  87.     DIM Ding& '                  ding sound
  88.     DIM Flap& '                  flapping sound
  89.     DIM Smack& '                 bird smack sound
  90.     DIM Latch% '                 boolean: TRUE if mouse button held down
  91.     DIM WinX% '                  stops player from exiting program at will
  92.      
  93.     '------------------------
  94.     '- Main Program Section -
  95.     '------------------------
  96.      
  97.     SCREEN _NEWIMAGE(432, 768, 32) '                        create 432x768 game screen
  98.     _TITLE "FlappyBird" '                                   give window a title
  99.     CLS '                                                   clear the screen
  100.     _DELAY .5 '                                             slight delay before moving screen to middle
  101.     _SCREENMOVE _MIDDLE '                                   move window to center of desktop
  102.     WinX% = _EXIT '                                         program will handle all window close requests
  103.     LOADASSETS '                                            set/load game graphics/sounds/settings
  104.     Birdie.flap = 1 '                                       set initial wing position of bird
  105.     DO '                                                    BEGIN MAIN GAME LOOP
  106.         _LIMIT 60 '                                         60 frames per second
  107.         UPDATESCENERY '                                     update parallaxing scenery
  108.         _PUTIMAGE (40, 265), FlappyBird& '                  place game title on screen
  109.         _PUTIMAGE (350, 265), Fbird&(2, FLAPTHEBIRD%) '     place flapping bird on screen
  110.         IF BUTTON%(64, 535, StartButton&) THEN PLAYGAME '   if start button pressed play game
  111.         IF BUTTON%(248, 535, ScoreButton&) THEN SHOWSCORE ' if score button pressed show scores
  112.         IF BUTTON%(248, 480, RateButton&) THEN RATEGAME '   if rate button pressed bring up browser
  113.         _DISPLAY '                                          update screen with changes
  114.     LOOP UNTIL _KEYDOWN(27) OR _EXIT '                      END MAIN GAME LOOP when ESC pressed or window closed
  115.     CLEANUP '                                               clean the computer's RAM before leaving
  116.     SYSTEM '                                                return to Windows desktop
  117.      
  118.     '-------------------------------------
  119.     '- Subroutines and Functions section -
  120.     '-------------------------------------
  121.      
  122.     '----------------------------------------------------------------------------------------------------------------------
  123.      
  124.     FUNCTION FLAPTHEBIRD% ()
  125.      
  126.         '*
  127.         '* Returns the next index value used in Fbird&() to animate the bird's
  128.         '* flapping wings.
  129.         '*
  130.      
  131.         SHARED Birdie AS INFLIGHT
  132.      
  133.         Birdie.flapframe = Birdie.flapframe + 1 '     increment frame counter
  134.         IF Birdie.flapframe = 4 THEN '                hit limit?
  135.             Birdie.flapframe = 0 '                    yes, reset frame counter
  136.             Birdie.flap = Birdie.flap + 1 '           increment flap counter
  137.             IF Birdie.flap = 4 THEN Birdie.flap = 1 ' reset flap counter when limit hit
  138.         END IF
  139.         FLAPTHEBIRD% = Birdie.flap '                  return next index value
  140.      
  141.     END SUB
  142.      
  143.     '----------------------------------------------------------------------------------------------------------------------
  144.      
  145.     SUB MOVEPIPES ()
  146.      
  147.         '*
  148.         '* Creates and moves the pipe images across the screen.
  149.         '*
  150.      
  151.         SHARED Pipes() AS PIPE, Pipe&(), PipeImage&, Paused%, Score%, Ding&
  152.      
  153.         DIM p% ' counter indicating which pipe being worked on
  154.      
  155.         _DEST PipeImage& '                                    work on this image
  156.         CLS , _RGBA32(0, 0, 0, 0) '                           clear image with transparent black
  157.         _DEST 0 '                                             back to work on screen
  158.         DO '                                                  BEGIN PIPE LOOP
  159.             p% = p% + 1 '                                     increment pipe counter
  160.             IF NOT Paused% THEN '                             is game paused?
  161.                 Pipes(p%).x = Pipes(p%).x - 3 '               no, move pipe to the left
  162.                 IF Pipes(p%).x < -250 THEN '                  hit lower limit?
  163.                     Pipes(p%).x = 500 '                       yes, move pipe all the way right
  164.                     Pipes(p%).y = -(INT(RND(1) * 384) + 12) ' generate random pipe height position
  165.                 END IF
  166.                 IF Pipes(p%).x = 101 THEN '                   is pipe crossing bird location?
  167.                     _SNDPLAY Ding& '                          play ding sound
  168.                     Score% = Score% + 1 '                     increment player score
  169.                 END IF
  170.             END IF
  171.             IF Pipes(p%).x > -78 AND Pipes(p%).x < 432 THEN ' is pipe currently seen on screen?
  172.                 _PUTIMAGE (Pipes(p%).x, Pipes(p%).y), Pipe&(0), PipeImage& ' place top pipe
  173.                 _PUTIMAGE (Pipes(p%).x, Pipes(p%).y + 576), Pipe&(1), PipeImage& ' place bottom pipe
  174.             END IF
  175.         LOOP UNTIL p% = 3 '                                   END PIPE LOOP when all pipes moved
  176.         _PUTIMAGE (0, 0), PipeImage& '                        place pipe image on screen
  177.      
  178.     END SUB
  179.      
  180.     '----------------------------------------------------------------------------------------------------------------------
  181.      
  182.     SUB FLYBIRDIE ()
  183.      
  184.         '*
  185.         '* Controls the flight of bird on screen.
  186.         '*
  187.      
  188.         SHARED Birdie AS INFLIGHT, Fbird&(), Paused%, Flap&, HitBird%, Latch%, Smack&
  189.      
  190.         DIM b% '     boolean: TRUE if left mouse button pressed
  191.         DIM Angle% ' angle of bird in flight
  192.      
  193.         IF NOT Paused% THEN '                             is game paused?
  194.             WHILE _MOUSEINPUT: WEND '                     no, get latest mouse information
  195.             b% = _MOUSEBUTTON(1) '                        get left mouse button status
  196.             IF _KEYHIT > 0 THEN b% = -1 '                 any key will also make bird flap    (added 04/29/20)
  197.             IF NOT b% THEN Latch% = FALSE '               release latch if button let go
  198.             IF NOT HitBird% THEN '                        has bird hit something?
  199.                 IF NOT Latch% THEN '                      no, has left button been release?
  200.                     IF b% THEN '                          yes, was left button pressed?
  201.                         Birdie.yvel = -8 '                yes, reset bird y velocity
  202.                         _SNDPLAY Flap& '                  play flap sound
  203.                         Latch% = TRUE '                   remember mouse button pressed
  204.                     END IF
  205.                 END IF
  206.             END IF
  207.             Birdie.yvel = Birdie.yvel + .5 '              bleed off some bird y velocity
  208.             Birdie.y = Birdie.y + Birdie.yvel '           add velocity to bird's y direction
  209.             IF NOT HitBird% THEN '                        has bird hit something?
  210.                 IF Birdie.y < -6 OR Birdie.y > 549 THEN ' no, has bird hit top/bottom of screen?
  211.                     HitBird% = TRUE '                     yes, remeber bird hit something
  212.                     _SNDPLAY Smack& '                     play smack sound
  213.                 END IF
  214.             END IF
  215.             IF Birdie.yvel < 0 THEN '                     is bird heading upward?
  216.                 Birdie.angle = 1 '                        yes, set angle of bird accordingly
  217.             ELSE
  218.                 Angle% = INT(Birdie.yvel * .5) + 1 '      calculate angle according to bird velocity
  219.                 IF Angle% > 8 THEN Angle% = 8 '           keep angle within limits
  220.                 Birdie.angle = Angle% '                   set bird angle
  221.             END IF
  222.         END IF
  223.         _PUTIMAGE (100, Birdie.y), Fbird&(Birdie.angle, FLAPTHEBIRD%) ' place bird on screen
  224.      
  225.     END SUB
  226.      
  227.     '----------------------------------------------------------------------------------------------------------------------
  228.      
  229.     SUB UPDATESCORE ()
  230.      
  231.         '*
  232.         '* Displays player's score on screen.
  233.         '*
  234.      
  235.         SHARED Num&(), Score%
  236.      
  237.         DIM s$ ' score in string format
  238.         DIM w% ' width of score string
  239.         DIM x% ' x location of score digits
  240.         DIM p% ' position counter
  241.      
  242.         s$ = LTRIM$(RTRIM$(STR$(Score%))) ' convert score to string
  243.         w% = LEN(s$) * 23 '                 calculate width of score
  244.         x% = (432 - w%) \ 2 '               calculate x position of score
  245.         FOR p% = 1 TO LEN(s$) '             cycle through each position in score string
  246.             _PUTIMAGE (x%, 100), Num&(ASC(MID$(s$, p%, 1)) - 48, LARGE) ' place score digit on screen
  247.             x% = x% + 23 '                  move to next digit position
  248.         NEXT p%
  249.      
  250.     END SUB
  251.      
  252.     '----------------------------------------------------------------------------------------------------------------------
  253.      
  254.     SUB READY ()
  255.      
  256.         '*
  257.         '* displays instructions to the player and waits for player to start game.
  258.         '*
  259.      
  260.         SHARED Fbird&(), Finger&, GetReady&
  261.      
  262.         DIM b% ' boolean: TRUE if left mouse button pressed
  263.      
  264.         DO '                                 BEGIN READY LOOP
  265.             _LIMIT 60 '                      60 frames per second
  266.             UPDATESCENERY '                  move parallax scenery
  267.             _PUTIMAGE (180, 350), Finger& '  place finger instructions on screen
  268.             _PUTIMAGE (85, 225), GetReady& ' place get ready image on screen
  269.             _PUTIMAGE (100, 375), Fbird&(2, FLAPTHEBIRD%) ' place bird on screen
  270.             UPDATESCORE '                    place score on screen
  271.             _DISPLAY '                       update screen with changes
  272.             WHILE _MOUSEINPUT: WEND '        get latest mouse information
  273.             b% = _MOUSEBUTTON(1) '           get status of left mouse button
  274.             IF _KEYHIT > 0 THEN b% = -1 '    any key press will also begin game           (added 04/29/20)
  275.             IF _EXIT THEN CLEANUP: SYSTEM '  leave game if user closes game window
  276.         LOOP UNTIL b% '                      END READY LOOP when left button pressed
  277.         _DELAY .2 '                          slight delay to allow mouse button release
  278.      
  279.     END SUB
  280.      
  281.     '----------------------------------------------------------------------------------------------------------------------
  282.      
  283.     SUB PLAYGAME ()
  284.      
  285.         '*
  286.         '* Allows player to play the game.
  287.         '*
  288.      
  289.         SHARED Pipes() AS PIPE, Birdie AS INFLIGHT, PauseButton&, PlayButton&, Paused%, HitBird%, Score%
  290.      
  291.         RANDOMIZE TIMER '                                seed random number generator
  292.         Score% = 0 '                                     reset player score
  293.         Birdie.y = 0 '                                   reset bird y location
  294.         Birdie.yvel = 0 '                                reset bird y velocity
  295.         Birdie.flap = 1 '                                reset bird wing flap index
  296.         Pipes(1).x = 500 '                               reset position of first pipe
  297.         Pipes(2).x = 749 '                               reset position of second pipe
  298.         Pipes(3).x = 998 '                               reset position of third pipe
  299.         Pipes(1).y = -(INT(RND(1) * 384) + 12) '         calculate random y position of pipe 1
  300.         Pipes(2).y = -(INT(RND(1) * 384) + 12) '         calculate random y position of pipe 2
  301.         Pipes(3).y = -(INT(RND(1) * 384) + 12) '         calculate random y position of pipe 3
  302.         READY '                                          display instructions to player
  303.         DO '                                             BEGIN GAME PLAY LOOP
  304.             _LIMIT 60 '                                  60 frames per second
  305.             UPDATESCENERY '                              move parallax scenery
  306.             MOVEPIPES '                                  move pipes
  307.             UPDATESCORE '                                display player score
  308.             FLYBIRDIE '                                  move and display bird
  309.             CHECKFORHIT '                                check for bird hits
  310.             IF NOT Paused% THEN '                        is game paused?
  311.                 IF BUTTON%(30, 100, PauseButton&) THEN ' no, was pause button pressed?
  312.                     Paused% = TRUE '                     yes, place game in pause state
  313.                 END IF
  314.             ELSE '                                       no, game is not paused
  315.                 IF BUTTON%(30, 100, PlayButton&) THEN '  was play button pressed?
  316.                     Paused% = FALSE '                    yes, take game out of pause state
  317.                 END IF
  318.             END IF
  319.             _DISPLAY '                                   update screen with changes
  320.             IF _EXIT THEN CLEANUP: SYSTEM '              leave game if user closes game window
  321.         LOOP UNTIL HitBird% '                            END GAME PLAY LOOP if bird hits something
  322.         DO '                                             BEGIN BIRD DROPPING LOOP
  323.             _LIMIT 60 '                                  60 frames per second
  324.             Paused% = TRUE '                             place game in paused state
  325.             UPDATESCENERY '                              draw parallax scenery
  326.             MOVEPIPES '                                  draw pipes
  327.             Paused% = FALSE '                            take game out of pause state
  328.             FLYBIRDIE '                                  move bird on screen
  329.             _DISPLAY '                                   update screen with changes
  330.             IF _EXIT THEN CLEANUP: SYSTEM '              leave game if user closes game window
  331.         LOOP UNTIL Birdie.y >= 546 '                     END BIRD DROPPING LOOP when bird hits ground
  332.         SHOWSCORE '                                      display player's score plaque
  333.         HitBird% = FALSE '                               reset bird hit indicator
  334.      
  335.     END SUB
  336.      
  337.     '----------------------------------------------------------------------------------------------------------------------
  338.      
  339.     SUB CHECKFORHIT ()
  340.      
  341.         '*
  342.         '* Detects if bird hits a pipe.
  343.         '*
  344.      
  345.         SHARED Pipes() AS PIPE, Birdie AS INFLIGHT, HitBird%, Smack&
  346.      
  347.         DIM p% ' pipe counter
  348.      
  349.         FOR p% = 1 TO 3 '                                      cycle through all pipe positions
  350.             IF Pipes(p%).x <= 153 AND Pipes(p%).x >= 22 THEN ' is pipe in bird territory?
  351.                 IF BOXCOLLISION(105, Birdie.y + 6, 43, 41, Pipes(p%).x, Pipes(p%).y, 78, 432) THEN ' collision?
  352.                     HitBird% = TRUE '                          yes, remember bird hit pipe
  353.                 END IF
  354.                 IF BOXCOLLISION(105, Birdie.y + 6, 43, 41, Pipes(p%).x, Pipes(p%).y + 576, 78, 432) THEN ' collision?
  355.                     HitBird% = TRUE '                          yes, remember bird hit pipe
  356.                 END IF
  357.             END IF
  358.         NEXT p%
  359.         IF HitBird% THEN _SNDPLAY Smack& '                     play smack sound if bird hit pipe
  360.      
  361.     END SUB
  362.      
  363.     '----------------------------------------------------------------------------------------------------------------------
  364.      
  365.     SUB RATEGAME ()
  366.      
  367.         '*
  368.         '* Allows player to rate game.
  369.         '*
  370.      
  371.         SHELL "https://www.qb64.org/forum/index.php?topic=437.0" ' go to QB64 web site forum area for flappy bird
  372.      
  373.     END SUB
  374.      
  375.     '----------------------------------------------------------------------------------------------------------------------
  376.      
  377.     SUB SHOWSCORE ()
  378.      
  379.         '*
  380.         '* Display's current and high scores on score plaque
  381.         '*
  382.      
  383.         SHARED Fbird&(), Num&(), Medal&(), FlappyBird&, GameOver&, Plaque&, OKButton&, ShareButton&
  384.         SHARED HitBird%, HighScore%, Score%, New&
  385.      
  386.         DIM Ok% '        boolean: TRUE if OK button pressed
  387.         DIM Scores%(1) ' current and high scores
  388.         DIM sc% '        current score being drawn
  389.         DIM x% '         x location of score digits
  390.         DIM p% '         digit position counter
  391.         DIM ShowNew% '   boolean: TRUE if score is a new high score
  392.         DIM s$ '         score in string format
  393.      
  394.         IF Score% > HighScore% THEN '                               is this a new high score?
  395.             OPEN "fbird.sco" FOR OUTPUT AS #1 '                     yes, open score file
  396.             PRINT #1, Score% '                                      save new high score
  397.             CLOSE #1 '                                              close score file
  398.             HighScore% = Score% '                                   remember new high score
  399.             ShowNew% = TRUE '                                       remember this is a new high score
  400.         END IF
  401.         Scores%(0) = Score% '                                       place score in array
  402.         Scores%(1) = HighScore% '                                   place high score in array
  403.         Ok% = FALSE '                                               reset OK button status indicator
  404.         DO '                                                        BEGIN SCORE LOOP
  405.             _LIMIT 60 '                                             60 frames per second
  406.             IF HitBird% THEN '                                      did bird hit something?
  407.                 _PUTIMAGE (75, 200), GameOver& '                    yes, place game over image on screen
  408.             ELSE '                                                  no, bird did not hit anything
  409.                 UPDATESCENERY '                                     move parallax scenery
  410.                 _PUTIMAGE (40, 200), FlappyBird& '                  place flappy bird title on screen
  411.                 _PUTIMAGE (350, 200), Fbird&(2, FLAPTHEBIRD%) '     place flapping bird on screen
  412.             END IF
  413.             _PUTIMAGE (46, 295), Plaque& '                          place plaque on screen
  414.             SELECT CASE HighScore% '                                what is range of high score?
  415.                 CASE 25 TO 49 '                                     from 25 to 49
  416.                     _PUTIMAGE (85, 360), Medal&(SILVER, LIGHT) '    display a light silver medal
  417.                 CASE 50 TO 99 '                                     from 50 to 99
  418.                     _PUTIMAGE (85, 360), Medal&(SILVER, DARK) '     display a dark silver medal
  419.                 CASE 100 TO 199 '                                   from 100 to 199
  420.                     _PUTIMAGE (85, 360), Medal&(GOLD, LIGHT) '      display a light gold medal
  421.                 CASE IS > 199 '                                     from 200 and beyond
  422.                     _PUTIMAGE (85, 360), Medal&(GOLD, DARK) '       display a dark gold medal
  423.             END SELECT
  424.             FOR sc% = 0 TO 1 '                                      cycle through both scores
  425.                 s$ = LTRIM$(RTRIM$(STR$(Scores%(sc%)))) '           convert score to string
  426.                 x% = 354 - LEN(s$) * 23 '                           calculate position of score digit
  427.                 FOR p% = 1 TO LEN(s$) '                             cycle through score string
  428.                     _PUTIMAGE (x%, 346 + sc% * 64), Num&(ASC(MID$(s$, p%, 1)) - 48, LARGE) ' place digit on plaque
  429.                     x% = x% + 23 '                                  increment digit position
  430.                 NEXT p%
  431.             NEXT sc%
  432.             IF ShowNew% THEN _PUTIMAGE (250, 382), New& '           display red new image if new high score
  433.             IF BUTTON%(64, 535, OKButton&) THEN Ok% = TRUE '        remember if OK button was pressed
  434.             IF BUTTON%(248, 535, ShareButton&) THEN '               was share button pressed?
  435.                 SHAREPROGRAM '                                      yes, share program with others
  436.                 UPDATESCENERY '                                     draw parallax scenery
  437.                 MOVEPIPES '                                         draw pipes
  438.             END IF
  439.             _DISPLAY '                                              update screen with changes
  440.             IF _EXIT THEN CLEANUP: SYSTEM '                         leave game if user closes game window
  441.         LOOP UNTIL Ok% '                                            END SCORE LOOP when OK button pressed
  442.      
  443.     END SUB
  444.      
  445.     '----------------------------------------------------------------------------------------------------------------------
  446.      
  447.     SUB SHAREPROGRAM ()
  448.      
  449.         '*
  450.         '* Allows player to share program with others
  451.         '*
  452.      
  453.         SHARED Fbird&(), FlappyBird&, OKButton&
  454.      
  455.         DIM Message& ' composed message to player's friend(s)
  456.         DIM Ok% '      boolean: TRUE if OK button pressed
  457.      
  458.         Message& = _NEWIMAGE(339, 174, 32) '                   create image to hold message to player
  459.         _CLIPBOARD$ = "I just discovered a great game! You can download it here: http:\\www.qb64sourcecode.com\fbird.exe"
  460.         _PRINTMODE _KEEPBACKGROUND '                           printed text will save background
  461.         LINE (58, 307)-(372, 453), _RGB32(219, 218, 150), BF ' clear plaque image
  462.         COLOR _RGB32(210, 170, 79) '                           compose message to player on plaque
  463.         _PRINTSTRING (66, 316), "The following message has been copied"
  464.         COLOR _RGB32(82, 55, 71)
  465.         _PRINTSTRING (65, 315), "The following message has been copied"
  466.         COLOR _RGB32(210, 170, 79)
  467.         _PRINTSTRING (66, 331), "to your computer's clipboard:"
  468.         COLOR _RGB32(82, 55, 71)
  469.         _PRINTSTRING (65, 330), "to your computer's clipboard:"
  470.         COLOR _RGB32(210, 170, 79)
  471.         _PRINTSTRING (66, 351), "'I just discovered a great game! You"
  472.         COLOR _RGB32(82, 55, 71)
  473.         _PRINTSTRING (65, 350), "'I just discovered a great game! You"
  474.         COLOR _RGB32(210, 170, 79)
  475.         _PRINTSTRING (66, 366), "can download it here:"
  476.         COLOR _RGB32(82, 55, 71)
  477.         _PRINTSTRING (65, 365), "can download it here:"
  478.         COLOR _RGB32(210, 170, 79)
  479.         _PRINTSTRING (66, 381), "www.qb64sourcecode.com\fbird.exe'"
  480.         COLOR _RGB32(82, 55, 71)
  481.         _PRINTSTRING (65, 380), "www.qb64sourcecode.com\fbird.exe'"
  482.         COLOR _RGB32(210, 170, 79)
  483.         _PRINTSTRING (66, 401), "Create an email for your friends and"
  484.         COLOR _RGB32(82, 55, 71)
  485.         _PRINTSTRING (65, 400), "Create an email for your friends and"
  486.         COLOR _RGB32(210, 170, 79)
  487.         _PRINTSTRING (66, 416), "paste this message into it! Go ahead,"
  488.         COLOR _RGB32(82, 55, 71)
  489.         _PRINTSTRING (65, 415), "paste this message into it! Go ahead,"
  490.         COLOR _RGB32(210, 170, 79)
  491.         _PRINTSTRING (66, 431), "do it now before you change your mind!"
  492.         COLOR _RGB32(82, 55, 71)
  493.         _PRINTSTRING (65, 430), "do it now before you change your mind!"
  494.         _PUTIMAGE , _DEST, Message&, (46, 295)-(384, 468) '    place message in image
  495.         DO '                                                   BEGIN SHARE LOOP
  496.             _LIMIT 60 '                                        60 frames per second
  497.             UPDATESCENERY '                                    move parallax scenery
  498.             _PUTIMAGE (40, 200), FlappyBird& '                 place flappy bird title on screen
  499.             _PUTIMAGE (350, 200), Fbird&(2, FLAPTHEBIRD%) '    place flapping bird on screen
  500.             _PUTIMAGE (46, 295), Message& '                    place message on plaque
  501.             IF BUTTON%(156, 535, OKButton&) THEN Ok% = TRUE '  remeber if OK button pressed
  502.             _DISPLAY '                                         update screen with changes
  503.             IF _EXIT THEN CLEANUP: SYSTEM '                    leave game if user closes game window
  504.         LOOP UNTIL Ok% '                                       END SHRE LOOP when OK button pressed
  505.         _FREEIMAGE Message& '                                  message image no longer needed
  506.      
  507.     END SUB
  508.      
  509.     '----------------------------------------------------------------------------------------------------------------------
  510.      
  511.     FUNCTION BUTTON% (xpos%, ypos%, Image&)
  512.      
  513.         '*
  514.         '* Creates a button on the screen the player can click with the mouse button.
  515.         '*
  516.         '* xpos%  - x coordinate position of button on screen
  517.         '* ypos%  - y coordinate position of button on screen
  518.         '* Image& - button image
  519.         '*
  520.         '* Returns: boolean: TRUE  if button pressed
  521.         '*                   FALSE if button not pressed
  522.         '*
  523.      
  524.         DIM x% ' current mouse x coordinate
  525.         DIM y% ' current mouse y coordinate
  526.         DIM b% ' boolean: TRUE if left mouse button pressed
  527.      
  528.         _PUTIMAGE (xpos%, ypos%), Image& '                      place button image on the screen
  529.         WHILE _MOUSEINPUT: WEND '                               get latest mouse information
  530.         x% = _MOUSEX '                                          get current mouse x coordinate
  531.         y% = _MOUSEY '                                          get current mouse y coordinate
  532.         b% = _MOUSEBUTTON(1)
  533.         IF b% THEN '                                            is left mouse button pressed?
  534.             IF x% >= xpos% THEN '                               yes, is mouse x within lower limit of button?
  535.                 IF x% <= xpos% + _WIDTH(Image&) THEN '          yes, is mouse x within upper limit of button?
  536.                     IF y% >= ypos% THEN '                       yes, is mouse y within lower limit of button?
  537.                         IF y% <= ypos% + _HEIGHT(Image&) THEN ' yes, is mouse y within upper limit of button?
  538.                             BUTTON% = TRUE '                    yes, remember that button was clicked on
  539.                             _DELAY .2 '                         slight delay to allow button to release
  540.                         END IF
  541.                     END IF
  542.                 END IF
  543.             END IF
  544.         END IF
  545.      
  546.      
  547.     '----------------------------------------------------------------------------------------------------------------------
  548.      
  549.     SUB UPDATESCENERY ()
  550.      
  551.         '*
  552.         '* Updates the moving parallax scenery
  553.         '*
  554.      
  555.         SHARED Scenery() AS PARALLAX, Clean&, HazardBar&, Paused%
  556.      
  557.         DIM c% ' scenery index indicator
  558.      
  559.         _PUTIMAGE , Clean& '                                              clear screen with clean image
  560.         DO '                                                              BEGIN SCENERY LOOP
  561.             c% = c% + 1 '                                                 increment index value
  562.             IF NOT Paused% THEN '                                         is game in paused state?
  563.                 Scenery(c%).frame = Scenery(c%).frame + 1 '               no, update frame counter of current scenery
  564.                 IF Scenery(c%).frame = Scenery(c%).fmax THEN '            frame counter hit limit?
  565.                     Scenery(c%).frame = 0 '                               yes, reset frame counter
  566.                     Scenery(c%).x = Scenery(c%).x - 1 '                   move scenery 1 pixel to left
  567.                     IF Scenery(c%).x = -432 THEN '                        scenery hit lower limit?
  568.                         Scenery(c%).x = 0 '                               yes, reset scenery to start position
  569.                     END IF
  570.                 END IF
  571.             END IF
  572.             _PUTIMAGE (Scenery(c%).x, Scenery(c%).y), Scenery(c%).image ' place current scenery on screen
  573.         LOOP UNTIL c% = 3 '                                               END SCENERY LOOP when all scenery updated
  574.         IF NOT Paused% THEN '                                             is game in paused state?
  575.             Scenery(4).x = Scenery(4).x - 3 '                             no, move hazard bar 3 pixels to left
  576.             IF Scenery(4).x = -21 THEN Scenery(4).x = 0 '                 reset to start position if lower limit hit
  577.         END IF
  578.         _PUTIMAGE (Scenery(4).x, Scenery(4).y), HazardBar& '              place hazard bar on screen
  579.      
  580.     END SUB
  581.      
  582.     '----------------------------------------------------------------------------------------------------------------------
  583.      
  584.     SUB LOADASSETS ()
  585.      
  586.         '*
  587.         '* Loads game graphics, sounds and initial settings.
  588.         '*
  589.      
  590.         SHARED Scenery() AS PARALLAX, Birdie AS INFLIGHT, Pipes() AS PIPE, Pipe&(), Fbird&()
  591.         SHARED Num&(), Medal&(), Plaque&, FlappyBird&, GameOver&, GetReady&, Finger&
  592.         SHARED ScoreButton&, ShareButton&, StartButton&, OKButton&, RateButton&, MenuButton&
  593.         SHARED PlayButton&, PauseButton&, HazardBar&, Clouds&, City&, Bushes&, New&, Clean&
  594.         SHARED HighScore%, PipeImage&, Ding&, Flap&, Smack&
  595.      
  596.         DIM Sheet& '    sprite sheet image
  597.         DIM x% '        generic counter
  598.         DIM y% '        generic counter
  599.         DIM PipeTop& '  temporary top of pipe image
  600.         DIM PipeTube& ' temporary pipe tube image
  601.      
  602.         Ding& = _SNDOPEN("fbding.ogg", "VOL,SYNC") '         load game sounds
  603.         Flap& = _SNDOPEN("fbflap.ogg", "VOL,SYNC")
  604.         Smack& = _SNDOPEN("fbsmack.ogg", "VOL,SYNC")
  605.         Sheet& = _LOADIMAGE("fbsheet.png", 32) '             load sprite sheet
  606.         FOR y% = 0 TO 2 '                                          cycle through bird image rows
  607.             FOR x% = 0 TO 7 '                                      cycle through bird image columns
  608.                 Fbird&(x% + 1, y% + 1) = _NEWIMAGE(53, 53, 32) '   create image holder then get image
  609.                 _PUTIMAGE , Sheet&, Fbird&(x% + 1, y% + 1), (x% * 53, y% * 53)-(x% * 53 + 52, y% * 53 + 52)
  610.             NEXT x%
  611.         NEXT y%
  612.         FOR x% = 0 TO 9 '                                          cycle trough 9 numeral images
  613.             Num&(x%, 0) = _NEWIMAGE(21, 30, 32) '                  create image holder for big
  614.             Num&(x%, 1) = _NEWIMAGE(18, 21, 32) '                  create image holder for small
  615.             _PUTIMAGE , Sheet&, Num&(x%, 0), (x% * 21, 159)-(x% * 21 + 20, 188) ' get images
  616.             _PUTIMAGE , Sheet&, Num&(x%, 1), (x% * 18 + 210, 159)-(x% * 18 + 227, 179)
  617.         NEXT x%
  618.         Plaque& = _NEWIMAGE(339, 174, 32) '                        define remaining image sizes
  619.         FlappyBird& = _NEWIMAGE(288, 66, 32)
  620.         GameOver& = _NEWIMAGE(282, 57, 32)
  621.         GetReady& = _NEWIMAGE(261, 66, 32)
  622.         PipeTop& = _NEWIMAGE(78, 36, 32)
  623.         PipeTube& = _NEWIMAGE(78, 36, 32)
  624.         Pipe&(0) = _NEWIMAGE(78, 432, 32)
  625.         Pipe&(1) = _NEWIMAGE(78, 432, 32)
  626.         PipeImage& = _NEWIMAGE(432, 596, 32)
  627.         Medal&(0, 0) = _NEWIMAGE(66, 66, 32)
  628.         Medal&(0, 1) = _NEWIMAGE(66, 66, 32)
  629.         Medal&(1, 0) = _NEWIMAGE(66, 66, 32)
  630.         Medal&(1, 1) = _NEWIMAGE(66, 66, 32)
  631.         Finger& = _NEWIMAGE(117, 147, 32)
  632.         ScoreButton& = _NEWIMAGE(120, 42, 32)
  633.         ShareButton& = _NEWIMAGE(120, 42, 32)
  634.         StartButton& = _NEWIMAGE(120, 42, 32)
  635.         OKButton& = _NEWIMAGE(120, 42, 32)
  636.         RateButton& = _NEWIMAGE(120, 42, 32)
  637.         MenuButton& = _NEWIMAGE(120, 42, 32)
  638.         PlayButton& = _NEWIMAGE(39, 42, 32)
  639.         PauseButton& = _NEWIMAGE(39, 42, 32)
  640.         HazardBar& = _NEWIMAGE(462, 24, 32)
  641.         Clouds& = _NEWIMAGE(864, 120, 32)
  642.         City& = _NEWIMAGE(864, 57, 32)
  643.         Bushes& = _NEWIMAGE(864, 27, 32)
  644.         New& = _NEWIMAGE(48, 21, 32)
  645.         _PUTIMAGE , Sheet&, Plaque&, (0, 189)-(338, 362) '         grab images from sprite sheet
  646.         _PUTIMAGE , Sheet&, FlappyBird&, (0, 363)-(287, 428)
  647.         _PUTIMAGE , Sheet&, GameOver&, (588, 246)-(869, 302)
  648.         _PUTIMAGE , Sheet&, GetReady&, (588, 303)-(847, 368)
  649.         _PUTIMAGE , Sheet&, Medal&(0, 0), (339, 327)-(404, 392)
  650.         _PUTIMAGE , Sheet&, Medal&(0, 1), (405, 327)-(470, 392)
  651.         _PUTIMAGE , Sheet&, Medal&(1, 0), (339, 261)-(404, 326)
  652.         _PUTIMAGE , Sheet&, Medal&(1, 1), (405, 261)-(470, 326)
  653.         _PUTIMAGE , Sheet&, Finger&, (471, 246)-(587, 392)
  654.         _PUTIMAGE , Sheet&, ScoreButton&, (288, 417)-(407, 458)
  655.         _PUTIMAGE , Sheet&, ShareButton&, (408, 417)-(527, 458)
  656.         _PUTIMAGE , Sheet&, StartButton&, (528, 417)-(647, 458)
  657.         _PUTIMAGE , Sheet&, OKButton&, (424, 204)-(543, 245)
  658.         _PUTIMAGE , Sheet&, RateButton&, (544, 204)-(663, 245)
  659.         _PUTIMAGE , Sheet&, MenuButton&, (664, 204)-(783, 245)
  660.         _PUTIMAGE , Sheet&, PlayButton&, (784, 204)-(822, 245)
  661.         _PUTIMAGE , Sheet&, PauseButton&, (823, 204)-(861, 245)
  662.         _PUTIMAGE , Sheet&, HazardBar&, (288, 393)-(749, 416)
  663.         _PUTIMAGE (0, 0)-(431, 119), Sheet&, Clouds&, (424, 0)-(855, 119)
  664.         _PUTIMAGE (432, 0)-(863, 119), Sheet&, Clouds&, (424, 0)-(855, 119)
  665.         _PUTIMAGE (0, 0)-(431, 56), Sheet&, City&, (424, 120)-(855, 176)
  666.         _PUTIMAGE (432, 0)-(863, 56), Sheet&, City&, (424, 120)-(855, 176)
  667.         _PUTIMAGE (0, 0)-(431, 26), Sheet&, Bushes&, (424, 177)-(855, 203)
  668.         _PUTIMAGE (432, 0)-(863, 26), Sheet&, Bushes&, (424, 177)-(855, 203)
  669.         _PUTIMAGE , Sheet&, New&, (289, 363)-(336, 383)
  670.         _PUTIMAGE , Sheet&, PipeTop&, (339, 189)-(416, 224)
  671.         _PUTIMAGE , Sheet&, PipeTube&, (339, 225)-(416, 260)
  672.         _PUTIMAGE (0, 431)-(77, 395), PipeTop&, Pipe&(0) '         create bottom of upper tube image
  673.         _PUTIMAGE (0, 0), PipeTop&, Pipe&(1) '                     create top of lower tube image
  674.         FOR y% = 0 TO 395 STEP 36 '                                cycle through tube body of pipes
  675.             _PUTIMAGE (0, y% + 35)-(77, y%), PipeTube&, Pipe&(0) ' draw tube on upper pipe image
  676.             _PUTIMAGE (0, 36 + y%), PipeTube&, Pipe&(1) '          draw tube on lower pipe image
  677.         NEXT y%
  678.         _FREEIMAGE PipeTop& '                                      temporary image no longer needed
  679.         _FREEIMAGE PipeTube& '                                     temporary image no longer needed
  680.         _FREEIMAGE Sheet& '                                        sprite sheet no longer needed
  681.         Clean& = _NEWIMAGE(432, 768, 32) '                         create clean image holder
  682.         _DEST Clean& '                                             work on clean image
  683.         CLS , _RGB32(84, 192, 201) '                               clear image with sky blue color
  684.         LINE (0, 620)-(431, 767), _RGB32(219, 218, 150), BF '      create brown ground portion of image
  685.         LINE (0, 577)-(431, 595), _RGB32(100, 224, 117), BF '      create green grass portion of image
  686.         _DEST 0 '                                                  back to work on screen
  687.         Scenery(1).image = Clouds& '                               set scenery parallax information
  688.         Scenery(1).y = 457
  689.         Scenery(1).fmax = 8
  690.         Scenery(2).image = City&
  691.         Scenery(2).y = 510
  692.         Scenery(2).fmax = 4
  693.         Scenery(3).image = Bushes&
  694.         Scenery(3).y = 550
  695.         Scenery(3).fmax = 2
  696.         Scenery(4).image = HazardBar&
  697.         Scenery(4).y = 596
  698.         IF _FILEEXISTS("fbird.sco") THEN '                         does high score file exist?
  699.             OPEN "fbird.sco" FOR INPUT AS #1 '                     yes, open high score file
  700.             INPUT #1, HighScore% '                                 get high score from file
  701.             CLOSE #1 '                                             close high score file
  702.         END IF
  703.      
  704.     END SUB
  705.      
  706.     '----------------------------------------------------------------------------------------------------------------------
  707.      
  708.     FUNCTION BOXCOLLISION% (Box1X%, Box1Y%, Box1Width%, Box1Height%, Box2X%, Box2Y%, Box2Width%, Box2Height%)
  709.      
  710.         '**
  711.         '** Detects if two bounding box areas are in collision
  712.         '**
  713.         '** INPUT : Box1X%      - upper left corner X location of bounding box 1
  714.         '**         Box1Y%      - upper left corner Y location of bounding box 1
  715.         '**         Box1Width%  - the width of bounding box 1
  716.         '**         Box1Height% - the height of bounding box 1
  717.         '**         Box2X%      - upper left corner X location of bounding box 2
  718.         '**         Box2Y%      - upper left corner Y location of bounding box 2
  719.         '**         Box2Width%  - the width of bounding box 2
  720.         '**         Box2Height% - the height of bounding box 2
  721.         '**
  722.         '** OUTPUT: BOXCOLLISION - 0 (FALSE) for no collision, -1 (TRUE) for collision
  723.         '**
  724.      
  725.         IF Box1X% <= Box2X% + Box2Width% - 1 THEN '              is box1 x within lower limit of box2 x?
  726.             IF Box1X% + Box1Width% - 1 >= Box2X% THEN '          yes, is box1 x within upper limit of box2 x?
  727.                 IF Box1Y% <= Box2Y% + Box2Height% - 1 THEN '     yes, is box1 y within lower limit of box2 y?
  728.                     IF Box1Y% + Box1Height% - 1 >= Box2Y% THEN ' yes, is box1 y within upper limit of box2 y?
  729.                         BOXCOLLISION% = TRUE '                   yes, then a collision occured, return result
  730.                     END IF
  731.                 END IF
  732.             END IF
  733.         END IF
  734.      
  735.      
  736.     '----------------------------------------------------------------------------------------------------------------------
  737.      
  738.     SUB CLEANUP ()
  739.      
  740.         '*
  741.         '* Removes all game assets from the computer's RAM.
  742.         '*
  743.      
  744.         SHARED Fbird&(), Pipe&(), Num&(), Medal&(), Plaque&, FlappyBird&, GameOver&, GetReady&
  745.         SHARED Finger&, ScoreButton&, ShareButton&, StartButton&, OKButton&, RateButton&
  746.         SHARED MenuButton&, PlayButton&, PauseButton&, HazardBar&, Clouds&, City&, Bushes&
  747.         SHARED New&, Clean&, PipeImage&, Ding&, Flap&, Smack&
  748.      
  749.         DIM x% '              generic counter
  750.         DIM y% '              generic counter
  751.      
  752.         _SNDCLOSE Ding& '                           remove game sounds from RAM
  753.         _SNDCLOSE Flap&
  754.         _SNDCLOSE Smack&
  755.         FOR y% = 0 TO 2 '                           cycle through bird image rows
  756.             FOR x% = 0 TO 7 '                       cycle through bird image columns
  757.                 _FREEIMAGE Fbird&(x% + 1, y% + 1) ' remove bird image from RAM
  758.             NEXT x%
  759.         NEXT y%
  760.         FOR x% = 0 TO 9 '                           cycle trough 9 numeral images
  761.             _FREEIMAGE Num&(x%, 0) '                remove large numeral image from RAM
  762.             _FREEIMAGE Num&(x%, 1) '                remove small numeral image from RAM
  763.         NEXT x%
  764.         _FREEIMAGE Plaque& '                        remove all remaining images from RAM
  765.         _FREEIMAGE FlappyBird&
  766.         _FREEIMAGE GameOver&
  767.         _FREEIMAGE GetReady&
  768.         _FREEIMAGE Pipe&(0)
  769.         _FREEIMAGE Pipe&(1)
  770.         _FREEIMAGE PipeImage&
  771.         _FREEIMAGE Medal&(0, 0)
  772.         _FREEIMAGE Medal&(0, 1)
  773.         _FREEIMAGE Medal&(1, 0)
  774.         _FREEIMAGE Medal&(1, 1)
  775.         _FREEIMAGE Finger&
  776.         _FREEIMAGE ScoreButton&
  777.         _FREEIMAGE ShareButton&
  778.         _FREEIMAGE StartButton&
  779.         _FREEIMAGE OKButton&
  780.         _FREEIMAGE RateButton&
  781.         _FREEIMAGE MenuButton&
  782.         _FREEIMAGE PlayButton&
  783.         _FREEIMAGE PauseButton&
  784.         _FREEIMAGE HazardBar&
  785.         _FREEIMAGE Clouds&
  786.         _FREEIMAGE City&
  787.         _FREEIMAGE Bushes&
  788.         _FREEIMAGE New&
  789.         _FREEIMAGE Clean&
  790.      
  791.     END SUB
  792.      
  793.     '----------------------------------------------------------------------------------------------------------------------
  794.      

 
« Last Edit: April 30, 2020, 04:32:51 AM by Qwerkey »