Skip to content

Introduction to Vectors

Vectors are a fundamental tool in game development, enabling precise control over movement, collision, and physics. Understanding vectors unlocks the ability to create dynamic and realistic game experiences. SplashKit excels in handling vector operations, offering intuitive functions and robust support for 2D game mechanics.
Written by: Shaun Ratcliff
Last updated: 08 Dec 24

While some Python code has been included in basic functions, full Python code for this tutorial is still in development.


Introduction to Vectors

In programming, vectors are used to represent quantities that have both magnitude and direction. They are used in various applications, including graphics, physics simulations, and game development. This tutorial will guide you through the basics of vectors, their applications, and how to visualise them using SplashKit.

SplashKit Vector Functions Used in This Tutorial

  1. Vector To String
  2. Vector Point to Point

SplashKit Vectors

SplashKit is a powerful game development framework that allows you to create 2D games and simulations with realistic physics. By leveraging SplashKit’s built-in physics engine, developers can create engaging and immersive experiences that mimic the behavior of real-world objects.

Understanding Vectors in SplashKit

One of the key considerations when working with physics in SplashKit is the coordinate system and axis orientation. SplashKit uses a coordinate system where the y-axis is reversed compared to the traditional Cartesian coordinate system. This means that the positive y-direction points downwards, while the positive x-direction points to the right. Developers must keep this in mind when calculating and applying physics-based forces and movements.

SplashKit Axis

Vectors are mathematical constructs used to represent quantities that have both magnitude and direction. Unlike scalars, which only have magnitude (like temperature or mass), vectors can describe more complex concepts like displacement, velocity, and force.

2D vectors are represented in programming as pairs of values (x, y). These values give rise to the two key propertise of vectors:

  • Magnitude - The length or size of the vector.
  • Direction - The orientation of the vector in space.

Where and When to Use Vectors

Vectors are essential in many areas of programming, particularly in:

  • Movement: To represent the direction and speed of an object, such as controlling the path of a character in a game.
  • Forces: In physics simulations, vectors represent forces acting on objects, such as calculating a bullet trajectory.
  • Graphics: For drawing shapes, determining object positions, and performing transformations like scaling or rotating objects.

Vector Usage in Programming

A position vector represents the location of a point in 2D space relative to an origin. For example, consider a point located at coordinates (3, 4). This vector indicates that the point is 3 units to the right and 4 units up from the origin (0, 0).

A velocity vector represents the speed and direction of an object’s motion. For example, if an object is moving to the right and slightly upwards at a speed, it can be represented by the components (5, 2). Here, the vector indicates that the object moves 5 units to the right and 2 units upwards per unit of time.

A force vector represents the magnitude and direction of a force acting on an object. For example, if a force is applied downwards and to the left, it might be represented as (-3, -6). The components indicate that the force has a magnitude directed 3 units to the left and 6 units downwards.

Visualising Vectors

To visualise vectors, we will create a simple program using SplashKit to draw vectors on a Cartesian plane.

We will first need to declare and initialise a vector with some x and y values:

vector_2d my_vector;
my_vector.x = 200;
my_vector.y = 100;
  • vector_2d holds two values, x and y, representing the vector’s coordinates in 2D space.
  • my_vector is an instance of this structure.
  • my_vector.x and my_vector.y specify the vector’s horizontal and vertical components, respectively. In this example, the vector points to a location that is 200 units to the right and 100 units up from the origin (0, 0).

In our code, we can call the vector_to_string function to convert the vector back in to a human-readable string format.

Pulling this all together, we can visualise this vector on a Cartesian plane and view the output of the vector_to_string function on the screen.

Introduction to Vectors

  • The vector is drawn on the grid from the origin (0, 0) to the point (200, 100) on the plane. The output of the vector_to_string function is seen in the top left of the screen with the x and y values.
  • The direction of the vector is represented by the angle that the line makes with the x-axis. This demonstrates how the vector is oriented in 2D space.
  • The magnitude of the vector is represented by the length of the red line.
Use this code in your own IDE to play with the functions for yourself!
#include "splashkit.h"
using std::to_string;
const int GRID_SPACING = 50;
void draw_cartesian_grid()
{
// Draw vertical lines and labels
for (int x = 0; x < screen_width(); x += GRID_SPACING)
{
draw_line(COLOR_LIGHT_GRAY, x, 0, x, screen_height());
if (x != screen_width() / 2) // Avoid overlapping with the y-axis label
{
draw_text(to_string(x - screen_width() / 2), COLOR_BLACK, x, screen_height() / 2 + 5);
}
}
// Draw horizontal lines and labels
for (int y = 0; y < screen_height(); y += GRID_SPACING)
{
draw_line(COLOR_LIGHT_GRAY, 0, y, screen_width(), y);
if (y != screen_height() / 2) // Avoid overlapping with the x-axis label
{
draw_text(to_string(screen_height() / 2 - y), COLOR_BLACK, screen_width() / 2 + 5, y);
}
}
// Draw x-axis and y-axis
draw_line(COLOR_BLACK, 0, screen_height() / 2, screen_width(), screen_height() / 2); // x-axis
draw_line(COLOR_BLACK, screen_width() / 2, 0, screen_width() / 2, screen_height()); // y-axis
// Label the origin
draw_text("0", COLOR_BLACK, screen_width() / 2 + 5, screen_height() / 2 + 5);
}
int main()
{
open_window("Introduction to Vectors", 800, 600);
// Define a vector
vector_2d my_vector;
my_vector.x = 200;
my_vector.y = 100;
// Define the origin (centre of the window)
point_2d origin;
origin.x = 400;
origin.y = 300;
// Main loop
while (!window_close_requested("Introduction to Vectors"))
{
process_events();
clear_screen(COLOR_WHITE);
// Draw Cartesian grid
draw_cartesian_grid();
// Draw the vector as a line from the center of the screen
draw_line(COLOR_RED, origin.x, origin.y, origin.x + my_vector.x, origin.y - my_vector.y);
// Draw the vector_to_string output to the screen
draw_text(vector_to_string(my_vector), COLOR_BLACK, 10, 10);
refresh_screen(60);
}
return 0;
}

Creating Vectors from Points

The vector_point_to_point function is useful because it calculates the vector that represents the direction and distance from one point to another. This functionality is particularly valuable in various applications:

  • Character Movement: In games, this function helps determine the direction and distance a character needs to move to reach a specific destination.
  • Impact Calculations: When detecting collisions or interactions between objects, you can use vector_point_to_point to compute the vector representing the direction of impact.
  • Vector Addition/Subtraction: You can use the resulting vector from vector_point_to_point to perform further vector operations, such as addition or subtraction, to achieve complex transformations.

Let’s see it in action. Suppose we have two points, start and end_pt. To compute the vector from start to end_pt, you can use:

point_2d start = {-100, -150};
point_2d end_pt = {100, 150};
vector_2d v = vector_point_to_point(start, end_pt);

Vector Point to Point

Use this code in your own IDE to play with the functions for yourself!
#include "splashkit.h"
using std::to_string;
const int GRID_SPACING = 50;
void draw_cartesian_grid()
{
// Draw vertical lines and labels
for (int x = 0; x < screen_width(); x += GRID_SPACING)
{
draw_line(COLOR_LIGHT_GRAY, x, 0, x, screen_height());
if (x != screen_width() / 2) // Avoid overlapping with the y-axis label
{
draw_text(to_string(x - screen_width() / 2), COLOR_BLACK, x, screen_height() / 2 + 5);
}
}
// Draw horizontal lines and labels
for (int y = 0; y < screen_height(); y += GRID_SPACING)
{
draw_line(COLOR_LIGHT_GRAY, 0, y, screen_width(), y);
if (y != screen_height() / 2) // Avoid overlapping with the x-axis label
{
draw_text(to_string(screen_height() / 2 - y), COLOR_BLACK, screen_width() / 2 + 5, y);
}
}
// Draw x-axis and y-axis
draw_line(COLOR_BLACK, 0, screen_height() / 2, screen_width(), screen_height() / 2); // x-axis
draw_line(COLOR_BLACK, screen_width() / 2, 0, screen_width() / 2, screen_height()); // y-axis
// Label the origin
draw_text("0", COLOR_BLACK, screen_width() / 2 + 5, screen_height() / 2 + 5);
}
int main()
{
open_window("Vector Point to Point Example", 800, 600);
point_2d start = {-100, -150};
point_2d end_pt = {100, 150};
vector_2d v = vector_point_to_point(start, end_pt);
while (!window_close_requested("Vector Point to Point Example"))
{
process_events();
clear_screen(COLOR_WHITE);
// Draw Cartesian grid
draw_cartesian_grid();
// Draw the vector as a line from start to end point
draw_line(COLOR_RED, start.x + screen_width() / 2, screen_height() / 2 - start.y,
end_pt.x + screen_width() / 2, screen_height() / 2 - end_pt.y);
// Draw labels for the start and end points
draw_text("Start (" + to_string(start.x) + ", " + to_string(start.y) + ")", COLOR_BLACK,
start.x + screen_width() / 2 + 5, screen_height() / 2 - start.y + 5);
draw_text("End (" + to_string(end_pt.x) + ", " + to_string(end_pt.y) + ")", COLOR_BLACK,
end_pt.x + screen_width() / 2 + 5, screen_height() / 2 - end_pt.y + 5);
// Draw the vector_to_string output to the screen
draw_text("Vector: " + vector_to_string(v), COLOR_BLACK, 10, 10);
refresh_screen(60);
}
return 0;
}

Conclusion

Vectors are an exciting concept in programming that help us represent and manipulate quantities with both magnitude and direction. From positioning objects in 2D space to simulating movement and forces, understanding vectors helps us to create dynamic and interactive applications.