10-03-2024, 07:53 PM
(This post was last modified: 10-03-2024, 10:40 PM by TerryRitchie.)
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.
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