'Ken:
'I've always wanted to make this game ever since I started programming in the 80's.
'This was made using the BASIC and compile language QB64 from QB64.org
'This was created by Ken G. with much help from others below.
'Thank you to B+ for posting much of this math code on the QB64.org forum!
'Also thank you to johnno56 for a little help on the explosions, from the QB64.org forum.
'It takes the computer a little time to learn how to hit your base.
'Created on June 25, 2019.
'Hi Ken, I made a couple of changes to the game. Do you recognize it :D MOD 2019-07-01 B+
' 2019-07-03 fix items mentioned by Pete label Computer Power and Angle display, apply constant wind change.
CONST xmax
= 1200, ymax
= 740 _TITLE "Ken's Artillery MOD B+ Hey! They only have one cannon ball between the two of them :D" 'mod B+ makeover started 2019-06-25
CONST groundC
= &HFF405020 CONST cannonC
= &HFF884422 CONST printC
= &HFFEEDDCC
bg
= _NEWIMAGE(xmax
, ymax
, 32) 'get bg snap shot area readysetPlayerConstants
initGame
SetDisplayWind
p.baseX = 10: c.baseX = xmax - 10
p.baseY = groundY - baseHeight: c.baseY = groundY - baseHeight
p.baseC = &HFF880000: c.baseC = &HFF000088
p.cannonAngle
= _D2R(360 - 45) p.velocity = 7
p.points = 0: c.points = 0
MakeMountain xmax / 2, rrnd(200, (xmax - 220) / 2.3), ymax
LINE (0, groundY
)-(xmax
, ymax
), groundC
, BF
'ground LINE (p.baseX
, p.baseY
)-STEP(baseLength
, baseHeight
), p.baseC
, BF
LINE (c.baseX
, c.baseY
)-STEP(-baseLength
, baseHeight
), c.baseC
, BF
airX = rrnd(-20, 20)
SetDisplayWind
showScore
p.cannonAngle
= 360 - _R2D(p.cannonAngle
) 'IF p.cannonAngle = 360 THEN p.cannonAngle = 0
LOCATE 44, 1:
PRINT "Power: Left/Right Angle: Up/Down Fire: Spacebar";
LOCATE 45, 10:
PRINT "Power (0-10): " + TS$
(p.velocity
);
LOCATE 46, 10:
PRINT "Angle (0-90): " + TS$
(p.cannonAngle
);
IF kh
= 18432 AND p.cannonAngle
+ 1 < 90 THEN p.cannonAngle
= p.cannonAngle
+ 1 IF kh
= 20480 AND p.cannonAngle
- 1 > 0 THEN p.cannonAngle
= p.cannonAngle
- 1 IF kh
= 19712 AND (p.velocity
+ .2 <= 10) THEN p.velocity
= p.velocity
+ .2 IF kh
= 19200 AND (p.velocity
- .2 >= .2) THEN p.velocity
= p.velocity
- .2 LOCATE 45, 10:
PRINT "Power (0-10): " + TS$
(p.velocity
);
LOCATE 46, 10:
PRINT "Angle (0-90): " + TS$
(p.cannonAngle
);
p.cannonAngle
= _D2R(360 - p.cannonAngle
) drawCannon cannonC
b.x
= p.baseX
+ baseLength
* COS(p.cannonAngle
) b.y
= p.baseY
+ baseLength
* SIN(p.cannonAngle
) b.dx
= p.velocity
* COS(p.cannonAngle
) b.dy
= p.velocity
* SIN(p.cannonAngle
) playBall
IF ABS(airX
- lastWind
) > 2 OR c.cannonAngle
<= _D2R(5 + 180) THEN 'new game or wind c.cannonAngle
= _D2R(180 + 50 - airX
/ 7) c.velocity = 7.2 + airX / 10
lastWind = airX
drawCannon cannonC
b.x
= c.baseX
+ baseLength
* COS(c.cannonAngle
) b.y
= c.baseY
+ baseLength
* SIN(c.cannonAngle
) b.dx
= c.velocity
* COS(c.cannonAngle
) b.dy
= c.velocity
* SIN(c.cannonAngle
) LOCATE 45, xmax
/ 8 - 25:
PRINT "Power: " + TS$
(c.velocity
);
LOCATE 46, xmax
/ 8 - 25:
PRINT "Angle: " + TS$
(_R2D(c.cannonAngle
) - 180);
playBall
IF b.x
- (p.baseX
+ .5 * baseLength
) > 0 THEN c.velocity = c.velocity + (b.x - p.baseX + .5 * baseLength) / 1000
c.velocity = c.velocity - ((groundY - b.y) + (p.baseX + .5 * baseLength - b.x)) / 1000
LINE (p.baseX
, p.baseY
)-STEP(baseLength
* COS(p.cannonAngle
), baseLength
* SIN(p.cannonAngle
)), K
LINE (c.baseX
, c.baseY
)-STEP(baseLength
* COS(c.cannonAngle
), baseLength
* SIN(c.cannonAngle
)), K
b.dx = b.dx + airX / 1000
b.dy = b.dy + gravity
b.x = b.x + b.dx
b.y = b.y + b.dy
fcirc b.x, b.y, ballRadius, ballC 'draw new
CenterPrint 45, " "
CenterPrint 45, TS$(b.x) + ", " + TS$(b.y)
_SOURCE bg
'oh! need this to read point(x, y) off bg !!!!!!!!!1 SOUND 100 + explosion
, .25 p.points = p.points + 1
showScore
c.points = c.points + 1
showScore
fcirc b.x, b.y, 3 * ballRadius, skyC
'take a snap of new background when ever we blow up
CenterPrint 45, " "
CenterPrint 45, " "
drawCannon skyC
s$ = "Human: " + TS$(p.points) + " Computer: " + TS$(c.points)
IF p.points
= 5 THEN s$
= s$
+ " YOU WIN!" IF c.points
= 5 THEN s$
= s$
+ " Computer won." CenterPrint 46, s$
airX = airX + rrnd(-1.5, 1.5)
IF airX
< -20 THEN airX
= -19.99 IF airX
> 20 THEN airX
= 19.99 IF airX
< 0 THEN CenterPrint
44, "<<< Wind at: " + TS$
(airX
) IF airX
> 0 THEN CenterPrint
44, "Wind at: " + TS$
(airX
) + " >>>"
SUB MakeMountain
(xcenter
, maxHeight
, mountainbaseY
) DIM centerDist
, i
, xc
, yc
, xl
, xr
, dir
LINE (0, 0)-(xmax
+ 50, ymax
+ 50), skyC
, BF
centerDist
= 15 * RND + 15 xc
= xcenter
+ dir
* centerDist: yc
= maxHeight
- centerDist
- RND * 25 xl = xc - rrnd(1.15 * yc, yc): xr = xc + rrnd(1.15 * yc, yc)
IF mountainbaseY
- yc
< mountainbaseY
THEN ftri xl
, mountainbaseY
, xc
, mountainbaseY
- yc
, xr
, mountainbaseY
, _RGB32(110 - i
* 4, RND * 20 + 100 - i
* 2, 100 - i
* 8) centerDist
= centerDist
+ 40 * RND + 30
Radius
= ABS(R
): RadiusError
= -Radius: X
= Radius: Y
= 0 LINE (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
RadiusError = RadiusError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF
FUNCTION rrnd
(n1
, n2
) 'return real number between n1, n2 rrnd
= (n2
- n1
) * RND + n1
SUB CenterPrint
(row
, s$
)
TS$
= _TRIM$(STR$(INT(n
* 100 + .5) / 100)) 'I have to add .5 for rounding coreectly