Make sure you understand the tutorial before doing this lab.

For-each loops

The scripting panel will be the focus of this lab. Feel free to re-read the scripting section of the tutorial, or keep it open for reference.

Using the scripting engine, how would you print all the numbers from 1 to 5? You could write:

print(1);
print(2);
print(3);
print(4);
print(5);

However, most programming languages have loops, which allow us to repeat code many times.

The main type of loop we'll use in this class is the for-each loop, which runs code for every element (a.k.a item) in a list. This is usually called "iterating" over a list.

For example, to print the numbers from 1 to 5, we could instead write:

for i in [1, 2, 3, 4, 5] {
    print(i);
}

A useful note is that Rhai has special syntax for ranges, so 1..5 == [1, 2, 3, 4, 5].

Let's use this knowledge to find the sum of every number from 1 to 100:

let total = 0;
for i in 1..100 {
    total = total + i;
}

print(total);

For-each loops are a very common kind of loop. However, two other common kinds are for loops and while loops.

while loops are important because they can be used to keep executing some code forever. This is how the update function is run by the engine every frame.

Iterating over Bodies

First, create some bodies by clicking the 'Create' button in the top left or by pressing your 'c' key, then clicking and dragging. You'll want a few bodies with close to zero velocity for the next step.

The basic update function looks like this:

let update = |ids, bodies| {
};

You may have noticed the ids and bodies parameters. In this class, we'll primarily use ids, which contains the ID of every body in the simulation. The engine grabs the ID of every body in the simulation and calls this function on them each frame.

As with the last lab, we can use these IDs to interact with the bodies through the scripting engine.

For example, what does this code do?

let update = |ids, bodies| {
    for body in ids {
        body.add_pos(vec(5.0, 0.0));
    } 
};

Position Update

Start with a clear scene. The engine has a function called set_integration that can enable or disable the engine's integration. Try the following script:

set_integration(false);

Now, try creating bodies with different velocities. They'll just stand still. However, if you click them, you can see that they do have a velocity. Because the engine's integration system is disabled, you'll have to implement position update yourself in the scripting engine.

In class, you learned that:

x_f = x_0 + v_0 * dt

You can get the dt of the engine using the function DT().

Using this equation, fill in the following script to implement the position update function:

set_integration(false);

let update = |ids, bodies| {
    for id in ids {
        let x_0 = id.get_pos();
        let v_0 = id.get_vel();
        let dt = DT();

        let x_f = ???;

        id.set_pos(x_f);
    }
}

Once you're done, try instantiating more bodies. You can try colliding them too. However, since we've implemented only position update and not velocity update, gravity won't work properly and it will be impossible to create an orbit.