[OLD FALL 2018] 15-104 • Introduction to Computing for Creative Practice https://courses.ideate.cmu.edu/15-104/f2018 Professor Roger B. Dannenberg • Fall 2018 • Introduction to Computing for Creative Practice Sat, 12 Sep 2020 00:17:52 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.25 Yiran Xuan – Final Project – Dueling Dragons https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/yiran-xuan-final-project-dueling-dragons/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/yiran-xuan-final-project-dueling-dragons/#respond Sat, 08 Dec 2018 06:17:50 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39273 Continue reading "Yiran Xuan – Final Project – Dueling Dragons"]]>
/*
Yiran Xuan
Section A
yxuan@andrew.cmu.edu
Final Project
*/

var redframes = []; // array for red dragon sprites
var blueframes = []; //array for blue dragon sprites

var beat; //sound variables
var impact;
var fire;
var growl;
var charge;
/*
status key:
0 = default
1 = attack
2 = shield
4 = impact
5 = shielded impact
6 = death (not real status)
*/

//---------------------------------------
//each sprite's index in array should match the status it represents
//ex) the red dragon's default sprite should have index of zero
/*

*/

//default
//attack
//shield
//impact
//shielded impact
//death

}

//--------------------------------------- Game Process functions

var RedDragon;
var BlueDragon;

var deadframecounter = 0; //after the endgame, counts number of frames before the game restarts

var cycle = 24; //number of frames in a cycle
var secondspercycle = 1; //how long one cycle
var framerate = cycle/secondspercycle;
var framecounter = 0; //counts frames to control the cycle

var actionwindow = cycle*2/3; //window for player input

function setup() {
createCanvas(600, 400);
imageMode(CENTER);

textStyle(BOLD);
textAlign(CENTER);
frameRate(framerate);

RedDragon = createDragon(3, 0, 1, redframes); //start with one health and no ammo
BlueDragon = createDragon(3, 0, -1, blueframes);

}

var redturn = true; //becomes false once a player has made move, ensures each player only makes one action per round
var blueturn = true;

function draw() {
background('white');

if(RedDragon.death || BlueDragon.death){ //if one dragon had died, just display default renders
GameEnd();
}

else{
if(framecounter < actionwindow){ //Stage 1: allowing player action input, displaying default renders
fill('green');
RedDragon.DefaultRender();
BlueDragon.DefaultRender();
}

else if (framecounter == actionwindow){ //Stage 2: processing player actions
fill('red');
RedDragon.Action();
BlueDragon.Action();
RedDragon.opponentaction = BlueDragon.currentaction;
BlueDragon.opponentaction = RedDragon.currentaction;
}
else if (framecounter < cycle*5/6){ //Stage 3: display player actions
fill('red');
RedDragon.ActionRender();
BlueDragon.ActionRender();
}
else if (framecounter == cycle*5/6){ //Stage 4: process opponent actions and end result
fill('red');
RedDragon.Result();
BlueDragon.Result();
}
else{ //Stage 5: display result of interaction
fill('red');
RedDragon.ResultRender();
BlueDragon.ResultRender();
}

framecounter++; //framecounter is here music stops after end of the game
}

textSize(30);
fill('green');
text("Health: " + RedDragon.health, RedDragon.x, RedDragon.y - 75); //display current healths
text("Health: " + BlueDragon.health, BlueDragon.x, BlueDragon.y - 75);

textSize(15);
fill('red');
text("J to attack, K to shield, L to reload", RedDragon.x, RedDragon.y - 125); //display current healths
fill('blue');
text("A to attack, S to shield, D to reload", BlueDragon.x, BlueDragon.y - 125);

if (framecounter == cycle){ //when cycle is complete
framecounter = 0;
redturn = true; //allows players action again
blueturn = true;
RedDragon.Reset(); //and reset round variables (currentmove, opponentmove, status)
BlueDragon.Reset();
beat.play();//beat starts playing here
}
}

//--------------------------------------- Event functions

function GameEnd(){

RedDragon.DefaultRender(); //display the dragons; DefaultRender contains death render as well
BlueDragon.DefaultRender();

var winner = "Nobody"; //default is draw
if(RedDragon.health > BlueDragon.health){ //comparing health to determine victor
winner = "Red Dragon";
}
if(RedDragon.health < BlueDragon.health){
winner = "Blue Dragon";
}

fill('black');
textSize(50);
text(winner + " Wins!", width/2, 75); //writing victory text

}

}

function keyPressed(){
if(key == 'a' || key == 's' || key == 'd'){ //is the pressed key a valid blue action?
if(framecounter < actionwindow & blueturn){ //is it within the action window, and has blue made a move already?
switch(key){
case 'a':
BlueDragon.currentaction = 1; //A to fire
break;
case 's':
BlueDragon.currentaction = 2; //S to shield
break;
case 'd':
BlueDragon.currentaction = 3; //D to reload
break;
}
blueturn = false; //blue has spent its move
}
}

if(key == 'j' || key == 'k' || key == 'l'){ //is the pressed key a valid red action?
if(framecounter < actionwindow & redturn){ //is it within the action window, and has blue made a move already?
switch(key){
case 'j':
RedDragon.currentaction = 1; //A to fire
break;
case 'k':
RedDragon.currentaction = 2; //S to shield
break;
case 'l':
RedDragon.currentaction = 3; //D to reload
break;
}
redturn = false; //red has spent its move
}
}
}

//--------------------------------------- Dragon creation functions

function createDragon(startinghealth, startingammo, drdirection, drsprites) {
var dragon = {

health: startinghealth,
death: 0,
ammo: startingammo,
shield: false,
status: 0,
currentaction: 0, //action key: 0 = nonaction, 1 = shoot, 2 = shield, 3 = reload
opponentaction: 0,

direction: drdirection,
sprites: drsprites,
x: width/2 + drdirection*150, //where to render the sprite
y: 225,

Action: dragonAction, //processing gameplay
Result: dragonResult,
Reset: dragonReset,
GameOver: isAlive,

ActionRender: dragonActionRender,
ResultRender: dragonResultRender,
DefaultRender: dragonDefaultRender };
return dragon;
}

/*
status key:
0 = default
1 = attack
2 = shield
4 = impact
5 = shielded impact
6 = death (not real status)
*/

function dragonAction(){ //function to process dragon's action
switch(this.currentaction){ //processing currentaction
case 0: //if no action
break;

case 1: //if attacking
if(this.ammo == 0){
this.currentaction = 0; //if attempted to attack without ammo, will change to no action
}
else{
this.ammo--;
fire.play();
}
break;

case 2: //if shielding
this.shield = true;
break;

charge.play();
break;
}

this.ActionRender();
}

function dragonResult(){//function to process result of both dragon's actions
this.status = this.currentaction; //by default, status is the same as action

if(this.opponentaction == 1){ //unless attacked by other dragon
if(this.shield){
this.status = 5; //shield is up, attack is blocked
impact.play();
}
else{
this.status = 4;
this.health--; //otherwise, attack hits, takes damage
impact.play();
}
}
this.GameOver();
this.ResultRender();
}

function isAlive(){ //checks if dragon is alive or dead
if (this.health < 1){
this.death = 1;
growl.play();
}
else this.death = 0;
}

function dragonActionRender(){ //function to display the dragon
image(this.sprites[this.currentaction], this.x, this.y, 300, 225);
}

function dragonResultRender(){ //function to display the dragon
image(this.sprites[this.status], this.x, this.y, 300, 225);
}

function dragonDefaultRender(){
image(this.sprites[this.death*6], this.x, this.y, 300, 225); //renders either alive or dead state

}

function dragonReset(){ //resets the dragon actions and status to default at the end of the round
this.currentaction = 0;
this.status = 0;
this.opponentaction = 0;
this.shield = false;
}

(Using 1 Grace Day.)

(Recommend clicking the game to start it)

Dueling Dragons is the virtual, 1-computer-2-players version of the playground game “Shotgun”, in which players attempt to defeat their opponent by playing one of 3 moves (shoot, shield, reload) in accordance to a beat, usually clapping twice.

In my version, two dragons are fighting each other while “We Will Rock You”s stomp-stomp-clap plays; The final clap is starts a short time window in which both players can perform an action using the keys displayed.

Each player starts with 3 health and no ammo. Health is displayed, but ammo isn’t, for tactical reasons.

A player can make 4 moves:
0) no action (don’t press a key or press it out of the timing window); left vulnerable
1) attack; will expend an ammo only if there is any, otherwise will become no action
2) shield; protects the player from damage
3) reload; increases ammo by one, can increase indefinitely. A reload is still successful even if the player is damaged.

If both players are attacked, both of them will suffer damage

The game continues until at least one player’s health drops to zero, after which a win screen appears for 3 seconds, and then the page attempts to refresh (recommend manually refreshing the page)

Of course, there are sound effects!

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/yiran-xuan-final-project-dueling-dragons/feed/ 0
Hannah Cai—Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/hannah-cai-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/hannah-cai-final-project/#respond Sat, 08 Dec 2018 05:01:11 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39182 Continue reading "Hannah Cai—Final Project"]]>

(The audio seems to only work in wordpress on Chrome).

instructions:
hover over points to hear their pitches.
click points to activate them.
click points again to deactivate them.
clicked points that are close enough to each other will link to each other. (try not to link too many or the program will lag lol)
explore and enjoy the soundscape!

/* Hannah Cai
Section C
hycai@andrew.cmu.edu
Final Project
*/

//particle position arrays
var particleNumber = 200; //number of particles
var psize = 1.5; //particle size
var px = []; //particle x position
var py = []; //particle y position
var pz = []; //particle z position
var distanceToPoint; //dist from (mouseX, mousY) to (px, py)
var amplitude = 3.14 * 3; //amplitude of bobbing animation
var waveSpeed; //speed of bobbing animation
var theta = 0; //plugin for sin()

//particle sound arrays
var threshold = 100; //minimum distance between mouse and particle to trigger glow/sound
var notes = [130.81, 146.83, 164,81, 174.61, 196, 220, 246.94, //pitches of whole notes from C3
261.63, 293.66, 329.63, 349.23, 392.00, 440, 493.88,
523.25, 587.33, 659.25, 698.46, 783.99, 880, 987.77,
1046.5, 1174.66, 1318.51, 1396.91, 1567.98, 1760, 2093]; //to C7
var ppitch = []; //pitch values for each particle
var pOsc = []; //oscillator for each particle
var pvolume = 0; //volume of each particle
var pOscOn = []; //array of booleans for if the oscillators are on

//misc other particle arrays
var pClicked = []; //array of booleans for if the particle was clicked
var glowSize; //size of particle glow

//arrays for cursor
var xarray = [0, 10, 20, 30, 40, 50];
var yarray = [0, 10, 20, 30, 40, 50];
var s;

//arrays for camera and perspective
var camX;
var camY;
var camZ;
var rotateX;
var rotateY;

//arrays for lines between particles
var connect = [];
var connectionThreshold = 500;

function setup() {
createCanvas(windowWidth, windowHeight, WEBGL); //fit canvas to window size

//set up variables; store in arrays
for (i = 0; i < particleNumber; i++) {
px.push(random(-width * 0.8, width * 0.8));
py.push(random(-height, height));
pz.push(random(-width, height / 2));
ppitch.push(notes[floor(random(0, notes.length))]);
pOscOn.push(false);
pClicked.push(false);
makeOsc(i);
}
}

function makeOsc(index) {
myOsc = new p5.SinOsc();
myOsc.freq(ppitch[index]);
pOsc.push(myOsc); //store oscillators in pOsc array
}

function playOsc(index) {
var maxVolume = 0.01;
pvolume = constrain(pvolume, 0, maxVolume);
//turn clicked particles permanently on
if (pClicked[index] === true) {
pvolume = maxVolume;
} else {
//unclicked particles get louder as the mouse gets closer
pvolume = map(distanceToPoint, threshold, 0, 0, maxVolume);
}
//make particles with lower pitches louder, so all ranges are heard clearly
var factor =  map(ppitch[index], ppitch[0], ppitch[ppitch.length - 1], 5, 1);
pvolume *= factor;
pOsc[index].amp(pvolume);
}

function stopOsc(index) {
pOsc[index].stop();
}

function draw() {
background(0);
noStroke(); //get rid of default black stroke

//map camera position to mouse position to simulate orbit control
camX = map(mouseX, 0, width, -width / 2, width / 2);
camY = map(mouseY, 0, height, -height / 2, height / 2);
camZ = (height/2.0) / tan(PI*30.0 / 180.0);
camera(camX, camY, camZ, 0, 0, 0, 0, 1, 0);

//set up particles
for (i = 0; i < particleNumber; i++) {
drawLines(i); //draw lines between clicked particles
//create bobbing movement

waveSpeed = map(pz[i], -width, height, 20000, 70000); //create parallax effect
theta += (TWO_PI / waveSpeed);
if (theta > amplitude) {
theta = -theta;
}
py[i] += sin(theta);

push();
translate(px[i], py[i], pz[i]);
drawGlow(i); //draw glow of each particle
//draw each particle
fill(255);
smooth();
sphere(psize);
pop();

//play a particle's oscillator if the mouse's
//distance is less than the threshold
if (distanceToPoint <= threshold) {
if (pOscOn[i] == false) {
pOsc[i].start();
pOscOn[i] = true;
}
playOsc(i);
}

//stop a particle's oscillator if the mouse's
//distance is greater than the threshold
if (distanceToPoint > threshold & pClicked[i] == false) {
stopOsc(i);
pOscOn[i] = false;
}
}

//cursor
noCursor(); //turn off the cursor icon, display below instead
//this is basically the code from the snake lab we did
for (var i = 0; i < xarray.length; i++) {
fill(255, 255, 200);
s = 8 - (xarray.length - i);
ellipse(xarray[i], yarray[i], s, s);
}
xarray.push(mouseX - width / 2);
yarray.push(mouseY - height / 2);
if (xarray.length > 8) {
xarray.shift();
yarray.shift();
}
}

function drawGlow(index) {
push();
noStroke();
//rotate the (flat) ellipses to face the cameras to simulate 3d glow
rotateX(radians(map(camY, -height / 2, height / 2, 40, -40)));
rotateY(radians(map(camX, -width / 2, width / 2, -45, 45)));

//calculate distance from mouse to each point
distanceToPoint = dist(mouseX - width / 2, mouseY - height / 2, px[index], py[index]);

//clicked particles have a pulsing glow;
//unclicked particles glow when the mouse hovers close to them
if (pClicked[index] === true) {
glowSize = map(sin(theta), TWO_PI, 0, psize, 100);
} else {
glowSize = map(distanceToPoint, 100, psize, psize, 100);
}
for (r = psize; r < glowSize; r += 1.5) {
fill(255, 255, 200, map(r, psize, glowSize, 2, 0));
ellipse(0, 0, r);
}
pop();
}

function drawLines(index) {
push();
//push the indices of clicked particles in the "connect" array;
//turn off/remove particles from the array if clicked again
if (pClicked[index] == true & ! connect.includes(index)) {
connect.push(index);
} else if (pClicked[index] == false) {
connect.splice(index, 1);
}

//connect groups of particles that are clicked if the distance between is less than the threshold
stroke(255);
strokeWeight(1);
noFill();
for (i = 0; i < connect.length; i++) {
for (j = i + 1; j < connect.length; j++) {
if (dist(px[connect[i]], py[connect[i]], pz[connect[i]],
px[connect[j]], py[connect[j]], pz[connect[j]]) < connectionThreshold) {
beginShape(LINES);
vertex(px[connect[i]], py[connect[i]], pz[connect[i]]);
vertex(px[connect[j]], py[connect[j]], pz[connect[j]]);
endShape();
}
}
}
noStroke();
pop();
}

//if window is resized, refit the canvas to the window
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}

function mouseClicked() {
for (i = 0; i < particleNumber; i++) {
distanceToPoint = dist(mouseX - width / 2, mouseY - height / 2, px[i], py[i]);
//toggle pClicked on and off if mouse clicks within 10 pixels of a particle
if (distanceToPoint < 10 & pClicked[i] == false) {
pClicked[i] = true;
} else if (distanceToPoint < 10 & pClicked[i] == true) {
pClicked[i] = false;
}
}
}

Here’s a zip file for the fullscreen version.
final project fin

There are still a few bugs I’m aware of that I don’t know how to fix:
1. sometimes the links will flicker, adding another grouped point sometimes fixes it
2. sometimes the volume is louder than it should be upon refreshing/starting the program. I constrained the volume to try and avoid this but it didn’t seem to help
3. sometimes all the oscillators start off turned on upon refreshing/starting the program (if you move your mouse close to a point, the sine wave will start and stop, instead of fading in and out).

Generally, refreshing the page fixes all of these bugs, so please refresh the page if you notice any of the above!

I enjoyed this project a lot. Even though I spent a lot of time struggling and debugging, I feel like I learned a lot about both WEBGL and using sound/oscillators. I’m pretty satisfied in the final visual effects as well, although unfortunately, the program will start to lag if too many linked points are formed. Also unfortunately, my aim with this project was to familiarize myself more with objects, but I was completely stuck trying to format things in objects so I made everything with a ton of arrays instead. I definitely want to revisit this project in the future and format it properly with objects. In general, I definitely want to keep adding to this project because it’s still pretty clunky and buggy right now. I was planning to add a start screen, instructions, the ability to record audio, and different modes (eg a “wander” mode where the cursor moves around on its own), but I didn’t have time to even try implementing most of those before the deadline. In the future, though, I definitely want to try and make this something that could be a standalone interactive website (and add it to my portfolio, lol).

In general, I loved this class and I learned a lot! Thank you to Dannenberg and all the TAs!

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/08/hannah-cai-final-project/feed/ 0
Victoria Reiter Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/victoria-reiter-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/victoria-reiter-final-project/#comments Sat, 08 Dec 2018 04:59:33 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39235 Continue reading "Victoria Reiter Final Project"]]>
/*
Victoria Reiter
vreiter@andrew.cmu.edu
Section B
Final Project
*/

var mapImage; // loads map background
var toggledOn; // makes country bio appear
var countryVicinity; // maximum distance possible between mouseX/Y and country position
var countries = []; // array to contain all countries
var whichSelected; // array value of selected country

}

// creates each country as an object and pushes them into an array
// each country has a color, location, and image it will pop up with
function setup() {
createCanvas(1300, 659);
background(220);

var america = {
color: color(255, 255, 191),
x: 120,
y: 200,
}
countries.push(america);

var argentina = {
color: color(8, 104, 172),
x: 360,
y: 550,
}
countries.push(argentina);

var chile = {
color: color(8, 64, 129),
x: 320,
y: 570,
}
countries.push(chile);

var uruguay = {
color: color(43, 140, 190),
x: 420,
y: 544,
}
countries.push(uruguay);

var peru = {
color: color(78, 179, 211),
x: 340,
y: 455,
}
countries.push(peru);

var germany = {
color: color(33, 102, 172),
x: 620,
y: 200,
}
countries.push(germany);

var france = {
color: color(54, 144, 192),
x: 550,
y: 230,
}
countries.push(france);

var italy = {
color: color(166, 189, 219),
x: 640,
y: 230,
}
countries.push(italy);

var britain = {
color: color(5, 112, 176),
x: 565,
y: 175,
}
countries.push(britain);

var australia = {
color: color(190, 186, 218),
x: 1105,
y: 530,
}
countries.push(australia);

var newZealand = {
color: color(142, 56, 142),
x: 1235,
y: 595,
}
countries.push(newZealand);

var cameroon = {
color: color(129, 15, 124),
x: 650,
y: 400,
}
countries.push(cameroon);

var nicaragua = {
color: color(2, 56, 88),
x: 300,
y: 363,
}
countries.push(nicaragua);

color: color(4, 90, 141),
x: 260,
y: 125,
}

var moldova = {
color: color(158, 80, 170),
x: 715,
y: 220,
}
countries.push(moldova);

var spain = {
color: color(116, 169, 207),
x: 585,
y: 250,
}
countries.push(spain);

var china = {
color: color(146, 197, 222),
x: 975,
y: 265,
}
countries.push(china);

var haiti = {
color: color(141, 10, 135),
x: 220,
y: 330,
}
countries.push(haiti);

var hongKong = {
color: color(74, 126, 195),
x: 975,
y: 330,
}
countries.push(hongKong);

var indonesia = {
color: color(152, 78, 163),
x: 1040,
y: 430,
}
countries.push(indonesia);

var nepal = {
color: color(140, 107, 177),
x: 910,
y: 300,
}
countries.push(nepal);

color: color(158, 188, 218),
x: 300,
y: 430,
}
}

function draw() {
image(mapImage, 0, 0);

// rectangle pop up of information will pop up if toggledOn is turned on
if (toggledOn) {
image(countries[whichSelected].img, 200, 25, width - 400, height - 25);

}
}

// based on location and pixel color, the specific country will be identified
function mousePressed() {
toggledOn = false;
countryVicinity = 200;
var colorAtMouseX = mapImage.get(mouseX, mouseY);
var transformedColorAtMouseX = color(colorAtMouseX[0], colorAtMouseX[1], colorAtMouseX[2], colorAtMouseX[3]);
//whichSelected = what? your if statement is essentially going to check which item in the array of countries is the right one!
for(var i = 0; i < countries.length; i++) {
if ((dist(countries[i].x, countries[i].y, mouseX, mouseY) < countryVicinity)) {
// print((countries[i].color).toString());
// print((transformedColorAtMouseX).toString());
if ((countries[i].color).toString() == transformedColorAtMouseX.toString()) {
whichSelected = i;
toggledOn = true;
}
}

}
}

My final project! An interactive map of places I’ve been and places where I know people from. Click a country and explore what I’ve explored!

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/victoria-reiter-final-project/feed/ 1
Yingyang Zhou-Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/yingyang-zhou-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/yingyang-zhou-final-project/#respond Sat, 08 Dec 2018 04:58:03 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39190 Continue reading "Yingyang Zhou-Final Project"]]>

Instruction:
-press blank space for next line
-press “a” when you see the line you like
-press “g” for generating your poem
(your poem will be on top but you can press blank space to keep skimming the rest of the poem)
//running this on website, you probably need to click the canvas first because the blank space key is conflict with the scrolling down on web page.

//Yingyang Zhou
//yingyanz@andrew.cmu.edu
//Final Project
//section A

var poemRilke = "After_the summer's_yield_Lord_it is_time_to let_your shadow_lengthen_on the sundials_and in the pastures_let_the rough winds_fly_As for_the final fruits_coax them_to roundness_Direct_on them_two days of warmer light_to hale them golden_toward their term_and harry_the last few drops_of sweetness_through the wine.";
var words = poemRilke.split("_");
var num = 0;
var numMy = 0;
var l = 0;
var speed = 1;
var myPoem = [];

var inc = 0.1;
var scl = 10;
var cols, rows;
var zoff = 0;
var particles = [];
var flowfield;

// }

function setup() {
createCanvas(400, 400);
colorMode(RGB, 255);
cols = floor(width / scl);
rows = floor(height / scl);

flowfield = new Array(cols * rows);

for (var i = 0; i < 300; i++) {
particles[i] = new Particle();
}
background(255);

// var button = createButton("generate my poem");
// button.mousePressed(generatePoem);
}

function draw() {

var yoff = 0;
for (var y = 0; y < rows; y++) {
var xoff = 0;
for (var x = 0; x < cols; x++) {
var index = x + y * cols;
var angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
var v = p5.Vector.fromAngle(angle);
v.setMag(1);
flowfield[index] = v;
xoff += inc;
stroke(0);
}
yoff += inc;
zoff += 0.0003;
}

for (var i = 0; i < particles.length; i++) {
particles[i].follow(flowfield);
particles[i].update();
particles[i].edges();
particles[i].show();
}
for(var i = 0; i < words.length; i++){
textAlign(CENTER, CENTER);
fill(50, 50, 50, random(10));
textFont("Segoe Script");
// stroke(50, 50, 50, random(10));
strokeWeight(0.5);
text(words[l-1], width/2, 20*(num+1) - speed);
}

if(num > 18){
num = 0;
reset();
}
if(l > words.length){
l = 0;
}

// whiteNoise.play();
}
function reset(){

flowfield = new Array(cols * rows);

for (var i = 0; i < 300; i++) {
particles[i] = new Particle();
}
background(255);
}

function generatePoem(){
background(220);
// var randomLine;
for(var i = 0; i < myPoem.length; i++){
stroke(0);
text(myPoem[i], width/2, 20*(i+1));
}

}

function Particle() {
this.pos = createVector(random(width), random(height));
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.maxspeed = 4;
this.h = 0;

this.prevPos = this.pos.copy();

this.update = function() {
this.vel.limit(this.maxspeed);
this.acc.mult(0);
}

var x = floor(this.pos.x / scl);
var y = floor(this.pos.y / scl);
var index = x + y * cols;
var force = vectors[index];
this.applyForce(force);
}

this.applyForce = function(force) {
}

this.show = function() {
stroke(this.h, 5);
this.h = this.h + 1;
if (this.h > 255) {
this.h = 0;
}
strokeWeight(1);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.updatePrev();
}

this.updatePrev = function() {
this.prevPos.x = this.pos.x;
this.prevPos.y = this.pos.y;
}

this.edges = function() {
if (this.pos.x > width) {
this.pos.x = 0;
this.updatePrev();
}
if (this.pos.x < 0) {
this.pos.x = width;
this.updatePrev();
}
if (this.pos.y > height) {
this.pos.y = 0;
this.updatePrev();
}
if (this.pos.y < 0) {
this.pos.y = height;
this.updatePrev();
}

}

}

function keyTyped(){
if(key === ' '){
num ++;
numMy ++;
l ++;
}
if(key === 'a'){
myPoem.push(words[l-1]);
for(var i = 0; i < 5; i++){
print(myPoem[i]);
}

}
if(key ==='g'){
generatePoem();
}

}

For the final, I was initially had idea doing something more related to sound but realized that would be hard on WordPress website, so I change the idea a little bit.

I was always interested the what random can do for programming, it always turn out surprising. I had idea of gerating a poem of my own, from the pecies of poem/sentence/paragraph, poem is sometime a collection of different fragaments.

This program shows here as from an example, it is a poem I like very much from Rilke, a germany poet.

I use perlin noise keep running as a dynamic background, which I am very pleased I had it working.

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/yingyang-zhou-final-project/feed/ 0
Xindi Lyu_Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/xindi-lyu_final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/xindi-lyu_final-project/#respond Sat, 08 Dec 2018 04:56:23 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39223 Continue reading "Xindi Lyu_Final Project"]]>
var puzzle1A = [
{ x:40, y:40,active: false,color:138 },

]
var puzzle1B = [
{ x:40, y:120,active: false,color:138 },

]
var puzzle1C = [
{ x:40, y:210,active: false,color:138 },

]
var puzzle1D = [
{ x:40, y:300,active: false,color:138 },

]
var puzzle1E = [
{ x:40, y:380,active: false,color:138 },

]
var puzzle1F = [
{ x:40, y:460,active: false,color:138 },

]
var puzzle1G = [
{ x:40, y:540,active: false,color:138 },

]
var puzzle2A = [
{ x:40, y:40,active: false,color:31},

]
var puzzle2B = [
{ x:40, y:120,active: false,color:31 },

]
var puzzle2C = [
{ x:40, y:200,active: false,color:31 },

]
var puzzle2D = [
{ x:60, y:280,active: false,color:31 },

]
var puzzle2E = [
{ x:40, y:350,active: false,color:31 },

]
var puzzle2F = [
{ x:40, y:430,active: false,color:31 },

]
var puzzle2G = [
{ x:40, y:510,active: false,color:31},

]
var countB1=1;
var countB2=1;
var countB3=1;
var countB4=1;
var countB5=1;
var countB6=1;
var countB7=1;

var countA1=1;
var countA2=1;
var countA3=1;
var countA4=1;
var countA5=1;
var countA6=1;
var countA7=1;
var button;

var a=28;
// Set up canvas
function setup() {
frameRate(16);
// Create canvas using width/height of window.
createCanvas(500, 600);
rectMode(CENTER);
a=a+1;
}

// Draw on the canvas.
function draw() {
background(100,48,40);
stroke(50,48,40)
strokeWeight(1.3);
line(0,400,600,400);
noStroke();
fill(49,48,46);
rect(380,360,60+random(0,5),80+random(0,3));
rect(120,360,60+random(0,5),80+random(0,3));
textSize(15);
fill(random(100,105));

text("1800",360,360);
text("1662",100,360);
textStyle(BOLD);
textSize(15);

fill(100);
text("CLICK TO ENTER",50,500);
text("CLICK TO ENTER",350,500);

if(a==20){
puzzle2();
}else if(a==10){
puzzle1();
}

}
function mouseClicked(){
if(350<mouseX){
a=20;
}else if(mouseX<150){
a=10;
}
}
function puzzle1() {
background(67,99,138);
stroke(67,99,138);
var countA=countA1+countA2+countA3+countA4+countA5+countA6+countA7;

//triangle(288,160,358,160,323,195);
if (puzzle1A.length > 0) {
for (var i = 0; i < puzzle1A.length; i++) {

var ta=puzzle1A[i];
var dist1A=dist(ta.x,ta.y,323,171.67)

if(dist1A<10&mouseIsPressed){
ta.x=323;
ta.y=171.67
countA1=0
}
noFill();
stroke(ta.color-71,ta.color-39,ta.color);
triangle(288,160,358,160,323,195);
stroke(67,99,138);
fill(28,41,81);
triangle(ta.x-35,ta.y-11.67,ta.x,ta.y+23.33,ta.x+35,ta.y-11.67);
}
}

if (puzzle1B.length > 0) {
for (var i = 0; i < puzzle1B.length; i++) {

var tb=puzzle1B[i];
var dist1B=dist(tb.x,tb.y,305.5,211)

if(dist1B<10&mouseIsPressed){
tb.x=305.5;
tb.y=211
countA2=0
}
noFill();
stroke(tb.color-71,tb.color-39,tb.color);
beginShape();
vertex(288,228);
vertex(323,261);
vertex(323,195);
vertex(288,160);
endShape(CLOSE)
stroke(67,99,138);
fill(28,41,81);
beginShape();
vertex(tb.x-17.5,tb.y+17);
vertex(tb.x+17.5,tb.y+50);
vertex(tb.x+17.5,tb.y-16);
vertex(tb.x-17.5,tb.y-51);
endShape(CLOSE);
}
}
if (puzzle1C.length > 0) {
for (var i = 0; i < puzzle1C.length; i++) {

var tc=puzzle1C[i];
var dist1C=dist(tc.x,tc.y,288,262)

if(dist1C<10&mouseIsPressed){
tc.x=288;
tc.y=262;
countA3=0
}
noFill();
stroke(tc.color-71,tc.color-39,tc.color);
beginShape();
vertex(288,228);
vertex(323,261);
vertex(288,298);
vertex(253,261);
endShape(CLOSE)
stroke(67,99,138);
fill(28,41,81);
beginShape();
vertex(tc.x,tc.y-34);
vertex(tc.x+35,tc.y-1);
vertex(tc.x,tc.y+36);
vertex(tc.x-35,tc.y-1);
endShape(CLOSE);
}
}
fill(28,41,81);

if (puzzle1D.length > 0) {
for (var i = 0; i < puzzle1D.length; i++) {

var td=puzzle1D[i];
var dist1D=dist(td.x,td.y,253,285.67)

if(dist1D<10&mouseIsPressed){
td.x=253;
td.y=285.67;
countA4=0
}
noFill();
stroke(td.color-71,td.color-39,td.color);
triangle(253,261,288,298,218,298);
stroke(67,99,138);
fill(28,41,81);
triangle(td.x,td.y-24.67,td.x+35,td.y+12.33,td.x-35,td.y+12.33);
}
}
fill(28,41,81);
if (puzzle1E.length > 0) {
for (var i = 0; i < puzzle1E.length; i++) {

var te=puzzle1E[i];
var dist1E=dist(te.x,te.y,234.75,253.75)

if(dist1E<10&mouseIsPressed){
te.x=234.75;
te.y=253.75;
countA5=0
}
noFill();
stroke(te.color-71,te.color-39,te.color);
beginShape();
vertex(209,253.75);
vertex(234.75,228);
vertex(260.5,253.75);
vertex(234.75,279.5);
endShape(CLOSE)
stroke(67,99,138);
fill(28,41,81);
beginShape();
vertex(te.x-25.75,te.y);
vertex(te.x,te.y-25.75);
vertex(te.x+25.75,te.y);
vertex(te.x,te.y+25.75);
endShape(CLOSE);
}
}
if (puzzle1F.length > 0) {
for (var i = 0; i < puzzle1F.length; i++) {

var tf=puzzle1F[i];
var dist1F=dist(tf.x,tf.y,288,315.17)

if(dist1F<10&mouseIsPressed){
tf.x=288;
tf.y=315.17;
countA6=0
}
noFill();
stroke(tf.color-71,tf.color-39,tf.color);
triangle(288,298,313.75,323.75,262.25,323.75);
stroke(67,99,138);
fill(28,41,81);
triangle(tf.x,tf.y-17.17,tf.x+25.75,tf.y+8.58,tf.x-25.75,tf.y+8.58);
}
}
if (puzzle1G.length > 0) {
for (var i = 0; i < puzzle1G.length; i++) {

var tg=puzzle1G[i];
var dist1G=dist(tg.x,tg.y,236.5,315.17)

if(dist1G<10&mouseIsPressed){
tg.x=236.5;
tg.y=315.17;
countA7=0
}
noFill();
stroke(tg.color-71,tg.color-39,tg.color);
triangle(236.5,298,262.25,323.75,210.75,323.75);
stroke(67,99,138);
fill(28,41,81);
triangle(tg.x,tg.y-17.17,tg.x+25.75,tg.y+8.58,tg.x-25.75,tg.y+8.58);
}
}
fill(28,41,81);

if (countA<1){
hint1();
}
textSize(40);
textStyle(BOLD);
fill(255);
text(countA,400,50);
}

function puzzle2() {
background(69,93,31);
stroke(69,93,31);
fill(33,64,22);
var countB=countB1+countB2+countB3+countB4+countB5+countB6+countB7;

if (puzzle2A.length > 0) {
for (var i = 0; i < puzzle2A.length; i++) {

var ka=puzzle2A[i];
var dist2A=dist(ka.x,ka.y,336.67,176.67)

if(dist2A<10&mouseIsPressed){
ka.x=336.67;
ka.y=176.67
countB1=0
}
noFill();
stroke(ka.color+38,ka.color+62,ka.color);
triangle(320,160,370,160,320,210);
stroke(69,93,31);
fill(33,64,22);
triangle(ka.x-16.67,ka.y-16.67,ka.x+33.33,ka.y-16.67,ka.x-16.67,ka.y+33.33);
}
}

if (puzzle2B.length > 0) {
for (var i = 0; i < puzzle2B.length; i++) {

var kb=puzzle2B[i];
var dist2B=dist(kb.x,kb.y,295,210)

if(dist2B<10&mouseIsPressed){
kb.x=295;
kb.y=210;
countB2=0
}
noFill();
stroke(kb.color+38,kb.color+62,kb.color);
rect(295,210,50,50);
stroke(69,93,31);
fill(33,64,22);
rect(kb.x,kb.y,50,50);
}
}

if (puzzle2C.length > 0) {
for (var i = 0; i < puzzle2C.length; i++) {

var kc=puzzle2C[i];
var dist2C=dist(kc.x,kc.y,253.33,176.67)

if(dist2C<10&mouseIsPressed){
kc.x=253.33;
kc.y=176.67
countB3=0
}
noFill();
stroke(kc.color+38,kc.color+62,kc.color);
triangle(270,210,270,160,220,160);
stroke(69,93,31);
fill(33,64,22);
triangle(kc.x+16.67,kc.y-16.67,kc.x-33.33,kc.y-16.67,kc.x+16.67,kc.y+33.33);
}
}

if (puzzle2D.length > 0) {
for (var i = 0; i < puzzle2D.length; i++) {

var kd=puzzle2D[i];
var dist2D=dist(kd.x,kd.y,325,252.5)

if(dist2D<10&mouseIsPressed){
kd.x=325;
kd.y=252.5
countB4=0
}
noFill();
stroke(kd.color+38,kd.color+62,kd.color);
beginShape();
vertex(270,235);
vertex(345,235);
vertex(380,270);
vertex(305,270);
endShape(CLOSE)
stroke(69,93,31);
fill(33,64,22);
beginShape();
vertex(kd.x-55,kd.y-17.5);
vertex(kd.x+20,kd.y-17.5);
vertex(kd.x+55,kd.y+17.5);
vertex(kd.x-20,kd.y+17.5);
endShape(CLOSE)
}
}

if (puzzle2E.length > 0) {
for (var i = 0; i < puzzle2E.length; i++) {

var ke=puzzle2E[i];
var dist2E=dist(ke.x,ke.y,370,235)

if(dist2E<10&mouseIsPressed){
ke.x=370;
ke.y=235
countB5=0
}
noFill();
stroke(ke.color+38,ke.color+62,ke.color);
beginShape();
vertex(345,235);
vertex(370,210);
vertex(395,235);
vertex(370,260);
endShape(CLOSE)
stroke(69,93,31);
fill(33,64,22);
beginShape();
vertex(ke.x-25,ke.y);
vertex(ke.x,ke.y-25);
vertex(ke.x+25,ke.y);
vertex(ke.x,ke.y+25);
endShape(CLOSE)
}
}

//triangle(305,270,280,295,330,295) 305 286.67;
if (puzzle2F.length > 0) {
for (var i = 0; i < puzzle2F.length; i++) {

var kf=puzzle2F[i];
var dist2F=dist(kf.x,kf.y,305,286.67)

if(dist2F<10&mouseIsPressed){
kf.x=305;
kf.y=286.67
countB6=0
}
noFill();
stroke(kf.color+38,kf.color+62,kf.color);
triangle(305,270,280,295,330,295);
stroke(69,93,31);
fill(33,64,22);
triangle(kf.x,kf.y-16.67,kf.x-25,kf.y+8.33,kf.x+25,kf.y+8.33);
}
}
//triangle(380,270,355,295,405,295);
if (puzzle2G.length > 0) {
for (var i = 0; i < puzzle2G.length; i++) {

var kg=puzzle2G[i];
var dist2G=dist(kg.x,kg.y,380,286.67)

if(dist2G<10&mouseIsPressed){
kg.x=380;
kg.y=286.67
countB7=0
}
noFill();
stroke(kg.color+38,kg.color+62,kg.color);
triangle(380,270,355,295,405,295);
stroke(69,93,31);
fill(33,64,22);
triangle(kg.x,kg.y-16.67,kg.x-25,kg.y+8.33,kg.x+25,kg.y+8.33);
}
}
if (countB<1){
hint2();
}
textSize(40);
textStyle(BOLD);
fill(255);
text(countB,400,50);
}

function mousePressed() {
if (puzzle1A.length > 0) {
for (var i = 0; i < puzzle1A.length; i++) {

var ta = puzzle1A[i];
distance1A = dist(mouseX, mouseY,ta.x,ta.y);
ta.active = true;
} else {
ta.active = false;
}
}
}
if (puzzle1B.length > 0) {
for (var i = 0; i < puzzle1B.length; i++) {

var tb = puzzle1B[i];
distance1B = dist(mouseX, mouseY,tb.x,tb.y);
tb.active = true;
} else {
tb.active = false;
}
}
}
if (puzzle1C.length > 0) {
for (var i = 0; i < puzzle1C.length; i++) {

var tc = puzzle1C[i];
distance1C = dist(mouseX, mouseY,tc.x,tc.y);
tc.active = true;
} else {
tc.active = false;
}
}
}
if (puzzle1D.length > 0) {
for (var i = 0; i < puzzle1D.length; i++) {

var td = puzzle1D[i];
distance1D = dist(mouseX, mouseY,td.x,td.y);
td.active = true;
} else {
td.active = false;
}
}
}
if (puzzle1E.length > 0) {
for (var i = 0; i < puzzle1E.length; i++) {

var te = puzzle1E[i];
distance1E = dist(mouseX, mouseY,te.x,te.y);
te.active = true;
} else {
te.active = false;
}
}
}
if (puzzle1F.length > 0) {
for (var i = 0; i < puzzle1F.length; i++) {

var tf = puzzle1F[i];
distance1F = dist(mouseX, mouseY,tf.x,tf.y);
tf.active = true;
} else {
tf.active = false;
}
}
}
if (puzzle1G.length > 0) {
for (var i = 0; i < puzzle1G.length; i++) {

var tg = puzzle1G[i];
distance1G = dist(mouseX, mouseY,tg.x,tg.y);
tg.active = true;
} else {
tg.active = false;
}
}
}
if (puzzle2A.length > 0) {
for (var i = 0; i < puzzle2A.length; i++) {

var ka = puzzle2A[i];
distance2A = dist(mouseX, mouseY,ka.x,ka.y);
ka.active = true;
} else {
ka.active = false;
}
}
}

if (puzzle2B.length > 0) {
for (var i = 0; i < puzzle2B.length; i++) {

var kb = puzzle2B[i];
distance2B = dist(mouseX, mouseY,kb.x,kb.y);
kb.active = true;
} else {
kb.active = false;
}
}
}
if (puzzle2C.length > 0) {
for (var i = 0; i < puzzle2C.length; i++) {

var kc = puzzle2C[i];
distance2C = dist(mouseX, mouseY,kc.x,kc.y);
kc.active = true;
} else {
kc.active = false;
}
}
}
if (puzzle2D.length > 0) {
for (var i = 0; i < puzzle2D.length; i++) {

var kd = puzzle2D[i];
distance2D = dist(mouseX,mouseY,kd.x,kd.y);
kd.active = true;
} else {
kd.active = false;
}
}
}
if (puzzle2E.length > 0) {
for (var i = 0; i < puzzle2E.length; i++) {

var ke = puzzle2E[i];
distance2E = dist(mouseX,mouseY,ke.x,ke.y);
ke.active = true;
} else {
ke.active = false;
}
}
}
if (puzzle2F.length > 0) {
for (var i = 0; i < puzzle2F.length; i++) {

var kf = puzzle2F[i];
distance2F = dist(mouseX,mouseY,kf.x,kf.y);
kf.active = true;
} else {
kf.active = false;
}
}
}
if (puzzle2G.length > 0) {
for (var i = 0; i < puzzle2G.length; i++) {

var kg = puzzle2G[i];
distance2G = dist(mouseX,mouseY,kg.x,kg.y);
kg.active = true;
} else {
kg.active = false;
}
}
}
return false;
}
function mouseDragged() {
if (puzzle1A.length > 0) {
for (var i = 0; i < puzzle1A.length; i++) {
var ta = puzzle1A[i];

if (ta.active) {
ta.x = mouseX;
ta.y = mouseY;
ta.color=ta.color+0.2;
break;
}

}

}
if (puzzle1B.length > 0) {
for (var i = 0; i < puzzle1B.length; i++) {
var tb = puzzle1B[i];

if (tb.active) {
tb.x = mouseX;
tb.y = mouseY;
tb.color=tb.color+0.2;
break;
}

}

}
if (puzzle1C.length > 0) {
for (var i = 0; i < puzzle1C.length; i++) {
var tc = puzzle1C[i];

if (tc.active) {
tc.x = mouseX;
tc.y = mouseY;
tc.color=tc.color+0.2;
break;
}

}

}

if (puzzle1D.length > 0) {
for (var i = 0; i < puzzle1D.length; i++) {
var td = puzzle1D[i];

if (td.active) {
td.x = mouseX;
td.y = mouseY;
td.color=td.color+0.2;
break;
}

}

}

if (puzzle1E.length > 0) {
for (var i = 0; i < puzzle1E.length; i++) {
var te = puzzle1E[i];

if (te.active) {
te.x = mouseX;
te.y = mouseY;
te.color=te.color+0.2;
break;
}

}

}
if (puzzle1F.length > 0) {
for (var i = 0; i < puzzle1F.length; i++) {
var tf = puzzle1F[i];

if (tf.active) {
tf.x = mouseX;
tf.y = mouseY;
tf.color=tf.color+0.2;
break;
}

}

}
if (puzzle1G.length > 0) {
for (var i = 0; i < puzzle1G.length; i++) {
var tg = puzzle1G[i];

if (tg.active) {
tg.x = mouseX;
tg.y = mouseY;
tg.color=tg.color+0.2;
break;
}

}

}
if (puzzle2A.length > 0) {
for (var i = 0; i < puzzle2A.length; i++) {
var ka = puzzle2A[i];

if (ka.active) {
ka.x = mouseX;
ka.y = mouseY;
ka.color=ka.color+0.2;
break;
}
}
}
if (puzzle2B.length > 0) {
for (var i = 0; i < puzzle2B.length; i++) {
var kb = puzzle2B[i];

if (kb.active) {
kb.x = mouseX;
kb.y = mouseY;
kb.color=kb.color+0.2;
break;
}
}
}
if (puzzle2C.length > 0) {
for (var i = 0; i < puzzle2C.length; i++) {
var kc = puzzle2C[i];

if (kc.active) {
kc.x = mouseX;
kc.y = mouseY;
kc.color=kc.color+0.2;
break;
}
}
}
if (puzzle2D.length > 0) {
for (var i = 0; i < puzzle2D.length; i++) {
var kd = puzzle2D[i];

if (kd.active) {
kd.x = mouseX;
kd.y = mouseY;
kd.color=kd.color+0.2;
break;
}
}
}
if (puzzle2E.length > 0) {
for (var i = 0; i < puzzle2E.length; i++) {
var ke = puzzle2E[i];

if (ke.active) {
ke.x = mouseX;
ke.y = mouseY;
ke.color=ke.color+0.2;
break;
}
}
}
if (puzzle2F.length > 0) {
for (var i = 0; i < puzzle2F.length; i++) {
var kf = puzzle2F[i];

if (kf.active) {
kf.x = mouseX;
kf.y = mouseY;
kf.color=kf.color+0.2;
break;
}
}
}
if (puzzle2G.length > 0) {
for (var i = 0; i < puzzle2G.length; i++) {
var kg = puzzle2G[i];

if (kg.active) {
kg.x = mouseX;
kg.y = mouseY;
kg.color=kg.color+0.2;
break;
}
}
}
// Prevent default functionality.
return false;
}

function hint1(){
textSize(40);
var b=0;
b=b+30;
textStyle(BOLD);

fill(67+b,99+b,138+b);
text("DODO BIRD",100,400);
textStyle(ITALIC);
text("~1662",150,450);
}

function hint2(){
textSize(40);
var b=0;
b=b+30;
textStyle(BOLD);

fill(69+b,93+b,31+b);
text("BLUEBUCK",100,400);
textStyle(ITALIC);
text("~1800",150,450);
}

This Project is inspired by Chinese puzzle and is focused on two extincted animals. The player can click left or right side of the canvas to enter either of the two puzzles. Each puzzle is consist of 7 pieces and hints will show up while the players is “stuck”. After the puzzle is completed the name of the extincted specie will reveal.

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/xindi-lyu_final-project/feed/ 0
Lingfan Jiang & Kai Zhang – Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/lingfan-jiang-kai-zhang-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/lingfan-jiang-kai-zhang-final-project/#respond Sat, 08 Dec 2018 04:51:24 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39200 Continue reading "Lingfan Jiang & Kai Zhang – Final Project"]]>
//Lingfan Jiang/ Kai Zhang
//Section B
//lingfanj@andrew.cmu.edu / kaiz1@andrew.cmu.edu
//final project

//bird variables
var g = 0.5;
var v = 0;
//upforce
var Fup = 20;
var birdx = 120;
var birdy = 240;
//pipe
var pipes = [];
var currentPipeY;
var gap = 170;
//counter
var successC = 0;
//lean degrees
var gameOn = true;
//terrain
var terrainDetail = 0.002;
var terrainSpeed = -0.001;
//clouds
var clouds = [];
var cloudsx = [];
var cloudsy = [];
var cloudsSpeed = -0.5;
var cloudsSize = [];

var gameOn = true;

var totalTime;
//board content
var level = ["Bronze", "Silver", "Gold", "Platinum", "Diamond", "Master", "王者！"]
var newcolor = ["green", "pink", "gold", "orchid", "tan", "grey", "white"]
var numbercount;

function setup() {
createCanvas(640,480);
frameRate(80);
pipes.push(makePipes());
}

function draw() {

background(170, 237, 239);

//create cloud objects
updateAndDisplayclouds();

terrain();

updateAndDisplayPipes();

drawBird(birdx, birdy);

controlBird();

//create pipe each 80 frames
if (frameCount % 90 == 0 & gameOn) {
pipes.push(makePipes());
}

if (pipes.length != 0) {
if (pipes[0].x < -50) {
pipes.shift();
}

//hit test
if (pipes[0].x < birdx + 18 & pipes[0].x + 30 > birdx - 18) {
if (birdy - 15 < pipes[0].gapY || birdy + 15 > pipes[0].gapY + gap) {
//hit indicator
fill("red");
ellipse(birdx + 5, birdy, 30, 30);
//make the pipes stop
for (var i = 0; i < pipes.length; i++) {
pipes[i].speed = 0;
}
gameOn = false;

//game over content
textAlign(CENTER);
textSize(50);
fill("orange");
text("GAME OVER", width / 2, height / 2);
fill("orange");
push();
rectMode(CENTER);
textSize(18);
rect(320, 300, 100, 50);
fill(255);
noStroke();
text("RESTART", 321, 307);
pop();

} else if (pipes[0].x == birdx - 2) {
successC ++;
}
}
}

drawBoard();
}

////////////////////////////////
function controlBird(){
v += g;
birdy += v;

//make the bird stop when it hits the bottom or the top
if (birdy > height & gameOn) {
birdy = height;
v = 0;
}
else{
birdy = birdy;
}

if (birdy < -30) {
birdy = -30;
v = 0;
}
}

function updateAndDisplayclouds(){
for (var n = 0; n < 8; n ++) {
cloudsx.push(-150, random(width) + 150);
cloudsy.push(random(40, 100));
cloudsSize.push(random(80, 140));

clouds[n] = makeClouds(cloudsx[n], cloudsy[n], cloudsSize[n]);
clouds[n].cdraw();
cloudsx[n] += cloudsSpeed;
if (cloudsx[n] < -100) {
cloudsx[n] = random (width + 100, width + 150);
}
}
}

function drawBird(x, y) {
push();
translate(x, y);
angleMode(DEGREES);
rotate(1.5 * v);
fill("yellow");
ellipse(0, 0, 36, 30);
fill("white");
ellipse(0 + 9, 0 - 5, 15, 15);
ellipse(0 - 15, 0, 17, 8);
fill("black");
ellipse(0 + 13, 0 - 6, 5, 5);
fill("orange");
ellipse(0 + 10, 0 + 8, 20, 8);
ellipse(0 + 10, 0 + 2, 20, 8);
pop();
}

function drawBoard(){
noFill();
strokeWeight(2);
stroke(0);
rect(10, 10, 140, 46);
noStroke();
fill(0);
textSize(18);
textAlign(CENTER);
text("Score: " + successC, 80, 30);
text("Level: " + level[numbercount], 80, 48);
strokeWeight(1);
stroke(0);
}

function keyPressed() {
if (key === " " & gameOn) {
v -= Fup;
//set up a maximum speed for the bird
if (v < -10) {
v = -10;
}
}
}

function mouseClicked() {
//reset the game when the game is over
if (mouseX > 270 & mouseX < 370 && mouseY > 275 && mouseY < 325 && gameOn == false) {
pipes = [];
gameOn = true;
successC = 0;
}
}

function makePipes() {
var pipe = {
x: 640,
gapY: random(50, height - gap - 40),
pwidth: 50,
speed: 2,
move: pipeMove,
draw: pipeDraw,
col: "green"
}
return pipe;
}

function pipeDraw() {
//change the color and level when the score gets higher
numbercount = floor(successC / 5);
if (numbercount > 6) {
numbercount = 6;
}
fill(newcolor[numbercount]);
push();
translate(this.x, 0);
rect(0, -10, this.pwidth, this.gapY);
rect(-3, this.gapY - 30, this.pwidth + 6, 30);
rect(0, this.gapY + gap, this.pwidth, height - this.gapY - gap + 10);
rect(-3, this.gapY + gap, this.pwidth + 6, 30);

strokeWeight(5);
stroke(255);
line(10, 10, 10, this.gapY - 40);
line(10, 470, 10, this.gapY + gap + 40);

line(7, this.gapY - 10, 7, this.gapY - 20);
line(7, gap + this.gapY + 10, 7, gap + this.gapY + 20);
pop();
}

function pipeMove(){
this.x -= this.speed;
}

function updateAndDisplayPipes() {
for (var i = 0; i < pipes.length; i++) {
pipes[i].move();
pipes[i].draw();
}
}

function terrain() {
push();
stroke(135, 210, 167);

for (var q = 0; q < width; q++) {
var t = (q * terrainDetail) - (millis() * terrainSpeed / 10);
var y = map(noise(t), 0, 1 , height / 2 - 40, height - 50);
line(q, y, q, height);
}
pop();

}

function makeClouds(x, y, size) {
var cloud = {"cx": x, "cy": y, "csize": size, "cdraw": cloudDraw};
return cloud;
}

function cloudDraw() {
push();
noStroke();
fill(255);
ellipse(this.cx, this.cy, this.csize, this.csize * 0.7);
pop();
}

###### Introduction:

For our group final project, we decided to recreate the once viral game on mobile platforms – Flappy Birds, back in 2013. I(Kai) still recall how I would spend hours playing the game and tried to master it. Unfortunately, the game was removed from App Store because of it being “too addictive”. Up till now, I still have the game on my phone, despite it was too old for my current operating system. In order to experience a very unique game again, we tried to take a shot to develop the game.

###### Development Process:

First of all, Lingfan started to build the basic framework of the game, by creating an object “the bird” that will rise as we press the space button using basic physics, along with an array of tubes as objects that show up as time lapsed from right end of the canvas. Then I’ve taken over the file. I first used primitive geometries to create the tubes and the bird so they resemble the original look of the game. Also I’ve created the background and clouds that moved along with the camera panned, of course, of a much slower speed. As a next step, I started working on the “collision” moments when bird hit the tube. The logic is when the x position of tube passes through the location of the bird, the program determines if the bird is in between the gap of the tubes. If not, the tube turned grey, and an indicator would show up and informed the player the bird has hit the tube. The game was pretty much playable at this point, but we still need a reward/failure system, otherwise the game would run forever, even if the bird hits the tube. Lingfan then took over the file again and created it. He set a Boolean that determines if the game is over or not, which changes its value from true to false as it hits the tube. And then a button was created to restart the game. Every time the bird hits the tube, it would fall and we’ll see the “GAME OVER” appearing at the center of the screen. After the restart button is clicked, the code wipes the existing tubes array and brings back the bird so we can replay the game. As a final step, we worked together to clean up the code and further polish the game, including adding the score counter, a game rank indicator that tells you how good you are playing this game, the change of tube colors as you promote to the next level, the 3-dimensional look of the tube, etc. As this point, the game was pretty much finished.

###### Reflections:

One of the surprises about the game we’ve created is how it felt so close to the original game as we are playing. And during the development of the game, we’ve taken advantage of most skills that we acquired during the semester, so we got to practice pretty much everything again. Please go ahead and give it a try, and we hope you will enjoy the game as much as we do.

###### Game instruction:

Simply tap the space key so the bird rises to avoid the tube and earn 1 point each time the bird flies past a gap. You will get to the next level of the rank every time you successfully passed 5 tubes. (We tried to make it a little easier and more rewarding for you, as the original game was pretty hard to beat.)

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/lingfan-jiang-kai-zhang-final-project/feed/ 0
Tanvi Harkare – Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/tanvi-harkare-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/tanvi-harkare-final-project/#respond Sat, 08 Dec 2018 04:50:36 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39160 Continue reading "Tanvi Harkare – Final Project"]]>
//position of ball
var px = 100;
var py = 100;
var yvel = 4;
var ox = 400;
var bs = 30;

var r = 100;
var rx = 200;
var count = 0;
var score = 0;
var hscore = 0;

var obspeed = 2;

var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var terrainSpeed2 = 0.0002;
var terrainDetail2 = 0.002;

mySnd.setVolume(0.5);
}
// to play the sound from within draw() or anywhere:

function setup(){
createCanvas(400, 400);
frameRate(30);
}

function draw(){
background(255);
py -= yvel;
yvel -= 0.3;

for (var x = 0; x < width; x++) {
stroke(243, 184, 141);
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, 0, height);
line(x, y, x, height);
stroke(143, 61, 75);
var t2 = (x * terrainDetail2) + (millis() * terrainSpeed2);
var y2 = map(noise(t2), 0,1, 0, height);
line(x, y2 + (y2 / 2), x, height);
}
noStroke();
fill(74, 47, 72);
ellipse(px, py, bs, bs);
fill(43, 29, 66);
if(ox > 0){
rect(ox, 0, 10, r);
rect(ox, height - rx, 10, rx);
ox -= obspeed;
}

else if(ox <= 0){
r = random(0, 200);
rx = 300 - r;
ox = 400;
score++;
count++;
if (count % 5 === 0){
obspeed += 1;
}
}
intersect();
fill(0);
textSize(12);
text("Score: " + score, 10, 10);
}

function mousePressed(){
mySnd.play();
yvel = 6;

}

function intersect(){
if(py - (bs / 2) < r || py + (bs / 2) > height - rx ){
if(px < ox + 10 & px > ox - 10){
if(score > hscore){
hscore = score;
score = 0;
}
noLoop();
textSize(18);
text("You Lost :(", 300, 20);
text("Score: " + hscore, 300, 50);
text("Play Again!", 300, 80);
}
}
}

For this project, I wanted to create a game that would have a level of difficulty as time progressed. This game is a classic spinoff of the popular game flappy bird – a sphere that bounces every time you click the mouse. Your job is to make sure your sphere doesn’t hit any of the obstacles that move along the screen. In order to get the boing sound every time the ball bounces, download the zip file with all the files!

tharkare_finalzip

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/tanvi-harkare-final-project/feed/ 0

I am providing a zip file containing all the files involved in this project, available here: zip file .

There were too many files for the project to run adequately on word press. In order to run this program, the provided zip file must be downloaded, and a local server must be set up using either terminal in OSX or a command window in Windows. This would be accomplished by changing the directory to the file named Elizabeth Maday Final Project, and then typing in “python -m SimpleHTTPServer” or “python -m http.server”. Then the project can be viewed with the URL http://localhost:8000.

Sometimes this project seems to run better on Firefox than on Chrome.

This project was enjoyable to complete because it gave me an idea of what I might like to use p5 for in the future. I am interested in learning more about music technology and experimental methods of producing music, and I believe that p5 could be a great creative outlet.

]]>
Alessandra Fleck – Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/alessandra-fleck-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/alessandra-fleck-final-project/#respond Sat, 08 Dec 2018 04:33:42 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39126 Continue reading "Alessandra Fleck – Final Project"]]>
//Name: Alessandra Fleck
//Class Section : B
//Email: afleck@andrew.cmu.edu
//Assignment-12-Final

//USING ML5 TO IMPLEMENT MACHINE LEARNING MODEL -- see html for library src
//POSENET - HUMAN POSE ESTIMATION, USING MACHINE LEARNING

var myCamera; //variable to hold onto webcam data
var poseNet;
var pose =[];
var imgPlanet; //store first planet image
var imgPlanet2; //store second planet image
var imgPlanet3; //store third planet image for right hip

//NON RESPONSIVE BACKGROUND ENVIRONMENT
var stars =[]; //array to hold the stars

//CHARACTER HELMET VARIABLES
//CHARACTER EYES VARIABLES
var lefteyeX = 0;
var lefteyeY = 0;
var righteyeX = 0;
var righteyeY = 0;
//CHARACTER HANDS
var lefthandX = 0;
var lefthandY = 0;
var righthandX = 0;
var righthandY = 0;
//CHARACTER HIP
var rightHipX = 0;
var rightHipY = 0;

//load media for use in the sketch
var planetOneURL = "https://i.imgur.com/f0QBerx.png";
var planetTwoURL = "https://i.imgur.com/v6UuYtt.png";
var planetThreeURL = "https://i.imgur.com/bjO4uOW.png";
}

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

myCamera = createCapture(VIDEO); //giving permission to browser to connect to webcam
myCamera.size(640,480); //setting display dimensions of camera
myCamera.hide(); // to hide extra video display below canvas
poseNet = ml5.poseNet(myCamera, modelLoaded); // load the posenet model and connect it to the video
poseNet.on('pose', myPose);//when person is detected, execute

}
//check that ml5 is running on p5js
}

//for one person at a time
function myPose(pose){
//TEST POSE
console.log(pose); //record+print the poses as detected by the camera
//note that pose is an array
if (pose.length > 0){
//CHARACTER HELMET CAMERA POSITION

//CHARACTER LEFT EYE CAMERA POSITION
lefteyeX = pose[0].pose.keypoints[1].position.x;
lefteyeY = pose[0].pose.keypoints[1].position.y;
//CHARACTER RIGHT EYE CAMERA POSITION
righteyeX = pose[0].pose.keypoints[2].position.x;
righteyeY = pose[0].pose.keypoints[2].position.y;
//CHARACTER LEFT HAND CAMERA POSITION - note that the index is for left wrist
lefthandX = pose[0].pose.keypoints[9].position.x;
lefthandY = pose[0].pose.keypoints[9].position.y;
//CHARACTER RIGHT HAND CAMERA POSITION - note that the index is for left wrist

//reduce jittering of shapes by implementing linear interpolation
//takes position of shape and camera position and taking 0.2 in between
//RIGHT HAND CAMERA POSTION AND LAG USING LERP FUNCTION
var righthandNX = pose[0].pose.keypoints[10].position.x;
var righthandNY = pose[0].pose.keypoints[10].position.y;
righthandX = lerp(righthandX,righthandNX,0.8);
righthandY = lerp(righthandY,righthandNY,0.8);

//CHARACTER RIGHT HIP CAMERA POSITION
rightHipX = pose[0].pose.keypoints[12].position.x;
rightHipY = pose[0].pose.keypoints[12].position.y;

}
}

function draw(){
//draw the camera image to the canvas using image function
image(myCamera, 0, 0, width, height);

//stars at random
for(var i=0; i<random(8); i++){
stars.push(new star()); //put new star into array
}

for (var birth of stars){
birth.display();
}

//maintain shape scale to distance from camera
var cameraDistance = dist(lefteyeX, lefteyeY, righteyeX, righteyeY);

filter(POSTERIZE,8); // filters video image into posterize
filter(INVERT); //overlay gray filter

fill(250);
fill(0);

//CHARACTER LEFT EYE SHAPE SETTING
fill(0);
//CHARACTER RIGHT EYE SHAPE SETTING
fill(0);

//FIRST (GREEN) PLANET IMAGE MOVING IN RESPONSE TO RIGHT HAND
image(imgPlanet,righthandX,righthandY,50,50);
image(imgPlanet,righthandX+50,righthandY+50,100,100);
image(imgPlanet,righthandX+20,righthandY+100,10,10);
//SECOND (ORANGE) PLANET IMAGE MOVING IN RESPONSE TO LEFT HAND
image(imgPlanet2,lefthandX+20,lefthandY,50,50);
image(imgPlanet2,lefthandX-100,lefthandY,30,30);
image(imgPlanet2,lefthandX+50,lefthandY+50,60,60);

//USING CHARACTER RIGHT HIP AS GALAXY
image(imgPlanet3,rightHipX,rightHipY-50,300,150);

}

function star(){
this.posX = 0;
this.posY = random(-100,400);
this.size = random(50,100);
this.display = function(){
fill(0);
ellipse(this.posX,this.posY, this.size);
}
}

index

afleck_Final

For the final project I wanted to explore a part of p5js that involved computer vision. Originally going to do an Augmented Reality project for objects placement, I ended up going more towards computer vision as it is easier to do with a webcam and there are lots of resources available for it in correlation with p5js. To use computer vision I added the Ml5 library to my html file and used the posNet() model that predicts live time human body estimation with machine learning.

Using posNet I was able to identify different keypoint indexes for different parts of the body and link those to where I could input shapes. As I love space, I thought it might be neat to create a responsive space environment with the movement of the body. I began with making the head and eyes as a large moon thats responds to different distances from the camera and scales to the distance. I then created planets in illustrator and added them into the scene. Using linear interpolation, I was able to detach the keypoint of the wrists from the body and create a bit of a lag so that the planets had the effects of following the wrists, where in reality they were being offset from the keypoint of the wrist and the coordinates of the object.

From this project I got to explore this form of machine learning for the first time. Though it was not as refined as I wanted it to be (as much of the information was very new to me), I enjoyed looking at how computer vision operates and the things it can can do with augmenting reality.

Note: the camera will not work as the library needs to be linked with the html, download and open the source code in the zip file and just open the html file to get started!

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/alessandra-fleck-final-project/feed/ 0
Nina Yoo- Final Project https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/nina-yoo-final-project/ https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/nina-yoo-final-project/#respond Sat, 08 Dec 2018 04:33:06 +0000 https://courses.ideate.cmu.edu/15-104/f2018/?p=39116 Continue reading "Nina Yoo- Final Project"]]>

Instructions:

You can use keys from A-K to make animations appear. If you match the number of times you press the keys with characters from the same movie the background will show a pic of the movie along with playing a song from the movie.

This project has helped me understand more about the sound and loading images from imgur function as well as looping for animations.It was fun and exciting to see my animations come to life, but I was sadly unable to upload to the site because of my zip file being too big.  The hardest part of this project was figuring out how to make the animations appear and disappear by pressing the same key. To do this I created a function to track if numbers were odd or even and set a value for each time a key is pressed.

How to use:

You have to download all the following files and put it in the same folder. Also,  do not forget to open a local host file. The reason I have to do it this way is because the songs are really big files that are unable to be uploaded all at once. Archive contains the code, index, and animations.

Songs and Background from Studio Ghibli

Totoro

Spirited Away

Kiki’s Delivery Service

Howl’s Moving Castle

songs 2

songss

Archive

]]>
https://courses.ideate.cmu.edu/15-104/f2018/2018/12/07/nina-yoo-final-project/feed/ 0