QB64 Phoenix Edition
Ken's Artillery 2 - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Programs (https://qb64phoenix.com/forum/forumdisplay.php?fid=7)
+---- Thread: Ken's Artillery 2 (/showthread.php?tid=284)

Pages: 1 2 3


Ken's Artillery 2 - SierraKen - 04-30-2022

This game was originally a very old early 80's (or so) DOS or Apple game. Microsoft used it to adapt it to their own QBasic game called Gorilla, throwing bananas instead of launching cannonballs. Today I added some features to my own version I made a couple years ago. The object of the game is to beat the computer by hitting its cannon 5 times in any level. Each level has a different sized mountain and color. If you hit him 5 times you advance to the next level. There is no ending to the game and after each level your score goes back to 0 but your Level does add up. To play, you type in a power of the cannonball and the angle. The wind also changes per turn so keep an eye on that to adjust your power and angle. B+ helped me on my original one with the math part of it so I have his name in the title as well. There's no added files. The computer has a small A.I. being almost as smart as you are in your turns (sorta), but don't ask me how I made it because I don't remember LOL. 

Code: (Select All)
'I've always wanted to make this game ever since I started programming in the 80's.
'This was created by Ken G. with much help from others below.
'Thank you to B+ for much of the math code.
'It takes the computer a little time to learn how to hit your base.
'Created on June 26, 2019.
'Version 2 made on April 30, 2022.
'Added: Levels, random colored mountains, and better looking cannons.

_Title "Ken's Artillery 2"
_Limit 200
Cls
Screen _NewImage(1200, 700, 32)
Print "                                              Ken's Artillery 2"
Print: Print: Print
Print "                                      By SierraKen with math help from B+."
Print: Print: Print
Print "                         Instructions: You play against the computer by shooting a cannonball"
Print "                         from your cannon at your base on the left side of the screen"
Print "                         to the computer's base on the right side of the screen."
Print "                         To do this, you type a power number between 0 and 80 and press Enter."
Print "                         Then you type an angle that the cannonball will travel at,"
Print "                         between 0 and 90 and press Enter."
Print "                         You get a point every time you hit the other base."
Print "                         If you hit the enemy 5 times you advance to the next mountain."
Print "                         If the enemy hits you 5 times in one mountain, you lose."
Print "                         Watch the wind speed indicator up on top to see the direction and"
Print "                         speed of the wind, which makes a big difference on where your"
Print "                         cannonball will land. Also, there will be a random sized mountain"
Print "                         and color for every level and game."
Print: Print: Print
Input "                         Press Enter to begin.", start$
Cls
level = 1

start:
c = 0
mountain = 0
win = 0
compoints = 0
points = 0
ground = 590 'up is negative in direction

'Your Cannon

cbx = 10 '              cannon butt end x, y
cby = ground - 20
cmx = 50 '              cannon mouth end
cmy = ground - 70

'Computer's Cannon

cbx2 = 1190
cby2 = cby
cmx2 = 1150
cmy2 = cmy


g = .15 '       with air resistance
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
Color , _RGB32(156, 210, 237)
Cls
'Bases
Line (cbx, ground)-(cbx + 100, ground - 20), _RGB32(4, 4, 4), BF
Line (cbx2, ground)-(cbx2 - 100, ground - 20), _RGB32(4, 4, 4), BF
'Mountain
Randomize Timer
sz = Int(Rnd * 300) + 100
circx = 595
cl1 = Int(Rnd * 55) + 50
cl2 = Int(Rnd * 55) + 50
cl3 = Int(Rnd * 55) + 50
Line (0, ground)-(1200, 700), _RGB32(cl1, cl2, cl3), BF 'ground
Circle (circx, ground), sz, _RGB32(cl1, cl2, cl3)
Paint (circx, ground - 2), _RGB32(cl1, cl2, cl3)

again:
Color _RGB(0, 0, 0)
Locate 10, 136: Print "              "
Locate 10, 2: Print "Your Turn     "
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
airx2 = airX * 1000
If airx2 < -1 Then winddir$ = "West"
If airx2 > 1 Then winddir$ = "East"
If airx2 > -1 And airx2 < 1 Then winddir$ = "Sunny"
If airx2 < 0 Then airx2 = airx2 * -1

GoSub Wind:
Color _RGB(0, 0, 0)
Locate 5, 1: Input "Type Power (0-80):>>> ", vel
Locate 6, 1: Input "Type Angle (0-90):>>> ", a
Locate 5, 1: Print "                                                                         "
Locate 6, 1: Print "                                                                         "
going:
If a > 90 Then a = 90
If a < 0 Then a = 0
If vel < 0 Then vel = 0
If vel > 80 Then vel = 80
vel = Int(vel / 4)
a = 360 - a
ca = _D2R(a)
cmx = cbx + (100 * Cos(_D2R(a)))
cmy = cby + (100 * Sin(_D2R(a)))

'initialize
bx = cmx 'ball x, y same as cannon mouth at start of shot
by = cmy


dx = vel * Cos(ca) 'start at cannon mouth
dy = vel * Sin(ca)

'shot

Do
    _Limit 200
    GoSub Wind:

    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx, by), 5, _RGB32(0, 0, 0)
    Paint (bx, by), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx = bx: oldby = by
    dx = dx + airX
    dy = dy + g
    bx = bx + dx
    by = by + dy
    _Display
    _Limit 30
    Circle (oldbx, oldby), 5, _RGB(156, 210, 237)
    Paint (oldbx, oldby), _RGB(156, 210, 237)
    If Point(bx, by) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx > cbx2 - 120 And bx < cbx2 + 20 And by >= ground - 2 Then
        points = points + 1
        win = 0
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If points = 5 And win = 0 Then win = 1: level = level + 1: GoTo start:
    End If
Loop Until mountain = 1 Or by > 700
For ccc = 0 To 7 Step .1
    Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
'The Computer's Turn

comp:

Color _RGB(0, 0, 0)
Locate 10, 2: Print "                      "
Locate 10, 137: Print "Computer Turn"
GoSub Wind:

'Computer learns as it goes but is not perfect, like a human.  ;-)
If c = 0 Then GoTo compstuff:
oldvel2 = vel2

compstuff:
Randomize Timer
vel2 = Int(Rnd * 35) + 30

a2 = a

vel2 = Int(vel2 / 4)

If c = 0 Then GoTo nex:
'Last shot was too far away.
If oldbx2 < cbx Then
    vel2 = oldvel2 - 1
    If vel2 < 8 Then vel2 = 8
End If
'Last shot wasn't far enough.
If oldbx2 > cbx Then
    vel2 = oldvel2 + 1
    If vel2 > 15 Then vel2 = 15
End If
nex:
c = 1
ca2 = _D2R(a2)
cmx2 = cbx2 - (100 * Cos(_D2R(a2)))
cmy2 = cby2 + (100 * Sin(_D2R(a2)))

'initialize
bx2 = cmx2 'ball x, y same as cannon mouth at start of shot
by2 = cmy2
dx2 = vel2 * Cos(ca2) 'start at cannon mouth
dy2 = vel2 * Sin(ca2)

'shot

Do
    _Limit 200
    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx2, by2), 5, _RGB32(0, 0, 0)
    Paint (bx2, by2), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx2 = bx2: oldby2 = by2
    dx2 = dx2 + airX
    dy2 = dy2 + g
    bx2 = bx2 - dx2
    by2 = by2 + dy2
    _Display
    _Limit 30
    Circle (oldbx2, oldby2), 5, _RGB(156, 210, 237)
    Paint (oldbx2, oldby2), _RGB(156, 210, 237)
    If Point(bx2, by2) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx2 > cbx - 20 And bx2 < cbx + 120 And by2 >= ground Then
        compoints = compoints + 1
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If compoints = 5 Then Color _RGB(0, 0, 0): Locate 20, 65: Print "COMPUTER WINS!": GoTo asking:
    End If
Loop Until mountain = 1 Or by2 > 700

For ccc = 0 To 7 Step .1
    Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
GoTo again:

'This code is used in a few different places in the program.
Wind:
Color _RGB(0, 0, 0)
Locate 1, 73: Print "Wind"
If winddir$ = "West" Then
    Locate 2, 82: Print "                               "
    Locate 2, 59: Print airx2; " mph   "
End If
If winddir$ = "East" Then
    Locate 2, 59: Print "               "
    Locate 2, 82: Print airx2; " mph   "
End If
Locate 2, 68: Print "West <-> East"
Locate 3, 64: Print "You: "; points; " Computer: "; compoints
Locate 4, 71: Print "Level: "; level
Return

asking:
Locate 22, 65: Input "Again? (Yes/No):", ag$
If ag$ = "y" Or ag$ = "Y" Or ag$ = "yes" Or ag$ = "Yes" Or ag$ = "YES" Or ag$ = "yES" Or ag$ = "yeS" Then points = 0: GoTo start:
End



RE: Ken's Artillery 2 - bplus - 05-01-2022

Yeah, this is fun to play!


RE: Ken's Artillery 2 - SierraKen - 05-01-2022

(05-01-2022, 12:04 AM)bplus Wrote: Yeah, this is fun to play!

Thanks B+, it's such an oldie I figured I better update it and put it here. Smile


RE: Ken's Artillery 2 - bplus - 05-01-2022

@SierraKen didn't the wind direction have the arrow, < or > point to left or right. Seems like when I was playing that was pointing both ways.


RE: Ken's Artillery 2 - OldMoses - 05-01-2022

That was pretty cool.


RE: Ken's Artillery 2 - Dav - 05-01-2022

Enjoyable little game.  Thanks for sharing.

- Dav


RE: Ken's Artillery 2 - johnno56 - 05-01-2022

Oh, this brings back memories. Reminds me of the old Apple II Super Artillery... The wind direction and velocity makes it a little difficult to judge the right power and angle. The Apple II game would relocate the 'enemy' and the height of the 'hill' would change each time it was hit. But, this version, is cool...

Nicely done!


RE: Ken's Artillery 2 - SierraKen - 05-01-2022

Thanks everyone! B+, I might have changed it awhile back and decided to keep both arrows showing because there really is no need for that. Instead it says West or East on different sides of the arrows with the speed.


RE: Ken's Artillery 2 - SierraKen - 05-01-2022

Johno, yeah someone was telling me last night that they once played a game like this called Tank Wars in the early 80's. He said that one had a time limit, if you didn't hit the other tank after so many turns, lightning would come and blow you up. LOL I think this one is the one I played back in the day. But I always got mad because I wanted to drill a hole through the entire mountain. Big Grin


RE: Ken's Artillery 2 - SierraKen - 05-01-2022

I just found 1 small problem. If you lose and want to play again, it doesn't reset the level back to 1. So here is the fix: 

Code: (Select All)
'I've always wanted to make this game ever since I started programming in the 80's.
'This was created by Ken G. with much help from others below.
'Thank you to B+ for much of the math code.
'It takes the computer a little time to learn how to hit your base.
'Created on June 26, 2019.
'Version 2 made on April 30, 2022.
'Added: Levels, random colored mountains, and better looking cannons.

_Title "Ken's Artillery 2"
_Limit 200
Cls
Screen _NewImage(1200, 700, 32)
Print "                                              Ken's Artillery 2"
Print: Print: Print
Print "                                      By SierraKen with math help from B+."
Print: Print: Print
Print "                         Instructions: You play against the computer by shooting a cannonball"
Print "                         from your cannon at your base on the left side of the screen"
Print "                         to the computer's base on the right side of the screen."
Print "                         To do this, you type a power number between 0 and 80 and press Enter."
Print "                         Then you type an angle that the cannonball will travel at,"
Print "                         between 0 and 90 and press Enter."
Print "                         You get a point every time you hit the other base."
Print "                         If you hit the enemy 5 times you advance to the next mountain."
Print "                         If the enemy hits you 5 times in one mountain, you lose."
Print "                         Watch the wind speed indicator up on top to see the direction and"
Print "                         speed of the wind, which makes a big difference on where your"
Print "                         cannonball will land. Also, there will be a random sized mountain"
Print "                         and color for every level and game."
Print: Print: Print
Input "                         Press Enter to begin.", start$
Cls
level = 1

start:
c = 0
mountain = 0
win = 0
compoints = 0
points = 0
ground = 590 'up is negative in direction

'Your Cannon

cbx = 10 '              cannon butt end x, y
cby = ground - 20
cmx = 50 '              cannon mouth end
cmy = ground - 70

'Computer's Cannon

cbx2 = 1190
cby2 = cby
cmx2 = 1150
cmy2 = cmy


g = .15 '       with air resistance
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
Color , _RGB32(156, 210, 237)
Cls
'Bases
Line (cbx, ground)-(cbx + 100, ground - 20), _RGB32(4, 4, 4), BF
Line (cbx2, ground)-(cbx2 - 100, ground - 20), _RGB32(4, 4, 4), BF
'Mountain
Randomize Timer
sz = Int(Rnd * 300) + 100
circx = 595
cl1 = Int(Rnd * 55) + 50
cl2 = Int(Rnd * 55) + 50
cl3 = Int(Rnd * 55) + 50
Line (0, ground)-(1200, 700), _RGB32(cl1, cl2, cl3), BF 'ground
Circle (circx, ground), sz, _RGB32(cl1, cl2, cl3)
Paint (circx, ground - 2), _RGB32(cl1, cl2, cl3)

again:
Color _RGB(0, 0, 0)
Locate 10, 136: Print "              "
Locate 10, 2: Print "Your Turn     "
Randomize Timer
air = Int(Rnd * 20)
air2 = air / 1000
Randomize Timer
air3 = Int(Rnd * 100)
If air3 > 50 Then air2 = -air2
airX = air2
airx2 = airX * 1000
If airx2 < -1 Then winddir$ = "West"
If airx2 > 1 Then winddir$ = "East"
If airx2 > -1 And airx2 < 1 Then winddir$ = "Sunny"
If airx2 < 0 Then airx2 = airx2 * -1

GoSub Wind:
Color _RGB(0, 0, 0)
Locate 5, 1: Input "Type Power (0-80):>>> ", vel
Locate 6, 1: Input "Type Angle (0-90):>>> ", a
Locate 5, 1: Print "                                                                         "
Locate 6, 1: Print "                                                                         "
going:
If a > 90 Then a = 90
If a < 0 Then a = 0
If vel < 0 Then vel = 0
If vel > 80 Then vel = 80
vel = Int(vel / 4)
a = 360 - a
ca = _D2R(a)
cmx = cbx + (100 * Cos(_D2R(a)))
cmy = cby + (100 * Sin(_D2R(a)))

'initialize
bx = cmx 'ball x, y same as cannon mouth at start of shot
by = cmy


dx = vel * Cos(ca) 'start at cannon mouth
dy = vel * Sin(ca)

'shot

Do
    _Limit 200
    GoSub Wind:

    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx, by), 5, _RGB32(0, 0, 0)
    Paint (bx, by), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx = bx: oldby = by
    dx = dx + airX
    dy = dy + g
    bx = bx + dx
    by = by + dy
    _Display
    _Limit 30
    Circle (oldbx, oldby), 5, _RGB(156, 210, 237)
    Paint (oldbx, oldby), _RGB(156, 210, 237)
    If Point(bx, by) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx > cbx2 - 120 And bx < cbx2 + 20 And by >= ground - 2 Then
        points = points + 1
        win = 0
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx, by), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If points = 5 And win = 0 Then win = 1: level = level + 1: GoTo start:
    End If
Loop Until mountain = 1 Or by > 700
For ccc = 0 To 7 Step .1
    Line (cbx, cby)-(cmx + ccc, cmy), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
'The Computer's Turn

comp:

Color _RGB(0, 0, 0)
Locate 10, 2: Print "                      "
Locate 10, 137: Print "Computer Turn"
GoSub Wind:

'Computer learns as it goes but is not perfect, like a human.  ;-)
If c = 0 Then GoTo compstuff:
oldvel2 = vel2

compstuff:
Randomize Timer
vel2 = Int(Rnd * 35) + 30

a2 = a

vel2 = Int(vel2 / 4)

If c = 0 Then GoTo nex:
'Last shot was too far away.
If oldbx2 < cbx Then
    vel2 = oldvel2 - 1
    If vel2 < 8 Then vel2 = 8
End If
'Last shot wasn't far enough.
If oldbx2 > cbx Then
    vel2 = oldvel2 + 1
    If vel2 > 15 Then vel2 = 15
End If
nex:
c = 1
ca2 = _D2R(a2)
cmx2 = cbx2 - (100 * Cos(_D2R(a2)))
cmy2 = cby2 + (100 * Sin(_D2R(a2)))

'initialize
bx2 = cmx2 'ball x, y same as cannon mouth at start of shot
by2 = cmy2
dx2 = vel2 * Cos(ca2) 'start at cannon mouth
dy2 = vel2 * Sin(ca2)

'shot

Do
    _Limit 200
    a$ = InKey$
    If a$ = Chr$(27) Then End
    Circle (bx2, by2), 5, _RGB32(0, 0, 0)
    Paint (bx2, by2), _RGB32(0, 0, 0), _RGB32(0, 0, 0)
    For ccc = 0 To 7 Step .1
        Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(150, 50, 0) 'cannon line
    Next ccc
    oldbx2 = bx2: oldby2 = by2
    dx2 = dx2 + airX
    dy2 = dy2 + g
    bx2 = bx2 - dx2
    by2 = by2 + dy2
    _Display
    _Limit 30
    Circle (oldbx2, oldby2), 5, _RGB(156, 210, 237)
    Paint (oldbx2, oldby2), _RGB(156, 210, 237)
    If Point(bx2, by2) = _RGB32(cl1, cl2, cl3) Then
        mountain = 1
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
    End If
    If bx2 > cbx - 20 And bx2 < cbx + 120 And by2 >= ground Then
        compoints = compoints + 1
        Locate 3, 64: Print "You: "; points; " Computer: "; compoints
        For explosion = 0 To 20 Step .5
            Circle (bx2, by2), explosion, _RGB32(156, 210, 237)
            Sound 100 + explosion, .25
        Next explosion
        For sndd = 500 To 700 Step 50
            Sound sndd, 1
        Next sndd
        mountain = 1
        If compoints = 5 Then Color _RGB(0, 0, 0): Locate 20, 65: Print "COMPUTER WINS!": GoTo asking:
    End If
Loop Until mountain = 1 Or by2 > 700

For ccc = 0 To 7 Step .1
    Line (cbx2, cby2)-(cmx2 - ccc, cmy2), _RGB32(156, 210, 237) 'delete cannon line
Next ccc
mountain = 0
GoTo again:

'This code is used in a few different places in the program.
Wind:
Color _RGB(0, 0, 0)
Locate 1, 73: Print "Wind"
If winddir$ = "West" Then
    Locate 2, 82: Print "                               "
    Locate 2, 59: Print airx2; " mph   "
End If
If winddir$ = "East" Then
    Locate 2, 59: Print "               "
    Locate 2, 82: Print airx2; " mph   "
End If
Locate 2, 68: Print "West <-> East"
Locate 3, 64: Print "You: "; points; " Computer: "; compoints
Locate 4, 71: Print "Level: "; level
Return

asking:
Locate 22, 65: Input "Again? (Yes/No):", ag$
If ag$ = "y" Or ag$ = "Y" Or ag$ = "yes" Or ag$ = "Yes" Or ag$ = "YES" Or ag$ = "yES" Or ag$ = "yeS" Then points = 0: level = 1: GoTo start:
End