Characters are encoded in ASCII, which maps numbers to symbols.
Strings are internally implemented as an array of characters, but this is not exposed to you as the user! Have to use special methods.
void setup(){
String s = "Hello there!";
// Like before, we cannot mix string and char
// initializations. These lines are both illegal.
String x = 'howdy';
String z = 'z';
// While strings are internally arrays of
// chars, Processing intentionally hides
// this from you. This line is illegal.
char s3 = s[3];
}
Read files with loadStrings()
Write files with PrintWriter
class
Strings and characters control the content of text, fonts and layout control how it's displayed.
What makes Unicode so hard to work with?
A small slice of the problem at https://eev.ee/blog/2015/09/12/dark-corners-of-unicode/
What is the correct way to capitalize "istanbul"?
Istanbul
İstanbul
Which of the following strings are whitespace?
What is the length of this string?
"💣"
How do we sort the following strings alphabetically?
Pokémon
How do fonts deal with Unicode and different languages?
In practice: split fonts into language packs. Only download font parts that you need on your system.
Unicode literally has two different glyph which are intended to be used when the software cannot display a symbol (e.g. when the font does not have a glyph for that codepoint)
Do people still make fonts?
IBM Plex family (2018)
Adobe Source Code Pro (2012)
Can we make our own fonts?
Absolutely! You can do it in a variety of ways: most pro fonts these days are made with designers, but you can also vectorize handwritten texts.
Are some fonts more efficient than others?
Generally, no. Some things will cause font layout engines to work a lot harder (e.g. Arabic) but that's usually a function of the language and not the font.
﷽
How large does a text file have to be before pulling it in all at once starts to affect your runtime?
It varies from computer to computer, but BIG.
A rule of thumb on modern desktop/laptop class systems is that a file load of 1GB is noticeable but not annoying.
Would vector fonts be better than bitmapped fonts for an 8-bit game?
Can we move text across the screen like we can with shapes?
No, sometimes you want the "ugliness" of bitmap fonts for aesthetic reasons.
Yep.
float xpos;
void setup(){
size(1000,500);
xpos = 0.0;
}
void draw(){
background(50);
xpos += 1.0;
textSize(50);
text("Away into the unknown!",
xpos, 300);
}
How do you handle multiple keypresses in Processing?
How are vector fonts any better if they're ultimately being displayed on a pixel grid?
import java.util.HashMap;
HashMap<char, boolean> keysHeld;
void keyPressed(){
keysHeld.put(key, true);
}
void keyReleased(){
keysHeld.put(key, false);
}
Vector fonts retain the info needed to scale them up on a pixel grid, bitmaps do not.
So far, all the systems we've worked on have been relatively simple.
Real graphics are complex!
https://processing.org/examples/multipleparticlesystems.html
Our car has two variables: fuel and speed.
It can do three things:
Variables:
Actions the car can take:
Rules that we might want to enforce:
Just remember to apply the rules!
float car1_speed = 0.0;
float car1_fuel = 0.0;
// Lots of intermediate code
// car1_fuel -= 0.5;
// car1_speed += 100.0;
if (car1_fuel > 0.5){
car1_fuel -= 0.5;
car1_speed += 100.0;
}
float car1_speed = 0.0;
float car1_fuel = 0.0;
// Lots of intermediate code
car1_speed += 100.0;
Use functions so that we can't forget to do all the operations.
// Magic floats which have changes
// reflected outside the function
void accelerate(float fuel, float speed){
if (fuel == 0.0){
return;
} else if (fuel <= 0.5){
// Use what fuel we have left
speed += 100.0 * (fuel / 0.5);
fuel = 0.0;
} else {
speed += 100.0;
fuel -= 0.5;
}
}
Since this is wrapped in a function, we can afford to be complex now!
float car1_speed = 0.0;
float car1_fuel = 0.3;
accelerate(car1_speed, car1_fuel);
float car1_speed = 0.0;
float car1_fuel = 0.3;
// Oops.
accelerate(car1_fuel, car1_fuel);
float car1_speed = 0.0;
float car1_fuel = 1.0;
float car2_speed = 0.0;
float car2_fuel = 1.0;
// Oops.
accelerate(car1_fuel, car2_speed);
Instead of passing the data in separately, we're going to bundle the data together with the functions for manipulating it.
// float car1_speed = 0.0;
// float car1_fuel = 0.3;
Car car1 = new Car(0.0, 0.3);
car1.accelerate();
Code can get complicated!
Two time-honored tricks for reducing complexity:
One of the techniques that evolved out of these two ideas is Object Oriented Programming.
Define a class.
class Car {
float fuel;
float speed;
Car(float f, float s){
// Code goes here
}
void accelerate(){
// Code goes here
}
}
Note that we don't define values for fuel
and speed
. This is because the class acts as a blueprint for instances of Car
s.
Elements of this class (fuel
, speed
, accelerate()
) are known as members.
Data members are known as fields.
Function members are known as methods.
Create objects from the class and use them.
Car c1 = new Car(0.0, 0.0);
Car c2 = new Car(0.0, 0.5);
println(c1.fuel);
c1.accelerate();
println(c1.fuel);
Things to note:
c1
is Car
).new
keyword to create an object. This is different from Python!Car class
Car object
Car
s!class Spot {
float x, y, radius;
void display() {
ellipse(x, y, radius, radius);
}
Spot(){
x = 50.0;
y = 50.0;
radius = 30.0;
}
Spot(float x, float y, float r) {
this.x = x;
this.y = y;
this.radius = r;
}
}
Things to note:
this
keyword to refer to the current object. Similar to self
in Python.Spot sp1, sp2;
void setup(){
sp1 = new Spot();
sp2 = new Spot(75, 80, 15);
}
void draw(){
sp1.display();
sp2.display();
}
A single file can contain all of a program’s classes BUT
please use separate files for each class for this course when submitting projects (for hands-on, you can keep it all in one file if you'd like).
Multiple files provide modularity and make it easier to share/reuse code later if you choose to work in groups for the final project.
Note: Each Processing sketch can only have one setup and draw function call
speed
represent in Spot
?direction
represent in Spot
?move()
method in Spot
?chameleon()
method in Spot
? Would we need to add fields to support this?Reminder: these are sometimes collectively referred to as class members or just members.
Spot
class in a Processing sketch. Create it within its own file.speed
field and a move()
method so the spot's position can update.draw()
method for Spot.Spot
objects that start out with different positions and speeds, then draw things out. (It is okay if the spots eventually move off the screen, as long as it doesn't occur too quickly).class Spot{
int x;
/* Other fields */
// Constructors
Spot(){}
Spot(int _x){}
// Methods
void move(/* args */){}
}
PVector
provides support for vectors.
https://processing.org/reference/PVector.html
class Spot {
PVector position;
float radius;
void display() {
ellipse(position.x,
position.y,
radius, radius);
}
}
new
new
allocates memory for an object. This allocation of memory can be expensive. Doing this too often may degrade performance.
new
in draw()
.setup()
instead of every draw()
.new
from draw()
, consider saving objects into global arrays so you can reuse them on the next frame. (Dangerous!)