diff --git a/content/06_libraries.html b/content/06_libraries.html index 2e4ed77e..00ef729b 100644 --- a/content/06_libraries.html +++ b/content/06_libraries.html @@ -1005,7 +1005,7 @@

Collision Events

Step 3: Bodies, could you tell me which particles you’re associated with?

Getting from the relevant Matter.js bodies to the Particle objects they’re associated with is a little harder. After all, Matter.js doesn’t know anything about my code. Sure, it’s doing all sorts of stuff to keep track of the relationships between bodies and constraints, but it’s up to me to manage my own objects and their associations with Matter.js elements. That said, every Matter.js body is instantiated with an empty object—{ }—called plugin, ready to store any custom data about that body. I can link the body to a custom object (in this case, a Particle) by storing a reference to that object in the plugin property.

Take a look at the updated constructor in the Particle class where the body is made. Note that the body-making procedure has been expanded by one line of code to add a particle property inside plugin. It’s important to make sure you’re adding a new property to the existing plugin object (in this case, plugin.particle = this) rather than overwriting the plugin object (for example, with plugin = this). The latter could interfere with other features or customizations.

-
+
class Particle {
 
   constructor(x, y, radius) {
diff --git a/content/07_ca.html b/content/07_ca.html
index f533248f..f3f66cec 100644
--- a/content/07_ca.html
+++ b/content/07_ca.html
@@ -431,7 +431,7 @@ 

The Game of Life

In 1970, Martin Gardner wrote a Scientific American article that documented mathematician John Conway’s new Game of Life, describing it as recreational mathematics: “To play life you must have a fairly large checkerboard and a plentiful supply of flat counters of two colors. It is possible to work with pencil and graph paper but it is much easier, particularly for beginners, to use counters and a board.”

The Game of Life has become something of a computational cliché, as myriad projects display the game on LEDs, screens, projection surfaces, and so on. But practicing building the system with code is still valuable for a few reasons.

For one, the Game of Life provides a good opportunity to practice skills with 2D arrays, nested loops, and more. Perhaps more important, however, this CA’s core principles are tied directly to a core goal of this book: simulating the natural world with code. The Game of Life algorithm and technical implementation will provide you with the inspiration and foundation to build simulations that exhibit the characteristics and behaviors of biological systems of reproduction.

-

Unlike von Neumann, who created an extraordinarily complex system of states and rules, Conway wanted to achieve a similar lifelike result with the simplest set of rules possible. Gardner outlined Conway’s goals as follows:

+

Unlike von Neumann, who created an extraordinarily complex system of states and rules, Conway wanted to achieve a similar lifelike result with the simplest set of rules possible. Gardner outlined Conway’s goals as follows.

  1. There should be no initial pattern for which there is a simple proof that the population can grow without limit.
  2. There should be initial patterns that apparently do grow without limit.
  3. @@ -571,7 +571,6 @@

    The Implementation

    Putting this all together:

    // The next board
     let next = create2DArray(columns, rows);
    -
     //{!2} Loop but skip the edge cells.
     for (let i = 1; i < columns - 1; i++) {
       for (let j = 1; j < rows - 1; j++) {
    @@ -585,7 +584,6 @@ 

    The Implementation

    } // Correct by subtracting the cell state. neighborSum -= board[i][j]; - //{!4} The rules of life! if (board[i][j] === 1 && neighborSum < 2) next[i][j] = 0; else if (board[i][j] === 1 && neighborSum > 3) next[i][j] = 0; @@ -593,7 +591,6 @@

    The Implementation

    else next[i][j] = board[i][j]; } } - board = next;

    Now I just need to draw the board. I’ll draw a square for each spot: white for off, black for on.

    diff --git a/content/08_fractals.html b/content/08_fractals.html index 9b901a0f..e2686eaa 100644 --- a/content/08_fractals.html +++ b/content/08_fractals.html @@ -117,12 +117,12 @@

    Implementing Recursive Functions

    return n * factorial(n - 1); } }
+

The factorial() function calls itself within its own definition. It may look a bit odd at first, but it works, as long as a stopping condition exists (in this case, n <= 1) so the function doesn’t get stuck calling itself forever. (I’m using <= instead of === as a safeguard against infinite recursion, but I should probably include additional error checking to manage noninteger or negative inputs to be more mathematically accurate.) Figure 8.7 illustrates the steps that unfold when factorial(4) is called.

+

The function keeps calling itself, descending deeper and deeper down a rabbit hole of nested function calls until it reaches the stopping condition. Then it works its way up out of the hole, returning values until it arrives back home at the original call of factorial(4).

Figure 8.7: Visualizing the process of calling the recursive factorial() function
Figure 8.7: Visualizing the process of calling the recursive factorial() function
-

The factorial() function calls itself within its own definition. It may look a bit odd at first, but it works, as long as a stopping condition exists (in this case, n <= 1) so the function doesn’t get stuck calling itself forever. (I’m using <= instead of === as a safeguard against infinite recursion, but I should probably include additional error checking to manage noninteger or negative inputs to be more mathematically accurate.) Figure 8.7 illustrates the steps that unfold when factorial(4) is called.

-

The function keeps calling itself, descending deeper and deeper down a rabbit hole of nested function calls until it reaches the stopping condition. Then it works its way up out of the hole, returning values until it arrives back home at the original call of factorial(4).

You can apply the same recursive principle illustrated by the factorial() function to graphics in a canvas, only instead of returning values, you draw shapes. This is precisely what you’ll see in the examples throughout this chapter. To begin, here’s a simple recursive function that draws increasingly smaller circles.

Example 8.1: Recursive Circles Once

diff --git a/content/examples/06_libraries/6_1_default_matter_js/sketch.js b/content/examples/06_libraries/6_1_default_matter_js/sketch.js index 296ae58f..bbed175a 100644 --- a/content/examples/06_libraries/6_1_default_matter_js/sketch.js +++ b/content/examples/06_libraries/6_1_default_matter_js/sketch.js @@ -10,7 +10,6 @@ function setup() { // Make the Engine let engine = Engine.create(); - engine.gravity.set(1, 0); let render = Matter.Render.create({ canvas: canvas.elt,