[bb] Vector2 Lib by Sauer [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Vector2 Lib
Author : Sauer
Posted : 1+ years ago

Description : This lib does various operations on 2D vectors, which have hundreds of applications in game programming.

If you have any suggestions on functionality to improve the lib, please comment and let me know.


Code :
Code (blitzbasic) Select
;----------------------------
;  Vector2 Library
;----------------------------

Type Vector2
Field x#,y#
End Type

Function init.Vector2(x,y)
;easy way to init a new vector
tmp.Vector2=New Vector2
tmpx=x
tmpy=y
Return tmp
End Function

Function copy.Vector2(v.Vector2)
;makes a unique instance copying another vector
tmp.Vector2=New Vector2
tmpx=vx
tmpy=vy
Return tmp
End Function

Function dot#(v.Vector2,w.Vector2)
;returns the dot product of two vectors, returned value is a scalar
Return (vx#*wx#)+(vy#*wy#)
End Function

Function length#(v.Vector2)
;returns the length (magnitude) of a vector
Return Sqr(dot(v.Vector2,v.Vector2))
End Function

Function angle_between#(v.Vector2,w.Vector2)
;finds the angle, in degrees, between two vectors
Return ACos(dot(normalize(v),normalize(w)))
End Function

Function rotate_vector2.Vector2(v.Vector2,deg#)
;counter clockwise rotation, in degrees
tmp.Vector2=New Vector2
tmpx#=(Cos#(deg)*vx#)-(Sin#(deg)*vy#)
tmpy#=(Sin#(deg)*vx#)+(Cos#(deg)*vy#)
Return tmp
End Function

Function cross.Vector2(v.Vector2)
;returns a vector perpendicular to v
tmp.Vector2=New Vector2
tmpx=vy*1
tmpy=-vx*1
Return tmp
End Function

Function normalize.Vector2(v.Vector2)
;creates a vector with length one in the same direction as original
tmp.Vector2=New Vector2
leng#=length#(v)
tmpx#=vx#/leng#
tmpy#=vy#/leng#
Return tmp
End Function

Function mul.Vector2(v.Vector2,mag#)
;multiply a vector by a scalar
tmp.Vector2=New Vector2
tmpx#=vx#*mag#
tmpy#=vy#*mag#
Return tmp
End Function  

Function add.Vector2(v.Vector2,w.Vector2)
;adds two vectors
tmp.Vector2=New Vector2
tmpx#=vx#+wx#
tmpy#=vy#+wy#
Return tmp
End Function

Function sub.Vector2(v.Vector2,w.Vector2)
;subtracts two vectors
tmp.Vector2=New Vector2
tmpx#=vx#-wx#
tmpy#=vy#-wy#
Return tmp
End Function  

Function ref.Vector2(v.Vector2,w.Vector2,through=False)
;a reflection vector, v being direction of object and w being surface.  Through means through wall or bounce off wall (default)
If through=False
n.Vector2=copy(w)
Else
n.Vector2=cross(w)
EndIf
l.Vector2=normalize(v)
n=normalize(n)
q.Vector2=mul(n,dot(l,n))
r.Vector2=sub(mul(q.Vector2,2),l)
r=normalize(r)
Return r
End Function

Function random.Vector2()
;returns a vector pointing in a random direction
tmp.Vector2=init(Rnd(-10,10),Rnd(10,10))
tmp=normalize(tmp)
Return tmp
End Function

Function print_vector2(v.Vector2,name$="-")
;prints a vector with an optional name
Print "Vector2 '"+name$+"' X: "+vx#+" Y: "+vy#
End Function

Function draw_vector2(v.Vector2,w.Vector2)
;draws a line representing a vector, taking a vector v as an origin and w as direction/magnitude
Line vx#,vy#,vx#+wx#,vy#+wy#
End Function

Function circle_circle(v.Vector2,w.Vector2,dist#)
;simple circle to circle collision using vectors
If dist(v,w)<dist#*dist#
Return True
Else
Return False
EndIf
End Function

Function dist(v.Vector2,w.Vector2)
;returns the distance squared between two vectors
Return (vx-wx)*(vx-wx)+(vy-wy)*(vy-wy)
End Function


Function circle_vector2(v.Vector2,w.Vector2,w1.Vector2,dist#)
;determines if circle (with center v and radius dist) and vector w are colliding, where w is direction/magnitude and w1 is origin
Local v1.Vector2=sub(v,w1)
Local tmp.Vector2=normalize(w)
Local proj.Vector2=mul(tmp,dot(tmp,v1))
Local a=circle_circle(v1,proj,dist#)
Local leng#=length#(w)+dist#
leng#=(leng#*leng#)
Return a And dist(proj,init(0,0))<=leng#+dist# And dist(proj,w)<=leng#+dist#
End Function


Comments :


Sauer(Posted 1+ years ago)

 Here are some applications of vectors:Bubble Shooter:
AppTitle "Bubble Shooter"
Graphics 640,480,32,2

Include "vector2.bb"

Type bullet
Field pos.Vector2
Field dir.Vector2
End Type

Type enemy
Field pos.Vector2
Field dir.Vector2
Field level
End Type

Global turret_aim.Vector2=init(0,-20)
Global turret_base.Vector2=init(320,480)

Global x_.Vector2=init(1,0)
Global y_.Vector2=init(0,1)

Global ticker=100
Global score=0

Global e.enemy

Global t=CreateTimer(60)

SetBuffer BackBuffer()
While Not KeyHit(1)
WaitTimer(t)
Cls
updateTurret()
updateBullet()
updateEnemy()
updateLevel()
HUD()
info()
Flip
Wend
End

Function info()
;print_vector2(add(turret_base,turret_aim))
;Text 0,0,ticker
End Function

Function HUD()
Color 128,128,128
Rect 0,0,640,20,1
Color 255,255,25
Text 10,0,"Score: "+score
End Function  


Function updateTurret()
Color 0,0,255
Oval turret_basex-10,turret_basey-10,20,20,0
draw_vector2(turret_base,turret_aim)

If KeyDown(203) And angle_between(x_,turret_aim)<170
turret_aim=rotate_vector2(turret_aim,-2)
EndIf
If KeyDown(205) And angle_between(x_,turret_aim)>10
turret_aim=rotate_vector2(turret_aim,2)
EndIf
If KeyHit(57)
b.bullet=New bullet
bpos=add(turret_base,turret_aim)
bdir=copy(turret_aim)
EndIf
End Function

Function updateBullet()
Color 255,0,0
For b.bullet=Each bullet
Oval bposx-4,bposy-2,4,4,0
bpos=add(bpos,bdir)
If bposx<=0 Or bposx>=640
bdirx=bdirx*-1
EndIf
If bposy<=20
Delete b
EndIf
If b<> Null
For e.enemy=Each enemy
If e<>Null And b<>Null
If circle_circle(epos,bpos,elevel*8+2)
If elevel>1
For xx =1 To elevel
e1.enemy=New enemy
e1pos=copy(epos)
Repeat
e1dir=init(Rnd(-1,1),Rnd(-1,1))
Until(e1dirx<>0 And e1diry<>0)
e1level=elevel-1
Next
EndIf
score=score+4-elevel
Delete e
Delete b
EndIf
EndIf
Next
EndIf
Next
End Function

Function updateEnemy()
Color 0,255,0
For e.enemy=Each enemy
Oval eposx-elevel*8,eposy-elevel*8,elevel*16,elevel*16,0
edir=rotate_vector2(edir,Rand(-elevel,elevel))
epos=add(epos,mul(edir,4-elevel))
If eposx<=elevel*8 Or eposx>=640-elevel*8
edirx=edirx*-1
EndIf
If eposy<=elevel*8
ediry=ediry*-1
EndIf  
If eposy>=480-elevel*8
Delete e
EndIf
Next
End Function

Function createEnemy()
e.enemy=New enemy
epos=init(Rand(100,540),25)
edir=init(0,1)
elevel=3
End Function

Function updateLevel()
ticker=ticker-1
If ticker<=0
createEnemy()
ticker=100
EndIf
End Function
Mini Golf:AppTitle "Mini Golf"
Graphics 640,480,32,2

Include "vector2.bb"

Type wall
Field base.Vector2
Field dir.Vector2
End Type

Type ball
Field pos.Vector2
Field dir.Vector2
Field speed#
End Type


Global w.wall
Global b.ball=New ball
bpos=init(0,0)
bdir=init(0,0)

Global mouse.Vector2=init(0,0)
Global h.Vector2=init(0,0)
Global pstart.Vector2=init(-10,-10)
Global power.Vector2=init(0,0)

Global strokes=0
Global lowstrokes=10

loadHole(1)
SetBuffer BackBuffer()
ClsColor 0,100,0
While Not KeyHit(1)
Cls
HUD()
updateMouse()
updateBall()
drawHole()
Flip
Wend

Function HUD()
Color 255,255,0
Text 10,0,"Strokes: "+strokes
Text 10,12,"Low Strokes: "+lowstrokes
End Function

Function updateMouse()
mousex=MouseX()
mousey=MouseY()

If MouseDown(2)
loadHole(1)
EndIf

If MouseDown(1)
If pstartx=-10 And pstarty=-10 And circle_circle(mouse,bpos,9)
pstart=copy(mouse)
EndIf
power=sub(pstart,mouse)
Color 255,0,0
draw_vector2(pstart,power)
Text pstartx+10,pstarty+10,Int(length(power)/2)
EndIf
If Not MouseDown(1)
If pstartx<>-10 And pstarty<>-10 And length(power)>0
pstartx=-10
pstarty=-10
bdir=normalize(power)
bspeed=length(power)/2
strokes=strokes+1
EndIf
EndIf
Color 255,0,0
Oval mousex-2,mousey-2,4,4,1
End Function

Function updateBall()
Color 255,255,255
Oval bposx-4,bposy-4,8,8,1
If bspeed>20
bspeed=20
EndIf
bpos=add(bpos,mul(bdir,bspeed))
bspeed=bspeed-.5
If bspeed<=0
bspeed=0
EndIf

For w.wall=Each wall
If circle_vector2(bpos,wdir,wase,10)
;bspeed=0
bdir=ref(bdir,wdir)
EndIf
Next

If circle_circle(bpos,h,18)
If bspeed>10
bdir=random()
Else
If strokes<lowstrokes
lowstrokes=strokes
EndIf
strokes=0
loadHole(1)
EndIf
EndIf


End Function


Function drawHole()
Color 0,255,0
For w.wall=Each wall
draw_vector2(wase,wdir)
Next
Color 0,0,0
Oval hx-5,hy-5,10,10,1
End Function

Function loadHole(hole)
Delete Each wall
Select hole
Case 1
Restore hole1
End Select
Read x,y
bposx=x
bposy=y
bdirx=0
bdiry=0
Read x,y
hx=x
hy=y
Read numwalls
For x=1 To numwalls
Read a,bb,c,d
w.wall=New wall
wase=init(a,bb)
wdir=init(c,d)
Next
End Function

.hole1
Data 120,380 ;ball coords
Data 380,120 ;hole coords
Data 5;number of walls
Data 100,100 ;wall origin
Data 300,0   ;wall dir

Data 400,100
Data 0,300

Data 400,400
Data -300,0

Data 100,400
Data 0,-300

Data 200,200
Data 100,100