epubjs
Version:
Render ePub documents in the browser, across many devices
748 lines (410 loc) • 25 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="utf-8"/>
<title>Getting Started with Processing</title>
<script type="text/javascript">
if(!window.atlasplugins) window.atlasplugins = {}
atlasplugins.codeMirrorSettings = {
theme: "3024-day"
}
</script>
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css"> </link>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> </script>
<link rel="stylesheet" type="text/css" href="theme/html/html.css"/>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/4.4.0/codemirror.min.css"/>
<link rel="stylesheet" type="text/css" href="https://d2uogd9jz9k9zm.cloudfront.net/processingjs-0.0.3.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js" type="text/javascript"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/4.4.0/codemirror.min.js" type="text/javascript"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/4.5.0/mode/clike/clike.min.js" type="text/javascript"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js" type="text/javascript"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/processing.js/1.4.8/processing.min.js" type="text/javascript"> </script>
<script src="https://d2uogd9jz9k9zm.cloudfront.net/processingjs-0.0.3.min.js" type="text/javascript"> </script>
<script type="text/javascript">
$(function() {
// Make all non runnable examples readonly codemirrors
$('pre:not(*[data-executable], .CodeMirror pre)').each(function(i, el) {
var textArea = $('<textarea>' + el.innerHTML + '</textarea>')
$(el).replaceWith(textArea);
var editor = CodeMirror.fromTextArea(textArea[0], {
mode: "text/x-java",
theme: "3024-day",
readOnly: true,
viewportMargin: 0
});
});
});
</script>
<style type="text/css">
/* This needs to come last to set auto height, and html.css is always included first */
.CodeMirror {
height: auto;
font-size: 14px;
padding: 15px;
border-radius: 5px;
}
.CodeMirror-scroll {
overflow-y: hidden;
overflow-x: auto;
height: auto;
}
</style>
<script type="text/javascript" src="theme/html/epub.js"> </script>
<script type="text/javascript" src="theme/html/reader.js"> </script>
</head>
<body data-type="book" id="viewer">
<section data-type="chapter" data-pdf-bookmark="Chapter 10. Arrays" id="arrays">
<h1>Arrays</h1>
<p>We’ve introduced new programming ideas in each chapter (variables, functions, objects) and now we’ve come to the last step—arrays! An <em>array</em> is a list of variables that share a common name. Arrays are useful because they make it possible to work with more variables without creating a new name for each. This makes the code shorter, easier to read, and more convenient to update.</p>
<section data-type="sect1" data-pdf-bookmark="PROD: Insert Section Title Here" id="example_10-1_colon_many_variables">
<h1>PROD: Insert Section Title Here</h1>
<section data-type="sect2" data-pdf-bookmark="Example 10-1: Many Variables" id="example_10-1_colon_many_variables-id1">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_01">Example 10-1: Many Variables</a></h2>
<p>To see what we mean, refer to <a data-type="xref" href="ch07.html#example_7-3_colon_move_a_shape">“<a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_07_03">Example 7-3: Move a Shape</a>”</a>. This code works fine if we’re moving around only one shape, but what if we want to have two? We need to make a new <em>x</em> variable and update it within <em>draw()</em>:</p>
<figure>
<img src="images/Ex_10_01.png" alt="Ex 10 01"/>
<figcaption/>
</figure>
<pre data-type="programlisting" data-code-language="processingjslive">float x1 = -20;
float x2 = 20;
void setup() {
size(240, 120);
smooth();
noStroke();
}
void draw() {
background(0);
x1 += 0.5;
x2 += 0.5;
arc(x1, 30, 40, 40, 0.52, 5.76);
arc(x2, 90, 40, 40, 0.52, 5.76);
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-2: Too Many Variables" id="example_10-2_colon_too_many_variables">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_02">Example 10-2: Too Many Variables</a></h2>
<p>The code for the previous example is still manageable, but what if we want to have five circles? We need to add three more variables to the two we already have:</p>
<figure>
<img src="images/Ex_10_02.png" alt="Ex 10 02"/>
<figcaption/>
</figure>
<pre data-type="programlisting" data-code-language="processingjslive">float x1 = -10;
float x2 = 10;
float x3 = 35;
float x4 = 18;
float x5 = 30;
void setup() {
size(240, 120);
smooth();
noStroke();
}
void draw() {
background(0);
x1 += 0.5;
x2 += 0.5;
x3 += 0.5;
x4 += 0.5;
x5 += 0.5;
arc(x1, 20, 20, 20, 0.52, 5.76);
arc(x2, 40, 20, 20, 0.52, 5.76);
arc(x3, 60, 20, 20, 0.52, 5.76);
arc(x4, 80, 20, 20, 0.52, 5.76);
arc(x5, 100, 20, 20, 0.52, 5.76);
}</pre>
<p>This code is starting to get out of control.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-3: Arrays, Not Variables" id="example_10-3_colon_arrays_comma_not_vari">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_03">Example 10-3: Arrays, Not Variables</a></h2>
<p>Imagine what would happen if you wanted to have 3,000 circles. This would mean creating 3,000 individual variables, then updating each one separately. Could you keep track of that many variables? Would you want to? Instead, we use an array:</p>
<figure>
<img src="images/Ex_10_03.png" alt="Ex 10 03"/>
<figcaption/>
</figure>
<pre data-type="programlisting" data-code-language="processingjslive">float[] x = new float[3000];
void setup() {
size(240, 120);
smooth();
noStroke();
fill(255, 200);
for (int i = 0; i < x.length; i++) {
x[i] = random(-1000, 200);
}
}
void draw() {
background(0);
for (int i = 0; i < x.length; i++) {
x[i] += 0.5;
float y = i * 0.4;
arc(x[i], y, 12, 12, 0.52, 5.76);
}
}</pre>
<p>We’ll spend the rest of this chapter talking about the details that make this example possible.</p>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Make an Array" id="make_an_array">
<h1>Make an Array</h1>
<p>Each item in an array is called an <em>element</em>, and each has an <em>index</em> value to mark its position within the array. Just like coordinates on the screen, index values for an array start counting from 0. For instance, the first element in the array has the index value 0, the second element in the array has the index value 1, and so on. If there are 20 values in the array, the index value of the last element is 19. <a data-type="xref" href="#an_array_is_a_list_of_one_or_more_variab">Figure 10-1</a> shows the conceptual structure of an array.</p>
<figure id="an_array_is_a_list_of_one_or_more_variab">
<img src="images/Fig_10_01.png" alt="Fig 10 01"/>
<figcaption>An array is a list of one or more variables that share the same name.</figcaption>
</figure>
<p>Using arrays is similar to working with single variables; it follows the same patterns. As you know, you can make a single integer variable called <em>x</em> with this code:</p>
<pre data-type="programlisting">int x;</pre>
<p>To make an array, just place brackets after the data type:</p>
<pre data-type="programlisting">int[] x;</pre>
<p>The beauty of creating an array is the ability to make 2, 10, or 100,000 variable values with only one line of code. For instance, the following line creates an array of 2,000 integer variables:</p>
<pre data-type="programlisting">int[] x = new int[2000];</pre>
<p>You can make arrays from all Processing data types: <em>boolean</em>, <em>float, String</em>, <em>PShape</em>, and so on, as well as any user-defined classes. For example, the following code creates an array of 32 <em>PImage</em> variables:</p>
<pre data-type="programlisting">PImage[] images = new PImage[32];</pre>
<p>To make an array, start with the name of the data type, followed by the brackets. The name you select for the array is next, followed by the assignment operator (the equal symbol), followed by the <em>new</em> keyword, followed by the name of the data type again, with the number of elements to create within the brackets. This pattern works for arrays of all data types.</p>
<div data-type="note">
<p>Each array can store only one type of data (<em>boolean</em>, <em>int</em>, <em>float</em>, <em>PImage</em>, etc.). You can’t mix and match different types of data within a single array. If you need to do this, work with objects instead.</p>
</div>
<p>Before we get ahead of ourselves, let’s slow down and talk about working with arrays in more detail. Like making an <em>object</em>, there are three steps to working with an array:</p>
<ol>
<li>
<p>Declare the array and define the data type.</p>
</li>
<li>
<p>Create the array with the keyword <em>new</em> and define the length.</p>
</li>
<li>
<p>Assign values to each element.</p>
</li>
</ol>
<p>Each step can happen on its own line, or all the steps can be compressed together. Each of the three following examples shows a different technique to create an array called <em>x</em> that stores two integers, 12 and 2. Pay close attention to what happens before <em>setup()</em> and what happens within <em>setup()</em>.</p>
<section data-type="sect2" data-pdf-bookmark="Example 10-4: Declare and Assign an Array" id="example_10-4_colon_declare_and_assign_an">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_04">Example 10-4: Declare and Assign an Array</a></h2>
<p>First we’ll declare the array outside of <em>setup()</em> and then create and assign the values within. The syntax <em>x[0]</em> refers to the first element in the array and <em>x[1]</em> is the second:</p>
<pre data-type="programlisting">int[] x; // Declare the array
void setup() {
size(200, 200);
x = new int[2]; // Create the array
x[0] = 12; // Assign the first value
x[1] = 2; // Assign the second value
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-5: Compact Array Assignment" id="example_10-5_colon_compact_array_assignm">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_05">Example 10-5: Compact Array Assignment</a></h2>
<p>Here’s a slightly more compact example, in which the array is both declared and created on the same line, then the values are assigned within <em>setup()</em>:</p>
<pre data-type="programlisting">int[] x = new int[2]; // Declare and create the array
void setup() {
size(200, 200);
x[0] = 12; // Assign the first value
x[1] = 2; // Assign the second value
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-6: Assigning to an Array in One Go" id="example_10-6_colon_assigning_to_an_array">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_06">Example 10-6: Assigning to an Array in One Go</a></h2>
<p>You can also assign values to the array when it’s created, if it’s all part of a single statement:</p>
<pre data-type="programlisting">int[] x = { 12, 2 }; // Declare, create, and assign
void setup() {
size(200, 200);
}</pre>
<div data-type="note">
<p>Avoid creating arrays within <em>draw()</em>, because creating a new array on every frame will slow down your frame rate.</p>
</div>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-7: Revisiting the First Example" id="example_10-7_colon_revisiting_the_first">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_07">Example 10-7: Revisiting the First Example</a></h2>
<p>As a complete example of how to use arrays, we’ve recoded <a data-type="xref" href="#example_10-1_colon_many_variables-id1">“<a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_01">Example 10-1: Many Variables</a>”</a> here. Although we don’t yet see the full benefits revealed in <a data-type="xref" href="#example_10-3_colon_arrays_comma_not_vari">“<a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_03">Example 10-3: Arrays, Not Variables</a>”</a>, we do see some important details of how arrays work:</p>
<pre data-type="programlisting">float[] x = {-20, 20};
void setup() {
size(240, 120);
smooth();
noStroke();
}
void draw() {
background(0);
x[0] += 0.5; // Increase the first element
x[1] += 0.5; // Increase the second element
arc(x[0], 30, 40, 40, 0.52, 5.76);
arc(x[1], 90, 40, 40, 0.52, 5.76);
}</pre>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Repetition and Arrays" id="repetition_and_arrays">
<h1>Repetition and Arrays</h1>
<p>The <em>for</em> loop, introduced in <a data-type="xref" href="ch04.html#repetition">“Repetition”</a> in <a data-type="xref" href="ch04.html#variables">Chapter 4</a>, makes it easier to work with large arrays while keeping the code concise. The idea is to write a loop to move through each element of the array one by one. To do this, you need to know the length of the array. The <em>length</em> field associated with each array stores the number of elements. We use the name of the array with the dot operator (a period) to access this value. For instance:</p>
<pre data-type="programlisting">int[] x = new int[2]; // Declare and create the array
println(x.length); // Prints 2 to the Console
int[] y = new int[1972]; // Declare and create the array
println(y.length); // Prints 1972 to the Console</pre>
<section data-type="sect2" data-pdf-bookmark="Example 10-8: Filling an Array in a for Loop" id="example_10-8_colon_filling_an_array_in_a">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_08">Example 10-8: Filling an Array in a <em>for</em> Loop</a></h2>
<p>A <em>for</em> loop can be used to fill an array with values, or to read the values back out. In this example, the array is first filled with random numbers inside <em>setup()</em>, and then these numbers are used to set the stroke value inside <em>draw()</em>. Each time the program is run, a new set of random numbers is put into the array:</p>
<figure>
<img src="images/Ex_10_08.png" alt="Ex 10 08"/>
<figcaption/>
</figure>
<pre data-type="programlisting">float[] gray;
void setup() {
size(240, 120);
gray = new float[width];
for (int i = 0; i < gray.length; i++) {
gray[i] = random(0, 255);
}
}
void draw() {
for (int i = 0; i < gray.length; i++) {
stroke(gray[i]);
line(i, 0, i, height);
}
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-9: Track Mouse Movements" id="example_10-9_colon_track_mouse_movements">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_09">Example 10-9: Track Mouse Movements</a></h2>
<p>In this example, there are two arrays to store the position of the mouse—one for the x-coordinate and one for the y-coordinate. These arrays store the location of the mouse for the previous 60 frames. With each new frame, the oldest x- and y-coordinate values are removed and replaced with the current <em>mouseX</em> and <em>mouseY</em> values. The new values are added to the first position of the array, but before this happens, each value in the array is moved one position to the right (from back to front) to make room for the new numbers. This example visualizes this action. Also, at each frame, all 60 coordinates are used to draw a series of ellipses to the screen:</p>
<figure>
<img src="images/Ex_10_09.png" alt="Ex 10 09"/>
<figcaption/>
</figure>
<pre data-type="programlisting">int num = 60;
int [] x = new int[num];
int [] y = new int[num];
void setup() {
size(240, 120);
smooth();
noStroke();
}
void draw() {
background(0);
// Copy array values from back to front
for (int i = x.length-1; i < 0; i−−) {
x[i] = x[i-1];
y[i] = y[i-1];
}
x[0] = mouseX; // Set the first element
y[0] = mouseY; // Set the first element
for (int i = 0; i < x.length; i++) {
fill(i * 4);
ellipse(x[i], y[i], 40, 40);
}
}</pre>
<div data-type="note">
<p>The technique for storing a shifting buffer of numbers in an array shown in this example and <a data-type="xref" href="#shifting_the_values_in_an_array_one_plac">Figure 10-2</a> is less efficient than an alternative technique that uses the % (modulo) operator. This is explained in the Examples→Basics→Input→StoringInput example included with Processing.</p>
</div>
<figure id="shifting_the_values_in_an_array_one_plac">
<img src="images/Fig_10_02.png" alt="Fig 10 02"/>
<figcaption>Shifting the values in an array one place to the right.</figcaption>
</figure>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Arrays of Objects" id="arrays_of_objects">
<h1>Arrays of Objects</h1>
<p>The two short examples in this section bring together every major programming concept in this book: variables, iteration, conditionals, functions, objects, and arrays. Making an array of objects is nearly the same as making the arrays we introduced on the previous pages, but there’s one additional consideration: because each array element is an object, it must first be created with the keyword <em>new</em> (like any other object) before it is assigned to the array. With a custom-defined class such as <em>JitterBug</em> (see <a data-type="xref" href="ch09.html#objects">Chapter 9</a>), this means using <em>new</em> to set up each element before it’s assigned to the array. Or, for a built-in Processing class such as <em>PImage</em>, it means using the <em>loadImage()</em> function to create the object before it’s assigned.</p>
<section data-type="sect2" data-pdf-bookmark="Example 10-10: Managing Many Objects" id="example_10-10_colon_managing_many_object">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_10">Example 10-10: Managing Many Objects</a></h2>
<p>This example creates an array of 33 <em>JitterBug</em> objects and then updates and displays each one inside <em>draw()</em>. For this example to work, you need to add the <em>JitterBug</em> class to the code:</p>
<figure>
<img src="images/Ex_10_10.png" alt="Ex 10 10"/>
<figcaption/>
</figure>
<pre data-type="programlisting">JitterBug[] bugs = new JitterBug[33];
void setup() {
size(240, 120);
smooth();
for (int i = 0; i < bugs.length; i++) {
float x = random(width);
float y = random(height);
int r = i + 2;
bugs[i] = new JitterBug(x, y, r);
}
}
void draw() {
for (int i = 0; i < bugs.length; i++) {
bugs[i].move();
bugs[i].display();
}
}
// Copy JitterBug class here</pre>
<p>The final array example loads a sequence of images and stores each as an element within an array of <em>PImage</em> objects.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 10-11: Sequences of Images" id="example_10-11_colon_sequences_of_images">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_10_11">Example 10-11: Sequences of Images</a></h2>
<p>To run this example, get the images from the <em>media.zip</em> file as described in <a data-type="xref" href="ch06.html#media">Chapter 6</a>. The images are named sequentially (<em>frame-0000.png</em>, <em>frame-0001.png</em>, and so forth), which makes it possible to create the name of each file within a <em>for</em> loop, as seen in the eighth line of the program:</p>
<figure>
<img src="images/Ex_10_11.png" alt="Ex 10 11"/>
<figcaption/>
</figure>
<pre data-type="programlisting">int numFrames = 12; // The number of frames
PImage[] images = new PImage[numFrames]; // Make the array
int currentFrame = 0;
void setup() {
size(240, 120);
for (int i = 0; i < images.length; i++) {
String imageName = "frame-" + nf(i, 4) + ".png";
images[i] = loadImage(imageName); // Load each image
}
frameRate(24);
}
void draw() {
image(images[currentFrame], 0, 0);
currentFrame++; // Next frame
if (currentFrame &gt;= images.length) {
currentFrame = 0; // Return to first frame
}
}</pre>
<p>The <em>nf()</em> function formats numbers so that <em>nf(1, 4)</em> returns the string “0001” and <em>nf(11, 4)</em> returns “0011”. These values are concatenated with the beginning of the file name (“frame-”) and the end (“.png”) to create the complete file name as a <em>String</em> variable. The files are loaded into the array on the following line. The images are displayed to the screen one at a time in <em>draw()</em>. When the last image in the array is displayed, the program returns to the beginning of the array and shows the images again in sequence.</p>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Robot 8: Arrays" id="robot_8_colon_arrays">
<h1><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Robot8_Arrays">Robot 8: Arrays</a></h1>
<figure>
<img src="images/NRobot_Arrays.png" alt="NRobot Arrays"/>
<figcaption/>
</figure>
<p>Arrays make it easier for a program to work with many elements. In this example, an array of <em>Robot</em> objects is declared at the top. The array is then allocated inside <em>setup()</em>, and each <em>Robot</em> object is created inside the <em>for</em> loop. In <em>draw()</em>, another <em>for</em> loop is used to update and display each element of the <em>bots</em> array.</p>
<p>The <em>for</em> loop and an array make a powerful combination. Notice the subtle differences between the code for this example and Robot 7 (see <a data-type="xref" href="ch09.html#robot_7_colon_objects">“<a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Robot7_Objects">Robot 7: Objects</a>”</a> in <a data-type="xref" href="ch09.html#objects">Chapter 9</a>) in contrast to the extreme changes in the visual result. Once an array is created and a <em>for</em> loop is put in place, it’s as easy to work with 3 elements as it is 3,000.</p>
<p>The decision to load the SVG file within <em>setup()</em> rather than in the <em>Robot</em> class is the major change from Robot 7. This choice was made so the file is loaded only once, rather than as many times as there are elements in the array (in this case, 20 times). This change makes the code start faster because loading a file takes time, and it uses less memory because the file is stored once. Each element of the <em>bot</em> array references the same file.</p>
<pre data-type="programlisting">Robot[] bots; // Declare array of Robot objects
void setup() {
size(720, 480);
PShape robotShape = loadShape("robot1.svg");
// Create the array of Robot objects
bots = new Robot[20];
// Create each object
for (int i = 0; i < bots.length; i++) {
// Create a random x-coordinate
float x = random(-40, width-40);
// Assign the y-coordinate based on the order
float y = map(i, 0, bots.length, −100, height-200);
bots[i] = new Robot(robotShape, x, y);
}
smooth();
}
void draw() {
background(204);
// Update and display each bot in the array
for (int i = 0; i < bots.length; i++) {
bots[i].update();
bots[i].display();
}
}
class Robot {
float xpos;
float ypos;
float angle;
PShape botShape;
float yoffset = 0.0;
// Set initial values in constructor
Robot(PShape shape, float tempX, float tempY) {
botShape = shape;
xpos = tempX;
ypos = tempY;
angle = random(0, TWO_PI);
}
// Update the fields
void update() {
angle += 0.05;
yoffset = sin(angle) * 20;
}
// Draw the robot to the screen
void display() {
shape(botShape, xpos, ypos + yoffset);
}
}</pre>
</section>
</section>
</body>
</html>