; Vector: ; ; Point 1 ; ; O ; `-_ ; '-_ ; `-_ ; '-_ , ; `-_l ; _-' ; O ; ; Point 2 ; ; This can be anything ; from calculation motion ; to drawing a simple line. ; ; O --- ; / /|\ ; / | ; / | distance Y ; / | ; / | ; / \|/ ; O --- ; ; |<---->| ; ; distance X ; ; It doesn't really matter ; where point 1 is ; compared to point 2. ; ; It can go in any direction. ; ; :` ; : ` ; 1 ; ` ; O ' 225 degrees ; / ` ; / ' ; distance / ''' ; / ; / ; / ; O ; 2 ; ; Going from point 1 to point 2 ; means going in the direction of 225 degrees ; when 0 degrees means UP ; and clockwise means positive. ; ; Some people use anti-clockwise ; and 0 degrees means RIGHT. ; ; It's all up to the programmer :) ; ; So you can actually look at vectors ; in multiple ways. ; ; Distance X and Distance Y ; ; or ; ; Distance and Direction (angle) ; ; I've created 4 functions you can use ; to convert to/from each of these ; without breaking your head over maths. ; ;,,,,,,,, ; Easy to use functions ;---- ; ; For those of you (including me) ; who don't like doing all the maths ; every time and time again :P ; ;= Get horizontal size of vector using distance and angle Function VectorX# ( Distance# , Angle# ) Return Sin ( Angle ) * Distance End Function ;= Get vertical size of vector using distance and angle Function VectorY# ( Distance# , Angle# ) Return Sin ( Angle - 90 ) * Distance End Function ;= Get true length of a vector Function VectorDistance# ( X# , Y# ) Return Sqr ( X * X + Y * Y ) End Function ;= Get true angle of a vector Function VectorAngle# ( X# , Y# ) Return -Atan2 ( X , Y ) + 180 End Function ; ;---- ; ; And here's how they work: ; ; DistanceX = VectorX ( Distance , Angle ) ; DistanceY = VectorY ( Distance , Angle ) ; ; Distance = VectorDistance ( DistanceX , DistanceY ) ; Angle = VectorAngle ( DistanceX , DistanceY ) ; ; Note that the orientation used ; in the functions is: ; ; - clockwise ; - 0 degrees means UP ; ; I've included 5 example programs ; to demonstrate the usage of the functions. ; E.g. to display that you can create ; entire games without complicated maths :) ; ; I've created functions out of the sections ; so you can just run each section ; without having to copy/paste ; everything to a new program. ; ; Here are the first 5 functions ; (name, description): ; ; prog1 How vectors work ; prog2 Motion using vectors (example 1) ; prog3 Motion using vectors (example 2) ; prog4 Space physics (example 1) ; prog5 Space physics (example 2) ; ; If you want to dive deeper into ; how exactly Sin and Cos work, ; here's a number of more ; math intensive programs ; to demonstrate how they work. ; ; sine1 What Sin and Cos look like ; sine2 What values Sin has ; sine3 Sin(a) = Cos(a - 90) ; sine4 Simple vector example ; sine5 Elaborate vector example ; sine6 Circle ; sine7 Rays ; ; If you only want to use the functions, ; here's the function call to try out ; a particular section. prog1 ; Below I'll explain more about ; how Sin and Cos work. ; ; First, some more vector ; orientation explanation ; found on BlitzCoder: ; ; There are different ways to use vectors. ; The most common vector is simply having an X and Y. ; These would be used to, for example, calculate a ship's displacement. ; Imagine a matrix or grid with (0,0) as the center. ; When visualizing, a vector would always be drawn from this point. ; Another way is to use Angle and Length. ; Angle would be the angle of the line from (0,0) to (X,Y). ; And Length being the actual distance between these points. ; ; The graph below displays: ; ; T ; * ; /I ; / I ; / I ; v / I ; / I y ; / I ; / I ; / I ; /a I ; *---------* ; V B ; x ; ; Line VB represents the horizontal distance x ; Line BT represents the vertical distance y ; Line VT (v) represents the length of the vector ; E.g. the combined of distance x and y ; Angle 'a' represents the angle of the vector ; ; X ; Native vector notation: --- ; Y ; ; Default pythagoras formula applies to this triangle: x^2 + y^2 = v^2 ; There are also various Sin, Cos and Tan formulas to apply. ; Basically anything with trigonometry. ; ; The first section (prog1) is a representation of the above. ; ; Now, even though Sin and Cos are functions ; which calculate something for you, ; they should always return the same value ; when giving the same parameter. ; ; So you can basically look at them like ; arrays containing values. ; ; You can take a look at sine1 ; (the program or function) ; to see what the values look like ; when you draw them. ; ; Program sine2 will display a table ; of exactly which values you get ; with which angles. ; ; Why not displaying a table ; with the values of Cos? ; ; Actually Sin and Cos have ; the exact same pattern, a sinewave. ; ; The only difference is where they begin. ; When you look at sine1 again, ; you'll see the phase difference. ; ; Sine3 will show you that ; you can use any phase or offset ; using only Sin. ; ; When you multiply the value ; from Sin/Cos you can get ; a distance of your choice. ; ; Normally the returned value ; is in range of [-1..1] ; e.g. max distance = 1. ; ; When looking at sine4 ; you'll find that: ; ; PosX = Sin ( Angle ) * Radius ; ; And when running sine5 ; you might find that it's ; actually a lot like prog1. ; ; Finally there's sine6 which ; plots pixels on the path ; making a circle. ; ; And sine7 where lines ; are drawn towards the path ; creating rays from the center. ; ; Below you'll find all the code inside separated functions. ; Example of displaying a true vector ; ---------------------------------------------------------------------------- ; ; Move your mouse to alternate the vector Function prog1 () Graphics 640 , 480 SetBuffer BackBuffer() ; Double buffering, e.g. draw to invisible buffer and swap to visible when done X1 = GraphicsWidth() / 2 ; Center of screen is center of vector Y1 = GraphicsHeight() / 2 ; MoveMouse X1 + 100 , Y1 - 100 ; Put mouse in a spot to resemble the graph in the vector help Repeat ; Main loop Cls ; Clear screen each frame X2 = MouseX() ; Use mouse for vector coordinates Y2 = MouseY() ; Length = VectorDistance( X2-X1 , Y2-Y1 ) ; Calculate true length of the vector Angle = VectorAngle( X2-X1 , Y2-Y1 ) ; And true angle Color 0 , 127 , 255 ; Display relevant info Text 0 , 0 * FontHeight() , "X Length: " + (X2-X1) Text 0 , 1 * FontHeight() , "Y Length: " + (Y2-Y1) Text 0 , 2 * FontHeight() , "Vector Length: " + Length Text 0 , 3 * FontHeight() , "Vector Angle: " + Angle X2 = X1 + VectorX( Length , Angle ) ; REcalculate vector coordinates, to demonstrate using GetVector Y2 = Y1 + VectorY( Length , Angle ) ; The vector is drawn from center of screen Color 0 , 255 , 0 Line X1 , Y1 , X2 , Y2 ; Draw vector line (v) Color 255 , 255 , 0 Line X1 , Y1 , X2 , Y1 ; Draw the horizontal line (x) Line X2 , Y2 , X2 , Y1 ; Draw the vertical line (y) Flip ; Using double buffering so, display all Until GetKey() ; Until any ASCII keypress EndGraphics End End Function ; Specific example for GetLength and GetAngle ; ---------------------------------------------------------------------------- ; ; Demonstrates 'ashies' (grey dots) floating around. Type Dot ; Ashy Field PosX# ; All ashies have unique positions Field PosY# ; Field LastAngle% ; And an angle to remember where they're going Field Color% ; Also a color End Type Function prog2 () Graphics 640 , 480 SetBuffer BackBuffer() SeedRnd MilliSecs() ; Randomize TotalDots = 100 ; Total number of dots to create Local Dot.Dot ; Creating a collection of dots For Counter = 1 To TotalDots ; Creating the dolly dots Dot = New Dot Dot\PosX = Rnd( 0 , GraphicsWidth() ) ; Random position on screen Dot\PosY = Rnd( 0 , GraphicsHeight() ) ; Dot\LastAngle = Rnd( 0 , 359 ) ; Random direction to begin with Dot\Color = Rnd( 64 , 255 ) ; And a random color (grey shade) Next Repeat Cls For Dot = Each Dot ; Iterate through all dots Repeat IncX# = Rnd( -5 , 5 ) ; Get random horizontal increment IncY# = Rnd( -5 , 5 ) ; Get random vertical increment Length = VectorDistance( IncX , IncY ) ; Calculate the real length of the line (size of the vector) Angle = VectorAngle( IncX , IncY ) ; Calculate the real angle Until Length >= 2 And Length <= 5 And Abs ( Dot\LastAngle - Angle ) <= 10 ; Repeat calculating until we get a line with length between 2 and 5 ; and an angle that differs no more than 10 degrees from the current angle ; This technique is very slow but demonstrates the purpose Dot\LastAngle = Angle ; Remember the current angle Dot\PosX = Dot\PosX + IncX ; Update the dot's horizontal position by the new increment If Dot\PosX < 0 Then Dot\PosX = Dot\PosX + GraphicsWidth() ; But if it goes off-screen, make it warp If Dot\PosX > GraphicsWidth() Then Dot\PosX = Dot\PosX - GraphicsWidth() Dot\PosY = Dot\PosY + IncY ; Same for vertical position If Dot\PosY < 0 Then Dot\PosY = Dot\PosY + GraphicsHeight() If Dot\PosY > GraphicsHeight() Then Dot\PosY = Dot\PosY - GraphicsHeight() Color Dot\Color , Dot\Color , Dot\Color ; Pick da color Plot Dot\PosX , Dot\PosY ; Plot the dot, you can use writepixel too Next Flip Until GetKey() Delete Each Dot ; Wipe them out EndGraphics End End Function ; Specific example for GetVectorX and GetVectorY ; -------------------------------------------------------------------------------------------------------------------- ; ; Demonstrates 'fishies' (nibbles/lines) wondering about with various speeds, sizes and colors. Type Nibble ; Fishy Field TailX# ; Fishy has head and tail Field TailY# ; Program uses tail for positioning Field Speed% ; Fishy has speed Field Heading% ; Fishy has angle or heading Field Size% ; Fishy has size, e.g. difference between head and tail Field Color% ; And color (simple grey scale) End Type Function prog3 () Graphics 640 , 480 SetBuffer BackBuffer() SeedRnd MilliSecs() TotalNibbles = 20 ; Total number of nibbles to create Local Nibble.Nibble ; Our collection of nibbles For Counter = 1 To TotalNibbles ; Create nibbles Nibble = New Nibble Nibble\TailX = Rnd( 0 , GraphicsWidth() ) ; Random position within screen boundaries Nibble\TailY = Rnd( 0 , GraphicsHeight() ) ; Nibble\Speed = Rnd( 2 , 5 ) ; Random speed Nibble\Heading = Rnd( 0 , 359 ) ; Random heading to start with Nibble\Size = Rnd( 5 , 10 ) ; Random size too Nibble\Color = Rnd( 64 , 255 ) ; And random shade Next Repeat Cls For Nibble = Each Nibble ; Iterate through all nibbles Nibble\Heading = Nibble\Heading + Rnd( -10 , 10 ) ; Randomly alternate heading with max 10 degrees If Nibble\Heading < 0 Then Nibble\Heading = Nibble\Heading + 360 ; Keep angle in range of 0 and 359 If Nibble\Heading > 359 Then Nibble\Heading = Nibble\Heading - 360 Nibble\TailX = Nibble\TailX + VectorX( Nibble\Speed , Nibble\Heading ) ; Update position If Nibble\TailX < 0 Then Nibble\TailX = Nibble\TailX + GraphicsWidth() ; Warp if off-screen If Nibble\TailX >= GraphicsWidth() Then Nibble\TailX = Nibble\TailX - GraphicsWidth() Nibble\TailY = Nibble\TailY + VectorY( Nibble\Speed , Nibble\Heading ) ; Same for vertical If Nibble\TailY < 0 Then Nibble\TailY = Nibble\TailY + GraphicsHeight() If Nibble\TailY >= GraphicsHeight() Then Nibble\TailY = Nibble\TailY - GraphicsHeight() HeadX# = Nibble\TailX + VectorX( Nibble\Size , Nibble\Heading ) ; Calculate head based on tail HeadY# = Nibble\TailY + VectorY( Nibble\Size , Nibble\Heading ) ; (can go off-screen) Color Nibble\Color , Nibble\Color , Nibble\Color ; Nibble color Line Nibble\TailX , Nibble\TailY , HeadX , HeadY ; Line from tail to head Next Flip Until GetKey() Delete Each Nibble EndGraphics End End Function ; Example of space physics using vector translation (Method A) ; ---------------------------------------------------------------------------- ; ; Demonstrates the use of angle, thrust, heading and velocity Function prog4 () Graphics 640 , 480 SetBuffer BackBuffer() ; Keyboard scancodes KeyCursorUp% = 200 KeyCursorDown% = 208 KeyCursorLeft% = 203 KeyCursorRight% = 205 KeyEscape% = 1 KeySpace% = 57 ; Craft specifications ThrustMax# = 0.1 ; Maximum thrust speed SpeedMax# = 5 ; Maximum allowed velocity RotateMax# = 4 ; Maximum rotation speed (degrees) ; Craft related PosX# = GraphicsWidth() / 2 ; Start at center of screen PosY# = GraphicsHeight() / 2 ; Thrust# = 0 ; Current thrust speed - in the direction of where the ship is pointing at Angle% = 0 ; Current angle (rotation) - where the ship is pointing at Speed# = 0 ; Current actual speed of the ship Heading% = 0 ; Current heading - where the ship is moving towards (degrees) ; Logic related Local Thrusting% = False ; Thrusts forwards/backwards when True, automatically decelerates thrust when False Local VelocityX# = 0 ; Temporary variables for calculating the new velocity vector Local VelocityY# = 0 ; Repeat Cls If KeyDown( KeyCursorLeft ) Then Angle = Angle - RotateMax ; Rotate anti-clockwise If KeyDown( KeyCursorRight ) Then Angle = Angle + RotateMax ; Rotate clockwise If Angle < 0 Then Angle = Angle + 360 ; Make sure angle is in range of 0-359 (shift) If Angle > 359 Then Angle = Angle - 360 Thrusting = False ; Automatically decelerate thrust - reset thrusting flag If KeyDown( KeyCursorUp ) Then ; Cursor up held down Thrust = ThrustMax ; Start thrusting forwards at max speed Thrusting = True ; Do not decelerate thrust EndIf If KeyDown( KeyCursorDown ) Then ; Cursor down held down Thrust = -ThrustMax ; Start thrusting backwards at max speed Thrusting = True ; Do not decelerate thrust EndIf If Not Thrusting Then Thrust = 0 ; Automatically decelerate thrusting when not thrusting (on request) ; Note: ; Speed & Heading = Current velocity vector [ VelocityX VelocityY ] ; Thrust & Angle = Current thrust vector [ ThrustX ThrustY ] VelocityX = VectorX( Speed , Heading ) + VectorX( Thrust , Angle ) ; The new velocity vector is the sum of VelocityY = VectorY( Speed , Heading ) + VectorY( Thrust , Angle ) ; the current velocity and thrust vector Speed = VectorDistance( VelocityX , VelocityY ) ; Translate back to speed and heading Heading = VectorAngle( VelocityX , VelocityY ) ; If Speed > SpeedMax Then Speed = SpeedMax ; Limit speed to maximum If KeyDown( KeySpace ) Then Speed = 0 ; Handbrake PosX = PosX + VectorX( Speed , Heading ) ; Update horizontal position with current horizontal velocity inc. If PosX < 0 Then PosX = PosX + GraphicsWidth() ; Warp if off-screen If PosX >= GraphicsWidth() Then PosX = PosX - GraphicsWidth() PosY = PosY + VectorY( Speed , Heading ) ; Same for vertical If PosY < 0 Then PosY = PosY + GraphicsHeight() If PosY >= GraphicsHeight() Then PosY = PosY - GraphicsHeight() Color 0 , 127 , 255 ; Additional information Oval PosX - 10 , PosY - 10 , 21 , 21 , True Text 0 , 0 * FontHeight() , "X: " + Int(PosX) + " Y: " + Int(PosY) Color 127 , 255 , 127 Line PosX , PosY , PosX + VectorX( 10 , Heading ) , PosY + VectorY( 10 , Heading ) Text 0 , 1 * FontHeight() , "Speed: " + Int(Speed) + " Heading: " + Heading Color 255 , 255 , 255 Line PosX , PosY , PosX + VectorX( 20 , Angle ) , PosY + VectorY( 20 , Angle ) Text 0 , 2 * FontHeight() , "Thrust: " + Thrusting + " Angle: " + Angle Flip Until KeyDown( KeyEscape ) EndGraphics End End Function ; Example of space physics using vector translation (Method B) ; ---------------------------------------------------------------------------- ; ; Demonstrates the use of native thrust and velocity vectors Function prog5 () Graphics 640 , 480 SetBuffer BackBuffer() ; Keyboard scancodes KeyCursorUp% = 200 KeyCursorDown% = 208 KeyCursorLeft% = 203 KeyCursorRight% = 205 KeyEscape% = 1 KeySpace% = 57 ; Craft specifications ThrustMax# = 0.1 ; Maximum thrust speed SpeedMax# = 5 ; Maximum allowed velocity RotateMax# = 4 ; Maximum rotation speed (degrees) ; Craft related PosX# = GraphicsWidth() / 2 ; Start at center of screen PosY# = GraphicsHeight() / 2 ; ThrustX# = 0 ; Native vector for thrust ThrustY# = 0 ; VelocityX# = 0 ; Native vector for velocity VelocityY# = 0 ; Angle% = 0 ; Current angle (degrees) ; Logic related Local Thrusting% = False ; Thrusts forwards/backwards when True, automatically decelerates thrust when False Local Speed# ; Temporary variables for calculation Local Heading% ; Repeat Cls If KeyDown( KeyCursorLeft ) Then Angle = Angle - RotateMax ; Rotate anti-clockwise If KeyDown( KeyCursorRight ) Then Angle = Angle + RotateMax ; Rotate clockwise If Angle < 0 Then Angle = Angle + 360 ; Make sure angle is in range of 0-359 (shift) If Angle > 359 Then Angle = Angle - 360 Thrusting = False ; Automatically decelerate thrust - reset thrusting flag If KeyDown( KeyCursorUp ) Then ; Cursor up held down ThrustX = VectorX( ThrustMax , Angle ) ; Start thrusting forwards at max speed ThrustY = VectorY( ThrustMax , Angle ) ; Thrusting = True ; Do not decelerate thrust EndIf If KeyDown( KeyCursorDown ) Then ; Cursor down held down ThrustX = VectorX( -ThrustMax , Angle ) ; Start thrusting backwards at max speed ThrustY = VectorY( -ThrustMax , Angle ) ; Thrusting = True ; Do not decelerate thrust EndIf If Not Thrusting Then ThrustX = 0 ; Automatically decelerate thrusting when not thrusting (on request) ThrustY = 0 ; EndIf VelocityX = VelocityX + ThrustX ; The new velocity vector is the sum of the current velocity and thrust vector VelocityY = VelocityY + ThrustY ; Speed = VectorDistance( VelocityX , VelocityY ) ; Calculate actual speed Heading = VectorAngle( VelocityX , VelocityY ) ; Calculate actual heading If Speed > SpeedMax Then Speed = SpeedMax ; Limit speed to maximum If KeyDown( KeySpace ) Then Speed = 0 ; Handbrake VelocityX = VectorX( Speed , Heading ) ; Translate back to native velocity vector VelocityY = VectorY( Speed , Heading ) ; PosX = PosX + VelocityX ; Update horizontal position with current horizontal velocity increment If PosX < 0 Then PosX = PosX + GraphicsWidth() ; Warp if off-screen If PosX >= GraphicsWidth() Then PosX = PosX - GraphicsWidth() PosY = PosY + VelocityY ; Same for vertical If PosY < 0 Then PosY = PosY + GraphicsHeight() If PosY >= GraphicsHeight() Then PosY = PosY - GraphicsHeight() Color 0 , 127 , 255 ; Additional information Oval PosX - 10 , PosY - 10 , 21 , 21 , True Text 0 , 0 * FontHeight() , "X: " + Int(PosX) + " Y: " + Int(PosY) Color 127 , 255 , 127 Line PosX , PosY , PosX + VectorX( 10 , Heading ) , PosY + VectorY( 10 , Heading ) Text 0 , 1 * FontHeight() , "Speed: " + Int(Speed) + " Heading: " + Heading Color 255 , 255 , 255 Line PosX , PosY , PosX + VectorX( 20 , Angle ) , PosY + VectorY( 20 , Angle ) Text 0 , 2 * FontHeight() , "Thrust: " + Thrusting + " Angle: " + Angle Flip Until KeyDown( KeyEscape ) EndGraphics End End Function ;------------------------------------------------------------------------------- Function sine1 () Height = 50 Offset = Height Graphics 360 + 10 , Height*2 + Offset*2 + 10 , 2 ClsColor 255 , 255 , 255 Color 0 , 0 , 0 Cls Text 0 , 0 , "SIN" Text 0 , Offset + Height , "COS" For PosX = 0 To 360 Step 10 For PosY = 0 To Height*2 + Offset*2 Step 4 Plot PosX , PosY Next Next Line 0 , 0 , 360 , 0 Line 0 , Offset + Height , 360 , Offset + Height Text 0 , Height*2 + Offset*2 , "0" , True , True Text 90 , Height*2 + Offset*2 , "90" , True , True Text 180 , Height*2 + Offset*2 , "180" , True , True Text 270 , Height*2 + Offset*2 , "270" , True , True Text 360 , Height*2 + Offset*2 , "360" , True , True For Position = 0 To 359 Color 0 , 0 , 255 Plot Position , Sin ( Position ) * Height + Offset Color 255 , 0 , 0 Plot Position , Cos ( Position ) * Height + Offset*2 + Height Next WaitKey End Function ;------------------------------------------------------------------------------- Function sine2 () Graphics 300 , 600 , 2 Text 0 , 0 , "Angle" Text 100 , 0 , "Sine" Text 200 , 0 , "(rounded)" pos = 10 For angle = 0 To 360 Step 10 value# = Sin ( angle ) pos = pos + 10 Text 0 , pos , angle Text 100 , pos , value Text 200 , pos , Int value Next WaitKey End Function ;------------------------------------------------------------------------------- Function sine3 () offset = 180 finish = offset + 360 Repeat pos = pos + 1 value# = Sin ( pos + offset ) Plot pos , value * 50 + 50 Until pos + offset >= finish WaitKey End Function ;------------------------------------------------------------------------------- Function sine4 () Graphics 640 , 480 middleX = 320 middleY = 240 radius = 100 ; range Oval middleX - radius , middleY - radius , radius*2 , radius*2 , False ; center point Oval middleX - 5 , middleY - 5 , 10 , 10 , True ; start in center startX = middleX startY = middleY ; direction angle = 123 ; calculate end point endX = Sin ( angle ) * radius + startX endY = Sin ( angle - 90 ) * radius + startY ; draw vector from center Line startX , startY , endX , endY WaitKey End Function ;------------------------------------------------------------------------------- Function sine5 () Graphics 400 , 300 , 2 SetBuffer BackBuffer () middlex = GraphicsWidth () / 2 middley = GraphicsHeight () / 2 radius = 100 Repeat angle = angle + 1 If angle = 360 Then angle = 0 x = Sin ( angle ) * radius y = Sin ( angle - 90 ) * radius SpecialRect middlex , middley , x , y , False Line middlex , middley , middlex + x , middley + y Text 0 , 0 , "Angle: " + angle Flip Cls Until KeyHit ( 1 ) End Function Function SpecialRect ( x1 , y1 , sizex , sizey , filled = True ) x = x1 y = y1 xs = sizex ys = sizey If xs < 0 xs = -xs x = x - xs End If If ys < 0 ys = -ys y = y - ys End If Rect x , y , xs , ys , filled End Function ;------------------------------------------------------------------------------- Function sine6 () Graphics 640 , 480 SetBuffer BackBuffer () middleX = GraphicsWidth () / 2 middleY = GraphicsHeight () / 2 radius = 100 For angle = 0 To 359 Step 5 ; calculate end point X = Sin ( angle ) * radius + middleX Y = Sin ( angle - 90 ) * radius + middleY Plot X , Y Next WaitKey End Function ;------------------------------------------------------------------------------- Function sine7 () Graphics 640 , 480 SetBuffer BackBuffer () middleX = GraphicsWidth () / 2 middleY = GraphicsHeight () / 2 radius = 100 For angle = 0 To 359 Step 5 ; calculate end point endX = Sin ( angle ) * radius + middleX endY = Sin ( angle - 90 ) * radius + middleY ; draw vector from center Line middleX , middleY , endX , endY Next WaitKey End Function ;--> End