# Example of 2D projectile. The screenshot shows a demonstration of code to model projectile flight in two dimensions. You are presented with a randomly-positioned target, and can use the mouse left-click in the little aiming box to set direction and speed of the discharge. Vertical motion experiences gravity and air drag; horizontally it meets only air drag.

When you've set the velocity, click 'Fire!'.

As set up, it leaves a trace of the track. You could instead move a sprite.....

You can easily change parameters like 'g', mass, cross sectional area and friction coefficient. It also can be easily made to loop through a family of curves. Now try a ( we hope better) launch velocity and angle.

You could easily add a routine to check if you made a 'Hit' and add scoring, etc.

The following code runs in Liberty or Just BASIC.

```    '   *************************************************
'   **                                             **
'   **            Trebuchet4.bas                   **
'   **                                             **
'   *************************************************

'   **     tenochtitlanuk ( John F) Feb. 2011      **

'   Investigating real-world projectile motion.
'   Allows you to play with 2D motion in g-field
'   Includes effect of air friction.
'   You can alter initial velocity and angle.

'   To-dos:-
'       Add dialogue boxes to change the variables.
'       Add option of a target to hit.

nomainwin

UpperLeftX   =  10
UpperLeftY   =  10
WindowWidth  =1000
WindowHeight = 680

graphicbox #w.g2, 25, 278,  40,  40
graphicbox #w.g,  20,  10, 970, 610

button     #w.b1, "Fire!", [here], LR, 50, 400

statictext #w.st1, "Initialise", 20, 630, 550, 20

open "Projectile simulation for Trebuchet" for window as #w

#w,   "trapclose [quit]"
#w.g2 "when leftButtonDown [vector]"

#w.g, "cls ; size 2 ; color red "
#w.g  "down ; fill lightgray"
#w.g  "up ; goto "; 400 +400 *rnd( 1); " "; 305 -200 *rnd( 1)
#w.g  "down ; backcolor red ; circlefilled 10"

#w.g  "up ; goto 5 305 ; color darkblue"
#w.g  "down ; goto 985 305 ; color black ; size 1 ; down ; flush"

#w.g2 "size 2 ; down ; fill cyan ; flush"

m           =   1                   '   fixed mass of stone in    kg.

A           =   0.002               '   csa of stone in           m^2.
g           =   9.81                '   acc'n of gravity          m^s2.
D           =   1.2                 '   density of air.
Cd          =   0.75                '   allows for the shape.

v           =  60                   '   release velocity in       m/s.
theta       =  30                   '   release angle in          degrees,
theta       =theta /180 *3.14159265 '     ... changed to         radians.

y           =   0                   '   initial vertical height.
vy          =  v *cos( theta)       '   initial vertical vel'y.

x           =   0                   '   initial horizontal position.
vx          =  v *sin( theta)       '   initial horizontal vel'y.

t           =   0                   '   initial time.             s
dt          =   0.001               '   time interval between updates.

wait

[here]
#w.b1 "!disable"
[h]
fy      =0 -g *m -0.5 *D *vy^2 *Cd *A *sgn( vy)
ay      =fy /m
vy      =vy +ay *dt
y       =y  +vy *dt

fx      =0       -0.5 *D *vx^2 *Cd *A *sgn( vx)
ax      =fx /m
vx      =vx +ax *dt
x       =x  +vx *dt

t       =t  +dt

#w.g, "set "; 5 +2.5 *x; " "; 305 -2.5 *y

scan

if x <400 and y >-40 then [h]

#w.g "flush"
#w.b1 "!enable"

wait

[vector]
x           =0
y           =0
xx          =MouseX
yy          =MouseY

#w.g2 "cls ; down ; fill cyan ; up ; goto 0 39 ; down ; goto "; xx; " "; yy

theta =atn( ( 39 -yy) /xx)
v           =2 *( xx^2 +( 39-yy)^2)^0.5

#w.st1 "v ="; using( "###.#", v); " & angle ="; using( "###.#", theta *180 /3.14159265); " degrees."

vy          =  v *sin( theta)       '   initial vertical vel'y.
vx          =  v *cos( theta)       '   initial horizontal vel'y.
wait

function sgn( x)
if x <0 then
sgn =-1
else
sgn = 1
end if
end function 'sgn

[quit]
close #w
end

```

And here's a later version.

```
'   *************************************************
'   **                                             **
'   **            Trebuchet7.bas                   **
'   **                                             **
'   *************************************************

'   **     tenochtitlanuk ( John F) Feb. 2011      **

'   Investigating real-world projectile motion.
'   Allows you to play with 2D motion in g-field
'   Includes effect of air friction.
'   You can alter initial velocity and angle.

'   To-dos:-
'       Move graphics vertically                        done
'       Add dialogue boxes to change the variables.
'           possibly use cursor keys to tweak...
'       Add option of a target to hit.                  done
'       Add a score based on time taken to hit target?
'       Score near-misses as well as hits. (air bursts)

nomainwin

UpperLeftX   =  10
UpperLeftY   =  10
WindowWidth  =1000
WindowHeight = 680

graphicbox #w.g2, 25, 465, 100, 100
stylebits  #w.g2, 0, _WS_BORDER, 0, 0
graphicbox #w.g,  20,  10, 970, 610

button     #w.b1, "Fire!", [here], LR, 940,  50

statictext #w.st1, "Initialise", 20, 630, 550, 20

open "Projectile simulation for Trebuchet" for window as #w

#w,   "trapclose [quit]"
#w.g2 "when leftButtonDown [vector]"
#w.g2 "when characterInput [here]"

#w.g, "cls ; size 2 ; color red "
#w.g  "down ; fill darkgray"

xt =100 +250 *rnd( 1)
yt =200 -200 *rnd( 1)
#w.g  "up ; goto "; 5 +2.5 *xt; " "; 555 -2.5 *yt
#w.g  "down ; backcolor red ; circlefilled 10"

#w.g  "up ; goto 5 555 ; color darkblue"
#w.g  "down ; goto 985 555 ; color black ; size 1 ; down ; flush"

#w.g2 "size 3 ; down ; fill cyan ; color lightgray ; box 99 99 ; flush ; color black"

m           =   1                   '   fixed mass of stone in    kg.

A           =   0.005               '   csa of stone in           m^2.   More like 0.002
g           =   9.81                '   acc'n of gravity          m^s2.
D           =   1.2                 '   density of air.
Cd          =   2                   '   allows for the shape. Correct value =0.75??

v           =  60                   '   release velocity in       m/s.
theta       =  30                   '   release angle in          degrees,
theta       = theta /180*3.14159265 '     ... changed to         radians.

y           =   0                   '   initial vertical height.
vy          =  v *cos( theta)       '   initial vertical vel'y.

x           =   0                   '   initial horizontal position.
vx          =  v *sin( theta)       '   initial horizontal vel'y.

t           =   0                   '   initial time.             s
dt          =   0.004               '   time interval between updates.

wait

[here]
#w.b1 "!disable"
#w.g "color "; 256 *rnd( 1); " "; 256 *rnd( 1); " "; 256 *rnd( 1)
[h]
fy      =0 -g *m -0.5 *D *vy^2 *Cd *A *sgn( vy)
ay      =fy /m
vy      =vy +ay *dt
y       =y  +vy *dt

fx      =0       -0.5 *D *vx^2 *Cd *A *sgn( vx)
ax      =fx /m
vx      =vx +ax *dt
x       =x  +vx *dt

t       =t  +dt

#w.g, "set "; 5 +2.5 *x; " "; 555 -2.5 *y

proximity =( xt -x)^2 +( yt -y)^2
if proximity <400 *4 /25 then #w.g "color yellow" else #w.g "color black"

scan

if x <400 and y >-40 then [h]

#w.g "flush"
#w.b1 "!enable"

wait

[vector]
x           =0
y           =0
xx          =MouseX
yy          =MouseY

#w.g2 "cls ; down ; fill darkgray ; up ; goto 0 99 ; down ; goto "; xx; " "; yy

theta =atn( ( 99 -yy) /xx)
v           =( xx^2 +( 99-yy)^2)^0.5

#w.st1 "v ="; using( "###.#", v); " & angle ="; using( "###.#", theta *180 /3.14159265); " degrees."

vy          =  v *sin( theta)       '   initial vertical vel'y.
vx          =  v *cos( theta)       '   initial horizontal vel'y.

#w.b1 "!enable"

wait

function sgn( x)
if x <0 then
sgn =-1
else
sgn = 1
end if
end function 'sgn

[quit]
close #w
end
```

e-mail me on mr.john.f at gmail.com for any explanations, comments, etc...