(09-02-2025, 08:50 PM)dcoterel Wrote: As you can tell by my programming structure I come from the old days (goto's and gosub's), learning now how to declare variables, use sub's and functions, etc. in order to program in a much more modern way...Well at least you managed to avoid using line numbers, LOL!
I edited your program to be a little less "spaghetti code" (see below)
- Break up multi-statement lines - other people here use them, and I try to use them judiciously, but if I want to make code easier to follow, one statement per line helps.
- Make all IF statements have a matching END IF, so QB64PE's editor auto-indents which makes it easier to follow the flow of logic.
- Do ... Loop statements are a lot easier to follow when everything is on a separate line and indented.
- Avoid cute "space saving" tricks like " Next b, a" - for me at least, it's easier to follow logic where each block has a matching end or next statement.
- Add in some horizontal line comments to help visually break up the sections.
That's just the beginning. Next I would
- Add comments at the top of each section, that describe what the code is doing.
- Use longer more descriptive variable names -
I know back in the old days many computers (like the C64) only let you use 2-letter variable names.
Thankfully modern programming languages let you name your variables in a way that makes it easier to follow the code.
e.g., instead of fir& name it GunSound&, instead of bl& name it black&
- Move the "GOSUB" routine and anything reusable inside a Sub or a Function
(if you need to return a value, use a Function, else use a Sub).
Giving each routine a name that describes what it's doing.
- Get rid of GOTO statements and rewrite the logic using structured programming.
This is just how I try to approach it, but there's more than one way to cook an egg, and sometimes I break my own rules when it makes sense.
I think you'll find that everyone here has their own personal preferences.
I tend to use a lot of comments and stuff that tends to give some of the guys a headache (right, Steve?
LOL)Anyway, I hope this helps. Thanks again for sharing your game!
BTW, it might be fun to add other features like
- computer-controlled tanks
- weapon and shield "powerups"
- limited ammo and fuel (players have to return to base to reload?)
- a screen editor to change the terrain, walls, etc.
- maybe a way to edit the tanks and other graphics
- etc.
Here is the cleaned up code:
Code: (Select All)
' Tank Battle - Two Player
' https://qb64phoenix.com/forum/showthread.php?tid=3899
' #1 dcoterel
' 08-31-2025, 09:07 PM (This post was last modified: 6 hours ago by dcoterel.)
' I originally wrote this program in assembly for the commodore pet in 1979-80ish.
' Revised 9/2/25 - Bullets reflect off brown walls, 2 active bullets on the screen per tank at same time.
' Download the zip file for all supporting files
' Some code cleanup by MadSciJr 9/2/2025
'$ExeIcon:'./\data\favicon.ico'
$Resize:Smooth
_Title "Tank Battle"
DefInt A-Z
dw = _DesktopWidth
dh = _DesktopHeight
If dw < 1024 Or dh < 768 Then
Cls
Print "A minimum Screen Resolution of 1024 x 768 is required to play"
End
End If
' DISABLED FULLSCREEN BY DEFAULT. MAYBE AT STARTUP PROMPT THE USER "FULLSCREEN? (Y/N)"
If dw = 1024 And dh = 768 Then
'_FullScreen
End If
Const wh& = _RGB32(255, 255, 255)
Const bl& = _RGB32(0, 0, 0)
Const bor& = _RGB32(155, 100, 255)
Const t1& = _RGB32(255, 255, 0)
Const t2& = _RGB32(0, 255, 0)
Const mi& = _RGB32(255, 0, 0)
Const bro& = _RGB32(133, 72, 11)
fir& = _SndOpen("data\gun.wav")
ex& = _SndOpen("data\explosion.wav")
tm1& = _SndOpen("data\tm1.wav")
tm2& = _SndOpen("data\tm2.wav")
bu& = _LoadImage("data\bush.png", 32)
br& = _LoadImage("data\brick.png", 32)
bru& = _LoadImage("data\bricku.png", 32)
pls& = _NewImage(1024, 768, 32)
_Dest pls&
Cls
Line (15, 15)-(1009, 753), bor&, B
Paint (3, 3), bor&, bor&
Line (59, 59)-(965, 709), bro&, B
Line (69, 69)-(954, 698), bro&, B
Paint (61, 61), bro&, bro&
Line (20, 99)-(1004, 669), bl&, BF
Line (99, 20)-(925, 748), bl&, BF
Line (206, 192)-(306, 242), bro&, BF
Line (216, 192)-(296, 232), bl&, BF
Line (718, 192)-(818, 242), bro&, BF
Line (728, 192)-(808, 232), bl&, BF
Line (206, 526)-(306, 576), bro&, BF
Line (216, 536)-(296, 576), bl&, BF
Line (718, 526)-(818, 576), bro&, BF
Line (728, 536)-(808, 576), bl&, BF
_PutImage (412, 59), br&
_PutImage (412, 660), br&
_PutImage (59, 284), bru&
_PutImage (916, 284), bru&
_PutImage (413, 326), bu&
' =============================================================================
Start:
a2 = -1
b2 = 0
x2 = 1
y2 = 0
f1 = 0
f2 = 0
f3 = 0
f4 = 0
x = 100
y = 100
a = 924
b = 668
fx1 = 0
fy1 = 0
fa1 = 0
fb1 = 0
Screen _NewImage(1024, 768, 32)
_ScreenMove dw * .5 - 512, dh * .5 - 384
If dio = 0 Then
GoSub GameStart
End If
Do
_Limit 60
_PutImage , pls&
d = 12 - (((Abs(x2) + Abs(y2)) - 1) * 4)
Circle (x, y), 6, t1&
Paint (x, y), t1&, t1&
Circle (x, y), 3, bl&
Line (x, y)-(x + x2 * d, y + y2 * d), mi&
d = 12 - (((Abs(a2) + Abs(b2)) - 1) * 4)
Circle (a, b), 6, t2&
Paint (a, b), t2&, t2&
Circle (a, b), 3, bl&
Line (a, b)-(a + a2 * d, b + b2 * d), mi&
x1 = 0
y1 = 0
a1 = 0
b1 = 0
If f1 = 1 Then
Circle (fx, fy), 2, mi&
Circle (fx + fx1, fy + fy1), 2, mi&
Circle (fx + fx1 * 2, fy + fy1 * 2), 2, mi&
fx = fx + fx1 * 3
fy = fy + fy1 * 3
End If
If f2 = 1 Then
Circle (fa, fb), 2, mi&
Circle (fa + fa1, fb + fb1), 2, mi&
Circle (fa + fa1 * 2, fb + fb1 * 2), 2, mi&
fa = fa + fa1 * 3
fb = fb + fb1 * 3
End If
If f3 = 1 Then
Circle (fc, fd), 2, mi&
Circle (fc + fc1, fd + fd1), 2, mi&
Circle (fc + fc1 * 2, fd + fd1 * 2), 2, mi&
fc = fc + fc1 * 3
fd = fd + fd1 * 3
End If
If f4 = 1 Then
Circle (fe, ff), 2, mi&
Circle (fe + fe1, ff + ff1), 2, mi&
Circle (fe + fe1 * 2, ff + ff1 * 2), 2, mi&
fe = fe + fe1 * 3
ff = ff + ff1 * 3
End If
If _KeyDown(100) Then
x1 = 1
ElseIf _KeyDown(97) Then
x1 = -1
End If
If _KeyDown(115) Then
y1 = 1
ElseIf _KeyDown(119) Then
y1 = -1
End If
If _KeyDown(19200) Then
a1 = -1
ElseIf _KeyDown(19712) Then
a1 = 1
End If
If _KeyDown(18432) Then
b1 = -1
ElseIf _KeyDown(20480) Then
b1 = 1
End If
If x1 <> 0 Or y1 <> 0 Then
x2 = x1
y2 = y1
End If
If a1 <> 0 Or b1 <> 0 Then
a2 = a1
b2 = b1
End If
If _KeyDown(32) Then
GoSub fire1
Else
ss1 = 0
End If
If _KeyDown(100305) Then
GoSub fire2
Else
ss2 = 0
End If
If Point(x + x1 * 13, y + y1 * 13) <> bl& Then
x1 = 0
y1 = 0
End If
If Point(a + a1 * 13, b + b1 * 13) <> bl& Then
a1 = 0
b1 = 0
End If
x = x + x1
y = y + y1
a = a + a1
b = b + b1
If x1 <> 0 Or y1 <> 0 Then
_SndLoop tm1&
Else
_SndStop tm1&
End If
If a1 <> 0 Or b1 <> 0 Then
_SndLoop tm2&
Else
_SndStop tm2&
End If
If f1 = 1 And Point(fx + fx1 * 2, fy + fy1 * 2) = t2& Then
s1 = s1 + 1
f1 = 0
thit = 2
GoTo tahit
End If
If f2 = 1 And Point(fa + fa1 * 2, fb + fb1 * 2) = t1& Then
s2 = s2 + 1
f2 = 0
thit = 1
GoTo tahit
End If
If f3 = 1 And Point(fc + fc1 * 2, fd + fd1 * 2) = t2& Then
s1 = s1 + 1
f3 = 0
thit = 2
GoTo tahit
End If
If f4 = 1 And Point(fe + fe1 * 2, ff + ff1 * 2) = t1& Then
s2 = s2 + 1
f4 = 0
thit = 1
GoTo tahit
End If
If f1 = 1 And Point(fx + fx1 * 3, fy + fy1 * 3) = bro& Then
p1 = 1
Reflect fx, fy, fx1, fy1
Else
p1 = 0
End If
If f2 = 1 And Point(fa + fa1 * 3, fb + fb1 * 3) = bro& Then
p2 = 1
Reflect fa, fb, fa1, fb1
Else
p2 = 0
End If
If f3 = 1 And Point(fc + fc1 * 3, fd + fd1 * 3) = bro& Then
p3 = 1
Reflect fc, fd, fc1, fd1
Else
p3 = 0
End If
If f4 = 1 And Point(fe + fe1 * 3, ff + ff1 * 3) = bro& Then
p4 = 1
Reflect fe, ff, fe1, ff1
Else
p4 = 0
End If
If f1 = 1 And Point(fx + fx1 * 2, fy + fy1 * 2) <> bl& Then
f1 = 0
End If
If f2 = 1 And Point(fa + fa1 * 2, fb + fb1 * 2) <> bl& Then
f2 = 0
End If
If f3 = 1 And Point(fc + fc1 * 2, fd + fd1 * 2) <> bl& Then
f3 = 0
End If
If f4 = 1 And Point(fe + fe1 * 2, ff + ff1 * 2) <> bl& Then
f4 = 0
End If
Color bl&, bor&
Locate 1, 54
Print Using "Yellow ## - Green ##"; s1; s2;
Color bl&, bl&
_Display
Loop Until _KeyDown(27)
GoTo Gameover
' =============================================================================
tahit:
_SndStop tm1&
_SndStop tm2&
Color bl&, bor&
Locate 1, 54
Print Using "Yellow ## - Green ##"; s1; s2;
Color bl&, bl&
If thit = 2 Then
x = a
y = b
End If
_SndPlay ex&
For a = 1 To 3
For b = 1 To 17
_Limit 20
Circle (x, y), b, wh&
Circle (x, y), b - 1, bl&
_Display
Next b
Next a
If s1 = 10 Or s2 = 10 Then
GoTo Gameover
Else
GoTo Start
End If
' =============================================================================
Gameover:
_SndStop tm1&
_SndStop tm2&
Do While _KeyDown(27)
_Limit 60
Loop
_AutoDisplay
Line (302, 274)-(722, 494), bor&, BF
Line (312, 284)-(712, 484), t2&, BF
Color bl&, t2&
Locate 23, 41
Print "Thanks for playing Tank Battle By David Coterel"
Locate 25, 41
If s1 > s2 Then
Print " Player 1 is the Winner"
End If
If s2 > s1 Then
Print " Player 2 Wins the game"
End If
If s2 = s1 Then
Print " Player 1 Tie Game Player 2"
End If
Locate 27, 41
Print " Press ESC to end"
Do
_Limit 60
Loop Until _KeyDown(27)
_FreeImage pls&
System
' =============================================================================
GameStart:
_PutImage , pls&
dio = 1
loc1 = 40
step1 = 1
Circle (x, y), 6, t1&
Paint (x, y), t1&, t1&
Circle (x, y), 3, bl&
Line (x, y)-(x + 12, y), mi&
Circle (a, b), 6, t2&
Paint (a, b), t2&, t2&
Circle (a, b), 3, bl&
Line (a, b)-(a - 12, b), mi&
Line (302, 274)-(722, 494), bor&, BF
Line (312, 284)-(712, 484), t2&, BF
Color bl&, t2&
Locate 20, 41: Print "Thanks for playing Tank Battle By David Coterel"
Locate 25, 41
Locate 22, 41: Print " Player 1 is the yellow tank and uses a,s,d & w"
Locate 23, 41: Print " to move, space to fire"
Locate 25, 41: Print " Player 2 is the green tank and uses the cursor"
Locate 26, 41: Print " keys to move, the right cntrl key to fire"
Locate 28, 41: Print " First player to reach 10 kills wins"
Do
_Limit 10
Locate 30, loc1
Print " Press Enter to Start ";
Sound 150, .1
loc1 = loc1 + step1
If loc1 = 68 Then
step1 = -1
ElseIf loc1 = 40 Then
step1 = 1
End If
_Display
Loop Until _KeyDown(13)
Return
' =============================================================================
fire1:
If f1 = 0 And (x2 <> 0 Or y2 <> 0) And Point(x + x2 * 18, y + y2 * 18) = bl& Then
f1 = 1
fx1 = x2
fy1 = y2
fx = x + fx1 * 13
fy = y + fy1 * 13
_SndPlay fir&
ss1 = 1
End If
If ss1 = 0 And f1 = 1 And f3 = 0 And (x2 <> 0 Or y2 <> 0) And Point(x + x2 * 18, y + y2 * 18) = bl& Then
f3 = 1
fc1 = x2
fd1 = y2
fc = x + fc1 * 13
fd = y + fd1 * 13
_SndPlay fir&
End If
Return
' =============================================================================
fire2:
If f2 = 0 And (a2 <> 0 Or b2 <> 0) And Point(a + a2 * 18, b + b2 * 18) = bl& Then
f2 = 1
fa1 = a2
fb1 = b2
fa = a + fa1 * 14
fb = b + fb1 * 14
_SndPlay fir&
ss2 = 1
End If
If ss2 = 0 And f2 = 1 And f4 = 0 And (a2 <> 0 Or b2 <> 0) And Point(a + a2 * 18, b + b2 * 18) = bl& Then
f4 = 1
fe1 = a2
ff1 = b2
fe = a + fe1 * 13
ff = b + ff1 * 13
_SndPlay fir&
End If
Return
' =============================================================================
Sub Reflect (a, b, e, f)
If Point(a, b + 3) = bro& Then
f = f * -1
End If
If Point(a, b - 3) = bro& Then
f = f * -1
End If
If Point(a + 3, b) = bro& Then
e = e * -1
End If
If Point(a - 3, b) = bro& Then
e = e * -1
End If
End Sub ' Reflect

