epubjs
Version:
Render ePub documents in the browser, across many devices
821 lines (647 loc) • 36.3 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 5. Response" id="response">
<h1>Response</h1>
<p>Code that responds to input from the mouse, keyboard, and other devices has to run continuously. To make this happen, place the lines that update inside a Processing function called <em>draw()</em>.</p>
<div data-type="note">
<p>Here’s a 2007 interview with Ben Fry where he talks about his book <a href="http://shop.oreilly.com/product/9780596514556.do">Visualizing Data</a>.</p>
<div><iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/P3kEni_xxTU" width="560"> </iframe></div>
</div>
<section data-type="sect1" data-pdf-bookmark="PROD: Insert Section Title Here" id="_prod_insert_section_title_here">
<h1>PROD: Insert Section Title Here</h1>
<section data-type="sect2" data-pdf-bookmark="Example 5-1: The draw() Function" id="example_5-1_colon_the_draw_open-id1">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_01">Example 5-1: The <em>draw()</em> Function</a></h2>
<p>To see how <em>draw()</em> works, run this example:</p>
<pre data-type="programlisting">
void draw() {
// Displays the frame count to the Console
println("I'm drawing");
println(frameCount);
}</pre>
<p>You’ll see the following:</p>
<pre data-type="programlisting">
I'm drawing
1
I'm drawing
2
I'm drawing
3
...</pre>
<p>The code within the <em>draw()</em> block runs from top to bottom, then repeats until you quit the program by clicking the Stop button or closing the window. Each trip through <em>draw()</em> is called a <em>frame</em>. (The default frame rate is 60 frames per second, but this can be changed. See for more information.) In the previous example program, the <em>println()</em> functions write the text “I’m drawing” followed by the current frame count as counted by the special <em>frameCount</em> variable (1, 2, 3, …). The text appears in the Console, the black area at the bottom of the Processing editor window.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-2: The setup() Function" id="example_5-2_colon_the_setup_open_parenth">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_02">Example 5-2: The <em>setup()</em> Function</a></h2>
<p>To complement the looping <em>draw()</em> function, Processing has a function called <em>setup()</em> that runs just once when the program starts:</p>
<pre data-type="programlisting">
void setup() {
println("I'm starting");
}
void draw() {
println("I'm running");
}</pre>
<p>When this code is run, the following is written to the Console:</p>
<pre data-type="programlisting">
I'm starting
I'm running
I'm running
I'm running
...</pre>
<p>The text “I’m running” continues to write to the Console until the program is stopped.</p>
<p>In a typical program, the code inside <em>setup()</em> is used to define the starting values. The first line is always the <em>size()</em> function, often followed by code to set the starting fill and stroke colors, or perhaps to load images and fonts. (If you don’t include the <em>size()</em> function, the Display Window will be 100×100 pixels.)</p>
<p>Now you know how to use <em>setup()</em> and <em>draw()</em>, but this isn’t the whole story. There’s one more location to put code—you can also place variables outside of <em>setup()</em> and <em>draw()</em>. If you create a variable inside of <em>setup()</em>, you can’t use it inside of <em>draw()</em>, so you need to place those variables somewhere else. Such variables are called <em>global</em> variables, because they can be used anywhere (“globally”) in the program. This is clearer when we list the order in which the code is run:</p>
<ol>
<li>
<p>Variables declared outside of <em>setup()</em> and <em>draw()</em> are created.</p>
</li>
<li>
<p>Code inside <em>setup()</em> is run once.</p>
</li>
<li>
<p>Code inside <em>draw()</em> is run continuously.</p>
</li>
</ol>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-3: setup(), Meet draw()" id="example_5-3_colon_setup_open_parenthesis">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_03">Example 5-3: <em>setup()</em>, Meet <em>draw()</em></a></h2>
<p>The following example puts it all together:</p>
<pre data-type="programlisting">
int x = 280;
int y = −100;
int diameter = 380;
void setup() {
size(480, 120);
smooth();
fill(102);
}
void draw() {
background(204);
ellipse(x, y, diameter, diameter);
}</pre>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Follow" id="follow">
<h1>Follow</h1>
<p>Now that we have code running continuously, we can track the mouse position and use those numbers to move elements on screen.</p>
<section data-type="sect2" data-pdf-bookmark="Example 5-4: Track the Mouse" id="example_5-4_colon_track_the_mouse">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_04">Example 5-4: Track the Mouse</a></h2>
<p>The <em>mouseX</em> variable stores the x-coordinate, and the <em>mouseY</em> variable stores the y-coordinate:</p>
<figure><img alt="Ex 05 04" src="images/Ex_05_04.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(480, 120);
fill(0, 102);
smooth();
noStroke();
}
void draw() {
ellipse(mouseX, mouseY, 9, 9);
}</pre>
<p>In this example, each time the code in the <em>draw()</em> block is run, a new circle is drawn to the window. This image was made by moving the mouse around to control the circle’s location. Because the fill is set to be partially transparent, denser black areas show where the mouse spent more time and where it moved slowly. The circles that are spaced farther apart show when the mouse was moving faster.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-5: The Dot Follows You" id="example_5-5_colon_the_dot_follows_you">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_05">Example 5-5: The Dot Follows You</a></h2>
<p>In this example, a new circle is added to the window each time the code in <em>draw()</em> is run. To refresh the screen and only display the newest circle, place a <em>background()</em> function at the beginning of <em>draw()</em> before the shape is drawn:</p>
<figure><img alt="Ex 05 05" src="images/Ex_05_05.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(480, 120);
fill(0, 102);
smooth();
noStroke();
}
void draw() {
background(204);
ellipse(mouseX, mouseY, 9, 9);
}</pre>
<p>The <em>background()</em> function clears the entire window, so be sure to always place it before other functions inside <em>draw()</em>; otherwise, the shapes drawn before it will be erased.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-6: Draw Continuously" id="example_5-6_colon_draw_continuously">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_06">Example 5-6: Draw Continuously</a></h2>
<p>The <em>pmouseX</em> and <em>pmouseY</em> variables store the position of the mouse at the previous frame. Like <em>mouseX</em> and <em>mouseY</em>, these special variables are updated each time <em>draw()</em> runs. When combined, they can be used to draw continuous lines by connecting the current and most recent location:</p>
<figure><img alt="Ex 05 06" src="images/Ex_05_06.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(480, 120);
strokeWeight(4);
smooth();
stroke(0, 102);
}
void draw() {
line(mouseX, mouseY, pmouseX, pmouseY);
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-7: Set Thickness on the Fly" id="example_5-7_colon_set_thickness_on_the_f">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_07">Example 5-7: Set Thickness on the Fly</a></h2>
<p>The <em>pmouseX</em> and <em>pmouseY</em> variables can also be used to calculate the speed of the mouse. This is done by measuring the distance between the current and most recent mouse location. If the mouse is moving slowly, the distance is small, but if the mouse starts moving faster, the distance grows. A function called <em>dist()</em> simplifies this calculation, as shown in the following example. Here, the speed of the mouse is used to set the thickness of the drawn line:</p>
<figure><img alt="Ex 05 07" src="images/Ex_05_07.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(480, 120);
smooth();
stroke(0, 102);
}
void draw() {
float weight = dist(mouseX, mouseY, pmouseX, pmouseY);
strokeWeight(weight);
line(mouseX, mouseY, pmouseX, pmouseY);
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-8: Easing Does It" id="example_5-8_colon_easing_does_it">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_08">Example 5-8: Easing Does It</a></h2>
<p>In , the values from the mouse are converted directly into positions on the screen. But sometimes you want the values to follow the mouse loosely—to lag behind to create a more fluid motion. This technique is called <em>easing</em>. With easing, there are two values: the current value and the value to move toward (see ). At each step in the program, the current value moves a little closer to the target value:</p>
<pre data-type="programlisting">
float x;
float easing = 0.01;
void setup() {
size(220, 120);
smooth();
}
void draw() {
float targetX = mouseX;
x += (targetX - x) * easing;
ellipse(x, 40, 12, 12);
println(targetX + " : " + x);
}</pre>
<p>The value of the <em>x</em> variable is always getting closer to <em>targetX</em>. The speed at which it catches up with <em>targetX</em> is set with the <em>easing</em> variable, a number between 0 and 1. A small value for easing causes more of a delay than a larger value. With an easing value of 1, there is no delay. When you run , the actual values are shown in the Console through the <em>println()</em> function. When moving the mouse, notice how the numbers are far apart, but when the mouse stops moving, the <em>x</em> value gets closer to <em>targetX</em>.</p>
<figure id="easing"><img alt="Fig 05 01" src="images/Fig_05_01.png"/>
<figcaption>Easing.</figcaption>
</figure>
<p>All of the work in this example happens on the line that begins <code>x +=</code>. There, the difference between the target and current value is calculated, then multiplied by the easing variable and added to <em>x</em> to bring it closer to the target.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-9: Smooth Lines with Easing" id="example_5-9_colon_smooth_lines_with_easi">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_09">Example 5-9: Smooth Lines with Easing</a></h2>
<p>In this example, the easing technique is applied to . In comparison, the lines are smoother:</p>
<figure><img alt="Ex 05 09" src="images/Ex_05_09.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjslive" data-type="programlisting">
float x;
float y;
float px;
float py;
float easing = 0.05;
void setup() {
size(480, 120);
smooth();
stroke(0, 102);
}
void draw() {
float targetX = mouseX;
x += (targetX - x) * easing;
float targetY = mouseY;
y += (targetY - y) * easing;
float weight = dist(x, y, px, py);
strokeWeight(weight);
line(x, y, px, py);
py = y;
px = x;
}</pre>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Map" id="map">
<h1>Map</h1>
<p>When numbers are used to draw to the screen, it’s often useful to convert the values from one range of numbers to another.</p>
<section data-type="sect2" data-pdf-bookmark="Example 5-10: Map Values to a Range" id="example_5-10_colon_map_values_to_a_range">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_10">Example 5-10: Map Values to a Range</a></h2>
<p>The <em>mouseX</em> variable is usually between 0 and the width of the window, but you might want to remap those values to a different range of coordinates. You can do this by making calculations like dividing <em>mouseX</em> by a number to reduce its range and then adding or subtracting a number to shift it left or right:</p>
<figure><img alt="Ex 05 10" src="images/Ex_05_10.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(240, 120);
strokeWeight(12);
smooth();
}
void draw() {
background(204);
stroke(255);
line(120, 60, mouseX, mouseY); // White line
stroke(0);
float mx = mouseX/2 + 60;
line(120, 60, mx, mouseY); // Black line
}</pre>
<p>The <em>map()</em> function is a more general way to make this type of change. It converts a variable from one range of numbers to another. The first parameter is the variable to be converted, the second and third parameters are the low and high values of that variable, and the fourth and fifth parameters are the desired low and high values. The <em>map()</em> function hides the math behind the conversion.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-11: Map with the map() Function" id="example_5-11_colon_map_with_the_map_open">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_11">Example 5-11: Map with the <em>map()</em> Function</a></h2>
<p>This example rewrites using <em>map()</em>:</p>
<pre data-type="programlisting">
void setup() {
size(240, 120);
strokeWeight(12);
smooth();
}
void draw() {
background(204);
stroke(255);
line(120, 60, mouseX, mouseY); // White line
stroke(0);
float mx = map(mouseX, 0, width, 60, 180);
line(120, 60, mx, mouseY); // Black line
}</pre>
<p>The <em>map()</em> function makes the code easy to read, because the minimum and maximum values are clearly written as the parameters. In this example, <em>mouseX</em> values between 0 and <em>width</em> are converted to a number from 60 (when <em>mouseX</em> is 0) up to 180 (when <em>mouseX</em> is <em>width</em>). You’ll find the useful <em>map()</em> function in many examples throughout this book.</p>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Click" id="click">
<h1>Click</h1>
<p>In addition to the location of the mouse, Processing also keeps track of whether the mouse button is pressed. The <em>mousePressed</em> variable has a different value when the mouse button is pressed and when it is not. The <em>mousePressed</em> variable is a data type called <em>boolean</em>, which means that it has only two possible values: <em>true</em> and <em>false</em>. The value of <em>mousePressed</em> is <em>true</em> when a button is pressed.</p>
<section data-type="sect2" data-pdf-bookmark="Example 5-12: Click the Mouse" id="example_5-12_colon_click_the_mouse">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_12">Example 5-12: Click the Mouse</a></h2>
<p>The <em>mousePressed</em> variable is used along with the <em>if</em> statement to determine when a line of code will run and when it won’t. Try this example before we explain further:</p>
<figure><img alt="Ex 05 12" src="images/Ex_05_12.png"/>
<figcaption> </figcaption>
</figure>
<pre data-code-language="processingjs" data-executable="true" data-type="programlisting">
void setup() {
size(240, 120);
smooth();
strokeWeight(30);
}
void draw() {
background(204);
stroke(102);
line(40, 0, 70, height);
if (mousePressed == true) {
stroke(0);
}
line(0, 70, width, 50);
}</pre>
<p>In this program, the code inside the <em>if</em> block runs only when a mouse button is pressed. When a button is not pressed, this code is ignored. Like the <em>for</em> loop discussed in in , the <em>if</em> also has a <em>test</em> that is evaluated to <em>true</em> or <em>false</em>:</p>
<pre data-type="programlisting">
if (test) {
statements
}</pre>
<p>When the test is <em>true</em>, the code inside the block is run; when the test is <em>false</em>, the code inside the block is not run. The computer determines whether the test is <em>true</em> or <em>false</em> by evaluating the expression inside the parentheses. (If you’d like to refresh your memory, the discussion of relational expressions is with .)</p>
<p>The == symbol compares the values on the left and right to test whether they are equivalent. This == symbol is different from the assignment operator, the single = symbol. The == symbol asks, “Are these things equal?” and the = symbol sets the value of a variable.</p>
<div data-type="note">
<p>It’s a common mistake, even for experienced programmers, to write = in your code when you mean to write ==. The Processing software won’t always warn you when you do this, so be careful.</p>
</div>
<p>Alternatively, the test in <em>draw()</em> in can be written like this:</p>
<pre data-type="programlisting">
if (mousePressed) {</pre>
<p>Boolean variables, including <em>mousePressed</em>, don’t need the explicit comparison with the == operator, because they can be only <em>true</em> or <em>false</em>.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-13: Detect When Not Clicked" id="example_5-13_colon_detect_when_not_click">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_13">Example 5-13: Detect When Not Clicked</a></h2>
<p>A single <em>if</em> block gives you the choice of running some code or skipping it. You can extend an <em>if</em> block with an <em>else</em> block, allowing your program to choose between two options. The code inside the <em>else</em> block runs when the value of the <em>if</em> block test is <em>false</em>. For instance, the stroke color for a program can be white when the mouse button is not pressed, and can change to black when the button is pressed:</p>
<figure><img alt="Ex 05 13" src="images/Ex_05_13.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
void setup() {
size(240, 120);
smooth();
strokeWeight(30);
}
void draw() {
background(204);
stroke(102);
line(40, 0, 70, height);
if (mousePressed) {
stroke(0);
} else {
stroke(255);
}
line(0, 70, width, 50);
}</pre>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-14: Multiple Mouse Buttons" id="example_5-14_colon_multiple_mouse_button">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_14">Example 5-14: Multiple Mouse Buttons</a></h2>
<p>Processing also tracks which button is pressed if you have more than one button on your mouse. The <em>mouseButton</em> variable can be one of three values: <em>LEFT</em>, <em>CENTER</em>, or <em>RIGHT</em>. To test which button was pressed, the == operator is needed, as shown here:</p>
<figure><img alt="Ex 05 14" src="images/Ex_05_14.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
void setup() {
size(120, 120);
smooth();
strokeWeight(30);
}
void draw() {
background(204);
stroke(102);
line(40, 0, 70, height);
if (mousePressed) {
if (mouseButton == LEFT) {
stroke(255);
} else {
stroke(0);
}
line(0, 70, width, 50);
}
}</pre>
<p>A program can have many more <em>if</em> and <em>else</em> structures (see ) than those found in these short examples. They can be chained together into a long series with each testing for something different, and <em>if</em> blocks can be embedded inside of other <em>if</em> blocks to make more complex decisions.</p>
<figure id="the_if_and_else_structure_makes_decision"><img alt="Fig 05 02" src="images/Fig_05_02.png"/>
<figcaption>The if and else structure makes decisions about which blocks of code to run.</figcaption>
</figure>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Location" id="location">
<h1>Location</h1>
<p>An <em>if</em> structure can be used with the <em>mouseX</em> and <em>mouseY</em> values to determine the location of the cursor within the window.</p>
<section data-type="sect2" data-pdf-bookmark="Example 5-15: Find the Cursor" id="example_5-15_colon_find_the_cursor">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_15">Example 5-15: Find the Cursor</a></h2>
<p>For instance, this example tests to see whether the cursor is on the left or right side of a line and then moves the line toward the cursor:</p>
<figure><img alt="Ex 05 15" src="images/Ex_05_15.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
float x;
int offset = 10;
void setup() {
size(240, 120);
smooth();
x = width/2;
}
void draw() {
background(204);
if (mouseX &gt; x) {
x += 0.5;
offset = −10;
}
if (mouseX &lt; x) {
x -= 0.5;
offset = 10;
}
line(x, 0, x, height);
line(mouseX, mouseY, mouseX + offset, mouseY - 10);
line(mouseX, mouseY, mouseX + offset, mouseY + 10);
line(mouseX, mouseY, mouseX + offset*3, mouseY);
}</pre>
<p>To write programs that have graphical user interfaces (buttons, checkboxes, scrollbars, and so on), we need to write code that knows when the cursor is within an enclosed area of the screen. The following two examples introduce how to check whether the cursor is inside a circle and a rectangle. The code is written in a modular way with variables, so it can be used to check for <em>any</em> circle and rectangle by changing the values.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-16: The Bounds of a Circle" id="example_5-16_colon_the_bounds_of_a_circl">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_16">Example 5-16: The Bounds of a Circle</a></h2>
<p>For the circle test, we use the <em>dist()</em> function to get the distance from the center of the circle to the cursor, then we test to see if that distance is less than the radius of the circle (see ). If it is, we know we’re inside. In this example, when the cursor is within the area of the circle, its size increases:</p>
<figure><img alt="Ex 05 16" src="images/Ex_05_16.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
int x = 120;
int y = 60;
int radius = 12;
void setup() {
size(240, 120);
smooth();
ellipseMode(RADIUS);
}
void draw() {
background(204);
float d = dist(mouseX, mouseY, x, y);
if (d &lt; radius) {
radius++;
fill(0);
} else {
fill(255);
}
ellipse(x, y, radius, radius);
}</pre>
<figure id="circle_rollover_test"><img alt="Fig 05 03" src="images/Fig_05_03.png"/>
<figcaption>Circle rollover test.</figcaption>
</figure>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-17: The Bounds of a Rectangle" id="example_5-17_colon_the_bounds_of_a_recta">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_17">Example 5-17: The Bounds of a Rectangle</a></h2>
<p>We use another approach to test whether the cursor is inside a rectangle. We make four separate tests to check if the cursor is on the correct side of each edge of the rectangle, then we compare each test and if they are all <em>true</em>, we know the cursor is inside. This is illustrated in . Each step is simple, but it looks complicated when it’s all put together:</p>
<figure><img alt="Ex 05 17" src="images/Ex_05_17.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
int x = 80;
int y = 30;
int w = 80;
int h = 60;
void setup() {
size(240, 120);
}
void draw() {
background(204);
if ((mouseX &gt; x) &amp;&amp; (mouseX &lt; x+w) &amp;&amp;
(mouseY &gt; y) &amp;&amp; (mouseY &lt; y+h)) {
fill(0);
} else {
fill(255);
}
rect(x, y, w, h);
}</pre>
<p>The test in the <em>if</em> statement is a little more complicated than we’ve seen. Four individual tests (e.g., <em>mouseX > x</em>) are combined with the logical AND operator, the <em>&&</em> symbol, to ensure that every relational expression in the sequence is <em>true</em>. If one of them is <em>false</em>, the entire test is <em>false</em> and the fill color won’t be set to black. This is explained further in the reference entry for <em>&&</em>.</p>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Type" id="type">
<h1>Type</h1>
<p>Processing keeps track of when any key on a keyboard is pressed, as well as the last key pressed. Like the <em>mousePressed</em> variable, the <em>keyPressed</em> variable is <em>true</em> when any key is pressed, and <em>false</em> when no keys are pressed.</p>
<figure id="rectangle_rollover_test"><img alt="Fig 05 04" src="images/Fig_05_04.png"/>
<figcaption>Rectangle rollover test.</figcaption>
</figure>
<section data-type="sect2" data-pdf-bookmark="Example 5-18: Tap a Key" id="example_5-18_colon_tap_a_key">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_18">Example 5-18: Tap a Key</a></h2>
<p>In this example, the second line is drawn only when a key is pressed:</p>
<figure><img alt="Ex 05 18" src="images/Ex_05_18.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
void setup() {
size(240, 120);
smooth();
}
void draw() {
background(204);
line(20, 20, 220, 100);
if (keyPressed) {
line(220, 20, 20, 100);
}
}</pre>
<p>The <em>key</em> variable stores the most recent key that has been pressed. The data type for <em>key</em> is <em>char</em>, which is short for “character” but usually pronounced like the first syllable of “charcoal.” A <em>char</em> variable can store any single character, which includes letters of the alphabet, numbers, and symbols. Unlike a <em>string</em> value (see ), which is distinguished by double quotes, the <em>char</em> data type is specified by single quotes. This is how a <em>char</em> variable is declared and assigned:</p>
<pre data-type="programlisting">
char c = 'A'; // Declares and assigns 'A' to the variable c</pre>
<p>And these attempts will cause an error:</p>
<pre data-type="programlisting">
char c = "A"; // Error! Can't assign a String to a char
char h = A; // Error! Missing the single quotes from 'A'</pre>
<p>Unlike the <em>boolean</em> variable <em>keyPressed</em>, which reverts to <em>false</em> each time a key is released, the <em>key</em> variable keeps its value until the next key is pressed. The following example uses the value of <em>key</em> to draw the character to the screen. Each time a new key is pressed, the value updates and a new character draws. Some keys, like Shift and Alt, don’t have a visible character, so when you press them, nothing is drawn.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-19: Draw Some Letters" id="example_5-19_colon_draw_some_letters">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_19">Example 5-19: Draw Some Letters</a></h2>
<p>This example introduces the <em>textSize()</em> function to set the size of the letters, the <em>textAlign()</em> function to center the text on its x-coordinate, and the <em>text()</em> function to draw the letter. These functions are discussed in more detail in –.</p>
<figure><img alt="Ex 05 19" src="images/Ex_05_19.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
void setup() {
size(120, 120);
textSize(64);
textAlign(CENTER);
}
void draw() {
background(0);
text(key, 60, 80);
}</pre>
<p>By using an <em>if</em> structure, we can test to see whether a specific key is pressed and choose to draw something on screen in response.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-20: Check for Specific Keys" id="example_5-20_colon_check_for_specific_ke">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_20">Example 5-20: Check for Specific Keys</a></h2>
<p>In this example, we test for an H or N to be typed. We use the comparison operator, the <em>==</em> symbol, to see if the <em>key</em> value is equal to the characters we’re looking for:</p>
<figure><img alt="Ex 05 20" src="images/Ex_05_20.png"/>
<figcaption> </figcaption>
</figure>
<pre data-type="programlisting">
void setup() {
size(120, 120);
smooth();
}
void draw() {
background(204);
if (keyPressed) {
if ((key == 'h') || (key == 'H')) {
line(30, 60, 90, 60);
}
if ((key == 'n') || (key == 'N')) {
line(30, 20, 90, 100);
}
}
line(30, 20, 30, 100);
line(90, 20, 90, 100);
}</pre>
<p>When we watch for H or N to be pressed, we need to check for both the lowercase and uppercase letters in the event that someone hits the Shift key or has the Caps Lock set. We combine the two tests together with a logical OR, the <em>||</em> symbol. If we translate the second <em>if</em> statement in this example into plain language, it says, “If the <em>h</em> key is pressed OR the <em>H</em> key is pressed.” Unlike with the logical AND (the <em>&&</em> symbol), only one of these expressions need be <em>true</em> for the entire <em>test</em> to be <em>true</em>.</p>
<p>Some keys are more difficult to detect, because they aren’t tied to a particular letter. Keys like Shift, Alt, and the arrow keys are <em>coded</em> and require an extra step to figure out if they are pressed. First, we need to check if the key that’s been pressed is a coded key, then we check the code with the <em>keyCode</em> variable to see which key it is. The most frequently used <em>keyCode</em> values are <em>ALT</em>, <em>CONTROL</em>, and <em>SHIFT</em>, as well as the arrow keys, <em>UP</em>, <em>DOWN</em>, <em>LEFT</em>, and <em>RIGHT</em>.</p>
</section>
<section data-type="sect2" data-pdf-bookmark="Example 5-21: Move with Arrow Keys" id="example_5-21_colon_move_with_arrow_keys">
<h2><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Ex_05_21">Example 5-21: Move with Arrow Keys</a></h2>
<p>The following example shows how to check for the left or right arrow keys to move a rectangle:</p>
<pre data-type="programlisting">
int x = 215;
void setup() {
size(480, 120);
}
void draw() {
if (keyPressed &amp;&amp; (key == CODED)) { // If it's a coded key
if (keyCode == LEFT) { // If it's the left arrow
x−−;
} else if (keyCode == RIGHT) { // If it's the right arrow
x++;
}
}
rect(x, 45, 50, 50);
}</pre>
</section>
</section>
<section data-type="sect1" data-pdf-bookmark="Robot 3: Response" id="robot_3_colon_response">
<h1><a href="http://examples.oreilly.com/0636920000570/interactive_examples/index.php?example=Robot3_Response">Robot 3: Response</a></h1>
<figure><img alt="NRobot Interact" src="images/NRobot_Interact.png"/>
<figcaption> </figcaption>
</figure>
<p>This program uses the variables introduced in Robot 2 (see in ) and makes it possible to change them while the program runs so that the shapes respond to the mouse. The code inside the <em>draw()</em> block runs many times each second. At each frame, the variables defined in the program change in response to the <em>mouseX</em> and <em>mousePressed</em> variables.</p>
<p>The <em>mouseX</em> value controls the position of the robot with an easing technique so that movements are less instantaneous and therefore feel more natural. When a mouse button is pressed, the values of <em>neckHeight</em> and <em>bodyHeight</em> change to make the robot short.</p>
<pre data-type="programlisting">
float x = 60; // X-coordinate
float y = 440; // Y-coordinate
int radius = 45; // Head Radius
int bodyHeight = 160; // Body Height
int neckHeight = 70; // Neck Height
float easing = 0.02;
void setup() {
size(360, 480);
smooth();
strokeWeight(2);
ellipseMode(RADIUS);
}
void draw() {
int targetX = mouseX;
x += (targetX - x) * easing;
if (mousePressed) {
neckHeight = 16;
bodyHeight = 90;
} else {
neckHeight = 70;
bodyHeight = 160;
}
float ny = y - bodyHeight - neckHeight - radius;
background(204);
// Neck
stroke(102);
line(x+12, y-bodyHeight, x+12, ny);
// Antennae
line(x+12, ny, x-18, ny-43);
line(x+12, ny, x+42, ny-99);
line(x+12, ny, x+78, ny+15);
// Body
noStroke();
fill(102);
ellipse(x, y-33, 33, 33);
fill(0);
rect(x-45, y-bodyHeight, 90, bodyHeight-33);
// Head
fill(0);
ellipse(x+12, ny, radius, radius);
fill(255);
ellipse(x+24, ny-6, 14, 14);
fill(0);
ellipse(x+24, ny-6, 3, 3);
}</pre>
</section>
</section>
</body>
</html>