Games.NitroFlox.com

++ Tutorials Section

This section contains some basic tutorials writen in JS (javascript) or C# (Windows Form App / Unity 2D).

++ Simple 2D Vector Object

Q: What is a vector?

A: Simply put, it is a mathematical object that represents direction and magnitude.


You use vectors in computer graphics and game development to represent positions, velocities, forces/accelerations, so on and so forth in 2D or 3D space. In the case of this tutorial, it will be in a 2D space.

What exactly do we need for a vector class in 2D game development? Well, in the case of JavaScript, we need an object that can return a new instance of a vector with x and y properties. Let's start by creating a new function that takes in two arguments, an _x, the horizontal value of the vector, and a _y, the vertical value.



Vector Object Example:

                        
function Vector(_x, _y)
{
    if(arguments.length == 0)
    {
	_x = 0;
	_y = 0;
    }

    this.x = _x;
    this.y = _y;
};
                        
                    

In the example above, we have a function that can be invoked with the [new] keyword. If you decide to no add any arguments, the object created is a Vector at position (0, 0), otherwise it will assign (x, y) position to the object.


When you write code in C#, you can overload operators to simplify calculations with vectors, but JavaScript does not allow you to do operations on vectors using mathematical operators such as +, -, x or /. So we need to add helper methods to our Vector object.


Operators Example:

                        
Vector.prototype.add = function(v, arg = false)
{
    if(arg) return new Vector(this.x + v.x, this.y + v.y);
    this.x += v.x;
    this.y += v.y;
};

Vector.prototype.subtract = function(v, arg = false)
{
    if(arg) return new Vector(this.x - v.x, this.y - v.y);
    this.x -= v.x;
    this.y -= v.y;
};

Vector.prototype.multiply = function(n, arg = false)
{
    if(arg) return new Vector(this.x * n, this.y * n);
    this.x *= n;
    this.y *= n;
};

Vector.prototype.divide = function(n, arg = false)
{
    if(arg) return new Vector(this.x / n, this.y / n);
    this.x /= n;
    this.y /= n;
};
                        
                    

In the example above we have four helper methods to add, subtract, multiply and divide Vector objects respectivly. Setting the second argument to true will return a new instance of the Vector after the calculations.


Code Example:

                        
let position = new Vector(0, 0);
let velocity = new Vector(2, 3);
let gravity = new Vector(0, 9.81);

position.add(gravity); // position is now (0, 9.81).
let newPosition = position.add(velocity, true); // newPosition is (2, 12.81), and position remains (0, 9.81).
                        
                    

Most of the time you need to know the angle or magnitude of the vector, and instead of having to calculate it manually each time it is good practice to have helper methods for getting set values. You can use JavaScript getters/setters or just have methods in the Vector object itself. I will show you both in the next example.


Helper Methods Example:

                        
Vector.prototype.getLength = function()
{
    // The length or magnitude is simply the hypotenuse of a right angle triangle.
    return Math.sqrt(this.x * this.x + this.y * this.y);
}

Vector.prototype.setLength = function(length)
{
    let angle = this.getAngle();
    this.x = Math.cos(angle) * length;
    this.y = Math.sin(angle) * length;
}

Vector.prototype.getAngle = function()
{
    return Math.atan2(this.y, this.x);
}

Vector.prototype.setAngle = function(angle)
{
    let length = this.getLength();
    this.x = Math.cos(angle) * length;
    this.y = Math.sin(angle) * length;
}
                        
                    

Getter/Setter Example:

                        
Object.defineProperty(Vector, "Length", {
	get : function() { return Math.sqrt(this.x * this.x + this.y * this.y); }
	set : function(length) {
	    let angle = this.Angle;
	    this.x = Math.cos(angle) * length;
	    this.y = Math.sin(angle) * length;
	}
});

Object.defineProperty(Vector, "Angle", {
	get : function() { return Math.atan2(this.y, this.x); }
	set : function(angle) {
	    let angle = this.Length;
	    this.x = Math.cos(angle) * length;
	    this.y = Math.sin(angle) * length;
	}
});
                        
                    

N.B.: Invoking the methods and calling the getter/setter work differently, but both are efficient.


Code Example:

                        
let position = new Vector(3, 5);

// method
let mag = position.getLength();
position.setLength(3.14);

// getter/setter
let angle = position.Angle;
position.Angle = Math.PI / 3;
                        
                    

Finally we can add a few more methods to help with vector calculations. This includes methods to be used with the vector object, as well as static methods to be used for vector calculations.


AngleTo() Example:

                        
Vector.prototype.AngleTo = function(v)
{
    return Math.atan2(v.y - this.y, v.x - this.x);
}
                        
                    

Normalize() Example:

                        
Vector.prototype.Normalize = function()
{
    let length = this.getLength();
    if(length > 0)
    {
	return this.Divide(length, true);
    }
    else
    {
	return new Vector();
    }
}
                        
                    

Negative() Example:

                        
Vector.prototype.Negative = function()
{
   return new Vector(-this.x, -this.y);
}
                        
                    

Equals() Example:

                        
Vector.prototype.Equals = function(v)
{
   return this.x === v.x && this.y === v.y;
}
                        
                    

Copy() Example:

                        
Vector.prototype.Copy = function()
{
   return new Vector(this.x, this.y);
}
                        
                    

In the example above, there are five helper methods.

AngleTo() - Gets the angle between two vectors.

Normalize() - Returns the vector, but normalized (values between 0 and 1).

Negative() - Returns the negative of a vector.

Equals() - Checks if two vectors are the same.

Copy() - Copies the vector.



Finally we have three static methods to add to the Vector object. These methods are important when calculating collisions in a 2D environment.


Static Methods Example:

                        
// Vector.DistanceBetween is useful for knowing the distance between two vectors.
Vector.DistanceBetween = function (v1, v2){
   let x = v1.x - v2.x;
   let y = v1.y - v2.y;
   return Math.sqrt(x * x + y * y);
}

// Vector.Cross returns the cross product of two vectors.
Vector.Cross = function(v1, v2){
   return v1.x * v2.y - v1.y * v2.x;
}

// Vector.Dot returns the dot product of two vectors.
Vector.Dot = function(v1, v2){
   return v1.x * v2.x + v1.y * v2.y;
}
                        
                    
$_GET: 
Array ( [url] => tutorials )