Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
BallShoot - A bare bones shooter game easy to expand on.
#21
Great job Dav! I got over 100 that time. Also, I might add _MOUSEHIDE to some of my games, it might be useful, thanks!
Reply
#22
And now, for the Ball Blaster -- it's a rotating ball that moves slowly across the screen, spins languidly in a 360 degree circle, and which fires shots out one side of it.  Anything it hits, be that other balls or the player, loses health and eventually explodes. Player gets no points for balls destroyed by The Ball Blaster.

Or, as I like to call it -- "Pete's Mother-in-Law".   Big Grin
Reply
#23
I just added _MOUSEHIDE to Tech Invaders 5 on my page. Smile
Reply
#24
Thanks, @SierraKen!  Glad you like it!

Steve, I know you were joking, but it's a good idea!  Working on the big blaster ball now.  Maybe it will be the big boss at the end to destroy.  That's a better name for the game -  Ball Blaster

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#25
(08-31-2024, 12:57 AM)Dav Wrote: Thanks, @SierraKen!  Glad you like it!

Steve, I know you were joking, but it's a good idea!  Working on the big blaster ball now.  Maybe it will be the big boss at the end to destroy.  That's a better name for the game -  Blaster ball.

- Dav

I was joking about Pete's Mother-in-Law.. She's not THAT nice, after having to put up with the way Pete's treated her precious daughter after all these years! 

But, I did think the idea might be something you'd enjoy incorporating into the game, which is why I mentioned it for you.  

Can I suggest perhaps one really powerful boss after a couple of levels of the first one?  It can be two round balls, with an oval launcher between them, that waves back and forth and shoots little green peas across the screen that stick and slow down anything they touch.  You can call it "The Pea Shooter!"  It'd make an awful mess of everything!

Big Grin
Big Grin
Big Grin

Special way to attack it would be with an unique missile which -- if it hits the top of the oval properly -- "unrolls" and covers the whole thing that works as a sort of ... latex shield... to block its steady stream of peas so the player can then attack the balls directly and destroy them!

(I know.  I know.  It's almost potty humor, but that still doesn't make it any less funny.

I guess I've just been feeling a little crappy lately. Tongue )
Reply
#26
I'll have you know my mother-in-law is a peach. It's my brother-in-law I have a problem with. He's a real son of a peach!

If I had the time, I would code this...

1) Copy image of Steve from forum.

2) Float image of Steve amongst the balls.

3) Have Steve play, and we all win when Steve shoots himself in the balls.

Now that's just good gaming!

Pete Big Grin
Shoot first and shoot people who ask questions, later.
Reply
#27
(08-31-2024, 09:24 PM)Pete Wrote: I'll have you know my mother-in-law is a peach. It's my brother-in-law I have a problem with. He's a real son of a peach!

Your brother-in-law is Momotarō??
Reply
#28
Very nice game!


Reply
#29
Thanks, @Petr!

Added 2 things in v7 which make the game more attractive and fun.  A big pulsating background that pulsates faster and faster as your health decreases.  Looks kind of iintense.  Also added Steve's Big ball that shoots out at every angle and can't be killed.  It's fire bombs only hurt you for now.  It flies through once in a blue moon (when (RND * 2000) = 1).  Fixed some errors I found.  Added a screenshot here for the curious.

- Dav

Code: (Select All)
'=============
'ballshoot.bas v7
'=============
'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, SEP/2024 for QB64PE v3.13

' WARNING: THIS GAME HAS FLASHING SCREENS (not much though)

'New for v7:
'            - Added itense pulsating backdrop
'              (pulses faster when health gets lower)
'            - halfway added super bigball & bigshots
'              (shots hurt you, you can't kill bigball)
'            - fixed: reset all settings at start of game

'Move player using arrow keys - SPACE bar shoots.
'Shoot the balls. Don't let any hit you or pass you by.
'Moving shields appears now and then to protect balls.
'See how many balls you can shoot down before dying.
'Catch green pill to increase your health points +1.
'Catch yellow pill to be invincible for 15 seconds.
'Catch red pill to get a flash bomb! ENTER to use it.

'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 7 health points then
'the game is over.

'If you catch green pills, it adds +1 to your health.
'If you catch yellow pills, you are invincible 15 secs.
'If you catch a red pill it gives you a flash bomb.
'Press ENTER to use you flash bombs, which will destroy
'all balls and dropping bombs on the screen.

'There are many ways to exand this into something better.
'If you do make more out of it, please share it also.


Randomize Timer

Screen _NewImage(640, 480, 32)
_FullScreen _SquarePixels
_PrintMode _KeepBackground
_MouseHide

'draw/save a background image to use
c = 0
For y = 425 To _Height
    Line (0, y)-(_Width, y), _RGBA(c / 3, c / 2, c, 225 + Rnd * 25), BF
    c = c + 1: If c = 255 Then c = 255
Next: back& = _CopyImage(_Display) 'copy backgraound as back& image

highscore = 0 'start at zero

'========
StartGame:
'========

balls = 6 'number of balls at one time
shots = 7 'number of shots allowed on screen

ReDim ballx(1 To balls) 'ball x pos
ReDim bally(1 To balls) 'ball y pos
ReDim balld(1 To balls) 'ball direction
ReDim ballr(1 To balls) 'ball radius
ReDim balls(1 To balls) 'ball drop speed

ReDim bombx(1 To balls) 'ball bomb x pos
ReDim bomby(1 To balls) 'ball bomb y pos
ReDim bomba(1 To balls) 'flag if bomb is active

ReDim shotx(1 To shots) 'shot x pos
ReDim shoty(1 To shots) 'shot y pos
ReDim shota(1 To shots) 'flag if shot is active

'set game defaults
score = 0 'score is zero
shotcount = 0 'no active shots
bombcount = 0 'no active bombs
playerx = _Width / 2 'x pos of player
playery = 475 'y pos of player (this stays same)
respawny = -300 'ball respawns off screen
healthmax = 7 'max level of health
health = 7 'start with max health
flashbombs = 1 'start with one flash bomb
'make sure these all off
bigballon = 0
shield1on = 0
shield2on = 0
healthpillon = 0
superpillon = 0
flashpillon = 0
kamikazeon = 0
zigzagon = 0

'generate random ball info
For i = 1 To balls
    bomba(i) = 0 'all ball bombs off
    ballx(i) = Int(Rnd * _Width) + 1 'x pos
    bally(i) = Int(Rnd * (_Height / 4)) + respawny 'y pos
    balld(i) = Int(Rnd * 3) - 1 'moving direction
    ballr(i) = 10 + Int(Rnd * 20) 'radius
    balls(i) = Int(Rnd * 2) + 1
Next

'start sound effect
Play "mbt200l16o2e,gg,o3cc,el8e,gl16c,el4c,e,g"


'==============  main game loop ==============

Do

    _PutImage (1, 1)-(_Width - 1, _Height - 1), back& 'put background down

    PulseBack 30, 7.25 - health 'gets faster as health decreases

    '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 * 400)-Step(Rnd * 3, Rnd * 3), _RGBA(255, 255, 255, Rnd * 200), BF

    'if health is getting low, show flashing yellow background
    If health = 2 Then Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 0, healthglow - 1), BF
    'if health is critially low, show flashing red screen
    If health = 1 Then Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, healthglow), BF
    If healthway = 0 Then healthglow = healthglow + .5 Else healthglow = healthglow - .5
    If healthglow > 5 Then healthway = 1
    If healthglow < 0 Then healthway = 0


    '========  Handle Shield1  =======
    If shield1on = 1 Then
        If Rnd < .1 Then wobble = Int(Rnd * 3) - 1
        shield1x = shield1x + 2 + wobble
        'if it moves off screen
        If shield1x > _Width Then
            'shield off
            shield1on = 0
        Else
            'draw shield1
            For s = 1 To shield1s Step 5
                glowball shield1x + s, shield1y, 5, 255, 255, 255, 200
            Next
        End If
    Else
        'randomly turn moving shield 2 on from time to time
        If Int(Rnd * 500) = 1 Then
            shield1on = 1: Play "mbt200l32o3ege"
            'reset shield values
            shield1s = 50 + Int(Rnd * 50) 'random sixe 50-100
            shield1x = -shield1s 'starting position
            shield1y = shield1s + (Rnd * 300)
        End If
    End If

    '======== Handle Shield2 ================
    If shield2on = 1 Then
        If Rnd < .1 Then wobble = Int(Rnd * 3) - 1
        shield2x = shield2x - 1 - wobble
        'if it moves off screen
        If shield2x < -shield2s Then
            'shield off
            shield2on = 0
        Else
            'draw shield 2
            For s = 1 To shield2s Step 5
                glowball shield2x + s, shield2y, 5, 255, 255, 255, 200
            Next
        End If
    Else
        'randomly turn moving shield2 on from time to time
        If Int(Rnd * 500) = 1 Then
            shield2on = 1: Play "mbt200l32o3ege"
            'reset shield values
            shield2s = 50 + Int(Rnd * 50)
            shield2x = _Width + shield2s
            shield2y = shield2s + (Rnd * 300)
        End If
    End If

    '====== Handle Green health pill =========
    If healthpillon = 1 Then
        healthpilly = healthpilly + 3
        'if it moves off screen
        If healthpilly + 10 > _Height Then
            'healthpill off
            healthpillon = 0
        Else
            'draw healthpill
            Line (healthpillx, healthpilly)-(healthpillx + 10, healthpilly + 10), _RGB(0, 255, 0), BF
            Color _RGBA(0, 255, 0, 25 + (Rnd * 75))
            _PrintString (7, 25), "CATCH GREEN PILL"
            Line (2, 22)-(148, 42), _RGBA(0, 255, 0, 25 + (Rnd * 75)), B
        End If
        'if healthpill hits player, add point to health
        If Abs(healthpillx - playerx) < 20 And Abs(healthpilly - playery) < 20 Then
            Play "mbt200l16o2cegec"
            Line (0, 0)-(_Width, _Height), _RGBA(0, 255, 0, 30), BF
            If health < healthmax Then health = health + 1
            healthpillon = 0
        End If
    Else
        'randomly drop a health pillfrom time to time
        If Int(Rnd * 700) = 1 And health <> healthmax Then
            healthpillon = 1: Play "mbt200l16o2baga"
            healthpillx = Int(Rnd * (_Width - 100)) + 50
            healthpilly = -10
        End If
    End If

    '======= Handle Yellow super pill ==========
    If superpillon = 1 Then
        superpilly = superpilly + 3
        'if it moves off screen
        If superpilly + 10 > _Height Then
            'superpill off
            superpillon = 0
        Else
            'draw superpill
            Line (superpillx, superpilly)-(superpillx + (10), superpilly + (10)), _RGB(255, 255, 0), BF
            Color _RGBA(255, 255, 0, 25 + (Rnd * 75))
            _PrintString (7, 55), "CATCH YELLOW PILL"
            Line (2, 52)-(148, 72), _RGBA(255, 255, 0, 25 + (Rnd * 75)), B
        End If
        'if superpill hits player, start invincible mode
        If Abs(superpillx - playerx) < 20 And Abs(superpilly - playery) < 20 Then
            Play "mbt200l16o2c,eg,eo3c,o2ge"
            Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 0, 30), BF
            supermode = 1: supertime = Timer 'start a supertimer
        End If
    Else
        'randomly drop a yellow superpill
        If Int(Rnd * 1200) = 1 And supermode = 0 Then
            superpillon = 1: Play "mbt200l16o3g,ee,c"
            superpillx = Int(Rnd * (_Width - 100)) + 50
            superpilly = -10
            superpillon = 0
        End If
    End If

    '======== Hnadle RED flash pill bomb ========
    If flashpillon = 1 Then
        flashpilly = flashpilly + 3
        'if it moves off screen
        If flashpilly + 10 > _Height Then
            'flashpill off
            flashpillon = 0
        Else
            'draw flashpill
            Line (flashpillx, flashpilly)-(flashpillx + 10, flashpilly + 10), _RGB(255, 0, 0), BF
            Color _RGBA(255, 0, 0, 25 + (Rnd * 75))
            _PrintString (7, 85), "CATCH RED PILL!!"
            Line (2, 82)-(148, 102), _RGBA(255, 0, 0, 25 + (Rnd * 75)), B
        End If
        'if flashpill hits player, add +1 to flashbombs count
        If Abs(flashpillx - playerx) < 20 And Abs(flashpilly - playery) < 20 Then
            Play "mbt200l16o2cegec"
            Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
            flashbombs = flashbombs + 1
            flashpillon = 0
        End If
    Else
        If Int(Rnd * 1600) = 1 Then
            flashpillon = 1: Play "mbt200l16o2baga"
            flashpillx = Int(Rnd * (_Width - 100)) + 50
            flashpilly = -10
        End If
    End If

    '======== Handle kamikaze ball ===========
    If kamikazeon = 1 Then
        'move kamikaze down
        kamikazey = kamikazey + 4
        'move kamikaze torwards players x pos
        If playerx > kamikazex Then kamikazex = kamikazex + 3
        If playerx < kamikazex Then kamikazex = kamikazex - 3
        'make sure kamikaze stays in bounds
        If kamikazex < kamikazer Then kamikazex = kamikazer
        If kamikazex > (_Width - kamikazer) Then kamikazex = (_Width - kamikazer)
        'if it moves off screen, turn it off
        If kamikazey > _Height Then
            'kamikaze off
            kamikazeon = 0
        Else
            'draw kamikaze
            glowball kamikazex, kamikazey, kamikazer, 255, 255, 255, 255
            Circle (kamikazex, kamikazey), kamikazer, _RGB(128 + Rnd * 128, 128, 0)
        End If
        'if kamikaze hits player, hurt health
        If Abs(kamikazex - playerx) < kamikazer And Abs(kamikazey - playery) < kamikazer Then
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (kamikazex, kamikazey), kamikazer, _RGB(255, 128, 0)
                health = health - 1
            End If
            kamikazeon = 0
        End If
    Else
        'radomly send a kamikaze ball
        If Int(Rnd * 1200) = 1 Then
            kamikazeon = 1: Play "mbt200l32o2efgfefefef"
            kamikazex = Int(Rnd * (_Width - 100)) + 50
            kamikazey = -10
            kamikazer = 10
        End If
    End If

    '========== Handle zigzag ball ============
    If zigzagon = 1 Then
        'move zigzag down
        zigzagy = zigzagy + 4
        'move zigzag in a zigzag way in x pos
        If zigway = 0 Then zigzagx = zigzagx + 5 Else zigzagx = zigzagx - 5
        'change zigzag movement with zigway variable
        If zigzagx > zigzagstartx + 50 Then zigway = 1
        If zigzagx < zigzagstartx - 50 Then zigway = 0
        'if it moves off screen, turn it off
        If zigzagy > _Height Then
            'zigzag off
            zigzagon = 0
        Else
            'draw zigzag
            glowball zigzagx, zigzagy, zigzagr, 255, 255, 255, 255
            Circle (zigzagx, zigzagy), zigzagr, _RGBA(255, 255, Rnd * 255, Rnd * 255)
        End If
        'if zigzag hits player, hurt health
        If Abs(zigzagx - playerx) < zigzagr And Abs(zigzagy - playery) < zigzagr Then
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (zigzagx, zigzagy), zigzagr, _RGB(255, 128, 0)
                health = health - 1
            End If
            zigzagon = 0
        End If
    Else
        If Int(Rnd * 1200) = 1 Then
            zigzagon = 1: Play "mbt200l32o2efgfefefef"
            zigzagx = Int(Rnd * (_Width - 200)) + 100
            zigzagstartx = zigzagx
            zigzagy = -20
            zigzagr = 10
        End If
    End If

    '======= Handle ENTER key (RED flash bomb =======
    If _KeyDown(13) And flashbombs > 0 Then
        'shake screen a little
        Play "mbt200l32o2bao1feo2cbo1fgo2ebo3efo2bfo1fgo2bco1fe"
        Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 255, 30), BF
        _Display
        shake& = _CopyImage(_Display)
        For T = 1 To 4
            _PutImage (Rnd * 5, Rnd * 5), shake&
            _Display
            _Delay .05
        Next
        _FreeImage shake&
        'destroy balls, and bombs
        For T = 1 To balls
            'Circle (ballx(t), bally(t)), ballr(t), _RGB(255, 255, 255)
            'explode ball
            For k = 1 To 50 'num of lines
                angle = Rnd * 360 'angle
                length = Rnd * ballr(T) * 1.5
                x2 = ballx(T) + Cos(_D2R(angle)) * length
                y2 = bally(T) + Sin(_D2R(angle)) * length
                Line (ballx(T), bally(T))-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
            Next
            bomba(T) = 0
            bally(T) = Int(Rnd * (_Height / 4)) + respawny 'respawny
            ballx(T) = Int(Rnd * _Width) + 1 'give ball a new x pos
            ballr(T) = 10 + Int(Rnd * 20) 'give ball new radius
            balls(T) = Int(Rnd * 2) + 1 'new ball speed
            'kill kamikaze
            kamikazex = Int(Rnd * _Width) + 1 'x pos
            kamikazey = -20 'y pos
            kamikazer = 10
            kamikazeon = 0
            'kill zigzag
            zigzagx = 50 + (Int(Rnd * _Width) - 100)
            zigzagstartx = zigzagx
            zigzagy = -20
            zigzagr = 10
            zigzagon = 0
        Next
        flashbombs = flashbombs - 1
    End If

    '======= Handle displaying 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
            'hurt health only if not in spuermode
            If supermode = 0 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)
            End If
            bally(i) = respawny 'new y pos
            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

        '==== handle bomb action
        'if ball has an active bomb, update bomb pos
        If bomba(i) Then
            'draw the bomb
            Circle (bombx(i), bomby(i)), 2, _RGB(255, 255, 255)
            bomby(i) = bomby(i) + 5 'make bomb go down
            'if bomb goes off screen, turn off
            If bomby(i) > _Height Then bomba(i) = 0 'set bomb active flag off
        Else
            'if not, randomly decide to drop one
            If bally(i) > 0 Then
                If Int(Rnd * 300) = 1 Then
                    bomba(i) = 1
                    bombx(i) = ballx(i)
                    bomby(i) = bally(i)
                End If
            End If
        End If
    Next


    '======= Draw player along bottom of screen =======
    If supermode = 1 Then
        'golden color (super mode)
        Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(255, 255, Rnd * 128), BF
    Else
        'normal red player
        Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(255, Rnd * 125, Rnd * 128), BF
    End If
    Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(0, 0, Rnd * 255), B
    'if in supermode, give player a protective shield
    If supermode = 1 Then Circle (playerx, playery), 10, _RGB(Rnd * 255, Rnd * 255, Rnd * 255)


    '======= Handle all active shots on screen =====
    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 shield1 then shot off
            If shotx(i) > shield1x And shotx(i) < (shield1x + shield1s) Then
                If shoty(i) > shield1y And shoty(i) < shield1y + 5 Then
                    Circle (shotx(i), shoty(i)), 5, _RGB(255, 255, 255)
                    Play "mbt200l32o6fb"
                    shota(i) = 0
                End If
            End If
            'if shot hits shield2 then shot off
            If shotx(i) > shield2x And shotx(i) < (shield2x + shield2s) Then
                If shoty(i) > shield2y And shoty(i) < shield2y + 5 Then
                    Circle (shotx(i), shoty(i)), 5, _RGB(255, 255, 255)
                    Play "mbt200l32o6fb"
                    shota(i) = 0
                End If
            End If
        End If
    Next


    '===== Handle left/right arrow keys pressed =======
    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

    '===== Handle 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 a shot hits a ball, kamikaze, zigzag balls too ======
    For i = 1 To balls
        For j = 1 To shotcount
            If shota(j) Then
                'if shot hits a ball
                If Abs(ballx(i) - shotx(j)) < ballr(i) And Abs(bally(i) - shoty(j)) < ballr(i) Then
                    Play "mbt200l64o2cdefgabag"
                    'explode ball
                    For k = 1 To 50 'num of lines
                        angle = Rnd * 360 'angle
                        length = Rnd * ballr(i) * 1.5
                        x2 = ballx(i) + Cos(_D2R(angle)) * length
                        y2 = bally(i) + Sin(_D2R(angle)) * length
                        Line (ballx(i), bally(i))-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
                    Next
                    shota(j) = 0 'set shot active flag off
                    'generate a new ball
                    bally(i) = respawny 'y pos
                    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
                'see if a shot hit kamikaze
                If kamikazeon = 1 Then
                    If Abs(kamikazex - shotx(j)) < kamikazer And Abs(kamikazey - shoty(j)) < kamikazer Then
                        'destroy kamikaze
                        Play "mbt200l64o2cdefgabag"
                        'Circle (kamikazex, kamikazey), kamikazer, _RGB(255, 255, 255)
                        'kill kamikaze ball
                        For k = 1 To 50 'num of lines
                            angle = Rnd * 360 'angle
                            length = Rnd * kamikazer * 1.5
                            x2 = kamikazex + Cos(_D2R(angle)) * length
                            y2 = kamikazey + Sin(_D2R(angle)) * length
                            Line (kamikazex, kamikazey)-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
                        Next
                        shota(j) = 0 'set shot active flag off
                        kamikazeon = 0
                        score = score + 5 'update score
                    End If
                End If
                'see if a shot hit zigzag
                If zigzagon = 1 Then
                    If Abs(zigzagx - shotx(j)) < zigzagr And Abs(zigzagy - shoty(j)) < zigzagr Then
                        'destroy zigzag
                        Play "mbt200l64o2cdefgabag"
                        'Circle (zigzagx, zigzagy), zigzagr, _RGB(255, 255, 255)
                        'kill zigzag ball
                        For k = 1 To 50 'num of lines
                            angle = Rnd * 360 'angle
                            length = Rnd * zigzagr * 1.5
                            x2 = zigzagx + Cos(_D2R(angle)) * length
                            y2 = zigzagy + Sin(_D2R(angle)) * length
                            Line (zigzagx, zigzagy)-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
                        Next
                        shota(j) = 0 'set shot active flag off
                        zigzagon = 0
                        score = score + 5 'update score
                    End If
                End If

            End If
        Next
    Next

    '===== See 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
            'only if not in supermode
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (ballx(i), bally(i)), ballr(i), _RGB(255, 0, 0)
                'generate a new ball
                bally(i) = respawny
                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
        End If
    Next

    '====== if a ball's falling bomb hits player, health decrease
    For i = 1 To balls
        If bomba(i) = 1 Then
            If Abs(bombx(i) - playerx) < 5 And Abs(bomby(i) - playery) < 5 Then
                'only if not in supermode
                If supermode = 0 Then
                    Play "mbt200l32o1bfc"
                    bomba(i) = 0
                    Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
                    health = health - 1
                End If
            End If
        End If
    Next

    '==== handle bigball =====
    If Int(Rnd * 2000) = 1 And bigballon = 0 Then
        bigballon = 1
        bigballx = -50
        bigbally = _Height / 2
        bigballs = 2
        bigshotnum = 100
        ReDim bigshotx(1 To bigshotnum) 'x
        ReDim bigshoty(1 To bigshotnum) 'y
        ReDim bigshotangle(1 To bigshotnum) 'angle
        ReDim bigshots(1 To bigshotnum) 'speed
        bigshotcount = 0
    End If

    If bigballon = 1 Then
        bigballr = 40 + (Rnd * 10)
        glowball bigballx, bigbally, bigballr, 255, 255, 255, 255

        'do bigshots
        For i = 1 To bigshotcount
            'move bigshots by angle and speed
            bigshotx(i) = bigshotx(i) + Cos(bigshotangle(i)) * bigshots(i)
            bigshoty(i) = bigshoty(i) + Sin(bigshotangle(i)) * bigshots(i)
            'glowball bigshotx(i), bigshoty(i), 5, 255, 255, 255, 255
            Circle (bigshotx(i), bigshoty(i)), 3, _RGB(255, 255, 0)
            'if bigshot goes off the screen
            If bigshotx(i) < 0 Or bigshotx(i) > _Width Or bigshoty(i) < 0 Or bigshoty(i) > _Height Then
                'remove bigshot by moving the last bigshot to its place
                bigshotx(i) = bigshotx(bigshotcount)
                bigshoty(i) = bigshoty(bigshotcount)
                bigshotcount = bigshotcount - 1
            End If

            'see if a bigshot hits a player
            If Abs(bigshotx(i) - playerx) < 5 And Abs(bigshoty(i) - playery) < 5 Then
                'only if not in supermode
                If supermode = 0 Then
                    Play "mbt200l32o1bfc"
                    'bomba(i) = 0
                    Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
                    health = health - 1
                End If
            End If

        Next

        'move bigball to the right until it goes off screen
        bigballx = bigballx + bigballs
        If bigballx > _Width + 150 Then
            bigballon = 0
            bigshotcount = 0 'reset bigshot count
        End If

        'randomly shoot bigshot at various angles
        If Int(Rnd * 5) = 0 And bigshotcount < bigshotnum Then
            bigshotcount = bigshotcount + 1
            bigshotx(bigshotcount) = bigballx
            bigshoty(bigshotcount) = bigbally
            bigshotangle(bigshotcount) = Rnd * (2 * 3.14159) 'angle
            bigshots(bigshotcount) = 3 + Rnd * 3 'speed
        End If

    End If



    'increase respawning y pos of balls as time goes on
    'this makes them come down more frequently as you go
    If respawny < 0 Then respawny = respawny + .1


    '==== draw information at top ======

    'show player score
    Color _RGB(255, 255, 255)
    _PrintString (2, 2), "SCORE:" + Str$(score)

    If score >= highscore Then highscore = score

    'show HI Score
    Color _RGB(255, 255, 0)
    _PrintString (300, 2), "HI:" + Str$(highscore)
    Color _RGB(255, 255, 255)

    'draww flashbombs
    Line (480, 5)-(490, 15), _RGB(196, 0, 0), BF
    Line (480, 5)-(490, 15), _RGB(255, 0, 0), B
    _PrintString (500, 3), "x" + Str$(flashbombs)

    'draw health status
    hcount = 1
    For h = 1 To (healthmax * 10) Step 10
        If health >= hcount Then
            Line (560 + h, 5)-(560 + h + 5, 15), _RGB(0, 255, 0), BF
        Else
            Line (560 + h, 5)-(560 + h + 5, 15), _RGB(0, 255, 0), B
        End If
        hcount = hcount + 1
    Next

    '==== Check supertimer, turn off in 15secs up ======
    'if in supermode, check supertimer.  If over 15 seconds, tunn off
    If supermode = 1 Then
        If Timer - supertime > 15 Then supermode = 0
    End If

    '===== Check your health status, act on it =====
    'if out of health, game over
    If health < 1 Then
        'game over sound effect
        Play "mbt200l32o4b,ga,fg,ef,de,cd,o3bo4c,o3ab,ga,fg,ef,de,cd,o2bo3c,o2ab,ga,fg,el8f,d"
        Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
        _Display
        shake& = _CopyImage(_Display)
        ReDim parts(100, 3) 'explosion particle array
        For i = 0 To 99
            parts(i, 0) = playerx 'particle x pos
            parts(i, 1) = playery 'particle y pos
            parts(i, 2) = Rnd * 360 'particle random angle
            parts(i, 3) = Int(Rnd * 5) + 4 'particle random speed
        Next
        For doit = 0 To 255 Step 4
            _PutImage (Rnd * 7, Rnd * 7), shake&
            For i = 0 To 99
                ' Move the particles
                parts(i, 0) = parts(i, 0) + Cos(parts(i, 2) * 3.14159 / 180) * parts(i, 3)
                parts(i, 1) = parts(i, 1) + Sin(parts(i, 2) * 3.14159 / 180) * parts(i, 3)
                If parts(i, 1) < _Height And parts(i, 1) > 0 And parts(i, 0) < _Width And parts(i, 0) > 0 Then
                    Line (parts(i, 0), parts(i, 1))-Step(Rnd * 4, Rnd * 4), _RGBA(255, Rnd * 125, Rnd * 128, 255 - doit)
                End If
            Next
            _Limit 30
            _Display
        Next
        _FreeImage shake&
        'fade out screen to black
        For f = 1 To 100
            Line (0, 0)-(_Width, _Height), _RGBA(0, 0, 0, 20), BF
            _Display
            _Delay .01
        Next
        Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 128), BF
        Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 255), B
        Color _RGB(255, 255, 255)
        _PrintString (275, 225), "  GAME OVER"
        _PrintString (275, 245), "OUT OF HEALTH"
        _PrintString (275, 265), "  SCORE:" + Str$(score)
        If score = highscore Then _PrintString (275, 340), "NEW HI SCORE!"
        _Display
        _Delay 6
        Cls: _Display
        GoTo StartGame
    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

Sub PulseBack (a, pulse)
    'creates that big pulsating circle backdrop
    'hardcoded x/y, min and max here, but you could make
    'those parameters instead to control/adapt look..
    t = Timer * pulse: x = _Width / 2: y = _Height / 2
    min = _Height / 2: max = _Height / 2
    cs = min + (max - min) * ((Sin(t) + 1) / 2)
    For y2 = y - max To y + max Step 4
        For x2 = x - max To x + max Step 4
            If Sqr((x2 - x) ^ 2 + (y2 - y) ^ 2) <= cs Then
                clr = (cs - Sqr((x2 - x) ^ 2 + (y2 - y) ^ 2)) / cs
                r = (Sin(t + 0) * 127 + 128) * clr
                g = (Sin(t + 3.14 / 2) * 127 + 128) * clr
                b = (Sin(t + 3.14) * 127 + 128) * clr
                If r > 255 Then r = 255
                If g > 255 Then g = 255
                If b > 255 Then b = 255
                If y2 < 425 Then
                    Line (x2, y2)-Step(3, 3), _RGBA(r, g, b, a), BF
                End If
            End If
        Next
    Next
End Sub

   

Find my programs here in Dav's QB64 Corner
Reply
#30
Added particle explosions when balls are shot - now they become space dust!  That added a lot of visual impact.  Made few tweaks/fixes here and there.  

The game is looks better, but the code doesn't.  I'm going to start putting routines in SUB's and FUNTIONS now to reduce code/optimize.   Need to update the sound effects, to sound files maybe.

Haven't tested this on my slower laptop, but it plays smooth on this faster one.  If anyone experiences sluggishness let me know and I will tone down the amount of space dust or something.

- Dav

Code: (Select All)
'=============
'ballshoot.bas v8
'=============
'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, SEP/2024 for QB64-PE (Phoenix Edition)

' WARNING: THIS GAME HAS FLASHING SCREENS (not much though)

'New for v8:
'            - shot balls now explode into space dust!
'            - added glowing effect around player piece
'            - increased background pulse intensisity
'            - decreased bigball entrance time (too fast)
'            - fixed superpill entrace (last ver broke it)

'Move player using arrow keys - SPACE bar shoots.
'Shoot the balls. Don't let any hit you or pass you by.
'Moving shields appears now and then to protect balls.
'See how many balls you can shoot down before dying.
'Catch green pill to increase your health points +1.
'Catch yellow pill to be invincible for 15 seconds.
'Catch red pill to get a flash bomb! ENTER to use it.

'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 7 health points then
'the game is over.

'If you catch green pills, it adds +1 to your health.
'If you catch yellow pills, you are invincible 15 secs.
'If you catch a red pill it gives you a flash bomb.
'Press ENTER to use you flash bombs, which will destroy
'all balls and dropping bombs on the screen.

'There are many ways to expand this into something better.
'If you do make more out of it, please share it also.


Randomize Timer

Screen _NewImage(640, 480, 32)
_FullScreen _SquarePixels
_PrintMode _KeepBackground
_MouseHide

'draw/save a background image to use
c = 0
For y = 425 To _Height
    Line (0, y)-(_Width, y), _RGBA(c / 3, c / 2, c, 225 + Rnd * 25), BF
    c = c + 1: If c = 255 Then c = 255
Next: back& = _CopyImage(_Display) 'copy backgraound as back& image

highscore = 0 'start at zero

'========
StartGame:
'========

balls = 6 'number of balls at one time
shots = 7 'number of shots allowed on screen

ReDim ballx(1 To balls) 'ball x pos
ReDim bally(1 To balls) 'ball y pos
ReDim balld(1 To balls) 'ball direction
ReDim ballr(1 To balls) 'ball radius
ReDim balls(1 To balls) 'ball drop speed

ReDim bombx(1 To balls) 'ball bomb x pos
ReDim bomby(1 To balls) 'ball bomb y pos
ReDim bomba(1 To balls) 'flag if bomb is active

ReDim shotx(1 To shots) 'shot x pos
ReDim shoty(1 To shots) 'shot y pos
ReDim shota(1 To shots) 'flag if shot is active

'=== for space dust (explosion particles)
dustmax = balls * 100 'make sure enough dust particles
ReDim dustx(dustmax), dusty(dustmax)
ReDim dustxv(dustmax), dustyv(dustmax)
ReDim dustr(dustmax), dusta(dustmax)
dustcount = 0 'no active dust particles yet


'set game defaults
score = 0 'score is zero
shotcount = 0 'no active shots
bombcount = 0 'no active bombs
playerx = _Width / 2 'x pos of player
playery = 475 'y pos of player (this stays same)
respawny = -300 'ball respawns off screen
healthmax = 7 'max level of health
health = 7 'start with max health
flashbombs = 1 'start with one flash bomb
'make sure these all off
bigballon = 0
shield1on = 0
shield2on = 0
healthpillon = 0
superpillon = 0
flashpillon = 0
kamikazeon = 0
zigzagon = 0

'generate random ball info
For i = 1 To balls
    bomba(i) = 0 'all ball bombs off
    ballx(i) = Int(Rnd * _Width) + 1 'x pos
    bally(i) = Int(Rnd * (_Height / 4)) + respawny 'y pos
    balld(i) = Int(Rnd * 3) - 1 'moving direction
    ballr(i) = 10 + Int(Rnd * 20) 'radius
    balls(i) = Int(Rnd * 2) + 1
Next

'start sound effect
Play "mbt200l16o2e,gg,o3cc,el8e,gl16c,el4c,e,g"


'==============  main game loop ==============

Do

    _PutImage (1, 1)-(_Width - 1, _Height - 1), back& 'put background down

    PulseBack 30, 7.25 - health 'gets faster as health decreases

    '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 * 400)-Step(Rnd * 3, Rnd * 3), _RGBA(255, 255, 255, Rnd * 200), BF

    'if health is getting low, show flashing yellow background
    If health = 2 Then Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 0, healthglow - 1), BF
    'if health is critially low, show flashing red screen
    If health = 1 Then Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, healthglow), BF
    If healthway = 0 Then healthglow = healthglow + .5 Else healthglow = healthglow - .5
    If healthglow > 5 Then healthway = 1
    If healthglow < 0 Then healthway = 0


    '========  Handle Shield1  =======
    If shield1on = 1 Then
        If Rnd < .1 Then wobble = Int(Rnd * 3) - 1
        shield1x = shield1x + 2 + wobble
        'if it moves off screen
        If shield1x > _Width Then
            'shield off
            shield1on = 0
        Else
            'draw shield1
            For s = 1 To shield1s Step 5
                glowball shield1x + s, shield1y, 5, 255, 255, 255, 200
            Next
        End If
    Else
        'randomly turn moving shield 2 on from time to time
        If Int(Rnd * 500) = 1 Then
            shield1on = 1: Play "mbt200l32o3ege"
            'reset shield values
            shield1s = 50 + Int(Rnd * 50) 'random sixe 50-100
            shield1x = -shield1s 'starting position
            shield1y = shield1s + (Rnd * 300)
        End If
    End If

    '======== Handle Shield2 ================
    If shield2on = 1 Then
        If Rnd < .1 Then wobble = Int(Rnd * 3) - 1
        shield2x = shield2x - 1 - wobble
        'if it moves off screen
        If shield2x < -shield2s Then
            'shield off
            shield2on = 0
        Else
            'draw shield 2
            For s = 1 To shield2s Step 5
                glowball shield2x + s, shield2y, 5, 255, 255, 255, 200
            Next
        End If
    Else
        'randomly turn moving shield2 on from time to time
        If Int(Rnd * 500) = 1 Then
            shield2on = 1: Play "mbt200l32o3ege"
            'reset shield values
            shield2s = 50 + Int(Rnd * 50)
            shield2x = _Width + shield2s
            shield2y = shield2s + (Rnd * 300)
        End If
    End If

    '====== Handle Green health pill =========
    If healthpillon = 1 Then
        healthpilly = healthpilly + 3
        'if it moves off screen
        If healthpilly + 10 > _Height Then
            'healthpill off
            healthpillon = 0
        Else
            'draw healthpill
            Line (healthpillx, healthpilly)-(healthpillx + 10, healthpilly + 10), _RGB(0, 255, 0), BF
            Color _RGBA(0, 255, 0, 25 + (Rnd * 75))
            _PrintString (7, 25), "CATCH GREEN PILL"
            Line (2, 22)-(148, 42), _RGBA(0, 255, 0, 25 + (Rnd * 75)), B
        End If
        'if healthpill hits player, add point to health
        If Abs(healthpillx - playerx) < 20 And Abs(healthpilly - playery) < 20 Then
            Play "mbt200l16o2cegec"
            Line (0, 0)-(_Width, _Height), _RGBA(0, 255, 0, 30), BF
            If health < healthmax Then health = health + 1
            healthpillon = 0
        End If
    Else
        'randomly drop a health pillfrom time to time
        If Int(Rnd * 700) = 1 And health <> healthmax Then
            healthpillon = 1: Play "mbt200l16o2baga"
            healthpillx = Int(Rnd * (_Width - 100)) + 50
            healthpilly = -10
        End If
    End If

    '======= Handle Yellow super pill ==========
    If superpillon = 1 Then
        superpilly = superpilly + 3
        'if it moves off screen
        If superpilly + 10 > _Height Then
            'superpill off
            superpillon = 0
        Else
            'draw superpill
            Line (superpillx, superpilly)-(superpillx + (10), superpilly + (10)), _RGB(255, 255, 0), BF
            Color _RGBA(255, 255, 0, 25 + (Rnd * 75))
            _PrintString (7, 55), "CATCH YELLOW PILL"
            Line (2, 52)-(148, 72), _RGBA(255, 255, 0, 25 + (Rnd * 75)), B
        End If
        'if superpill hits player, start invincible mode
        If Abs(superpillx - playerx) < 20 And Abs(superpilly - playery) < 20 Then
            Play "mbt200l16o2c,eg,eo3c,o2ge"
            Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 0, 30), BF
            supermode = 1: supertime = Timer 'start a supertimer
        End If
    Else
        'randomly drop a yellow superpill
        If Int(Rnd * 1200) = 1 And supermode = 0 Then
            superpillon = 1: Play "mbt200l16o3g,ee,c"
            superpillx = Int(Rnd * (_Width - 100)) + 50
            superpilly = -10
        End If
    End If

    '======== Handle RED flash pill bomb ========
    If flashpillon = 1 Then
        flashpilly = flashpilly + 3
        'if it moves off screen
        If flashpilly + 10 > _Height Then
            'flashpill off
            flashpillon = 0
        Else
            'draw flashpill
            Line (flashpillx, flashpilly)-(flashpillx + 10, flashpilly + 10), _RGB(255, 0, 0), BF
            Color _RGBA(255, 0, 0, 25 + (Rnd * 75))
            _PrintString (7, 85), "CATCH RED PILL!!"
            Line (2, 82)-(148, 102), _RGBA(255, 0, 0, 25 + (Rnd * 75)), B
        End If
        'if flashpill hits player, add +1 to flashbombs count
        If Abs(flashpillx - playerx) < 20 And Abs(flashpilly - playery) < 20 Then
            Play "mbt200l16o2cegec"
            Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
            flashbombs = flashbombs + 1
            flashpillon = 0
        End If
    Else
        If Int(Rnd * 1600) = 1 Then
            flashpillon = 1: Play "mbt200l16o2baga"
            flashpillx = Int(Rnd * (_Width - 100)) + 50
            flashpilly = -10
        End If
    End If

    '======== Handle kamikaze ball ===========
    If kamikazeon = 1 Then
        'move kamikaze down
        kamikazey = kamikazey + 4
        'move kamikaze torwards players x pos
        If playerx > kamikazex Then kamikazex = kamikazex + 3
        If playerx < kamikazex Then kamikazex = kamikazex - 3
        'make sure kamikaze stays in bounds
        If kamikazex < kamikazer Then kamikazex = kamikazer
        If kamikazex > (_Width - kamikazer) Then kamikazex = (_Width - kamikazer)
        'if it moves off screen, turn it off
        If kamikazey > _Height Then
            'kamikaze off
            kamikazeon = 0
        Else
            'draw kamikaze
            glowball kamikazex, kamikazey, kamikazer, 255, 255, 255, 255
            Circle (kamikazex, kamikazey), kamikazer, _RGB(128 + Rnd * 128, 128, 0)
        End If
        'if kamikaze hits player, hurt health
        If Abs(kamikazex - playerx) < kamikazer And Abs(kamikazey - playery) < kamikazer Then
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (kamikazex, kamikazey), kamikazer, _RGB(255, 128, 0)
                health = health - 1
            End If
            kamikazeon = 0
        End If
    Else
        'radomly send a kamikaze ball
        If Int(Rnd * 1200) = 1 Then
            kamikazeon = 1: Play "mbt200l32o2efgfefefef"
            kamikazex = Int(Rnd * (_Width - 100)) + 50
            kamikazey = -10
            kamikazer = 10
        End If
    End If

    '========== Handle zigzag ball ============
    If zigzagon = 1 Then
        'move zigzag down
        zigzagy = zigzagy + 4
        'move zigzag in a zigzag way in x pos
        If zigway = 0 Then zigzagx = zigzagx + 5 Else zigzagx = zigzagx - 5
        'change zigzag movement with zigway variable
        If zigzagx > zigzagstartx + 50 Then zigway = 1
        If zigzagx < zigzagstartx - 50 Then zigway = 0
        'if it moves off screen, turn it off
        If zigzagy > _Height Then
            'zigzag off
            zigzagon = 0
        Else
            'draw zigzag
            glowball zigzagx, zigzagy, zigzagr, 255, 255, 255, 255
            Circle (zigzagx, zigzagy), zigzagr, _RGBA(255, 255, Rnd * 255, Rnd * 255)
        End If
        'if zigzag hits player, hurt health
        If Abs(zigzagx - playerx) < zigzagr And Abs(zigzagy - playery) < zigzagr Then
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (zigzagx, zigzagy), zigzagr, _RGB(255, 128, 0)
                health = health - 1
            End If
            zigzagon = 0
        End If
    Else
        If Int(Rnd * 1200) = 1 Then
            zigzagon = 1: Play "mbt200l32o2efgfefefef"
            zigzagx = Int(Rnd * (_Width - 200)) + 100
            zigzagstartx = zigzagx
            zigzagy = -20
            zigzagr = 10
        End If
    End If

    '======= Handle ENTER key (RED flash bomb =======
    If _KeyDown(13) And flashbombs > 0 Then
        'shake screen a little
        Play "mbt200l32o2bao1feo2cbo1fgo2ebo3efo2bfo1fgo2bco1fe"
        Line (0, 0)-(_Width, _Height), _RGBA(255, 255, 255, 30), BF
        _Display
        shake& = _CopyImage(_Display)
        For T = 1 To 4
            _PutImage (Rnd * 5, Rnd * 5), shake&
            _Display
            _Delay .05
        Next
        _FreeImage shake&
        'destroy all balls, and bombs
        For T = 1 To balls
            'explode ball (turn it into space dust)
            For ex = 1 To ballr(T) * 2
                If dustcount < dustmax Then
                    dustcount = dustcount + 1
                    dustx(dustcount) = ballx(T)
                    dusty(dustcount) = bally(T)
                    dustxv(dustcount) = Rnd * 5 - 2.5
                    dustyv(dustcount) = Rnd * 5 - 2.5
                    dustr(dustcount) = Int(Rnd * 2) + 1
                    dusta(dustcount) = Rnd * 255
                End If
            Next
            bomba(T) = 0
            bally(T) = Int(Rnd * (_Height / 4)) + respawny 'respawny
            ballx(T) = Int(Rnd * _Width) + 1 'give ball a new x pos
            ballr(T) = 10 + Int(Rnd * 20) 'give ball new radius
            balls(T) = Int(Rnd * 2) + 1 'new ball speed
            'kill kamikaze
            kamikazex = Int(Rnd * _Width) + 1 'x pos
            kamikazey = -20 'y pos
            kamikazer = 10
            kamikazeon = 0
            'kill zigzag
            zigzagx = 50 + (Int(Rnd * _Width) - 100)
            zigzagstartx = zigzagx
            zigzagy = -20
            zigzagr = 10
            zigzagon = 0
        Next
        flashbombs = flashbombs - 1
    End If

    '======= Handle displaying 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
            'hurt health only if not in spuermode
            If supermode = 0 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)
            End If
            bally(i) = respawny 'new y pos
            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

        '==== handle bomb action
        'if ball has an active bomb, update bomb pos
        If bomba(i) Then
            'draw the bomb
            Circle (bombx(i), bomby(i)), 2, _RGB(255, 255, 255)
            bomby(i) = bomby(i) + 5 'make bomb go down
            'if bomb goes off screen, turn off
            If bomby(i) > _Height Then bomba(i) = 0 'set bomb active flag off
        Else
            'if not, randomly decide to drop one
            If bally(i) > 0 Then
                If Int(Rnd * 300) = 1 Then
                    bomba(i) = 1
                    bombx(i) = ballx(i)
                    bomby(i) = bally(i)
                End If
            End If
        End If
    Next


    '======= Draw player along bottom of screen =======
    If supermode = 1 Then
        'golden color (super mode)
        Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(255, 255, Rnd * 128), BF
    Else
        'normal red player
        Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(255, Rnd * 125, Rnd * 128), BF
    End If
    Line (playerx - 5, playery - 5)-(playerx + 5, playery + 5), _RGB(0, 0, Rnd * 255), B
    'if in supermode, give player a protective shield
    If supermode = 1 Then Circle (playerx, playery), 10, _RGB(Rnd * 255, Rnd * 255, Rnd * 255)
    glowball playerx, playery, 20, 1, 1, 1, 100

    '======= Handle all active shots on screen =====
    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 shield1 then shot off
            If shotx(i) > shield1x And shotx(i) < (shield1x + shield1s) Then
                If shoty(i) > shield1y And shoty(i) < shield1y + 5 Then
                    Circle (shotx(i), shoty(i)), 5, _RGB(255, 255, 255)
                    Play "mbt200l32o6fb"
                    shota(i) = 0
                End If
            End If
            'if shot hits shield2 then shot off
            If shotx(i) > shield2x And shotx(i) < (shield2x + shield2s) Then
                If shoty(i) > shield2y And shoty(i) < shield2y + 5 Then
                    Circle (shotx(i), shoty(i)), 5, _RGB(255, 255, 255)
                    Play "mbt200l32o6fb"
                    shota(i) = 0
                End If
            End If
        End If
    Next


    '===== Handle left/right arrow keys pressed =======
    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

    '===== Handle 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 a shot hits a ball, kamikaze, zigzag balls too ======
    For i = 1 To balls
        For j = 1 To shotcount
            If shota(j) Then
                'if shot hits a ball
                If Abs(ballx(i) - shotx(j)) < ballr(i) And Abs(bally(i) - shoty(j)) < ballr(i) Then
                    Play "mbt200l64o2cdefgabag"

                    'explode ball (turn it into space dust)
                    For ex = 1 To ballr(i) * 2
                        If dustcount < dustmax Then
                            dustcount = dustcount + 1
                            dustx(dustcount) = ballx(i)
                            dusty(dustcount) = bally(i)
                            dustxv(dustcount) = Rnd * 5 - 2.5
                            dustyv(dustcount) = Rnd * 5 - 2.5
                            dustr(dustcount) = Int(Rnd * 2) + 1
                            dusta(dustcount) = Rnd * 255
                        End If
                    Next

                    shota(j) = 0 'set shot active flag off
                    'generate a new ball
                    bally(i) = respawny 'y pos
                    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
                'see if a shot hit kamikaze
                If kamikazeon = 1 Then
                    If Abs(kamikazex - shotx(j)) < kamikazer And Abs(kamikazey - shoty(j)) < kamikazer Then
                        'destroy kamikaze
                        Play "mbt200l64o2cdefgabag"
                        'Circle (kamikazex, kamikazey), kamikazer, _RGB(255, 255, 255)
                        'kill kamikaze ball
                        For k = 1 To 50 'num of lines
                            angle = Rnd * 360 'angle
                            length = Rnd * kamikazer * 1.5
                            x2 = kamikazex + Cos(_D2R(angle)) * length
                            y2 = kamikazey + Sin(_D2R(angle)) * length
                            Line (kamikazex, kamikazey)-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
                        Next
                        shota(j) = 0 'set shot active flag off
                        kamikazeon = 0
                        score = score + 5 'update score
                    End If
                End If
                'see if a shot hit zigzag
                If zigzagon = 1 Then
                    If Abs(zigzagx - shotx(j)) < zigzagr And Abs(zigzagy - shoty(j)) < zigzagr Then
                        'destroy zigzag
                        Play "mbt200l64o2cdefgabag"
                        'Circle (zigzagx, zigzagy), zigzagr, _RGB(255, 255, 255)
                        'kill zigzag ball
                        For k = 1 To 50 'num of lines
                            angle = Rnd * 360 'angle
                            length = Rnd * zigzagr * 1.5
                            x2 = zigzagx + Cos(_D2R(angle)) * length
                            y2 = zigzagy + Sin(_D2R(angle)) * length
                            Line (zigzagx, zigzagy)-(x2, y2), _RGBA(255, 255, 255, 128 + (Rnd * 128))
                        Next
                        shota(j) = 0 'set shot active flag off
                        zigzagon = 0
                        score = score + 5 'update score
                    End If
                End If

            End If
        Next
    Next

    '===== See 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
            'only if not in supermode
            If supermode = 0 Then
                Play "mbt200l32o1bfc"
                Circle (ballx(i), bally(i)), ballr(i), _RGB(255, 0, 0)
                'generate a new ball
                bally(i) = respawny
                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
        End If
    Next

    '====== if a ball's falling bomb hits player, health decrease
    For i = 1 To balls
        If bomba(i) = 1 Then
            If Abs(bombx(i) - playerx) < 5 And Abs(bomby(i) - playery) < 5 Then
                'only if not in supermode
                If supermode = 0 Then
                    Play "mbt200l32o1bfc"
                    bomba(i) = 0
                    Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
                    health = health - 1
                End If
            End If
        End If
    Next

    '==== handle bigball =====
    If Int(Rnd * 2200) = 1 And bigballon = 0 Then
        bigballon = 1
        bigballx = -50
        bigbally = _Height / 2
        bigballs = 2
        bigshotnum = 100
        ReDim bigshotx(1 To bigshotnum) 'x
        ReDim bigshoty(1 To bigshotnum) 'y
        ReDim bigshotangle(1 To bigshotnum) 'angle
        ReDim bigshots(1 To bigshotnum) 'speed
        bigshotcount = 0
    End If

    If bigballon = 1 Then
        bigballr = 40 + (Rnd * 10)
        glowball bigballx, bigbally, bigballr, 255, 255, 255, 255

        'do bigshots
        For i = 1 To bigshotcount
            'move bigshots by angle and speed
            bigshotx(i) = bigshotx(i) + Cos(bigshotangle(i)) * bigshots(i)
            bigshoty(i) = bigshoty(i) + Sin(bigshotangle(i)) * bigshots(i)
            'glowball bigshotx(i), bigshoty(i), 5, 255, 255, 255, 255
            Circle (bigshotx(i), bigshoty(i)), 3, _RGB(255, 255, 0)
            'if bigshot goes off the screen
            If bigshotx(i) < 0 Or bigshotx(i) > _Width Or bigshoty(i) < 0 Or bigshoty(i) > _Height Then
                'remove bigshot by moving the last bigshot to its place
                bigshotx(i) = bigshotx(bigshotcount)
                bigshoty(i) = bigshoty(bigshotcount)
                bigshotcount = bigshotcount - 1
            End If

            'see if a bigshot hits a player
            If Abs(bigshotx(i) - playerx) < 5 And Abs(bigshoty(i) - playery) < 5 Then
                'only if not in supermode
                If supermode = 0 Then
                    Play "mbt200l32o1bfc"
                    'bomba(i) = 0
                    Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
                    health = health - 1
                End If
            End If

        Next

        'move bigball to the right until it goes off screen
        bigballx = bigballx + bigballs
        If bigballx > _Width + 150 Then
            bigballon = 0
            bigshotcount = 0 'reset bigshot count
        End If

        'randomly shoot bigshot at various angles
        If Int(Rnd * 5) = 0 And bigshotcount < bigshotnum Then
            bigshotcount = bigshotcount + 1
            bigshotx(bigshotcount) = bigballx
            bigshoty(bigshotcount) = bigbally
            bigshotangle(bigshotcount) = Rnd * (2 * 3.14159) 'angle
            bigshots(bigshotcount) = 3 + Rnd * 3 'speed
        End If

    End If

    'Handle/Update any space dust on screen
    If dustcount > 0 Then
        For i = 1 To dustcount
            dustyv(i) = dustyv(i) + .1 'gravity effect
            dustx(i) = dustx(i) + dustxv(i)
            dusty(i) = dusty(i) + dustyv(i)
            If dusta(i) > 0 Then
                Line (dustx(i), dusty(i))-Step(dustr(i), dustr(i)), _RGBA(Rnd * 155 + 100, Rnd * 155 + 100, Rnd * 155 + 100, dusta(i)), BF
                dusta(i) = dusta(i) - 4 'fading
            End If
        Next
        'cleanup dust fully faded out
        For i = 1 To dustcount
            If dusta(i) <= 0 Then
                dustcount = dustcount - 1
                For j = i To dustcount
                    dustx(j) = dustx(j + 1)
                    dusty(j) = dusty(j + 1)
                    dustxv(j) = dustxv(j + 1)
                    dustyv(j) = dustyv(j + 1)
                    dustr(j) = dustr(j + 1)
                    dusta(j) = dusta(j + 1)
                Next
            End If
        Next
    End If

    'increase respawning y pos of balls as time goes on
    'this makes them come down more frequently as you go
    If respawny < 0 Then respawny = respawny + .1


    '==== draw information at top ======

    'show player score
    Color _RGB(255, 255, 255)
    _PrintString (2, 2), "SCORE:" + Str$(score)

    If score >= highscore Then highscore = score

    'show HI Score
    Color _RGB(255, 255, 0)
    _PrintString (300, 2), "HI:" + Str$(highscore)
    Color _RGB(255, 255, 255)

    'draww flashbombs
    Line (480, 5)-(490, 15), _RGB(196, 0, 0), BF
    Line (480, 5)-(490, 15), _RGB(255, 0, 0), B
    _PrintString (500, 3), "x" + Str$(flashbombs)

    'draw health status
    hcount = 1
    For h = 1 To (healthmax * 10) Step 10
        If health >= hcount Then
            Line (560 + h, 5)-(560 + h + 5, 15), _RGB(0, 255, 0), BF
        Else
            Line (560 + h, 5)-(560 + h + 5, 15), _RGB(0, 255, 0), B
        End If
        hcount = hcount + 1
    Next

    '==== Check supertimer, turn off in 15secs up ======
    'if in supermode, check supertimer.  If over 15 seconds, tunn off
    If supermode = 1 Then
        If Timer - supertime > 15 Then supermode = 0
    End If

    '===== Check your health status, act on it =====
    'if out of health, game over
    If health < 1 Then
        'game over sound effect
        Play "mbt200l32o4b,ga,fg,ef,de,cd,o3bo4c,o3ab,ga,fg,ef,de,cd,o2bo3c,o2ab,ga,fg,el8f,d"
        Line (0, 0)-(_Width, _Height), _RGBA(255, 0, 0, 30), BF
        _Display
        shake& = _CopyImage(_Display)
        ReDim parts(100, 3) 'explosion particle array
        For i = 0 To 99
            parts(i, 0) = playerx 'particle x pos
            parts(i, 1) = playery 'particle y pos
            parts(i, 2) = Rnd * 360 'particle random angle
            parts(i, 3) = Int(Rnd * 5) + 4 'particle random speed
        Next
        For doit = 0 To 255 Step 4
            _PutImage (Rnd * 7, Rnd * 7), shake&
            For i = 0 To 99
                ' Move the particles
                parts(i, 0) = parts(i, 0) + Cos(parts(i, 2) * 3.14159 / 180) * parts(i, 3)
                parts(i, 1) = parts(i, 1) + Sin(parts(i, 2) * 3.14159 / 180) * parts(i, 3)
                If parts(i, 1) < _Height And parts(i, 1) > 0 And parts(i, 0) < _Width And parts(i, 0) > 0 Then
                    Line (parts(i, 0), parts(i, 1))-Step(Rnd * 4, Rnd * 4), _RGBA(255, Rnd * 125, Rnd * 128, 255 - doit)
                End If
            Next
            _Limit 30
            _Display
        Next
        _FreeImage shake&
        'fade out screen to black
        For f = 1 To 100
            Line (0, 0)-(_Width, _Height), _RGBA(0, 0, 0, 20), BF
            _Display
            _Delay .01
        Next
        Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 128), BF
        Line (250, 200)-(400, 300), _RGBA(128, 128, 128, 255), B
        Color _RGB(255, 255, 255)
        _PrintString (275, 225), "  GAME OVER"
        _PrintString (275, 245), "OUT OF HEALTH"
        _PrintString (275, 265), "  SCORE:" + Str$(score)
        If score = highscore Then _PrintString (275, 340), "NEW HI SCORE!"
        _Display
        _Delay 6
        Cls: _Display
        GoTo StartGame
    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

Sub PulseBack (a, pulse)
    'creates that big pulsating circle backdrop
    'hardcoded x/y, min and max here, but you could make
    'those parameters instead to control/adapt look..
    t = Timer * pulse: x = _Width / 2: y = _Height / 2
    min = _Height / 2: max = _Height / 2
    cs = min + (max - min) * ((Sin(t) + 1) / 2)
    For y2 = y - max To y + max Step 4
        For x2 = x - max To x + max Step 4
            If Sqr((x2 - x) ^ 2 + (y2 - y) ^ 2) <= cs Then
                clr = (cs - Sqr((x2 - x) ^ 2 + (y2 - y) ^ 2)) / cs
                r = (Sin(t + 0) * 127 + 128) * clr
                g = (Sin(t + 3.14 / 2) * 127 + 128) * clr
                b = (Sin(t + 3.14) * 127 + 128) * clr
                If r > 255 Then r = 255
                If g > 255 Then g = 255
                If b > 255 Then b = 255
                If y2 < 425 Then
                    Line (x2, y2)-Step(3, 3), _RGBA(r, g, b, a), BF
                End If
            End If
        Next
    Next
End Sub

Find my programs here in Dav's QB64 Corner
Reply




Users browsing this thread: 1 Guest(s)