Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Spinner Game Demo
#1
UPDATE: I renamed all asset file names to lower case to work with Linux (thanks for the heads-up Dav). I also made a small change to the source code fixing an issue.
UPDATE: The ZIP below contains the new code and renamed asset files.

I took the arcade spinner code I wrote in another post and converted it to a library. Here is a demo program using that spinner code to control a spaceship around a perimeter on the screen.

Use the mouse to spin the ship around and the left mouse button to fire a bullet.

This is just a demo to see how well the spinner code works but is a good start to a game if someone wants to expand upon it. Someone in another thread was discussing a game that utilized enemy ships coming out of a worm hole or time tunnel. This would be a good start. I would continue work on it but I have way too much to work on with the game library currently.

The ZIP file below contains the assets (sound and image), libraries needed, and demo code.

Code: (Select All)
OPTION _EXPLICIT

'Spinner game demo

'Game Library Variable Inclusions

'$INCLUDE:'lib_type_spoint.bi'           TYPE TYPE_SPOINT     SINGLE x,y point pair
'$INCLUDE:'lib_jpad_spinner.bi'          JPAD_Spinner         get degree of spinner
'$INCLUDE:'lib_img_introtate.bi'         IMG_INTRotate()      rotate an image
'$INCLUDE:'lib_math_deg2vec.bi'          MATH_Deg2Vec()       convert degree to vector
'$INCLUDE:'lib_math_distancep2p.bi'      MATH_DistanceP2P()   get distance of point to another point

CONST SWIDTH% = 800 '           width of screen
CONST SHEIGHT% = 600 '          height of screen
CONST MAXBULLETS% = 10 '        maximum number of bullets available

TYPE TYPE_BULLET '              BULLET PROPERTIES
    InUse AS INTEGER '          array index in use
    p AS TYPE_SPOINT '          bullet position
    v AS TYPE_SPOINT '          bullet vector
    Vel AS SINGLE '             bullet velocity
END TYPE

DIM Bullet(MAXBULLETS) AS TYPE_BULLET ' bullet array
DIM Center AS TYPE_SPOINT '     center point
DIM Degree AS INTEGER '         current spinner location
DIM ShipSheet AS LONG '         player ship sprite sheet
DIM Ship(-3 TO 3) AS LONG '     seven player ship images
DIM c AS INTEGER '              generic counter
DIM Bullets AS INTEGER '        total bullets flying on screen
DIM ShipRadius AS INTEGER '     radius of ship outer perimeter
DIM BulletRadius AS INTEGER '   radius of bullet outer perimeter
DIM SNDBullet AS LONG '         bullet sound

ShipSheet = _LOADIMAGE("shipsheet.png", 32) '          load player ship sprite sheet
SNDBullet = _SNDOPEN("bullet.ogg") '                   load bullet sound
Center.x = SWIDTH \ 2 '                                x center of screen
Center.y = SHEIGHT \ 2 '                               y center of screen
ShipRadius = (MATH_SNGMin(SWIDTH, SHEIGHT) - 64) \ 2 ' ship outer perimeter radius
BulletRadius = ShipRadius - 38 '                       bullet outer perimeter radius

' -----------------------------
'| Clip ship images from sheet |
' -----------------------------

FOR c = -3 TO 3 '                                                               cycle through seven images
    Ship(c) = _NEWIMAGE(64, 64, 32) '                                           create ship image canvas
    _PUTIMAGE , ShipSheet, Ship(c), ((c + 3) * 64, 0)-((c + 3) * 64 + 63, 63) ' clip ship image from sprite sheet
NEXT c

' -----------------
'| Begin demo code |
' -----------------

SCREEN _NEWIMAGE(SWIDTH, SHEIGHT, 32) '                               graphics window
_MOUSEHIDE '                                                          hide the mouse pointer
DO '                                                                  begin spinner game demo loop
    CLS '                                                             clear screen
    _LIMIT 60 '                                                       60 frames per second
    Degree = JPAD_Spinner '                                           get spinner location
    DrawShip Degree '                                                 draw the player ship
    IF _MOUSEBUTTON(1) THEN FireBullet Degree '                       fire a bullet if player presses left mouse button
    IF Bullets THEN UpdateBullets '                                   updates bullets if any flying
    LOCATE 2, 2: PRINT "Use the mouse tospin ship around perimeter" ' print instructions
    LOCATE 3, 2: PRINT "Left mouse button to fire"
    LOCATE 5, 2: PRINT "Press ESC to exit"
    _DISPLAY '                                                        update screen with changes
LOOP UNTIL _KEYDOWN(27) '                                             leave demo when ESC pressed

' ------------------------
'| Asset cleanup and exit |
' ------------------------

FOR c = -1 TO 3 '                                                     cycle through seven images
    _FREEIMAGE Ship(c) '                                              remove ship image from RAM
NEXT c
_SNDCLOSE SNDBullet '                                                 remove bullet sound from RAM
SYSTEM '                                                              return to the operating system

' ---------------
'| End demo code |
' ---------------

'------------------------------------------------------------------------------------------------------------------------------------------
SUB DrawShip (Degree AS INTEGER)

    ' ------------------------------------------------------
    '| Draw ship on screen at given degree around perimeter |
    '|                                                      |
    '| Degree - position on ship perimeter                  |
    ' ------------------------------------------------------

    SHARED Ship() AS LONG '         need access to ship images
    SHARED Center AS TYPE_SPOINT '  need access to center point
    SHARED ShipRadius AS INTEGER '  need access to ship perimeter radius
    STATIC pDegree AS INTEGER '     previous ship degree
    STATIC Tilt AS INTEGER '        ship tilt amount
    STATIC Frame AS INTEGER '       frame counter
    DIM rShip AS LONG '             rotated image of ship
    DIM ShipDir AS SINGLE '         direction of ship travel around perimeter

    ShipDir = SGN(MATH_ShortAngle(Degree, pDegree)) '   get direction of ship (-1 counter-clockwise, 1 clockwise, 0 still)
    IF ShipDir THEN '                                   is ship moving?
        Tilt = Tilt + ShipDir '                         yes, tilt ship in direction of movement
        IF Tilt < -3 THEN '                             keep tilt value between -3 and 3
            Tilt = -3
        ELSEIF Tilt > 3 THEN
            Tilt = 3
        END IF
        Frame = 0 '                                     reset frame counter
    ELSE '                                              no, ship is standing still
        IF Tilt THEN '                                  is ship tilted?
            Frame = Frame + 1 '                         yes, increment frame counter
            IF Frame = 4 THEN '                         have 4 frames gone by?
                Tilt = Tilt - SGN(Tilt) '               yes, tilt ship back toward center
                Frame = 0 '                             reset frame counter
            END IF
        END IF
    END IF
    rShip = _COPYIMAGE(Ship(Tilt)) '                    get ship image
    IMG_INTRotate rShip, MATH_FixDegree(Degree - 180) ' rotate ship image
    _PUTIMAGE (Center.x + MATH_SIN(Degree) * ShipRadius - _WIDTH(rShip) \ 2,_
               Center.y - MATH_COS(Degree) * ShipRadius - _HEIGHT(rShip) \ 2), rShip ' draw ship
    _FREEIMAGE rShip '                                  ship image no longer needed
    pDegree = Degree '                                  remember previous ship degree

END SUB

'------------------------------------------------------------------------------------------------------------------------------------------
SUB FireBullet (Degree AS INTEGER)

    ' -----------------------------------------
    '| Adds a bullet to the bullet array       |
    '|                                         |
    '| Degree - origin degree around perimeter |
    ' -----------------------------------------

    SHARED Bullet() AS TYPE_BULLET ' need access to bullet array
    SHARED Bullets AS INTEGER '      need access to number of bullets flying
    SHARED Center AS TYPE_SPOINT '   need access to center point
    SHARED BulletRadius AS INTEGER ' need access to bullet origin radius
    SHARED SNDBullet AS LONG '       need access to bullet sound
    STATIC ShotTimer AS INTEGER '    time (frames) between bullets
    DIM b AS INTEGER '               bullet counter
    DIM i AS INTEGER '               free array index

    IF Bullets = MAXBULLETS THEN EXIT SUB '                      leave if maximum bullets flying
    IF ShotTimer THEN '                                          ok to fire another bullet?
        ShotTimer = ShotTimer - 1 '                              no, decrement shot timer
        IF ShotTimer THEN EXIT SUB '                             leave if time still left on shot timer
    END IF
    Bullets = Bullets + 1 '                                      increment number of bullets flying
    ShotTimer = 5 '                                              reset shot timer
    _SNDPLAYCOPY SNDBullet '                                     play bullet sound

    ' ----------------------
    '| Get free array index |
    ' ----------------------

    b = 1 '                                                      reset bullet counter
    DO '                                                         begen bullet loop
        IF Bullet(b).InUse = 0 THEN i = b '                      use this array index if not in use
        b = b + 1 '                                              increment bullet counter
    LOOP UNTIL i '                                               leave when free array index found

    ' --------------------------
    '| Set up bullet parameters |
    ' --------------------------

    Bullet(i).InUse = -1 '                                       mark this array index in use
    Bullet(i).p.x = Center.x + MATH_SIN(Degree) * BulletRadius ' x location of bullet
    Bullet(i).p.y = Center.y - MATH_COS(Degree) * BulletRadius ' y location of bullet
    MATH_Deg2Vec MATH_FixDegree(Degree - 180), Bullet(i).v '     vector of bullet

END SUB

'------------------------------------------------------------------------------------------------------------------------------------------
SUB UpdateBullets ()

    ' --------------------------------------
    '| Updates any flying bullets on screen |
    ' --------------------------------------

    SHARED Bullet() AS TYPE_BULLET ' need access to bullet array
    SHARED Bullets AS INTEGER '      need access to number of bullets flying
    SHARED Center AS TYPE_SPOINT '   need access to center point
    SHARED BulletRadius AS INTEGER ' need access to bullet origin radius
    DIM b AS INTEGER '               bullet counter
    DIM d AS SINGLE '                distance of bullet to center point
    DIM c AS INTEGER '               brightness of bullet
    DIM clr AS _UNSIGNED LONG '      color of bullet

    b = 1 '                                                                 reset bullet counter
    DO '                                                                    begin bullet loop
        IF Bullet(b).InUse THEN '                                           is this bullet in use?
            Bullet(b).p.x = Bullet(b).p.x + Bullet(b).v.x * Bullet(b).Vel ' yes, update x coordinate
            Bullet(b).p.y = Bullet(b).p.y + Bullet(b).v.y * Bullet(b).Vel ' update y coordinate
            d = MATH_DistanceP2P(Bullet(b).p, Center) '                     distance of bullet to center
            IF d < 1 THEN '                                                 has bullet reached center?
                Bullet(b).InUse = 0 '                                       yes, bullet no longer flying
                Bullets = Bullets - 1 '                                     decrement total bullets flying
            ELSE '                                                          no, bullet still heading toward center
                Bullet(b).Vel = MATH_Map(d, 0, BulletRadius, 1, 10) '       update velocity of bullet
                c = MATH_Map(d, 0, BulletRadius, 96, 255) '                 brightness level of bullet
                clr = _RGB32(c, c, 0) '                                     color of bullet
                CIRCLE (Bullet(b).p.x, Bullet(b).p.y), Bullet(b).Vel, clr ' draw bullet
                PAINT (Bullet(b).p.x, Bullet(b).p.y), clr, clr '            paint bullet
            END IF
        END IF
        b = b + 1 '                                                         increment bullet counter
    LOOP UNTIL b > MAXBULLETS '                                             leave when all bullets updated

END SUB

'Game Library Subroutine/Function Inclusions

'$INCLUDE:'lib_jpad_spinner.bm'          JPAD_Spinner()       get degree of spinner
'$INCLUDE:'lib_img_introtate.bm'         IMG_INTRotate()      rotate an image
'$INCLUDE:'lib_math_fixdegree.bm'        MATH_FixDegree()     keep degree within 0 to 359.999...
'$INCLUDE:'lib_math_deg2vec.bm'          MATH_Deg2Vec()       convert degree to vector
'$INCLUDE:'lib_math_distancep2p.bm'      MATH_DistanceP2P()   get distance of point to another point
'$INCLUDE:'lib_math_sngmin.bm'           MATH_SNGMin()        get minimum SINGLE value
'$INCLUDE:'lib_math_map.bm'              MATH_Map()           map one number system to another
'$INCLUDE:'lib_math_shortangle.bm'       MATH_ShortAngle()    get shortest angle between two angles


Attached Files Image(s)
   

.zip   SpinnerGameDemo.zip (Size: 55.82 KB / Downloads: 16)
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply


Messages In This Thread
Spinner Game Demo - by TerryRitchie - 10-03-2024, 07:53 PM
RE: Spinner Game Demo - by RokCoder - 10-03-2024, 09:32 PM
RE: Spinner Game Demo - by TerryRitchie - 10-03-2024, 09:54 PM
RE: Spinner Game Demo - by Dav - 10-03-2024, 10:12 PM
RE: Spinner Game Demo - by TerryRitchie - 10-03-2024, 10:16 PM
RE: Spinner Game Demo - by Dav - 10-03-2024, 10:22 PM
RE: Spinner Game Demo - by TerryRitchie - 10-03-2024, 10:42 PM
RE: Spinner Game Demo - by Pete - 10-04-2024, 12:52 AM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 03:49 AM
RE: Spinner Game Demo - by JRace - 10-04-2024, 03:54 AM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 02:31 PM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 02:40 PM
RE: Spinner Game Demo - by NakedApe - 10-04-2024, 05:48 PM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 06:34 PM
RE: Spinner Game Demo - by NakedApe - 10-04-2024, 06:52 PM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 08:34 PM
RE: Spinner Game Demo - by NakedApe - 10-04-2024, 09:13 PM
RE: Spinner Game Demo - by NakedApe - 10-04-2024, 10:04 PM
RE: Spinner Game Demo - by SMcNeill - 10-04-2024, 10:24 PM
RE: Spinner Game Demo - by TerryRitchie - 10-04-2024, 10:57 PM
RE: Spinner Game Demo - by NakedApe - 10-05-2024, 04:31 AM
RE: Spinner Game Demo - by SMcNeill - 10-05-2024, 07:59 AM
RE: Spinner Game Demo - by NakedApe - 10-05-2024, 03:08 PM



Users browsing this thread: 2 Guest(s)