Tutorial 14: An Introduction to Vectors

Strap your focusing hats on, because we're about to cover something quite tricky. If you can get your head around this, you've just seriously leveled up. As always, getting the hang of using a new technique means practising and writing your own programs which use them. It's highly recommended that you have read the screen coordinates tutorial project before trying this one. If you're already comfortable with this, please go right on ahead!

With all that said and done, we should probably introduce the topic. This tutorial is about vectors. What they are, why they're useful, and some simple things we can do to begin using them.

We will only be covering the very basic parts of using vectors in this tutorial, for more advanced information on vectors in FUZE, check out the next vector project!

Vec-what?!

What is a vector? Well... to put it as simply as possible:

A vector is multiple numbers treated as one thing.

Let's go into a little more detail.

Some things in life can be described with a single measurement. Take temperature, for example. Temperature is only a measurement of heat. Nothing else.

We call things like this scalars. Height, weight, volume (both types - loudness and quantity!) are all examples of scalars.

But... What if we wanted to describe something like position? We live in 3 dimensions, so describing the position of something by just using a single number wouldn't give us very much information!

Let's take the example of a circle right in the middle of our screen. Here's some code to make that happen:

  1. loop
  2.     clear()
  3.
  4.     circle( gWidth() / 2, gHeight() / 2, 100, 16, white, false )
  5.
  6.     update()
  7. repeat

Simple enough! We have a single loop which just puts a circle on the screen in one place.

We put the circle at gwidth() / 2, gheight() / 2 which is exactly in the middle of our screen.

Now, if somebody asked: "Hey... Where's that circle?", and we answered with a only single dimension: "It's at gwidth divided by 2"... Do you see the problem?

The center of the circle is gwidth() / 2 on the x axis and gheight() / 2 on the y axis. This means that it is exactly at the intersection of the following straight lines:

  • vertical (parallel to the y axis) which crosses the x axis in gwidth() / 2 and
  • horizontal (parallel to the axis x) which crosses the axis y in gheight() / 2.

These two indications are essential to locate the point. If only one coordinate is used then all the points constituting the associated straight line are designated. One coordinate is not enough to locate a point on the screen!

Did you know? This way of representing coordinates is referred to as “cartesian”, and was invented in the 17th century by René Descartes to provide a link between euclidean geometry (also called 'plane' or 'flat' geometry) and algebra.

A vector tells us both pieces of information at the same time.

Using a Vector in a Program

We can set up a vector very easily, and use it to put our circle on screen again. Check out the code using a vector instead.

  1. position = { gWidth() / 2, gHeight() / 2 }
  2. 
  3. loop
  4.     clear()
  5.
  6.     circle( position.x, position.y, 100, 16, white, false )
  7.
  8.     update()
  9. repeat

As you can see, line 1 defines a variable called position. This variable stores a pair of coordinates in curly brackets {}.

Look out for these curly brackets! If you see some curly brackets in any FUZE code, you know it's a vector!

The clever part about vectors in FUZE4 Nintendo Switch is that we can simply define a variable as a vector, put what we want in the curly brackets, and FUZE will set up a structure with x and y properties. In our example, we now have position.x and position.y.

"But it does exactly the same thing!" we hear you scream. Well, yes this is true. But it's what we can do with this that counts.

Using Vectors to Move a Circle

Remember in the screen tutorial project, we learned how to move a circle around the screen by changing its x and y location using variables? In this tutorial, we'll be taking this project to the next level.

Because vectors are multiple numbers treated as one thing, we can apply one operation to the whole vector and things will work just fine. Check this out:

  1. position = { gWidth() / 2, gHeight() / 2 }
  2. 
  3. loop
  4.     clear()
  5.    
  6.     joy = controls( 0 )
  7.     position += { joy.lx, -joy.ly } * 8
  8.
  9.     circle( position.x, position.y, 100, 16, white, false )
 10.
 11.     update()
 12. repeat

Look at that neat code!

Instead of having separate variables to store the x and y position and operating on them separately, we can simply add the value of the Joy-Con left control stick to the whole position vector. Notice we are adding both the joy.lx and joy.ly value together in a vector also.

We have multiplied this vector by 8 to increase the movement speed, otherwise we get a very slow movement!

Remember, because the y axis is 0 at the top of the screen and gheight() at the bottom, we must use a minus sign (-) before joy.ly to make the circle move up when we push the control stick upwards.

Just to break this down even further, line 7 is taking each part of the position vector, adding the the joy.lx value to position.x and joy.ly to position.y.

It's really two lines of code in one!

Let's make this movement slightly more advanced, since we are leveling up in this tutorial after all.

Currently, when we let go of the control stick, our circle stops immediately. This might be what we want sometimes, but it is more realistic and certainly more satisfying to have a nice slow down effect.

We can achieve this with a few more lines of code, and with vectors it becomes neater than ever.

To achieve a slowdown effect, we need something called velocity. Change your code to look like the program below:

  1. position = { gWidth() / 2, gHeight() / 2 }
  2. velocity = { 0, 0 }
  3. slowdown = 0.9
  4. loop
  5.     clear()
  6.    
  7.     joy = controls( 0 )
  8.     velocity += { joy.lx, -joy.ly } * 8
  9.     position += velocity
 10.     velocity *= slowdown
 11.    
 12.     circle( position.x, position.y, 100, 16, white, false )
 13.    
 14.     update()
 15. repeat  

We now have another variable at the beginning of the program called velocity. This variable stores a Zero vector ({ 0, 0 }).

On line 8, you can see that rather than increasing the position variable by the control stick values, we increase the velocity vector instead. Separating things like this allows us to control how much deceleration (slowdown) we want to occur when we let go of the stick.

On line 10, we apply a multiplication to the velocity vector. By multiplying by slowdown every time the loop repeats, we are constantly reducing the value of each component of the vector. This only truly takes effect when we let go of the stick however, because if we are pushing the stick in a direction we are continually reading the value and applying it.

As soon as we let go, line 10 takes becomes much more visually apparent, and the amount of velocity applied to the circle's position begins decreasing. We see this as a slow down effect.

To make sense, the value of the slowdown variable can be changed from 0 to 1. The closer the value is to 0, the more noticeable the effect is. At 0 the stop is immediate. When the value approaches 1, the slowdown becomes less and less apparent. At 1, no slowdown applies.

Colours as Vectors

You may or may not know this, but all colours on a screen are created using a mix of red, green and blue light.

When we set up a vector, we know that FUZE gives us a structure with a .x and a .y. Actually, FUZE automatically creates a .z and a .w in addition to these, giving us 4 total values. If we do not define these values ina vector, they default to 0.

The cool thing about vectors in FUZE4 Nintendo Switch is that it also allows us to access these 4 numbers with .r, .g, .b and .a, standing for red, green, blue and alpha respectively.

This means we can use a vector as a colour! We can specify the amount of each colour, and a transparency (alpha).

These numbers are between 0 and 1, with 0 being no colour at all and 1 being maximum. Let's take the colour red for example.

In FUZE4 Nintendo Switch, the word red is really a label for the vector {1, 0, 0, 1}, for maximum red, no green or blue, and full opacity.

Let's say we wanted to create a colour of our very own. Check out the example below:

  1. col = { 0.5, 0.8, 0.1, 1 }
  2.
  3. loop
  4.     clear( col )
  5.     update()
  6. repeat

Here we set up a vector on line 1, then use a simple loop to clear the screen with our colour. A nice mint green!

If we wanted to increase the amount of blue in the colour during the loop, we could do something like this:

  1. col = { 0.5, 0.8, 0.1, 1 }
  2.
  3. loop
  4.     clear( col )
  5.     col.b += 0.001
  6.     update()
  7. repeat

Run the program to see our mint green colour gently shift into a light blue. Very nice!

Recap

A vector is multiple numbers treated as one thing.

You can notice them easily whenever you spot curly brackets {}.

We use them for all kinds of things. Mainly, they are used for position and colour.

This tutorial covers only the very basics of how to use vectors in a program. Using vectors gives us access to some very impressive and useful maths, but this is something we'll dive into later.

If we want objects to bounce off each other as they would in the real world, vectors make this much easier. However, this is much too complicated for an introduction to vectors, so we'll dive into that at a later time.

Well done. We're getting advanced now! Try setting up your own vectors in your projects and use them to control the position of objects, or to change the colour of certain things. Getting the hang of this will really open up a world of experimentation!

See you in the next tutorial!

Functions and Keywords used in this tutorial

circle(), clear(), loop, repeat, update()