Sound Test
type 1 2 3 4 to sketch to play sounds
var one, two, three, four;
function preload() {
one = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/one.wav");
two = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/two.wav");
three = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/three.wav");
four = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/four.wav");
}
function setup() {
createCanvas(200, 200);
background(200);
}
function keyPressed() {
print("" + keyCode);
if (keyCode == 49) one.play();
else if (keyCode == 50) two.play();
else if (keyCode == 51) three.play();
else if (keyCode == 52) four.play();
}
]]>https://helenxwu.github.io/ –> link to game
https://drive.google.com/a/andrew.cmu.edu/file/d/1NQmUsm_kBniAq7vku2QIYw7QzBkgUOP_/view?usp=sharing –> link to zip file
How to run zip:
1) download file
2) move to desktop
3) open zip folder
4) On mac– open terminal (command+space and search “terminal”)
5) type in “python -m SimpleHTTPServer 8000”
6) go to browser–type in localhost:8000 where the URL would usually go
7) find desktop listing and click on it
8) find downloaded folder and click on it
9) file will load!
For our final project, Tiffany and I made a dance dance revolution game to the Mii remix. We delved into an entirely new library (the p5js sound extension) and learned a lot about different techniques for signal processing. For the main sound visualizer, we used Fast Fourier Transform algorithm (FFT) to sample the music files’ signals over a period of time, and divided its frequency components to create the bouncing colors that react and move according to note and rhythm.
Additionally, we mapped the volume controls to create new objects under an object function, to randomly generate 4 different types of arrows. We then set a range for the function to work under so the score counter could add points. We also created a start screen and end screen for the game under two separate functions.
]]>I did not embed the code because of the pixel size as well as multiple files the code loads. This is my final project in a .zip file. It includes multiple photos, but more importantly a font file that I couldn’t link in any way other than the file.
]]>Because it can’t be viewed properly on WordPress, please download the file.
I was always fascinated in animation ever since I was little and I always wanted to create something that would help introduce people to making animations. I made this so anyone at any age can know or get the idea and possibly get inspired.
SAMPLE:
Instructions:
//Sheenu You
//Section E
//sheenuy@andrew.cmu.edu;
//Final Project
//Initial X and Y coordinates for the Ragdoll Bodyparts
var charx = 640;
var chary = 380;
var hedx = 640;
var hedy = 220;
var arlx = 640 - 160;
var arly = 380;
var arrx = 640 + 160;
var arry = 380;
var brlx = 640 - 80;
var brly = 650;
var brrx = 640 + 80;
var brry = 650;
//Arrays that register all the X Y coordinates of all the bodyparts
var xb = [];
var yb = [];
var xh = [];
var yh = [];
var xal = [];
var yal = [];
var xar = [];
var yar = [];
var xbl = [];
var ybl = [];
var xbr = [];
var ybr = [];
//Variables that track animation frames
var frameNumber = -1;
var frames = 0;
//Variables that test if functions are running.
var initialized = 0;
var forward = 0;
var backward = 0;
function setup() {
createCanvas(1280, 720);
background(220);
frameRate(24);
}
function draw() {
noStroke();
//Controls drawing of buttons
var playing = 0;
var blockyMath = 100;
var distance = 150;
background(255, 245, 195);
body();
fill(124, 120, 106);
textSize(20);
text("FRAMES: " + frames, 5, 20);
//Draws NewFrame Button
fill(252, 223, 135);
rect(width/2 - 10, 80 + 10, 180, 100);
fill(141, 205, 193);
rect(width/2, 80, 180, 100);
//Draws Play/Stop Button
fill(252, 223, 135);
rect((width/2) - distance - 10, 80 + 10, blockyMath, blockyMath);
fill(235, 110, 68);
rect((width/2) - distance, 80, blockyMath, blockyMath);
//Fills triangle if one frame is made
if (frames >= 1){
fill(255);
} else {
fill(231, 80, 29);
}
triangle((width/2) - distance + 40, 40, (width/2) - distance + 40, 120, (width/2) - distance - 40, 80);
push();
fill(255);
textSize(30);
text("ADD", 610, 75);
text("FRAME", 590, 110);
pop();
//Draws Rewind/Stop Button
fill(252, 223, 135);
rect((width/2) + distance - 10, 80 + 10, blockyMath, blockyMath);
fill(211, 227, 151);
rect((width/2) + distance, 80, blockyMath, blockyMath);
if (frames >= 1){
fill(255);
} else {
fill(182, 204, 104);
}
triangle((width/2) + distance - 40, 40, (width/2) + distance - 40, 120, (width/2) + distance + 40, 80);
//PLAY/Stop Button Functions-Cycles forward through frames if mouse is pressing the button
if (mouseX >= ((width/2) + distance - blockyMath/2) & mouseX <= ((width/2) +
distance + blockyMath/2) && mouseY >= 30 && mouseY <= 135 && mouseIsPressed && frames >= 1){
frameNumber += 1
//Cycles through all arrays
charx = xb[frameNumber];
chary = yb[frameNumber];
hedx = xh[frameNumber];
hedy = yh[frameNumber];
arlx = xal[frameNumber];
arly = yal[frameNumber];
arrx = xar[frameNumber];
arry = yar[frameNumber];
brlx = xbl[frameNumber];
brly = ybl[frameNumber];
brrx = xbr[frameNumber];
brry = ybr[frameNumber];
playing = 1;
initialized = 1;
forward = 1;
//Goes back to latest frame when mouse is released.
} else if (forward == 1){
frameNumber =xb.length - 1
playing = 0;
initialized = 0;
forward = 0;
}
//REWIND/Stop Button Functions-Cycles backward through frames if mouse is pressing the button
if (mouseX >= ((width/2) - distance - blockyMath/2) & mouseX <= ((width/2) - distance +
blockyMath/2) && mouseY >= 30 && mouseY <= 135 && mouseIsPressed && frames >= 1){
frameNumber -= 1;
//Cycles through all arrays
charx = xb[frameNumber];
chary = yb[frameNumber];
hedx = xh[frameNumber];
hedy = yh[frameNumber];
arlx = xal[frameNumber];
arly = yal[frameNumber];
arrx = xar[frameNumber];
arry = yar[frameNumber];
brlx = xbl[frameNumber];
brly = ybl[frameNumber];
brrx = xbr[frameNumber];
brry = ybr[frameNumber];
initialized = 1;
playing = 1;
backward = 1;
//Goes back to latest frame when mouse is released.
} else if (backward == 1){
frameNumber = xb.length - 1
playing = 0;
initialized = 0;
backward = 0;
}
//Allows frames to loop when animation is going forward
if (frameNumber >= xb.length - 1 & playing == 1 && forward == 1){
frameNumber = -1;
}
//Allows frame to loop when animation is going backward
if (frameNumber <= 0 & backward == 1 && playing == 1){
frameNumber = xb.length;
}
}
//Draws Ragdoll
function body(){
//Shadow
fill(252, 223, 135);
ellipse(charx, 670, (chary/2) + 100, 30);
//Ligaments
//Neck
push();
stroke(249, 213, 151);
strokeWeight(30);
line(charx, chary - 80, hedx, hedy);
stroke(190, 228, 171);
//ArmLeft
line(charx, chary - 80, arlx, arly);
//ArmRight
line(charx, chary - 80, arrx, arry);
stroke(88, 203, 172);
//FootLeft
line(charx - 20, chary + 70, brlx, brly);
//FootRight
line(charx + 20, chary + 70, brrx, brry);
pop();
noStroke();
rectMode(CENTER);
//Head
fill(249, 213, 151);
ellipse(hedx, hedy, 100, 100);
fill(80);
ellipse(hedx - 10, hedy - 10, 10, 20);
ellipse(hedx + 10, hedy - 10, 10, 20);
ellipse(hedx, hedy + 20, 30, 30);
fill(249, 213, 151);
ellipse(hedx, hedy + 15, 30, 30);
//Left Arm
fill(249, 213, 151);
ellipse(arlx, arly, 50, 50);
//Right Arm
fill(249, 213, 151);
ellipse(arrx, arry, 50, 50);
//Left Foot
fill(112, 47, 53);
rect(brlx, brly, 50, 50);
//Right Foot
fill(112, 47, 53);
rect(brrx, brry, 50, 50);
//Character
fill(190, 228, 171);
rect(charx, chary, 100, 200);
fill(88, 203, 172);
rect(charx, chary + 50, 100, 100);
fill(88, 203, 172);
rect(charx + 30, chary - 50, 20, 100);
rect(charx - 30, chary - 50, 20, 100);
//MouseDrag Body
if (mouseX >= charx - 50 & mouseX <= charx + 50 && mouseY >= chary - 100 && mouseY <= chary + 100 && mouseIsPressed){
charx = mouseX;
chary = mouseY;
}
//MouseDrag Head
if (mouseX >= hedx - 50 & mouseX <= hedx + 50 && mouseY >= hedy - 50 && mouseY <= hedy + 50 && mouseIsPressed){
hedx = mouseX;
hedy = mouseY;
}
//MouseDrag Left Arm
if (mouseX >= arlx - 25 & mouseX <= arlx + 25 && mouseY >= arly - 25 && mouseY <= arly + 25&& mouseIsPressed){
arlx = mouseX;
arly = mouseY;
}
//MouseDrag Right Arm
if (mouseX >= arrx - 25 & mouseX <= arrx + 25 && mouseY >= arry - 25 && mouseY <= arry + 25 && mouseIsPressed){
arrx = mouseX;
arry = mouseY;
}
//MouseDrag Left Foot
if (mouseX >= brlx - 25 & mouseX <= brlx + 25 && mouseY >= brly - 25 && mouseY <= brly + 25 && mouseIsPressed){
brlx = mouseX;
brly = mouseY;
}
//MouseDrag Right Foot
if (mouseX >= brrx - 25 & mouseX <= brrx +25 && mouseY >= brry - 25 && mouseY <= brry + 25 && mouseIsPressed){
brrx = mouseX;
brry = mouseY;
}
}
function mousePressed(){
//Register/records character coordinates to new frame when "New Frame" button is pressed
if (mouseX >= (width/2) - 90 & mouseX <= (width/2) + 90 && mouseY >= 30 && mouseY <= 135 && mouseIsPressed){
frameNumber += 1
frames += 1
//Push character coordinates to x y arrays.
xb.push(charx);
yb.push(chary);
xh.push(hedx);
yh.push(hedy);
xal.push(arlx);
yal.push(arly);
xar.push(arrx);
yar.push(arry);
xbl.push(brlx);
ybl.push(brly);
xbr.push(brrx);
ybr.push(brry);
//Flash
background(255, 0, 0, 90);
}
}
//Resets all body parts to x y coordinates of last frame created when mouse is released
//and cycling is over.
function mouseReleased(){
if (initialized == 1){
charx = xb[xb.length - 1];
chary = yb[yb.length - 1];
hedx = xh[xh.length - 1];
hedy = yh[yh.length - 1];
arlx = xal[xal.length - 1];
arly = yal[yal.length - 1];
arrx = xar[xar.length - 1];
arry = yar[yar.length - 1];
brlx = xbl[xbl.length - 1];
brly = ybl[ybl.length - 1];
brrx = xbr[xbr.length - 1];
brry = ybr[ybr.length - 1];
}
}
Because it can’t be viewed properly on WordPress, please download the file.
]]>
https://alpha.editor.p5js.org/shariwa/sketches/H16PfJF-G
Since this code has sounds, the WordPress account doesn’t display it properly. Above is a link to the p5.js alpha editor where you can properly view my code. Once at the website click the play button on the top left corner of the screen
My project looked at combining motion graphics and sounds. I wanted the graphics to work such that more was revealed as you moved around the canvas – everything is made out of two colours so as the mouse moves in the horizontal direction, you get to view more of the graphics as a differentiation is created between the background and the actual graphics.
I had an issue with running the local server on my laptop so I used the oscillation program from p5.js to get a sine curve amplitude and frequency to create a sound that my motion graphics responded to. The larger objects respond to the sound that is generated. The rippling, striped circle responds to the silence in between the beep noises. The white ellipse curve is its own thing that just renders what a traditional sine curve looks like.
When the canvas is clicked on, the noise stops and the motion graphics continue. To restart the noise you have to refresh the page.
^mouseX at at 0
^mouseX at maximum width
Instructions to run the file:
1)Download and unzip the file below
2) run a local server and access the file this way (it will not work otherwise unless you download the p5 editor and open it using the play button)
3) wait about 2 minutes before clicking the game to start. There are a lot of graphics so it takes a really long time to load so I would just keep clicking around the top of the screen after about 2 minutes until it loads and lets you play
4)refresh the page to restart if u lose and enjoy! Also don’t come too close to the edges of the screen.
Here is the embedded code just in case:
//Hannah Kim
//Section A
//hannahk2@andrew.cmu.edu
//Final Project
//variable for background image
var bg;
//variable for rain particles
var particles;
//variable for portal
var portalSprite;
//variable for random portal x position
var ran1;
//variable for random portal y position
var ran2;
//variable for spiders group
var spiders;
//arrays within array storing specific positions
//of spiders on top of lillypads
var spiderPos = [
[103, 242],
[155, 260],
[134, 292],
[160, 311],
[223, 290],
[207, 299],
[192, 304],
[200, 328],
[185, 322],
[193, 362],
[205, 347],
[220, 374],
[172, 377],
[193, 405],
[166, 399],
[240, 422],
[215, 428],
[182, 430],
[140, 410],
[157, 339],
[151, 362],
[130, 315],
[113, 347],
[229, 413],
[125, 377],
[101, 389],
[82, 356],
[37, 397],
[110, 429],
[88, 440],
[223, 459],
[176, 468],
[197, 488],
[275, 450],
[261, 436],
[220, 476],
[236, 518],
[191, 536],
[146, 546],
[160, 518],
[92, 480],
[260, 543],
[236, 582],
[269, 284],
[255, 289],
[252, 313],
[229, 314],
[251, 334],
[254, 378],
[281, 384],
[295, 271],
[303, 286],
[285, 300],
[289, 331],
[291, 352],
[311, 338],
[322, 318],
[320, 292],
[333, 340],
[321, 380],
[346, 361],
[332, 403],
[345, 429],
[308, 428],
[334, 449],
[377, 415],
[373, 391],
[320, 492],
[312, 476],
[349, 484],
[345, 502],
[337, 548],
[318, 529],
[376, 510],
[406, 375],
[381, 352],
[361, 301],
[85, 539],
[54, 575],
[101, 610],
[396, 301],
[416, 317],
[398, 338],
[445, 325],
[436, 352],
[416, 397],
[387, 448],
[384, 481],
[457, 437],
[435, 484],
[470, 352],
[431, 555]
];
//sets normal game state with timer at 0
var gameState = "menu";
var timer = 0;
//preloads background image
function preload() {
bg = loadImage("assets/spiderbg.png");
}
function setup() {
createCanvas(500, 668);
//sets random values for x position of portal
ran1 = random(100, 400);
//sets random values for y position of portal
ran2 = random(550, 600);
//creates sprite for the portal at random position
//and assigns animation
portalSprite = createSprite(ran1, ran2);
portalSprite.addAnimation("normal", "assets/portal0000.png", "assets/portal0002.png")
//scales the portal to be smaller
portalSprite.scale = .2;
//slows down the frame rate of the animation
portalSprite.animation.frameDelay = 20;
//creates particle group for rain
particles = new Group();
//assign new sprites to groups
for (var i = 0; i < 100; i++) {
//puts all creation and initialization instructions in a
//premade function found at bottom of code
createParticle();
}
//creates sprite group for spiders
spiders = new Group();
//for loop to create all spiders at positions in position array
for (var i = 0; i < spiderPos.length; i++) {
//creates spider sprites at specified positions
var s = createSprite(spiderPos[i][0], spiderPos[i][1]);
//animation for spiders in normal state
s.addAnimation("playing", "assets/spider0000.png", "assets/spider0009.png");
//plays the spider animation starting at different frames
var f = floor(random(0, s.animation.getLastFrame()));
s.animation.changeFrame(f);
//animation for spiders when they're looking at you before game ends
s.addAnimation("looking", "assets/spider0010.png", "assets/spider0012.png");
//sets the circle around the spider which ends the game when touched
s.setCollider("circle", 0, 0, 90);
//increases the size of the spider as the y position increases
//by indexing into the position array and multiplying by decimal
var spiderSize = 0.04;
s.scale = spiderSize * .005 * (spiderPos[i][1]);
//trigger the looking function + looking animation when
//mouse goes over the spider collider
s.onMouseOver = function() {
//changes animation to looking animation
looking(spiders);
}
//add spider sprites
spiders.add(s);
}
}
//function for when you touch a spider and
//it looks at you and the game ends
function looking(g) {
if (gameState == "game") {
for (var i = 0; i < g.length; i++) {
var sp = g[i];
sp.changeAnimation("looking");
//delays frame rate of animation
sp.animation.frameDelay = 10;
}
gameState = "looking";
//adds timer to countdown to game over state
//after the looking animation is triggered
timer = 60;
}
}
function draw() {
background(255);
//sets up the menu state with text and background
if (gameState == "menu") {
s = "OH NO! You have fallen down a sewer and have been plunged into a fantastical realm. Reach the portal swiftly to get back to the human realm without coming into contact with the spiders. Good luck! Click anywhere to begin."
background(0)
textSize(30);
fill(156, 183, 226)
text(s, 10, 10, 400, 400);
s2 = "This fantasy realm, The Conjured Isles, is inhabited by hundred eyed spiders who are extremely wise. They usually pass their time playing in never ending rain. They live ontop of lillypads in the blood river. They are currently ruled by a mysterious creature that looms over the realm atop a black cloud, whom the people respect intensely."
textSize(20);
fill(156, 183, 226)
text(s2, 10, 450, 400, 600);
//on clicking on the screen the game starts + goes into "game" state
if (mouseIsPressed) {
gameState = "game";
}
}
//draw sprites if the game state changes from menu
if (gameState != "menu") {
drawSprites();
//counts down from timer once game state goes into "looking" and
//at 0 the game state changes to "gameOver"
if (gameState == "looking") {
timer--;
if (timer <= 0) {
gameState = "gameOver";
}
}
//sets up the game over state with text and background
if (gameState == "gameOver") {
background(0);
s3 = "You were seen and banished by the spiders before you could reach the human realm. Better luck next time!"
textSize(30);
fill(156, 183, 226)
text(s3, 10, 10, 400, 400);
//if game state is not "gameOver" display normal background
} else {
image(bg);
//if the mouse is within the bounds of the portal,
//change game state to won
if (gameState == "game" & mouseX < ran1 + 25 && mouseX > ran1 - 25 &&
mouseY < ran2 + 25 && mouseY > ran2 - 25) {
gameState = "won";
}
//if the mouse gets too close to the left and right side
//and the bottom side, (for cheaters), end game
if (gameState == "game" & mouseX < 10 || mouseX > width - 10 || mouseY > height - 10) {
gameState = "gameOver"
}
//sets up the won state with text and background
//removes sprites
if (gameState == "won") {
background(0);
s4 = "You reached successfully the portal and returned to the human realm! Congrats!"
textSize(30);
fill(156, 183, 226)
text(s4, 10, 10, 400, 400);
s.remove();
}
//code to draw the rain particles
for (var i = 0; i < particles.length; i++) {
//stores the particle in a temporary variable called p
var p = particles[i];
//scales it down
p.scale = 0.15;
//moves all the y positions of the particles down
//for rain falling effect
p.position.y += 10;
//wraps particle to the top when it reaches the bottom
if (p.position.y > height) {
p.position.y = -50;
}
}
//draw all sprites
drawSprites();
}
}
}
//function to create the rain particle
function createParticle() {
//creates a sprite at a random position
var newParticle = createSprite(random(0, width), random(0, height));
//assigns an animation
newParticle.addAnimation("falling", "assets/cloud.png");
//adds it to the particle group
particles.add(newParticle);
}
Here are screenshots of the game also:
^ the menu page
^the game in its normal state
^ the game when the player touches a spider
^ the game over state
^ the winning state
For this project I wanted to create a game based mostly on graphics, visuals, and backgrounds. I wanted to create a game where the player has to navigate through a tricky trap-like environment. The player has to avoid coming into contact with the inhabitants of an imaginary realm while hurrying to reach a portal to get back to the human realm. They have to navigate through a mob of spiders resting on top of lillypads without touching them and being seen. This project was really fun for me, despite having to code the positions of the spiders individually so that they would fit nicely on top of the lillypads that I chose. I really enjoyed making the background in particular, which I made for this project by painting first in watercolor, then scanning into photoshop and drawing ontop of it digitally. I also really enjoyed coming up with the narrative aspect of the project, and the world building.
]]>//vertices and edge sets of the individual graphs
var V = [];
var E = [];
//total set of vertices
var vertices = [];
var spacing = 48;
//buttons for coloring vertices
var redbutton;
var bluebutton;
var greenbutton;
var pinkbutton;
var orangebutton
var buttons = [];
var levelnumber = 1;
var mousehasentbeenclicked;
function setup() {
createCanvas(480, 400);
background(255);
resetLevel();
}
function resetLevel() {
mousehasentbeenclicked = true;
background(255);
//create buttons
redbutton = makeButton(width/6, color(209, 90, 90));
bluebutton = makeButton(2 * width/6, color(93, 137, 196));
greenbutton = makeButton(3 * width/6, color(199, 197, 71));
pinkbutton = makeButton(4 * width/6, 'lightpink');
orangebutton = makeButton(5 * width/6, 'orange');
buttons = [redbutton, bluebutton, greenbutton, pinkbutton, orangebutton];
for (i = 0; i < buttons.length; i++) {
buttons[i].isoutlined = false;
buttons[i].draw();
}
//draw grid of small vertices and label them from 0 to 53 in an array
for (i = 0; i < width/spacing - 1; i++) {
for (j = 0; j < 300/spacing - 1; j++) {
vertices[i + ((width/spacing - 1) * j)] =
makeVertex(spacing + i * spacing, spacing + j * spacing);
}
}
}
//OBJECTS: VERTICES, EDGES, BUTTONS////////////////////////////////////////////
//vertices
function vertexboldDraw() {
noStroke();
if (this.isred == true) {
fill(209, 90, 90);
ellipse(this.x, this.y, 16, 16);
} else if (this.isblue == true) {
fill(93, 137, 196);
ellipse(this.x, this.y, 16, 16);
} else if (this.isgreen == true) {
fill(199, 197, 71);
ellipse(this.x, this.y, 16, 16);
} else if (this.ispink == true) {
fill('lightpink');
ellipse(this.x, this.y, 16, 16);
} else if (this.isorange == true) {
fill('orange');
ellipse(this.x, this.y, 16, 16);
} else {
stroke(150);
strokeWeight(1);
fill(255);
ellipse(this.x, this.y, 15, 15);
}
}
function vertexDraw() {
noStroke();
fill(180);
ellipse(this.x, this.y, 1.5, 1.5);
}
function makeVertex(px, py) {
v = {x: px, y: py, draw: vertexDraw, bolddraw: vertexboldDraw,
isred: false, isgreen: false, isblue: false, ispink: false,
isorange: false};
return v;
}
//edges
function edgeDraw(m, n) {
if (this.iscolored == true & this.iscorrect == true) {
strokeWeight(3);
stroke('limegreen');
} else if (this.iscolored == true & this.iscorrect == false) {
strokeWeight(3);
stroke('tomato');
} else if (this.iscolored == false) {
strokeWeight(.5);
stroke(200);
}
line(vertices[this.m].x, vertices[this.m].y,
vertices[this.n].x, vertices[this.n].y);
}
function makeEdge(pm, pn) {
e = {m: pm, n: pn, iscolored: false, iscorrect: true, draw: edgeDraw};
return e
}
//buttons
function buttonDraw() {
rectMode(CENTER);
if (this.isoutlined == true) {
strokeWeight(3);
stroke(255);
fill(this.buttoncolor);
rect(this.x, height - 50, 60, 20);
} else {
noStroke();
fill(this.buttoncolor);
rect(this.x, height - 50, 61.5, 21.5);
}
}
function makeButton(px, color) {
b = {x: px, buttoncolor: color, isoutlined: false, draw: buttonDraw};
return b;
}
//FUNCTIONS TO BE CALLED IN MOUSEPRESSED///////////////////////////////////////
function testEdge() {
//edges are green if the vertices are different color and red if they are
//the same colors
for (i = 0; i < E.length; i++) {
if (vertices[E[i].m].isred == true & vertices[E[i].n].isred == true) {
E[i].iscolored = true;
E[i].iscorrect = false;
}
if (vertices[E[i].m].isblue == true & vertices[E[i].n].isblue == true) {
E[i].iscolored = true;
E[i].iscorrect = false;
}
if (vertices[E[i].m].isgreen == true & vertices[E[i].n].isgreen == true) {
E[i].iscolored = true;
E[i].iscorrect = false;
}
if (vertices[E[i].m].ispink == true & vertices[E[i].n].ispink == true) {
E[i].iscolored = true;
E[i].iscorrect = false;
}
if (vertices[E[i].m].isorange == true & vertices[E[i].n].isorange == true) {
E[i].iscolored = true;
E[i].iscorrect = false;
}
if ((vertices[E[i].m].isred == true || vertices[E[i].m].isblue == true ||
vertices[E[i].m].isgreen == true || vertices[E[i].m].ispink == true
|| vertices[E[i].m].isorange == true) & (vertices[E[i].n].isred == true
|| vertices[E[i].n].isblue == true || vertices[E[i].n].isgreen == true
|| vertices[E[i].n].ispink == true || vertices[E[i].n].isorange == true)) {
E[i].iscolored = true;
}
if (E[i].iscolored == true & (vertices[E[i].m].isred !== vertices[E[i].n].isred
|| vertices[E[i].m].isblue !== vertices[E[i].n].isblue
|| vertices[E[i].m].isgreen !== vertices[E[i].n].isgreen
|| vertices[E[i].m].ispink !== vertices[E[i].n].ispink
|| vertices[E[i].m].isorange !== vertices[E[i].n].isorange)) {
E[i].iscolored = true;
E[i].iscorrect = true;
}
E[i].draw();
}
}
function colorVertices() {
//change colors of vertices when clicked, depending on which button has
//most recently been clicked
for (i = 0; i < V.length; i++) {
if (dist(mouseX, mouseY, vertices[V[i]].x, vertices[V[i]].y) < 10) {
if (buttons[0].isoutlined == true & buttons[1].isoutlined == false &&
buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
buttons[4].isoutlined == false) {
vertices[V[i]].isred = true;
vertices[V[i]].isblue = false;
vertices[V[i]].isgreen = false;
vertices[V[i]].ispink = false;
vertices[V[i]].isorange = false;
}
if (buttons[0].isoutlined == false & buttons[1].isoutlined == true &&
buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
buttons[4].isoutlined == false) {
vertices[V[i]].isred = false;
vertices[V[i]].isblue = true;
vertices[V[i]].isgreen = false;
vertices[V[i]].ispink = false;
vertices[V[i]].isorange = false;
}
if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
buttons[2].isoutlined == true && buttons[3].isoutlined == false &&
buttons[4].isoutlined == false) {
vertices[V[i]].isred = false;
vertices[V[i]].isblue = false;
vertices[V[i]].isgreen = true;
vertices[V[i]].ispink = false;
vertices[V[i]].isorange = false;
}
if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
buttons[2].isoutlined == false && buttons[3].isoutlined == true &&
buttons[4].isoutlined == false) {
vertices[V[i]].isred = false;
vertices[V[i]].isblue = false;
vertices[V[i]].isgreen = false;
vertices[V[i]].ispink = true;
vertices[V[i]].isorange = false;
}
if (buttons[0].isoutlined == false & buttons[1].isoutlined == false &&
buttons[2].isoutlined == false && buttons[3].isoutlined == false &&
buttons[4].isoutlined == true) {
vertices[V[i]].isred = false;
vertices[V[i]].isblue = false;
vertices[V[i]].isgreen = false;
vertices[V[i]].ispink = false;
vertices[V[i]].isorange = true;
}
}
}
}
function pressButton() {
//select color for vertex coloring
if (mouseX >= buttons[0].x - 30 & mouseX <= buttons[0].x + 30
&& mouseY <= height - 40 && mouseY >= height - 60) {
buttons[0].isoutlined = true;
buttons[1].isoutlined = false;
buttons[2].isoutlined = false;
buttons[3].isoutlined = false;
buttons[4].isoutlined = false;
for (i = 0; i < buttons.length; i++) {
buttons[i].draw();
}
}
if (mouseX >= buttons[1].x - 30 & mouseX <= buttons[1].x + 30
&& mouseY <= height - 40 && mouseY >= height - 60) {
buttons[0].isoutlined = false;
buttons[1].isoutlined = true;
buttons[2].isoutlined = false;
buttons[3].isoutlined = false;
buttons[4].isoutlined = false;
for (i = 0; i < buttons.length; i++) {
buttons[i].draw();
}
}
if (mouseX >= buttons[2].x - 30 & mouseX <= buttons[2].x + 30
&& mouseY <= height - 40 && mouseY >= height - 60) {
buttons[0].isoutlined = false;
buttons[1].isoutlined = false;
buttons[2].isoutlined = true;
buttons[3].isoutlined = false;
buttons[4].isoutlined = false;
for (i = 0; i < buttons.length; i++) {
buttons[i].draw();
}
}
if (mouseX >= buttons[3].x - 30 & mouseX <= buttons[3].x + 30
&& mouseY <= height - 40 && mouseY >= height - 60) {
buttons[0].isoutlined = false;
buttons[1].isoutlined = false;
buttons[2].isoutlined = false;
buttons[3].isoutlined = true;
buttons[4].isoutlined = false;
for (i = 0; i < buttons.length; i++) {
buttons[i].draw();
}
}
if (mouseX >= buttons[4].x - 30 & mouseX <= buttons[4].x + 30
&& mouseY <= height - 40 && mouseY >= height - 60) {
buttons[0].isoutlined = false;
buttons[1].isoutlined = false;
buttons[2].isoutlined = false;
buttons[3].isoutlined = false;
buttons[4].isoutlined = true;
for (i = 0; i < buttons.length; i++) {
buttons[i].draw();
}
}
}
//DESIGN LEVELS AND CALL THEM IN DRAW//////////////////////////////////////////
function levelOne() {
textSize(10);
strokeWeight(.4);
fill('grey');
text('Level One: Practice', 30, 10);
E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [4, 13], [25, 24],
[51, 41], [47, 39], [19, 20], [13, 41], [41, 20], [20, 24], [24, 39],
[39, 13]];
for (i = 0; i < E.length; i++) {
E[i] = makeEdge(E[i][0], E[i][1]);
if (mousehasentbeenclicked) {
E[i].draw();
}
}
V = [4, 13, 19, 20, 24, 25, 39, 41, 47, 51];
for (i = 0; i < V.length; i++) {
vertices[V[i]].bolddraw();
}
}
function levelTwo() {
textSize(10);
strokeWeight(.4);
fill('grey');
text('Level Two', 30, 10);
E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [38, 47], [47, 51],
[51, 42], [42, 38], [38, 51], [42, 47], [42, 19], [25, 38], [4, 38],
[4, 42], [19, 38], [25, 42]];
for (i = 0; i < E.length; i++) {
E[i] = makeEdge(E[i][0], E[i][1]);
if (mousehasentbeenclicked) {
E[i].draw();
}
}
V = [4, 19, 25, 38, 42, 47, 51];
for (i = 0; i < V.length; i++) {
vertices[V[i]].bolddraw();
}
}
function levelThree() {
textSize(10);
strokeWeight(.4);
fill('grey');
text('Level Three', 30, 10);
E = [[4, 31], [31, 17], [31, 53], [31, 45], [31, 9], [12, 14], [14, 33],
[33, 40], [40, 29], [29, 12], [4, 29], [4, 14], [17, 12], [17, 33], [53, 14],
[53, 40], [45, 33], [45, 29], [9, 40], [9, 12]];
for (i = 0; i < E.length; i++) {
E[i] = makeEdge(E[i][0], E[i][1]);
if (mousehasentbeenclicked) {
E[i].draw();
}
}
V = [4, 9, 12, 14, 17, 29, 33, 40, 45, 53, 31];
for (i = 0; i < V.length; i++) {
vertices[V[i]].bolddraw();
}
}
function levelFour() {
textSize(10);
strokeWeight(.4);
fill('grey');
text('Level Four', 30, 10);
E = [[4, 18], [18, 45], [45, 21], [21, 4], [4, 23], [23, 53], [53, 26],
[26, 4], [4, 28], [4, 34], [28, 34], [18, 28], [26, 34], [18, 21],
[23, 26], [28, 21], [34, 23], [21, 23], [28, 34], [23, 45], [21, 53]];
for (i = 0; i < E.length; i++) {
E[i] = makeEdge(E[i][0], E[i][1]);
if (mousehasentbeenclicked) {
E[i].draw();
}
}
V = [4, 18, 21, 23, 26, 28, 34, 45, 53];
for (i = 0; i < V.length; i++) {
vertices[V[i]].bolddraw();
}
}
function levelFive() {
textSize(10);
strokeWeight(.4);
fill('grey');
text('Level Five', 30, 10);
E = [[25, 4], [19, 4], [25, 51], [51, 47], [47, 19], [4, 13], [19, 13],
[25, 13], [29, 13], [33, 13], [47, 13], [51, 13], [4, 29], [4, 33],
[19, 29], [25, 33], [29, 51], [33, 47], [29, 47], [33, 51], [25, 29], [19, 33]];
for (i = 0; i < E.length; i++) {
E[i] = makeEdge(E[i][0], E[i][1]);
if (mousehasentbeenclicked) {
E[i].draw();
}
}
V = [4, 19, 25, 47, 51, 13, 33, 29];
for (i = 0; i < V.length; i++) {
vertices[V[i]].bolddraw();
}
}
function draw() {
for (k = 0; k < vertices.length; k++) {
vertices[k].draw();
}
if (levelnumber == 1) {
levelOne();
} else if (levelnumber == 2) {
levelTwo();
} else if (levelnumber == 3) {
levelThree();
} else if (levelnumber == 4) {
levelFour();
} else if (levelnumber == 5) {
levelFive();
}
}
function mousePressed() {
mousehasentbeenclicked = false;
pressButton();
colorVertices();
testEdge();
var is5colored = true;
for (i = 0; i < E.length; i ++) {
if (E[i].iscolored == false || E[i].iscorrect == false) {
is5colored = false;
}
}
if (is5colored == true) {
resetLevel();
levelnumber++;
}
if (levelnumber == 6) {
textSize(90);
fill('lightpink');
noStroke();
text('YOU WIN', 40, height/2);
}
}
My final project is a simple game based on graph coloring. Click on any of the colored boxes to select a color and then click in the vertices to color them with that color. The goal is to color in the graph so that there is no edge between vertices of the same color. When you succeed it will automatically move on to the next level. There are a total of 5 levels and when you complete them all you win!
]]>I wanted to create an interactive and hopefully addicting mini-game. This project is inspired by the old arcade games I used to spend all my allowance on to win the big prize at the top! Also the final stacked blocks of my project looks similar to a modern skyscraper building in the grey skylines.
//Grace Wanying Hou
//15-104 Section D
//ghou@andrew.cmu.edu
//Final Project
//blocks dimensions setup
var h = 20;
var w = 100;
var x = 0;
var y = 20;
var speed = 1;
var fall = 5;
var dropping = false;
var taps = 0;
//arrays
var blocks = [];
var land = [75];
//gameplay
var play = false;
var gameOver = false;
var win = false;
function setup() {
createCanvas(250, 400);
frameRate(50);
}
function draw(){
noStroke();
if (gameOver == true){
if (play == true){//game screen once "gameover"
makeBackground();
text("YOUR SCORE WAS " + taps, 60, height - h*taps - 2 * h);
text("PRESS ANY KEY TO PLAY AGAIN", 28, height - h * taps - h);
push();
textSize(10);
text("screenshot and share your architecture masterpiece :)", 5, 30)//hehe i like architecture
pop();
updateDisplay();
}
if (win == true){//game screen once player wins
makeBackground();
text("YOU WIN",100,40);
text("PRESS ANY KEY TO PLAY AGAIN", 28, height/2);
push();
textSize(10);
text("screenshot and share your architecture masterpiece :)", 5, 30)
pop();
updateDisplay();
}
//resetting the variables when restarting game
if (keyIsPressed){
gameOver = false;
play = false;
win = false;
blocks = [];
land = [75];
dropping = false;
w = 100;
x = 0;
y = 20;
speed = 1;
fall = 5;
taps = 0;
}
}
else if (play == true){//screen once game starts
makeBackground();
text("PRESS SPACE TO STACK BLOCKS", 30, height/2);
for (var i = 0; i < 3; i++){
var xstart = width / 2 - 50;
var ystart = height - 20;
blocks[i] = makeBlock(xstart, ystart, 100);
}//gameplay functions
blockDrop();
drawBlock();
blockMove();
addBase();
updateDisplay();
scoreDisplay();
}
else {
if (play == false){//starting screen
makeBackground();
text("PRESS ANY KEY TO BEGIN GAME", 28, height/2);
if (keyIsPressed == true){
play = true;
}
}
}
if (w <= 0){
gameOver = true;
play = true;
}
else if (taps >= 16 & y >= 50){
gameOver = true;
win = true;
}
}
function makeBackground(){//making a gradient for the background
strokeWeight(1);
for (var i = 0; i < height; i++){
stroke(255 - i / 8);
line(0, i, width, i);
}
}
function blockMove(){//hovering blocks moving side to side
if (x >= width - w){
speed = -1 - (taps * 0.2);
}
else if(x <= 0){
speed = 1+(taps * 0.2);
}
x = x + speed;
}
function blockDrop(){//dropping blocks
if (dropping == true){
y = y + fall;
speed = 0;
while (y > height - h * taps){
dropping = false;
y = 20;
speed = 1 + (taps * 0.2);
fall = 5;
}
}
}
function keyTyped(){//setting the blocks to drop once space is pressed
if (keyCode == 32 & dropping == false && play == true){
taps = taps + 1;
append(land, x);
dropping = true;
}
}
function drawBlock(){//drawing hovering block
noStroke();
fill(0);
rect(x,y,w,h);
}
function scoreDisplay(){//displaying score (numbers of blocks fallen)
push();
fill(255);
textSize(15);
text(taps,120,height-5);
pop();
}
function addBase(){//knida confusing measurements of blocks collected in the tower
var currenth = height - taps * h - h;//current height of tower
if (y == height - h * taps){//if falling blocks are on the LEFT side of the tower
if (land[taps] <= land[taps - 1]){
blocks.push(makeBlock(land[taps - 1], currenth ,w - (land[taps - 1] - land[taps])));
w = w - (land[taps - 1] - land[taps]);
shorten(land);
append(land, land[taps-1]);
}
else if (land[taps] > land[taps - 1]){//if falling blocks are on the RIGHT side of the tower
blocks.push(makeBlock(land[taps], currenth, w - (land[taps] - land[taps - 1])));
w = w - (land[taps] - land[taps - 1]);
}
}
}
function updateDisplay(){//drawing and updating the display of the stacked blocks
for (var i = 0; i < blocks.length; i++){
blocks[i].add();
}
}
function towerBlocks(){//drawing the blocks in the tower
noStroke();
fill(0);
rect(this.x, this.y, this.bw, this.bh);
}
//objects created for each block in the tower
function makeBlock(xlocation, ylocation, currentwidth){
var block = {x:xlocation,
y:ylocation,
bh:20,
bw:currentwidth,
add:towerBlocks,
}
return block;
}
]]>//Robert Managad
//Section-E
//rmanagad@andrew.cmu.edu
//Final Project -- Trigonometric Loading Icons
//This code loops on the basis of the trigonometric functions cosine, sine, and tangent.
//It can be modified to produce three distinct animations, depending on the trig function used,
// and on the axis be affected.
var spins = [];
var drips = [];
var warps = [];
var pluss = [];
function setup() {
createCanvas(420, 420);
//Spin Loop, center
push();
for (var i = 0; i < 12; i++){
var spinposition = createVector(i * 20, i);
var spinradius = i * 1; // Radius increases by 200% for every iteration of i, up to 12.
spins[i] = new Spin(spinposition, spinradius); //holds circle function in the array
}
pop();
//Drip loop, top center
for (var i = 0; i < 8; i++){
var dripposition = createVector(i*18, i);
var dripradius = i * 2;
drips[i] = new Drip(dripposition, dripradius);
}
//Warp loop, left center
for (var i = 0; i < 12; i++){
var warpposition = createVector(i*20, i);
var warpradius = i * 1.5;
warps[i] = new Warp(warpposition, warpradius);
}
//Plus loop, left center
for (var i = 0; i < 12; i++){
var plusposition = createVector(i*20, i);
var plusradius = i * 1.5;
pluss[i] = new Plus(plusposition, plusradius);
}
}
function draw() {
background(0);
//drip draw
for(var i = drips.length - 1; i >= 0; i--){
var drip = drips[i];
drip.update();
drip.display();
}
//rectangle mask
fill(0);
noStroke();
rect(140, 130, 140, 300);
//warp draw
for(var i = warps.length - 1; i >= 0; i--){
var warp = warps[i];
warp.update();
warp.display();
}
//spin draw
for(var i = spins.length - 1; i >= 0; i--){
var spin = spins[i];
spin.update();
spin.display();
}
//plus draw
for(var i = pluss.length - 1; i >= 0; i--){
var plus = pluss[i];
plus.update();
plus.display();
}
}
//--------------------
//elements of each circle are compounded into the Spin function.
function Spin(spinposition, spinradius){
this.position = spinposition;
this.radius = spinradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.007; //holds value of velocity. Higher radius value = higher speed.
this.position.y = (200 + 90 * cos(this.time))/2;
this.position.x = (200 + 90 * sin(this.time))/2;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x - 20, this.position.y - 20, this.radius, this.radius);
}
}
//---------------------
function Drip(dripposition, dripradius){
this.position = dripposition;
this.radius = dripradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.004; //holds value of velocity. Higher radius value = higher speed.
this.position.y = (200 + 90 * tan(this.time))/3;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x + 275, this.position.y - 10, this.radius, this.radius);
}
}
//------------------------
function Warp(warpposition, warpradius){
this.position = warpposition;
this.radius = warpradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.002; //holds value of velocity. Higher radius value = higher speed.
this.position.y = 200 + 30 * cos(this.time);
this.position.x = 200 + 30 * tan(this.time);
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x , this.position.y + 160, this.radius, this.radius);
}
}
//----------------------------
function Plus(plusposition, plusradius){
this.position = plusposition;
this.radius = plusradius;
this.direction = 1;
this.time = 0; //controls the placement of the starting anchor, time to jump towards.
//updates position every time draw is called.
this.update = function(){
this.time += this.direction * this.radius * 0.002; //holds value of velocity. Higher radius value = higher speed.
this.position.y = 200 + 40 * 1/cos(this.time)/3;
this.position.x = 200 + 40 * 1/sin(this.time)/3;
//trig function directs the animation (slowing down in middle/accelerating the circles as they approach the edges)
}
//holds visual presentation
this.display = function(){
noFill();
stroke(255);
strokeWeight(1.5);
ellipse(this.position.x , this.position.y, this.radius, this.radius);
}
}
If gifs below are frozen: right-click and open the image in a new tab.
My final project culminated in a series of six loading icons. I used trigonometric functions to calculate x and y positions — because of their cyclical behaviours, sin, cosine, and tangent worked well for looping animations. Individual animation gifs can be seen above. Process work can be seen below
From a design standpoint, I developed these loading icons with several human factors in mind — from longevity and human attention span, to interactivity and engagement. Repetition in form, symmetry in composition and shape, and cyclical rhythm all contribute to keeping people from becoming disengaged with the content. As a component living in a transitionary space, the loading icon serves to bridge one space to the next.