08-14-2024, 04:48 AM
This is the classic artillery-style game where you select an angle and power, with different winds, and try to hit the other cannon on the other side of the random mountain, before the computer cannon hits yours first. There is a tiny bit of "A.I." to this game in the fact that the computer slowly learns from its mistakes on every turn. The entire game is ran by your Mouse, using 2 different sliders for angle and power and a button to fire. Have fun!
Thanks to B+, OldMoses, and Steve for helping me a lot with this game.
Thanks to B+, OldMoses, and Steve for helping me a lot with this game.
Code: (Select All)
'I've always wanted to make this game ever since I started programming in the 80's.
'This was created by SierraKen with much help from others below.
'Thank you to B+ for much of the math code, Mouse and click bar help on https://qb64phoenix.com/forum/index.php
'It takes the computer a little time to learn how to hit your base.
'Created on June 26, 2019.
'Version 2 made on May 2, 2022.
'Added: Levels, random colored mountains, and better looking cannons.
'Added: Click Bars and Fire! button. Simpler Instructions. Changed 5 to 4 times needed to hit enemy and enemy to hit you.
'Added: Better mouse control thanks to B+, OldMoses, and Steve.
'Added: Delete click bars when it's not your turn.
'Added: Click mouse button to start game.
'Added: Set click bars remain the same per turn on each level.
_Title "Ken's Artillery 2"
_Limit 200
Cls
Screen _NewImage(1200, 700, 32)
Print " Ken's Artillery 2"
Print: Print: Print
Print " By SierraKen"
Print " with some help from B+, OldMoses, and Steve"
Print: Print: Print
Print " Instructions: Red Click Bar = Power"
Print " Green Click Bar = Angle"
Print " Fire! Button = Fire Cannonball"
Print
Print " Hit enemy 4 times you advance to next level."
Print " Get hit 4 times in a level and you lose."
Print: Print: Print
Print " Press Mouse Button To Start!"
Do
While _MouseInput: Wend
mx = _MouseX: my = _MouseY: mb = _MouseButton(1) ' this update the mouse x, y and button status save to variable because they change
If mb Then Clear_MB 1: GoTo continue:
Loop
continue:
Cls
level = 1
oldVelocityX = 100
oldAngleX = 100
vel = 40
a = 45
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)
Color _RGB32(0, 0, 0), _RGB32(0, 255, 0)
_PrintString (265, 80), Str$(a)
Color _RGB32(0, 0, 0), _RGB32(255, 0, 0)
_PrintString (265, 50), Str$(vel)
'Game Loop Starts Here -----------------------------------------------------
again:
drawVelocityBar oldVelocityX
drawAngleBar oldAngleX
Color _RGB32(156, 210, 237), _RGB32(156, 210, 237)
Locate 10, 129: Print " "
Color _RGB32(255, 0, 0), _RGB32(156, 210, 237)
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:
vel = (oldVelocityX - 60) / 200 * 100
a = (oldAngleX - 60) / 200 * 90 ' converts place in box to 0 to 90
Color _RGB32(0, 0, 0), _RGB32(156, 210, 237)
_PrintString (5, 50), "Power"
Color _RGB32(0, 0, 0), _RGB32(255, 0, 0)
_PrintString (265, 50), Str$(vel)
Color _RGB32(0, 0, 0), _RGB32(156, 210, 237)
_PrintString (5, 80), "Angle"
Color _RGB32(0, 0, 0), _RGB32(0, 255, 0)
_PrintString (265, 80), Str$(a)
Line (60, 40)-(260, 70), _RGB32(255, 255, 255), B
Line (60, 70)-(260, 100), _RGB32(255, 255, 255), B
Line (60, 100)-(120, 130), _RGB32(255, 0, 5), BF
Color _RGB32(0, 0, 0), _RGB32(255, 0, 5)
_PrintString (70, 110), "Fire!"
go:
_Limit 200
_Display ' update screen !!! sure like to know if my turn or not after computer
a2$ = InKey$
If a2$ = Chr$(27) Then End
fired = 0
While _MouseInput: Wend
mx = _MouseX: my = _MouseY: mb = _MouseButton(1) ' this update the mouse x, y and button status save to variable because they change
If mb Then
If mx > 60 And mx < 260 Then
If my >= 40 And my < 70 Then
If mx > 259 Then mx = 260
vel = (mx - 60) / 200 * 100 ' converts place in box to 0 to 100
drawVelocityBar mx
oldVelocityX = mx
vel3 = mx
Color _RGB32(0, 0, 0), _RGB32(255, 0, 0)
_PrintString (265, 50), Str$(vel)
Clear_MB 1
GoTo go
ElseIf my >= 70 And my < 100 Then
If mx > 259 Then mx = 260
a = (mx - 60) / 200 * 90 ' converts place in box to 0 to 90
drawAngleBar mx
oldAngleX = mx
a3 = mx
Color _RGB32(0, 0, 0), _RGB32(0, 255, 0)
_PrintString (265, 80), Str$(a)
Clear_MB 1
GoTo go
ElseIf my >= 100 And my < 130 And mx <= 120 Then
fired = 1
For pressed = 1 To 10
Line (60 + pressed, 100 + pressed)-(120 - pressed, 130 - pressed), _RGB32(200 - (pressed * 10), 10, 5), BF
Next pressed
Color _RGB32(0, 0, 0), _RGB32(100, 10, 5)
_PrintString (70, 110), "Fire!"
Clear_MB 1
GoTo going
End If
End If
End If
If fired = 0 Then GoTo go
going:
Color _RGB32(0, 0, 0), _RGB32(156, 210, 237)
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 = 4 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:
'Clear Click Bars and Fire! Button
Line (4, 39)-(330, 131), _RGB32(156, 210, 237), BF
Color _RGB32(156, 210, 237)
Locate 10, 2: Print " "
Color _RGB32(0, 0, 0), _RGB32(156, 210, 237)
Locate 10, 130: Print "Computer's 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 - 2 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 = 4 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
Sub Clear_MB (var As Integer)
Do Until Not _MouseButton(var)
While _MouseInput: Wend
Loop
End Sub 'Clear_MB
Sub drawVelocityBar (x) ' x is mouse x
Line (61, 41)-(259, 69), _RGB32(156, 210, 237), BF
Line (61, 41)-(x, 69), _RGB32(255, 0, 1), BF
End Sub
Sub drawAngleBar (x) ' x is mouse x
Line (61, 71)-(259, 99), _RGB32(156, 210, 237), BF
Line (61, 71)-(x, 99), _RGB32(0, 255, 1), BF
End Sub