Believe it, or not, these last couple of days, I’ve actually been having fun with QBasic.
Of course, this has all been a big distraction to my robotics.
Until now, all I’ve used it for is number crunching.
But, it turns out that there’s a lot more that one can do with it.
I’ve been making a game that will eventually be a low-graphics version of Worms/Gunbound (3rd person free-for-all shooters).
Right now, it’s in it’s baby stages.
Here’s what I’ve got so far.
Feel free to play around with the game or the code.
To play the game, follow these steps:
- Download an about 1992 version of QBasic (newer ones will probably work, too) for free.
- Copy the below code.
- Paste it into Notepad.
- Click Save As.
- Select “all types”
- Type in “CANNON.BAS”
- Click save.
- Go to the folder that you saved it in.
- Right click on it.
- Select Open With
- Click Browse
- Find your downloaded “QBasic.exe”
- Open it with that.
- When you see the code in an MS-DOS window, press F5.
i = more power
k = less power
j = more angle
l = less angle
spacebar = fire
q = quit
I’ve got the physics running well, now.
There’s still a couple formulas that I’ll need to add in, later, when I add in wind velocity and direction.
I’ll also have to add in weapon mass when I give the game more weapons.
Right now, I’m stuck trying to identify when I actually hit the green target.
I’m going to crack open my book, again, and learn how to read the screen pixels as an array, tommorrow.
That would be a slower way to determine hit or miss, but the “faster” way isn’t working for me.
If anyone sees why it isn’t, I’m all ears.
Here’s the code:
CANNON v.1.02 by: Nick Reiser last edited: 4/11/06
'***************************************************************************************
'*****************************SCREEN SETTINGS*******************************************
'***************************************************************************************
''''''''''''''''''''''''''''''Clear the screen.
CLS
''''''''''''''''''''''''''''''Switch to Medium graphics mode.
SCREEN 1
''''''''''''''''''''''''''''''Sky blue background, green, red, brown pallete.
COLOR 9, 0
''''''''''''''''''''''''''''''Make display screen's coordinates Cartesian.
WINDOW (0, 199)-(319, 0)
''''''''''''''''''''''''''''''Make Cartesian available to DRAW statements.
VIEW (0, 0)-(319, 199)
'***************************************************************************************
'***************************************************************************************
'*****************************DEFAULT GRAPHICS******************************************
'***************************************************************************************
''''''''''''''''''''''''''''''Default power value (m/s).
power = 25
''''''''''''''''''''''''''''''Default cannon angle (in degrees).
theta.deg = 45
''''''''''''''''''''''''''''''Default gravity value (m/s^2).
gravity = 9.81
''''''''''''''''''''''''''''''Default missile tail length.
missile.tail.length = 25
''''''''''''''''''''''''''''''Default game speed.
game.speed# = 1000
''''''''''''''''''''''''''''''Draw cannon at default angle and power.
FOR i = -1 TO 1
FOR j = -1 TO 1
PSET (i, j), 3
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
''''''''''''''''''''''''''''''Randomize first target width
RANDOMIZE TIMER
random.number.width = RND
target.width = INT(random.number.width * 7) + 3
''''''''''''''''''''''''''''''Randomize first target height
RANDOMIZE TIMER
random.number.height = RND
target.height = INT(random.number.height * 5) + 3
''''''''''''''''''''''''''''''Draw first target at random position.
RANDOMIZE TIMER
random.number.position = RND
target.position = INT(random.number.position * 249) + 70
FOR i = (target.width * -1) TO target.width
FOR j = 0 TO target.height
PSET (target.position + i, j), 1
NEXT j
NEXT i
'***************************************************************************************
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@MAIN PROGRAM@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
''''''''''''''''''''''''''''''Create infinite loop.
DO
''''''''''''''''''''''''''''''INKEY$ stores all keys that user presses.
SELECT CASE INKEY$
'***************************************************************************************
'*****************************UP KEY****************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses "i" (up) key.
CASE IS = "i"
''''''''''''''''''''''''''''''Hide the old cannon by coloring it sky blue.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 0
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
''''''''''''''''''''''''''''''Add 1 to cannon's length.
power = power + .5
''''''''''''''''''''''''''''''Restrict cannon from being longer than 60 pixels.
IF power > 60 THEN
power = 60
END IF
''''''''''''''''''''''''''''''Draw the new, longer cannon.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 3
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
'***************************************************************************************
'***************************************************************************************
'*****************************DOWN KEY**************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses "k" (down) key.
CASE IS = "k"
''''''''''''''''''''''''''''''Hide the old cannon by coloring it sky blue.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 0
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
''''''''''''''''''''''''''''''Subtract 1 from the length of the cannon.
power = power - .5
''''''''''''''''''''''''''''''Restrict cannon from being shorter than 1 pixel.
IF power < 1 THEN
power = 1
END IF
''''''''''''''''''''''''''''''Draw the new, shorter cannon.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 3
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
'***************************************************************************************
'***************************************************************************************
'*****************************LEFT KEY**************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses "j" (left) key.
CASE IS = "j"
''''''''''''''''''''''''''''''Hide old cannon by coloring it sky blue.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 0
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
''''''''''''''''''''''''''''''Add half a degree to the cannon's angle.
theta.deg = theta.deg + .5
''''''''''''''''''''''''''''''Restrict cannon's angle to a 90 degree maximum.
IF theta.deg > 90 THEN
theta.deg = 90
END IF
''''''''''''''''''''''''''''''Draw cannon at new, higher angle.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR" a starting point.
PSET (i, j), 3
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
'***************************************************************************************
'***************************************************************************************
'*****************************RIGHT KEY*************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses "l" (right) key.
CASE IS = "l"
''''''''''''''''''''''''''''''Hide old cannon by coloring it sky blue.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 0
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
''''''''''''''''''''''''''''''Subtract half an degree from cannon's angle.
theta.deg = theta.deg - .5
''''''''''''''''''''''''''''''Restrict cannon's angle to a 0 degree minimum.
IF theta.deg < 0 THEN
theta.deg = 0
END IF
''''''''''''''''''''''''''''''Draw cannon at new, higher angle.
FOR i = -1 TO 1
FOR j = -1 TO 1
''''''''''''''''''''''''''''''PSET gives "NR=" a starting point.
PSET (i, j), 3
DRAW "TA=" + VARPTR$(theta.deg) + "NR=" + VARPTR$(power)
NEXT j
NEXT i
'***************************************************************************************
'***************************************************************************************
'*****************************QUIT KEY**************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses "q" (quit) key.
CASE IS = "q"
''''''''''''''''''''''''''''''End the program.
END
'***************************************************************************************
'***************************************************************************************
'*****************************FIRE KEY**************************************************
'***************************************************************************************
''''''''''''''''''''''''''''''When user presses space bar (fire) key.
CASE IS = " "
''''''''''''''''''''''''''''''Hide old impact by coloring it sky blue.
FOR i = -1 TO 1
FOR j = 0 TO 1
PSET (impact + i, j), 0
NEXT j
NEXT i
''''''''''''''''''''''''''''''Hide old peak by coloring it sky blue.
PSET (0, ymax), 0
''''''''''''''''''''''''''''''Change cannon's angle from degrees to radians.
theta.rad = (theta.deg / 360 * 2 * 3.1415)
''''''''''''''''''''''''''''''Calculate the x coordinate of impact.
impact = (power ^ 2) / gravity * SIN(2 * theta.rad)
''''''''''''''''''''''''''''''Calculate, plot, and then hide the trajectory.
FOR x = 0 TO impact
FOR delay# = 1 TO game.speed#
NEXT delay#
PSET (x, y), 2
y = x * TAN(theta.rad) - .5 * gravity * (x ^ 2 / ((power ^ 2) * COS(theta.rad) * COS(theta.rad)))
PSET (hidex, hidey), 0
hidex = x - trajectory.tail.length
y = x * TAN(theta.rad) - .5 * gravity * (x ^ 2 / ((power ^ 2) * COS(theta.rad) * COS(theta.rad)))
NEXT x
''''''''''''''''''''''''''''''Hide old trajectory by coloring it sky blue.
FOR x = 0 TO impact
PSET (x, y), 0
y = x * TAN(theta.rad) - .5 * gravity * (x ^ 2 / ((power ^ 2) * COS(theta.rad) * COS(theta.rad)))
NEXT x
''''''''''''''''''''''''''''''Display the 3 x 2 impact rectangle.
FOR i = -1 TO 1
FOR j = 0 TO 1
PSET (impact + i, j), 2
NEXT j
NEXT i
'''''''''''''''''''''''''''''Target hit?
FOR i = (target.width * -1) TO target.width
'''''''''''''''''''''''''''''Find the value (1 or 2) of a target's pixel.
color.point = POINT((target.position + i), 1)
'''''''''''''''''''''''''''''If any of those pixels are red, then trigger.
IF color.point = 2 THEN
hide.target = 1
END IF
NEXT i
''''''''''''''''''''''''''''''If target hit, then hide the old target.
IF hide.target = 1 THEN
FOR i = (target.width * -1) TO target.width
FOR j = 0 TO target.height
PSET ((target.position + i), j), 0
NEXT j
NEXT i
''''''''''''''''''''''''''''''Randomize new target width
RANDOMIZE TIMER
random.number.width = RND
target.width = INT(random.number.width * 7) + 3
''''''''''''''''''''''''''''''Randomize new target height
RANDOMIZE TIMER
random.number.height = RND
target.height = INT(random.number.height * 5) + 3
''''''''''''''''''''''''''''''Draw new target at random position.
RANDOMIZE TIMER
random.number.position = RND
target.position = INT(random.number.position * 249) + 70
FOR i = (target.width * -1) TO target.width
FOR j = 0 TO target.height
PSET ((target.position + i), j), 1
NEXT j
NEXT i
''''''''''''''''''''''''''''''Reset the triggers for future events.
hide.target = 0
END IF
''''''''''''''''''''''''''''''Calculate the peak of the trajectory.
ymax = power ^ 2 * SIN(theta.rad) * SIN(theta.rad) / (2 * gravity)
''''''''''''''''''''''''''''''Display trajectory peak as a pixel on the left.
PSET (0, ymax), 3
'***************************************************************************************
END SELECT
LOOP
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@