The wonderful world of Vectors

  • Construct doesn't have any implimentation of Vectors...yet.... but anyways I thought I might write a quick article about them and how they can be useful for doing maths.

    Basically, a vector is like a position on your screen. It has an x component, and a y component. Similarily, it also usually has the ability to retrieve additional information, such as the length of the vector, and the angle of the vector. A vector can be graphically represented as an arrow like this:

    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/vector.png">

    So...lets look at an example where vector maths could be useful..

    Suppose we are making a sling shot....

    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/1.png">

    Lets think of some rules. Firstly...at rest, the player is in the middle.

    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/2.png">

    Secondly, we limit how far the user can drag the player by a radius. Lets call it 'drag_radius'

    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/3.png">

    So at this point...how would we do it using X and Y values?

    We would probably declare some variable:

    middleX = 100
    middleY = 50
    
    dragRadius = 50
    
    playerX = mouseX
    playerY = mouseY
    
    if distance between playerX, playerY, middleX, middeY is greater than dragRadius
    	angle = angle(middleX, middleY)
    	playerX = middleX + cos(angle) * dragRadius
    	playerY = middleY + sin(angle) * dragRadius
    [/code:32j3851s]
    
    So already, the code is getting a bit messy. You have sin and cos, and angle and distance formulars around the place. 
    
    Now, lets have a look at how we would do it using vectors.
    
    [code:32j3851s]
    middleXY = {100,50}
    dragRadius = 50
    offsetXY = mouseXY - middleXY
    
    if differenceXY.length is greater than dragRadius
    	differenceXY.length = dragRadius
    	
    playerXY = offsetXY + middleXY
    [/code:32j3851s]
    
    Okay, so we've done things a bit differently with the vectors. OffsetXY is a vector representing the offset of the player from the middle. If the length of offset is larger than dragRadius, we force the length to change to dragRadius
    
    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/4.png">
    
    So in this picture, the black arrow represents what offsetXY is, and the blue one represents what it becomes when we change its length to drag radius
    
    Okay now lets get a bit more complicated.
    
    Suppose we want to make it so the angle that the player fires towards is inbetween the two elastic bands...how would we go about doing that?
    
    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/5.png">
    
    Well, we need to declare some more variables, such as the position of the left and right pins that hold the elastic band.
    
    [code:32j3851s]
    leftPinX = 0
    leftPinY = 50
    rightPinX = 200
    rightPinY = 50
    middleX = 100
    middleY = 50
    
    playerX = ...
    playerY = ...
    
    playerToLeftPinAngle = angle(playerX, playerY, leftPinX, leftPinY)
    playerToRightPinAngle = angle(playerX, playerY, rightPinX, rightPinY)
    
    -- The only way to find the average between two angles to to convert them into component form, add them together, then find the angle
    
    playerToLeftPinX = cos(playerToLeftPinAngle)
    playerToLeftPinY = sin(playerToLeftPinAngle)
    
    playerToRightPinX = cos(playerToRightPinAngle)
    playerToRightPinY = sin(playerToRightPinAngle)
    
    playerShootAngle = angle(0,0, playerToLeftPinX + playerToRightPinX, playerToLeftPinY + playerToRightPinY)
    [/code:32j3851s]
    
    Now lets have a look at how this could be done using vectors
    
    [code:32j3851s]
    leftPinXY = {0, 50}
    middleXY = {100,50}
    rightPinXY = {200, 50}
    playerXY = {..., ...}
    
    playerToLeftPin = leftPinXY - playerXY
    playerToRightPin = rightPinXY - playerXY
    
    playerToLeftPin.length = 1
    playerToRightPin.length = 1
    
    playerShoot = playerToLeftPin + playerToRightPin
    playerShootAngle = playerShoot.angle
    [/code:32j3851s]
    
    So basically...in terms of vectors...we have something like this picture:
    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/6.png">
    
    So playerToLeftPin and playerToRightPin are the black vectors, and the one we want to find is the red one.
    
    By adding them together we can find the red one:
    <img src="http://dl.dropbox.com/u/939828/Tutorial/Vector/7.png">
    
    So yeah, thats pretty much what vectors can do. I personally love vectors because they are easy to visualise as arrows so its kind of a more 'arty' approach to thinking of positions and speeds etc.
  • Some expressions might be nice for this.

    Im thinkin v(x1,y1,x2,y2,a,l)?

    Edit:

    Oh wait you'd need a third x,y right?

  • Well you can use arrays in construct as {1,2} etc.

    So perhaps you have a private variable in your sprite called 'speed' and u set it to {1,2}... but then you want to set the length of that variable...

    All I can think of is something like:

    Set value 'speed' to vector.setLength('speed',10)

    .. so like...have:

    vector.setX

    vector.setY

    vector.setLength

    vector.setAngle

    and

    vector.x

    vector.y

    vector.length

    vector.angle

    and then some operational functions

    vector.add( v1, v2)

    vector.multiply(v1, v2)

    vector.subtract(v1, v2)

    vector.divide(v1, v2)

    vector.dot(v1, v2)

    vector.lerp(v1, v2, r)

    vector.distance(v1, v2)

    and some creational functions

    vector.left()

    vector.right()

    vector.up()

    vector.down()

    vector.one()

    vector.zero()

    and overloading the default expression i could make:

    vector(1,2)

    create the actual vector

    Shall I quickly program this and see how it goes?

  • Man Vector graphics in Construct would be sweet - my buddy draws his images in Illustrator for Construct, I love the vector 'look' though when we import in the images we can't scale them very well.

  • Man Vector graphics in Construct would be sweet - my buddy draws his images in Illustrator for Construct, I love the vector 'look' though when we import in the images we can't scale them very well.

    this is vector math, not the same thing as GFX

  • Vectors are immensely useful, especially in planned-but-not-realized space-opera-ish game.

  • > Man Vector graphics in Construct would be sweet - my buddy draws his images in Illustrator for Construct, I love the vector 'look' though when we import in the images we can't scale them very well.

    >

    this is vector math, not the same thing as GFX

    Nice try tho

    Shall I quickly program this and see how it goes?

    Something tells me you've already done it.

    Btw what does vector.dot mean?

  • Vector product, I guess?

  • dot product.

    Oh ignore 'cross' theres no such thing for 2d vectors.

    I made a plugin immediately after the post...only to realise you cant store arrays in private variables without a crash...bloody developers should fix that bug!

    ...

    oh wait...I'm a developer...F**K

  • ...only to realise you cant store arrays in private variables without a crash...bloody developers should fix that bug!

    Now there's a bug that WILL get fixed!

  • Vector math functions would be very usefull in playing with advanced physics.

    BTW: I would also want to see vector graphics implementation in scirra, any plans on it?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I've got a request davo,

    Can you overload some of the stuff so you can use sprite names in quotes in place of x,y as a shortcut to sprite.x,sprite.y?

  • lucid what do u mean? Can u give an example?

  • You know, reading the original post again, I suppose my request makes no sense, since you'll always be referring to the vector as a single value, rather than an xy pair. I think I misunderstood when I posted that

    The only instance where it makes sense would be to be able to set vector position to a sprite position,

    So aside from actions:

    Set vectorx to sprite.x

    Set vectory to sprite.y

    Just set vector position to object - sprite

    Also the regular angle actions would be convenient, too like

    Set angle towards position, or towards object

  • Ah I see, so

    Set position of head to 'player'

    Set angle of head to 'player'

    Set width of head to 'player'

    Set height of head to 'player'

    In all those cases, the word 'player' would become:

    player.position

    player.angle

    player.width

    player.height

    Thats actually a pretty cool idea, however, some plugins do overload their names, so using 'TextBox' infact means 'TextBox.text'

    Still, thats a pretty interesting idea anyways. Perhaps an action such as 'width' can have some kind of declaration to describe to other plugins which expression they should attempt to use...eg:

    for the action 'setWidth', if other object has a '.width' expression, use that when you type 'Sprite'

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)