State of Mind

The idea of "state" is a bit like "state of mind"... there is a variable that keeps track of what you are currently doing.

Old Joke

This reminds me of an old joke that perhaps hits a bit close to home:

A professor is walking down the hallway and is stopped by a student.

She is interested in discussing a project with the professor over lunch. "Have you had lunch yet?" she asks the professor.

"I'm not sure... which way was I walking when you stopped me?" the professor responds.

State

The basic idea (and need) for state is driven because you are updating an object at many frames per second. That is, you are constantly calling methods like object.draw() and object.move() and you need to be able to move each object a bit in the manner that it currently desires.

Bouncing Balls

We kept track of state with the bouncing ball examples by keeping track of their x, y positions and their velocities. But you can also keep track by using a name.

Moving People

In [4]:
class Person {
    int x;
    int y;
    String state;
    int speed;
    color mycolor;
    
    Person(int x, int y, String state) {
        this.x = x;
        this.y = y;
        this.state = state;
        this.speed = 1 + int(random(2));
        this.mycolor = color(random(255), random(255), random(255));
    }
    
    void draw() {
        fill(this.mycolor);
        if (state.equals("to right")) {
            ellipse(this.x + 5, this.y - 5, 5, 5);
        } else { // "to left"
            ellipse(this.x, this.y - 5, 5, 5);
        }
        rect(this.x, this.y, 5, 10);
    }
    
    void move() {
        // Change state if necessary:
        if (this.x > width) {
            state = "to left";
        } else if (this.x < 0) {
            state = "to right";            
        }
        
        // Update position based on state:
        if (state.equals("to right")) {
            this.x += this.speed;
        } else if (state.equals("to left")) {
            this.x -= this.speed;
        }
    }
}

Person[] people = new Person[10];

void setup() {
    size(500, 100);
    for (int i=0; i<people.length; i++) {
        people[i] = new Person(int(random(width)), int(random(height)), "to right");
    }
}

void draw() {
    background(color(255, 128, 0));
    for (int i=0; i<people.length; i++) {
        people[i].move();
        people[i].draw();
    }    
}
Sketch #4:

Sketch #4 state: Loading...

Sidebar: Breaking up code based on classes

Using Jupyter, you can create a file (in this case called "Person.java") by using the %%file magic:

In [5]:
%%file Person.java

class Person {
    int x;
    int y;
    String state;
    int time;
    
    Person(int x, int y, String state) {
        this.x = x;
        this.y = y;
        this.state = state;
        this.time = 0;
    }
    
    void draw() {
        if ((this.time % 20) < 10) {
            rect(this.x, this.y, 5, 10);
        } else {
            rect(this.x, this.y - 5, 5, 10);
        }
    }
    
    void move() {
        this.time += 1;
        // Change state if necessary:
        if (this.x > width) {
            state = "to left";
        } else if (this.x < 0) {
            state = "to right";            
        }
        
        // Update position based on state:
        if (state.equals("to right")) {
            this.x += 1;
        } else if (state.equals("to left")) {
            this.x -= 1;
        }
    }
}
Created file '/home/dblank/public_html/CS110 Intro to Computing/2017-Spring/Lectures/Person.java'.

You can then use that file by %including it in a Processing sketch:

In [6]:
%include Person.java

Person[] people = new Person[10];

void setup() {
    for (int i=0; i<people.length; i++) {
        people[i] = new Person(int(random(width)), int(random(height)), "to right");
    }
}

void draw() {
    background(color(255, 128, 0));
    for (int i=0; i<people.length; i++) {
        people[i].move();
        people[i].draw();
    }    
}
Sketch #5:

Sketch #5 state: Loading...