Kade Stewart – Final Project

Please download and unzip kades_final. Then just open the HTML file in your browser to play my game. It has instructions in the game itself to play.

My game strays a little bit form my proposal, but is ultimately pretty similar. You just have to reach the right side of the screen and avoid the red planes. Each level has controls that are manipulated in some way, which you’ll learn after you complete the level before. Most of the levels are controlled via the arrow keys, but levels 6 and 7 have special controls you’ll learn when you play. It is not the hardest game, but hopefully you can have some fun (and unlock hard mode when you complete the game)!

Kade Stewart – Project 12 – Proposal

I would like to create a game where you are a paper airplane. Because you have no on-board propulsion, you are constantly trying to fly through hoops that give you more energy. Beyond this, you go through levels that each have their own quirks. One level might require backwards controls, and another might require you to mash buttons instead of actually pressing the arrow keys. There might be some obstacles for the player to dodge, and their will probably be some meters on-screen saying how much energy you have left and how far you’ve gone.

Beyond this, I would like to show the data collected from keypresses, just because I think this would be interesting. It might give the player insights as to how they can do better, if they’re pressing keys too much, etc.

KadeStewart-LookingOutwards-12

Title screen for “Flight”
How the data is collected and visualized (A Dialogue between Four Hands, 2017)

Flight is a paper airplane simulator made by Armor Games, in which you can upgrade your airplane to go higher, faster, and farther. It really only the up and down arrow keys. This project is really interesting (in fact, I played a lot of it as a kid because it’s a fun flash game), but they missed on the opportunity to add difficulty via levels.

Another project is Giorgia Lupi’s 2017 “A dialogue between four hands.” She finds ways to collect data from a guitarist/drummer, and makes the data look interesting. It’s a great testament to our ability to eke out data from everyday life, not just from things with computers.

These two projects don’t seem to be very connected. However, Flight offers a great opportunity for data collection (simple key presses). The way that Lupi acquires data, on a very individual-level, could be enlightening for how good players of Flight are successful, and how bad players are…not so good.

 

Flight

A dialogue between four hands

Kade Stewart – Project 11 – Composition

ants

//Kade Stewart
//Section B
//kades@andrew.cmu.edu
//Project-11

//variables storing each of the ants, the repellent values, 
//and the foot variables
var ants = [];
var rpx;
var rpy;
var rpc = 0;
var foot = false;
var time = 0;


function setup() {
    createCanvas(480, 480);
    rectMode(CENTER);

    stroke(255);
    strokeWeight(6);
    strokeJoin(MITER);
    strokeCap(PROJECT);

    //initialize all of the ants (which are actually each of type turtle)
    for (var i = 0; i < 100; i++) {
        ants[i] = makeTurtle(random(0, width), random(0, height));
        ants[i].face(random(0, 360));
        ants[i].penDown();
        ants[i].setWeight(4);
        ants[i].setColor(255);
    }

}

function mousePressed() {
    //when the mouse is pressed, start the foot step

    foot = true;
    time = 120;
    rpx = mouseX;
    rpy = mouseY;
}

function draw() {
    background(0);
    

    //loop through each of the ants in the list
    for (var i = 0; i < ants.length; i++) {
        var t = ants[i];


        //if a foot is coming (if the mouse has been clicked)
        //make the ants start to avoid the shadow of the foot
        if (foot) {
            var d = dist(t.x, t.y, rpx, rpy);
            var f = rpc / (Math.pow(d, 2));
            var dirx = (t.x - rpx) / d;
            var diry = (t.y - rpy) / d;
            t.x += dirx * f;
            t.y += diry * f;
        }


        //make the ant wrap around the screen
        //because there are so many, it just looks like new ones are being added
        if (t.x >= width) {
            t.x -= width;
        } else if (t.x <= 0) {
            t.x += width;
        }
        if (t.y >= height) {
            t.y -= height;
        } else if (t.y <= 0) {
            t.y += height;
        }


        //actually move the ant...finally
        t.forward(5);

    }


    //if the foot is still terrorizing the ants (if there is still time),
    //decrease the time limit and make the repellent force larger
    //otherwise, make sure the foot variable is false
    if (time != 0) {
        time--;
        rpc = map(time, 120, 0, 0, 25000);
    } else {
        foot = false;
    }

    //if the foot is more than 1/3 of a second away, draw it's growing shadow
    //otherwise, the foot will start to stomp on the ground
    if (time >= 20) {
        noStroke();
        fill(255);
        ellipse(rpx, rpy, 100 - map(time, 0, 120, 0, 100), 100 - map(time, 0, 120, 0, 100));
    } else if (time > 0 & time < 20) {
        fill(210, 180, 140);
        noStroke();
        push();
        translate(rpx, rpy);
        scale(abs(- 2.5 + time/4));
        angleMode(DEGREES);
        rotate(5);
        rect(20, 45, 50, 80, 10);
        rect(0, 0, 10, 30, 10);
        rotate(5);
        rect(10, 1, 10, 30, 10);
        rotate(5);
        rect(20, 2, 10, 30, 10);
        rotate(5);
        rect(30, 3, 10, 30, 10);
        rotate(5);
        rect(40, 4, 10, 30, 10);
        pop();
        angleMode(RADIANS);
    }

    //the help text
    fill(0);
    stroke(255);
    textSize(20);
    text("click to stomp on these poor ants", width/6 + 10, 20);

}



function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

In the process of writing my code, I realized that the turtles each look like little ants. So, I made a shadow descend upon the ants, and eventually a foot try and stomp them. Don’t worry – none of them actually die, mostly because that would be annoying to code.

Plain ol screen
here comes the foot

KadeStewart-LookingOutwards-11

Proteus cover

Proteus is an indie video game that came out in 2013, focused on exploration with an emphasis on “nonviolence”. The soundtrack is written to reflect the natural beauty within the game, which is deterministic. However, the music that reaches the player’s ears is non-deterministic because it is influenced by the player’s environment and their interactions with the environment. For example, when the player is in a dense environment, the sound is very dense. When the player is walking, the sounds behave as they do when you yourself are walking.

The video game, as stated above, is intended to reflect a nonviolent existence. The soothing music plays into the message, and the exploratory theme is emphasized by the player’s active role in how the music sounds. I think that this is a very basic but incredibly powerful method of getting the designer’s message across.

Interactive Proteus Music

KadeStewart-Project10-Landscape

planes

//Kade Stewart
//Section B
//kades
//Project-10


var planes = [];
//a variable that holds each of the colors that a plane could be
var pastels = [230, 245, 245, 255, 250, 205, 180, 236, 180];
var terrain1 = [];
var terrain2 = [];
var terrain3 = [];

function setup() {
    createCanvas(480, 480);

    //initialize a plane
    planes[(planes.length)] = new Plane();


    //add terrain that has random but connected altitudes
    var y = height/4;
    for (var i = 0; i < width; i++) {
    	terrain1.push(y += random(-1,1));
    }

   	y = height/2;
   	for (var i = 0; i < width; i++) {
    	terrain2.push(y += random(-1,1));
    } 

    y = height * (3/4);
    for (var i = 0; i < width; i++) {
    	terrain3.push(y += random(-1,1));
    }
}

function Plane() {
	this.y = random(0, height);
	this.x = width + 50;
	this.speed = floor(random(-.01, -3));    //this is the speed that the plane actually goes back
	this.path = [];    //this is where the path is stored for the plane
	this.pathspeed = this.speed * 3;    //this is the speed that the path is made
	this.c = floor(random(1,4));    //this is where the color is determined

	//this is function that draws both the plane and the path
	this.draw = function() {
		stroke(0);
		strokeWeight(1);
		fill(pastels[this.c], pastels[this.c + 1], pastels[this.c + 2]);

		triangle(this.x - (6 * -this.pathspeed/2), this.y - 9 * -this.pathspeed/2,
				 this.x + 18 * -this.pathspeed/2, this.y,
				 this.x, this.y);

		//draw the path
		if (this.path.length > 2) {
			for (var i = 1; i < this.path.length; i++) {
				stroke(125);
				strokeWeight(1);
				noFill();
				line(this.x + (this.pathspeed * (i-1)), this.path[this.path.length - i - 1],
					 this.x + (this.pathspeed * (i)), this.path[this.path.length - i]);
			}
		}
	}
}

function updatePlanes(index) {
	planes[index].x += planes[index].speed;
	planes[index].y += random(-1, 1);

	//if the plane is past the window, delete it
	if (planes[index].x - (18 * planes[index].pathspeed/2) < 0) {
		planes.splice(index, 1);
	}
}

function updatePath(index) {
	var p = planes[index];

	//add the planes current position to the path to trace where it's been
 	p.path.push(p.y);

 	//if the path is longer than the window, delete what's outside of the window
	if (p.path.length * p.pathspeed > width) {
		p.path.splice(0, 1);
	}
}

function randomlyMakePlane(odds) {
	//this is the randomizer that decided whether the plane is made or not
	var newPlaneMaybe = random(-odds + 1, 1);
	if (newPlaneMaybe > 0) {
		planes[(planes.length)] = new Plane();
	}
}

//draw 3 different tiers of background, to give a sense of depth
function drawTerrain() {
	for (var j = 0; j < width; j++) {
		stroke(255, 241, 245);
		strokeWeight(5);
		noFill();
		line(j, terrain1[j], j, height);
	}
	for (var j = 0; j < width; j++) {
		stroke(255, 235, 239);
		strokeWeight(5);
		noFill();
		line(j, terrain2[j], j, height);
	}
	for (var j = 0; j < width; j++) {
		stroke(255, 209, 220);
		strokeWeight(5);
		noFill();
		line(j, terrain3[j], j, height);
	}
}

function updateTerrain() {
	terrain1.splice(0, 1);
	terrain1.push(terrain1[terrain1.length-1] + random(-1, 1));
	terrain2.splice(0, 1);
	terrain2.push(terrain2[terrain2.length-1] + random(-1, 1));
	terrain3.splice(0, 1);
	terrain3.push(terrain3[terrain3.length-1] + random(-1, 1));
}

function draw() {
	background(255, 250, 253);

	//this is where the terrain is drawn and then generated
	drawTerrain();
	updateTerrain();

	for (var i = 0; i < planes.length; i++) {
		var p = planes[i];

		//draw the planes
		planes[i].draw();

		//update its path
		updatePath(i);

		//update its x and y position, and delete it if it's too far off the screen
		updatePlanes(i);
	}

	//**60** to 1 odds that there is a new plane made (about 1 every second)
	randomlyMakePlane(60);

}

Sketch of my paper airplane landscape

I wanted to make a generative landscape that wasn’t just actual land, or even anything that was extremely natural, but something more artificial. I came up with paper airplanes, which ended up being an interesting challenge. I randomly generated airplanes that were large and fast to look closer to the viewer (who’s reference frame was moving forward) or small and slow to seem farther away. The background, varying pink levels, also moves to increase the viewer’s sense that they’re moving as well. Overall, I think I achieved my goal of giving the viewer a sense of wonderment.

KadeStewart-LookingOutwards-10

Advertisement for Meshu (2018)

Rachel Binx is a data visualizer and designer currently working at Netflix. At one point, she worked on a project called Meshu, which creates clothing accessories based on locations that a person marks. They’re meant to be reminders of trips or places from home. The location data is interpreted through Mapzen and comes from OpenStreetMaps.

Image of Binx

After attending Santa Clara University for Mathematics and Art History, Binx worked at Mapzen, NASAJPL, and Stamen Design, before landing at Netflix. She works to produce physical objects or computational visualizations out of data that is meaningful to each person. Binx’s dedication to making data concrete and beautiful to keep its meaning is so inspiring to me!

Rachel Binx’s Website

Meshu

KadeStewart-Project09-Portrait

sketch

//Kade Stewart
//Section B
//kades
//Project-09


var pic;
var bar = 0;
var barspeed = 5;


function preload() {
    pic = loadImage("https://i.imgur.com/TQDoVD9.png");
}


function setup() {
    createCanvas(480, 480);
}

function draw() {

	//resets the image every time draw is called
	image(pic, 0, 0);
	loadPixels(pic);


	// loop thru each row
	for (var y = 0; y < height; y++) {

		//every row, shift the pixels over some random amount
		//the limit is dictated by how recently an invisible bar has passed over it
		var limit = floor( ( ( (height + bar) - y) % height ) / 10 );
		var shift = floor(random(0, limit));

		// if (limit > 10) {
		// 	continue;
		// }

		// inner loop that goes thru each pixel in the row
		for (var x = 0; x < width; x++) {

			//this is the way to target each pixel in the pixels array
			var i = ( ( (x + shift) % width ) + y * width ) * 4;

			//setting the color of a pixel to the one a certain number away
			//pixels[i] is the red, [i+1] is the green, [i+2] is the blue
			set(x,y, color(pixels[i], pixels[i + 1], pixels[i + 2]))

		}

	}

	//actually draws the pixels as dictated above
	updatePixels();

	//moves the invisible bar down, wrapping when it hits the bottom
	bar = (bar + barspeed) % height;

}

Example of radar screen I wanted to emulate

I wanted to make a portrait that emulated the updating of a radar screen. While I didn’t do it exactly, I ended up using a downward moving bar to update the portrait. At first, it was wiping the screen to black. My final has the invisible bar resolving a horizontal shift in the bars of pixels.

KadeStewart – LookingOutwards – 09

The Cat Explorer footage (Leap Motion, 2018)

Helen Reynolds highlighted an interesting project in her Looking Outwards 01. As she says, the Cat Explorer is both simple and informative. This combination makes important information accessible, which is perfect for a project, such as this, that brings niche information outside of its usual group. The Cat Explorer motivates me with its simplicity and potential for impact.

The Cat Explorer

KadeStewart-LookingOutwards-08

A screencap from Posavec’s 2018 talk that emphasizes qualitative data and Posavec’s hand-drawn style

Hailing from Denver and currently living in London, Stefanie Posavec is artist and designer who focuses on data that is more qualitative than quantitative/computational. That is not to say that her data visualization is uninformative, as the project below is chock-full of information. I love that no matter what data she collects, she finds it important. This is apparent all over her work, from the picture above that appeared in her talk at Eyeo 2018 to her postcards-turned-book-turned-MoMA collection called Dear Data.

Data visualization done by Posavec from an album by OK GO that led to the album’s art

Posavec’s style of presentation is very conservative, treating every piece of her work equally. This is mirrored in her work, as she says that she strives to treat each piece of process with the same importance as the final product. Her slides are not touched up for presentation, but are often just raw drawings of random bits of data. This is inspiring to me as I value the iterative process of creating, but I really struggle to treat everything as important like the final product. The idea that everything matters, from bits of data collected to the thrown out ideas to the final presentation that you give, is substantial and makes the creative process much more interesting in my eyes.

 

Stefanie Posavec’s 2018 Talk – Anoraks and the Analogue

Stefanie Posavec’s Website