08-26-2024, 07:46 PM
A cancelled gig gave me time to play with this game today. Made it more like a real game, almost a little fun. Main changes are:
Added Sound effects using PLAY statements
Added health point count (5). Out of health points, game over.
(missing a ball or hitting one cost you a health point)
Some balls fall faster than others, more challenging.
Added moving shield that protects balls from your shots.
Added simple ground background for player to move on
Added simple game over message when health out.
See how many balls you can shoot down before running out of health.
- Dav
Added Sound effects using PLAY statements
Added health point count (5). Out of health points, game over.
(missing a ball or hitting one cost you a health point)
Some balls fall faster than others, more challenging.
Added moving shield that protects balls from your shots.
Added simple ground background for player to move on
Added simple game over message when health out.
See how many balls you can shoot down before running out of health.
- Dav
Code: (Select All)
'=============
'ballshoot.bas v2
'=============
'A bare-bones small shooter game that you can expand on.
'Follow game here: https://qb64phoenix.com/forum/showthread.php?tid=2978
'Coded by Dav, AUG/2024 for QB64PE v3.13
'New for v2: - Added Sound effects using PLAY
' - Added simple ground background
' - Some balls fall faster than others
' - Added moving shield that protects balls
' - Added health points. 5 hits, game over.
' - Added simple game over message
'Move player using arrow keys - SPACE bar shoots.
'Shoot the balls. Don't let any hit you or pass you by.
'A moving shield appears now and then to protect balls.
'See how many balls you can shoot down before dying.
'This is a basic shooter game that is easy enough to
'learn from and expand on so you can make your own game,
'I used balls as an enemy because I had a ball SUB handy,
'and it had a colorful effect. Used it for shots and
'for the moving shield. I also used an alpha screen
'clearing method using LINE instead of CLS. This gave
'all the moving pieces a neat trailing/fade effect.
'If you miss a ball, or a ball hits you, then you loose
'a health point. If you loose all 6 health point then
'the game is over.
'There are many ways to exand this into something better.
'If you do make more out of it, please share it also.
Randomize Timer
balls = 6 'number of balls at one time
shots = 6 'number of shots allowed on screen
Dim ballx(1 To balls) 'ball x pos
Dim bally(1 To balls) 'ball y pos
Dim balld(1 To balls) 'ball direction
Dim ballr(1 To balls) 'ball radius
Dim balls(1 To balls) 'ball drop speed
Dim shotx(1 To shots) 'shot x pos
Dim shoty(1 To shots) 'shot y pos
Dim shota(1 To shots) 'flag if shot is active
Screen _NewImage(640, 480, 32)
_FullScreen _SquarePixels
_PrintMode _KeepBackground
'========
StartGame:
'========
'set game defaults
score = 0 'score is zero
shotcount = 0 'no active shots
playerx = _Width / 2 'x pos of player
playery = 475 'y pos of player (this stays same)
shieldx = -50
shieldy = 50 + (Rnd * 200)
shieldon = 0
health = 5 'full health
'generate random ball info
For i = 1 To balls
ballx(i) = Int(Rnd * _Width) + 1 'x pos
bally(i) = Int(Rnd * (_Height / 4)) + 1 'y pos
balld(i) = Int(Rnd * 3) - 1 'moving direction
ballr(i) = 10 + Int(Rnd * 20) 'radius
balls(i) = Int(Rnd * 2) + 1
Next
'draw ground
c = 0
For y = 400 To _Height
Line (0, y)-(_Width, y), _RGBA(c / 3, c / 2, c, 225 + Rnd * 25), BF
c = c + .5: If c = 255 Then c = 255
Next
back& = _CopyImage(_Display) 'copy backgraound as image
'=== main game loop ===
Do
_PutImage (0, 0)-(_Width, _Height), back& 'put background down
'this make the trailing fade effect on screen (cooler than doing CLS)
Line (0, 0)-(_Width, _Height), _RGBA(0, 0, 0, 75), BF
'add some screen sparklers
Line (Rnd * _Width, Rnd * 375)-Step(Rnd * 3, Rnd * 3), _RGBA(255, 255, 255, Rnd * 200), BF
'randomly turn moving shield on from time to time
If Int(Rnd * 500) = 1 Then shieldon = 1: Play "mbt200l32o3ege"
'if shield is on...
If shieldon = 1 Then
shieldx = shieldx + 2
'if it moves off screen
If shieldx > _Width Then
'shield off
shieldon = 0
'reset shield values
shieldx = -50
shieldy = 50 + (Rnd * 200)
Else
'draw shield
For s = 1 To 50 Step 5
glowball shieldx + s, shieldy, 5, 255, 255, 255, 200
Next
End If
End If
'handle all balls
For i = 1 To balls
'randomly change ball direction by making a -1, 0 or 1 to add to x pos , sometimes.
If Rnd < .1 Then balld(i) = Int(Rnd * 3) - 1
'update ball x/y pos
ballx(i) = ballx(i) + balld(i) 'new ball x pos, with randomly generated direction
bally(i) = bally(i) + balls(i) 'drift ball y pos down...
'make sure ball stays in bounds
If ballx(i) < ballr(i) Then ballx(i) = ballr(i)
If ballx(i) > (_Width - ballr(i)) Then ballx(i) = (_Width - ballr(i))
'if you missed shooting a ball and it goes off screen, lower health
If bally(i) > _Height Then
Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
Play "mbt200l32o1bfc"
health = health - 1
Circle (ballx(i), bally(i)), ballr(i), _RGB(255, 0, 0)
bally(i) = 1 'give ball new y pos (top)
ballx(i) = Int(Rnd * _Width) + 1 'give ball a new x pos
ballr(i) = 10 + Int(Rnd * 20) 'give ball new radius
balls(i) = Int(Rnd * 2) + 1 'new ball speed
End If
'finally draw ball....
glowball ballx(i), bally(i), ballr(i), 255, 255, 255, 255
Next
'draw player along bottom of screen
Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(255, Rnd * 125, Rnd * 128), BF
Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(0, 0, Rnd * 255), B
'handle all active shots...
For i = 1 To shotcount
If shota(i) Then
'draw the shot
glowball shotx(i), shoty(i), 3, 255, 0, 0, 255
shoty(i) = shoty(i) - 5 'make shot go up
'if shot goes up off screen...
If shoty(i) < 0 Then shota(i) = 0 'set shot active flag off
'if shot hits shield then shot off
If shotx(i) > shieldx And shotx(i) < (shieldx + 50) Then
If shoty(i) > shieldy And shoty(i) < shieldy + 5 Then
Circle (shotx(i), shoty(i)), 3, _RGB(255, 255, 255)
Play "mbt200l32o6fb"
shota(i) = 0
End If
End If
End If
Next
'left/right arrows move player
If _KeyDown(19200) Then playerx = playerx - 7 'left arrow, move left
If _KeyDown(19712) Then playerx = playerx + 7 'right arrow, move right
'make sure player doesn't go off screen
If playerx < 0 Then
playerx = 0
ElseIf playerx > (_Width - 1) Then
playerx = (_Width - 1)
End If
'Spacebar fires a shot
If _KeyDown(32) Then
'look for first inactive shot to shoot
For i = 1 To UBound(shota)
'if this one is free, and lastshot time passed...
If shota(i) = 0 And Timer - lastshot > .2 Then
Play "mbt200l64o4bfag"
shotx(i) = playerx 'give it our x/y
shoty(i) = playery
shota(i) = 1 'mark it as active
'update shot count
If i > shotcount Then shotcount = i
lastshot = Timer 'mark time of this shot....
'Note: I'm using shot timer to prevent too rapid fire of shots
Exit For
End If
Next
End If
'see if shot hits a ball
For i = 1 To balls
For j = 1 To shotcount
If shota(j) Then
If Abs(ballx(i) - shotx(j)) < ballr(i) And Abs(bally(i) - shoty(j)) < ballr(i) Then
'flash a circle around hit ball
Play "mbt200l64o2cdefgabag"
Circle (ballx(i), bally(i)), ballr(i), _RGB(255, 255, 255)
shota(j) = 0 'set shot active flag off
bally(i) = 1 'give ball new y pos (top)
ballx(i) = Int(Rnd * _Width) + 1 'give ball a new x pos
ballr(i) = 10 + Int(Rnd * 20) 'give ball new radius
balls(i) = Int(Rnd * 2) + 1 'new ball speed
score = score + 1 'update score
End If
End If
Next
Next
'if a ball hits player, health decrease
For i = 1 To balls
If Abs(ballx(i) - playerx) < ballr(i) And Abs(bally(i) - playery) < ballr(i) Then
Play "mbt200l32o1bfc"
Circle (ballx(i), bally(i)), ballr(i), _RGB(255, 0, 0)
bally(i) = 1 'give ball new y pos (top)
ballx(i) = Int(Rnd * _Width) + 1 'give ball a new x pos
ballr(i) = 10 + Int(Rnd * 20) 'give ball new radius
balls(i) = Int(Rnd * 2) + 1 'new ball speed
Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
health = health - 1
End If
Next
'show score
_PrintString (1, 1), "Score:" + Str$(score)
'draw health status
hcount = 1
For h = 1 To 50 Step 10
If health >= hcount Then
Line (580 + h, 5)-(580 + h + 5, 10), _RGB(0, 255, 0), BF
Else
Line (580 + h, 5)-(580 + h + 5, 10), _RGB(0, 255, 0), B
End If
hcount = hcount + 1
Next
'if out of health, game over
If health = 0 Then
Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 128), BF
Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 255), B
_PrintMode _KeepBackground
_PrintString (275, 225), " GAME OVER"
_PrintString (275, 245), "OUT OF HEALTH"
_PrintString (275, 265), " SCORE:" + Str$(score)
_Display
_Delay 3
End
End If
_Display
_Limit 30
Loop Until _KeyDown(27) 'ESC quits
End
Sub glowball (x, y, size, r, g, b, a)
t = Timer
For y2 = y - size To y + size
For x2 = x - size To x + size
If Sqr((x2 - x) ^ 2 + (y2 - y) ^ 2) <= size Then
clr = (size - (Sqr((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)))) / size
noise = Int(Rnd * 50)
r = Sin(6.005 * t) * size - y2 + size + 255 * 2
g = Sin(3.001 * t) * size - x2 + size + 255
b = Sin(2.001 * x2 / size + t + y2 / size) * r + 255
t = t + .00195
PSet (x2, y2), _RGBA(clr * r - noise, clr * g - noise, clr * b - noise, a)
End If
Next
Next
End Sub