Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Another Mouse Issue?
#11
You can also control a player's fire rate by using a latching method that keeps track of a key's current state (pressed or released).

I made a quick demo to show how this can be used in a game.

I have no idea why my comments get skewed when posting using the QB tags? This happens when exporting to HTML as well. I wish someone would look into this.

Code: (Select All)
'+-----------------------------------------------------------------------------------+
'|                            Controlling Bullets                                  |
'|                                                                                  |
'|                          "Wearing the player out"                                |
'|                            ----------------------                                |
'|                                                                                  |
'| This method forces the player to release the fire button to fire the next bullet. |
'| This allows the player to rapid fire as fast as they can push the button which in |
'| turn wears the player out.                                                        |
'|                                                                                  |
'| A "latching" method is used to keep track of the fire button's current state.    |
'| This method is also used in the player's ship movements to keep the game from    |
'| registering the UP and DOWN arrow keys being pressed at the same time and the    |
'| RIGHT and LEFT arrows keys from being pressed at the same time as well.          |
'|                                                                                  |
'|                                                                                  |
'| This method can be combined with frame timers to limit the number of bullets per  |
'| second as well.                                                                  |
'|                                                                                  |
'|                        Demo by Terry Ritchie 04/25/24                            |
'+-----------------------------------------------------------------------------------+

OPTION _EXPLICIT '          force declaration of all variables

'+-----------------------+
'| Define game constants |
'+-----------------------+

CONST SCREENWIDTH% = 800 '  game screen width
CONST SCREENHEIGHT% = 600 ' game screen height
CONST BUTTONUP% = 0 '      button position is up (depressed)
CONST BUTTONDOWN% = 1 '    button position is down (pressed)

'+-----------------------------+
'| Define variables structures |
'+-----------------------------+

TYPE KEY '                  DEFINE KEYBOARD KEY
    Key AS INTEGER '        scan code of key
    Position AS INTEGER '  position of keyboard key (the "latch")
END TYPE

TYPE BUTTON '              DEFINE GAME BUTTONS
    North AS KEY '          up arrow key
    South AS KEY '          down arrow key
    East AS KEY '          right arrow key
    West AS KEY '          left arrow key
    Fire AS KEY '          space bar key
END TYPE

TYPE BULLET '              DEFINE BULLET
    Active AS INTEGER '    bullet active (y/n)
    x AS INTEGER '          center x coordinate of bullet
    y AS INTEGER '          center y coordinate of bullet
    Speed AS SINGLE '      bullet speed
END TYPE

TYPE SHIP '                DEFINE PLAYER SHIP
    x AS INTEGER '          center  x coordinate of ship
    y AS INTEGER '          center  y coordinate of ship
    MaxX AS INTEGER '      maximum x coordinate of ship \
    MaxY AS INTEGER '      maximum y coordinate of ship  \ Ship bounding box
    MinX AS INTEGER '      minimum x coordinate of ship  /
    MinY AS INTEGER '      minimum y coordinate of ship /
END TYPE

'+------------------+
'| Define variables |
'+------------------+

DIM Button AS BUTTON '            game buttons
REDIM Bullet(0) AS BULLET '      player bullet array
DIM Ship AS SHIP '                player ship

'+----------------------+
'| Initialize variables |
'+----------------------+

Button.North.Key = 18432 '        up arrow    key scan code
Button.South.Key = 20480 '        down arrow  key scan code
Button.East.Key = 19712 '        right arrow key scan code
Button.West.Key = 19200 '        left arrow  key scan code
Button.Fire.Key = 32 '            space bar  key scan code

Ship.x = 20 '                    initial ship x coordinate
Ship.y = (SCREENHEIGHT - 1) \ 2 ' initial ship y coordinate
Ship.MinX = 20 '                  ship minimum x coordinate
Ship.MinY = 20 '                  ship minimum y coordinate
Ship.MaxX = SCREENWIDTH \ 2 - 1 ' ship maximum x coordinate
Ship.MaxY = SCREENHEIGHT - 21 '  ship maximum y coordinate

'+--------------------------------------------------------------------------------------------------------------------+
'| BEGIN MAIN PROGRAM                                                                                                |
'+--------------------------------------------------------------------------------------------------------------------+

SCREEN _NEWIMAGE(SCREENWIDTH, SCREENHEIGHT, 32) ' enter game graphics screen
DO '                                              begin main program loop
    _LIMIT 60 '                                  nice and smooth at 60 FPS
    CLS '                                        clear the game screen
    DisplayDirections '                          display game's directions

    '+-----------------------------------+
    '| Update the player's ship position |
    '+-----------------------------------+

    MoveShip '                                    update and draw player ship

    '+-----------------------------------------------+
    '| Test for the fire button in the down position |
    '+-----------------------------------------------+

    IF _KEYDOWN(Button.Fire.Key) THEN '          fire button pressed? (space bar key)

        '+------------------------------------------------------------------------------+
        '| Test if the fire button has been released since the last time it was pressed |
        '+------------------------------------------------------------------------------+

        IF Button.Fire.Position = BUTTONUP THEN ' yes, has fire button been released?

            '+------------------------------------------------------------+
            '| Set the fire button into the down position and fire bullet |
            '+------------------------------------------------------------+

            Button.Fire.Position = BUTTONDOWN '  yes, latch fire button in down position
            FireBullet Ship.x + 15, Ship.y '      fire a bullet from the nose of the ship
        END IF
    ELSE '                                        no, fire button is not pressed
        Button.Fire.Position = BUTTONUP '        latch fire button in up position
    END IF

    '+------------------------------------+
    '| Update the active bullet positions |
    '+------------------------------------+

    ManageBullets '                              update and draw all active bullets
    _DISPLAY '                                    update game screen with changes

LOOP UNTIL _KEYDOWN(27) '                        leave main loop when ESC pressed
SYSTEM '                                          return to the operating system

'+--------------------------------------------------------------------------------------------------------------------+
'| END MAIN PROGRAM                                                                                                  |
'+--------------------------------------------------------------------------------------------------------------------+

'+--------------------------------------------------------------------------------------------------------------------+
'| Declare subroutines and functions                                                                                  |
'+--------------------------------------------------------------------------------------------------------------------+

' ____________________________________________________________________________________________________________________
'/                                                                                                                    \
SUB DisplayDirections () '                                                                          DisplayDirections |
    ' ________________________________________________________________________________________________________________/
    '/                                                                                                                \
    '| Displays the game's directions to the player.                                                                  |
    '\________________________________________________________________________________________________________________/

    LOCATE 2, 2
    PRINT "FORCE PLAYER TO PRESS AND RELEASE FIRE KEY"
    LOCATE 4, 2
    PRINT " - ARROW KEYS TO MOVE"
    LOCATE 5, 2
    PRINT " - SPACE BAR TO FIRE"
    LOCATE 6, 2
    PRINT " - ESC TO LEAVE GAME"

END SUB
' ____________________________________________________________________________________________________________________
'/                                                                                                                    \
SUB MoveShip () '                                                                                            MoveShip |
    ' ________________________________________________________________________________________________________________/
    '/                                                                                                                \
    '| Updates the ship location according to player keypresses then draws the ship on the game screen.              |
    '\________________________________________________________________________________________________________________/

    SHARED Button AS BUTTON ' need access to game buttons
    SHARED Ship AS SHIP '    need access to player ship

    '+---------------------------------+
    '| Check for forward ship movement |
    '+---------------------------------+

    IF _KEYDOWN(Button.East.Key) THEN '                    forward thrust button pressed? (right arrow key)
        IF Button.West.Position = BUTTONUP THEN '          yes, is the reverse button pressed?
            Button.East.Position = BUTTONDOWN '            no, latch forward button in down position
            Ship.x = Ship.x + 5 '                          move ship forward
            IF Ship.x > Ship.MaxX THEN Ship.x = Ship.MaxX ' keep x within upper limit
        END IF
    ELSE '                                                  no, forward thrust button is not pressed
        Button.East.Position = BUTTONUP '                  latch forward thrust button in up position
    END IF

    '+---------------------------------+
    '| Check for reverse ship movement |
    '+---------------------------------+

    IF _KEYDOWN(Button.West.Key) THEN '                    reverse button pressed? (left arrow key)
        IF Button.East.Position = BUTTONUP THEN '          yes, is the forward thrust button pressed?
            Button.West.Position = BUTTONDOWN '            no, latch reverse button in down position
            Ship.x = Ship.x - 5 '                          move ship backward
            IF Ship.x < Ship.MinX THEN Ship.x = Ship.MinX ' keep x within lower limit
        END IF
    ELSE '                                                  no, reverse button is not pressed
        Button.West.Position = BUTTONUP '                  latch reverse button in up position
    END IF

    '+--------------------------------+
    '| Check for upward ship movement |
    '+--------------------------------+

    IF _KEYDOWN(Button.North.Key) THEN '                    upward button pressed? (up arrow key)
        IF Button.South.Position = BUTTONUP THEN '          yes, is the downward button pressed?
            Button.North.Position = BUTTONDOWN '            no, latch upward button in down position
            Ship.y = Ship.y - 5 '                          move ship upward
            IF Ship.y < Ship.MinY THEN Ship.y = Ship.MinY ' keep y within lower limit
        END IF
    ELSE '                                                  no, upward button is not pressed
        Button.North.Position = BUTTONUP '                  latch upward button in up position
    END IF

    '+----------------------------------+
    '| Check for downward ship movement |
    '+----------------------------------+

    IF _KEYDOWN(Button.South.Key) THEN '                    downward button pressed? (down arrow key)
        IF Button.North.Position = BUTTONUP THEN '          yes, is the upward button pressed?
            Button.South.Position = BUTTONDOWN '            no, latch downward button in down position
            Ship.y = Ship.y + 5 '                          move ship downward
            IF Ship.y > Ship.MaxY THEN Ship.y = Ship.MaxY ' keep y within upper limit
        END IF
    ELSE '                                                  no, downward button is not pressed
        Button.South.Position = BUTTONUP '                  latch downward button in up position
    END IF

    '+------------------+
    '| Draw player ship |
    '+------------------+

    LINE (Ship.x - 15, Ship.y - 10)-(Ship.x - 15, Ship.y + 10) ' draw triangular ship
    LINE -(Ship.x + 15, Ship.y)
    LINE -(Ship.x - 15, Ship.y - 10)

END SUB
' ____________________________________________________________________________________________________________________
'/                                                                                                                    \
SUB ManageBullets () '                                                                                  ManageBullets |
    ' ________________________________________________________________________________________________________________/
    '/                                                                                                                \
    '| Updates and draws all currently active bullets to the game screen.                                            |
    '\________________________________________________________________________________________________________________/

    SHARED Bullet() AS BULLET ' need access to player bullet array
    DIM Index AS INTEGER '      array index counter

    '+------------------------------------------+
    '| Scan the bullet array for active bullets |
    '+------------------------------------------+

    Index = -1 '                                                      reset index counter value
    DO '                                                              begin array search loop
        Index = Index + 1 '                                          increment array index counter
        IF Bullet(Index).Active THEN '                                is this bullet active?

            '+------------------------------------------------------+
            '| This bullet is active, update its location and speed |
            '+------------------------------------------------------+

            Bullet(Index).x = Bullet(Index).x + Bullet(Index).Speed ' yes, move bullet to the right
            Bullet(Index).Speed = Bullet(Index).Speed * 1.05 '        increase speed slightly

            '+-----------------------------------------------------+
            '| Check to see if the bullet has left the game screen |
            '+-----------------------------------------------------+

            IF Bullet(Index).x >= _WIDTH(0) - 1 THEN '                has bullet left the game screen?

                '+------------------------------------------------+
                '| This bullet has left the screen, deactivate it |
                '+------------------------------------------------+

                Bullet(Index).Active = 0 '                            yes, deactivate bullet
            ELSE '                                                    no, bullet still on game screen

                '+----------------------------------------------+
                '| This bullet is still on game screen, draw it |
                '+----------------------------------------------+

                CIRCLE (Bullet(Index).x, Bullet(Index).y), 5 '        draw the bullet
                PAINT (Bullet(Index).x, Bullet(Index).y) '            paint the bullet
            END IF
        END IF
    LOOP UNTIL Index = UBOUND(Bullet) '                              leave when all indexes checked

END SUB
' ____________________________________________________________________________________________________________________
'/                                                                                                                    \
SUB FireBullet (x AS INTEGER, y AS INTEGER) '                                                              FireBullet |
    ' ________________________________________________________________________________________________________________/
    '/                                                                                                                \
    '| Initiates a bullet at the supplied coordinates                                                                |
    '|                                                                                                                |
    '| x,y - the on screen coordinates where the bullet will materialize                                              |
    '\________________________________________________________________________________________________________________/

    SHARED Bullet() AS BULLET ' need access to player bullet array
    DIM Index AS INTEGER '      array index counter

    '+-------------------------------------------------------+
    '| Scan the bullet array for an index that is not active |
    '+-------------------------------------------------------+

    Index = -1 '                                                    reset index counter
    DO '                                                            begin array search loop
        Index = Index + 1 '                                        increment array index counter
    LOOP UNTIL Index = UBOUND(Bullet) OR Bullet(Index).Active = 0 ' leave when inactive found or at end of array

    '+------------------------------------------------------------------------------+
    '| Test if the index value from the search loop yielded an inactive array index |
    '+------------------------------------------------------------------------------+

    IF Bullet(Index).Active THEN '                                  was an inactive array index found?

        '+------------------------------------------------------------------------------------------------------+
        '| No inactive bullets were found in the array so the array size will need to be increased by one. The  |
        '| maximum size of the array will eventually be determined by the speed of the player's button presses. |
        '+------------------------------------------------------------------------------------------------------+

        Index = Index + 1 '                                        no, increase the array index size
        REDIM _PRESERVE Bullet(Index) AS BULLET '                  resize the array while preserving exisiting data
    END IF

    '+---------------------------------------------------+
    '| Add the new bullet's information the bullet array |
    '+---------------------------------------------------+

    Bullet(Index).x = x '                                          new bullet's x coordinate
    Bullet(Index).y = y '                                          new bullet's y coordinate
    Bullet(Index).Speed = 5 '                                      new bullet's initial speed
    Bullet(Index).Active = 1 '                                      this array index is active
    SOUND 880, .5 '                                                awesome bullet sound

END SUB
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply


Messages In This Thread
Another Mouse Issue? - by NakedApe - 04-25-2024, 12:54 AM
RE: Another Mouse Issue? - by SMcNeill - 04-25-2024, 01:06 AM
RE: Another Mouse Issue? - by TerryRitchie - 04-25-2024, 01:40 AM
RE: Another Mouse Issue? - by NakedApe - 05-01-2024, 11:42 PM
RE: Another Mouse Issue? - by SMcNeill - 05-02-2024, 12:23 AM
RE: Another Mouse Issue? - by Pete - 04-25-2024, 01:27 AM
RE: Another Mouse Issue? - by bplus - 04-25-2024, 01:42 AM
RE: Another Mouse Issue? - by TerryRitchie - 04-25-2024, 02:08 AM
RE: Another Mouse Issue? - by NakedApe - 04-25-2024, 02:16 AM
RE: Another Mouse Issue? - by TerryRitchie - 04-25-2024, 05:33 AM
RE: Another Mouse Issue? - by a740g - 04-26-2024, 02:23 AM
RE: Another Mouse Issue? - by bplus - 04-25-2024, 11:50 AM
RE: Another Mouse Issue? - by NakedApe - 04-25-2024, 04:11 PM
RE: Another Mouse Issue? - by TerryRitchie - 04-25-2024, 05:43 PM
RE: Another Mouse Issue? - by NakedApe - 04-26-2024, 06:19 AM
RE: Another Mouse Issue? - by TerryRitchie - 05-02-2024, 12:31 AM
RE: Another Mouse Issue? - by SMcNeill - 05-02-2024, 12:31 AM
RE: Another Mouse Issue? - by NakedApe - 05-02-2024, 03:16 AM



Users browsing this thread: 3 Guest(s)