For my project I mainly based my project on whack a mole game combined with the pokemon that everyone loves, Diglet. The game lasts for 60 sec and during time the player would want to hit as many diglets as possible. Once the game ends the user can press r to restart the game. Hope you enjoy the game!
//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Final Project
//initialize constants and variables
//number of rows of diglets in the canvas
var rows = 3;
//body height of the diglet
var diglet_h = 30;
//number of diglets in the game
var num_diglets = 11;
//array to contain the diglet objects
var diglets = [];
//temporary dummie variable to help push all the diglets
var temp_diglet;
//number of diglets the player has hit in a single run of game/score
var num_hit;
//number of 0.5 sec passed elapsed
var time_elapsed = 0;
//duration of game 60sec
var game_time = 120;
//whether the game has ended
var ended = 0;
//hammer mode to determine if hammer is down or up
var mode;
//start position for even rows
var startx1 = 60;
//start position for odd row
var startx2 = 120;
//spacing with each diglet
var spacing = 120;
//height spacing
var dy = 90;
function setup() {
createCanvas(480, 360);
//creates the diglets in the right positions
// and pushes it into the array of diglets
for (var i = 0; i < rows; i++) {
//even rows
if ((i % 2) == 0){
for (var j = startx1; j < width; j += spacing){
temp_diglet = new diglet(j,dy*(i+1));
diglets.push(temp_diglet);
}
}
//odd rows
else {
for (var j = startx2; j < width; j += spacing){
temp_diglet = new diglet(j,dy*(i+1));
diglets.push(temp_diglet);
}
}
}
//initialize score for player
num_hit = 0;
//update the diglets ever half second to determine if they pop up
//and update timer every 0.5 sec
setInterval(function(){
for (var index = 0; index < num_diglets; index ++){
diglets[index].update();
}
time_elapsed += 1;
}, 500);
}
function draw() {
background(40,180,40);
noStroke();
//change the display of the hammer
if (mouseIsPressed){
mode = 1;
}
else {
mode = 0;
}
//end the game when the timer has ended
if (time_elapsed >= game_time){
ended = 1;
}
//if game has not ended, draw the holes for the diglets in the correct location
if (ended == 0){
for (var i = 0; i < rows; i++) {
//odd rows
if ((i % 2) == 0){
for (var j = 60; j < width; j += 120){
drawHole(j,dy*(i+1));
}
}
//even rows
else {
for (var j = 120; j < width; j += 120){
drawHole(j,dy*(i+1));
}
}
}
//draw every diglet in the array of diglets
for (var index = 0; index < num_diglets; index ++){
diglets[index].draw();
}
//draw hammer in passive position
if (mode == 0) {
fill(130,82,1);
rect(mouseX-5,mouseY-25,10,50);
fill(120);
rect(mouseX-25,mouseY-35, 50,20);
}
//draw hammer in active position
else {
fill(130,82,1);
rect(mouseX,mouseY-5,50,10);
fill(120);
rect(mouseX-10,mouseY-25, 20,50);
}
//display score and time left for the game
fill(255);
textSize(15);
text("Score : " + num_hit, 400,340);
text("Time Left : " + (game_time-time_elapsed)/2,5,340);
}
//game over screen
else {
fill(0);
rect(0,0,width,height);
fill(255);
text("Game Over!", width/2 - width/10, height/2);
text("Final Score : " + num_hit, width/2 - width/10,height/2 + height/15);
text("Press R to restart", width/2 - width/10, height/2 + 2*height/15);
}
}
//draw the hole sorry for much random numbers to make it look natural
function drawHole(x,y){
fill(0);
ellipse(x,y,80,40);
fill(103,104,76);
ellipse(x-40,y,22,12);
ellipse(x+40,y,22,12);
fill(90,77,65);
ellipse(x-32,y+8,20,12);
ellipse(x+28,y+8,24,14);
fill(119,120,119);
ellipse(x-22,y+13,20,12);
ellipse(x+12,y+16,24,15);
fill(100,100,100);
ellipse(x-4,y+18,28,15);
}
//object of diglet
function diglet(x,y,duration){
//base variables
this.x = x;
this.y = y;
this.duration = duration;
//draw the diglet, with eyes and body
this.draw = function() {
if (this.duration > 0) {
//brown of diglet
fill(181,147,119);
rect(this.x-diglet_h/2,this.y-diglet_h,diglet_h,diglet_h);
ellipse(this.x,this.y-diglet_h,diglet_h,diglet_h);
fill(0);
ellipse(this.x-diglet_h/6,this.y-diglet_h,3,6);
ellipse(this.x+diglet_h/6,this.y-diglet_h,3,6);
fill(255);
ellipse(this.x-diglet_h/6,this.y-diglet_h-2,1,1);
ellipse(this.x+diglet_h/6,this.y-diglet_h-2,1,1);
//nose color
fill(239,187,210);
ellipse(this.x,this.y-diglet_h+6,diglet_h/3,5);
}
}
//update whether the diglet appears
this.update = function(){
if (this.duration > 0){
this.duration = this.duration - 0.5;
}
else {
var temp_ratio = random(0,1);
if (temp_ratio < 0.15){
this.duration = random([1,2,3,4]);
}
}
}
//check if user clicked the diglet
this.inDiglet = function(click_x,click_y){
if (((click_x > this.x-diglet_h/2) & (click_x < this.x-diglet_h/2) && (click_y > this.y - diglet_h) && (click_y < this.y)) || (dist(click_x,click_y,this.x,this.y-diglet_h) < diglet_h)){
if (this.duration > 0){
this.duration = 0;
num_hit += 1;
}
}
}
}
//check if when the mouse is pressed if it hits any diglet
function mousePressed() {
for (var i = 0; i < num_diglets; i++){
diglets[i].inDiglet(mouseX,mouseY);
}
}
//when the game is over and you press r reset the game
function keyTyped(){
if ((key === 'r') & (ended == 1)){
ended = 0;
time_elapsed = 0;
ended = 0;
num_hit = 0;
}
}
]]>For my final project, my partner and I have decided to create a series of animations that are time sensitive every day activities. We also wanted also have it as a very colorful vibrant, colorful and cartoonish style to make it fun for the user to see. We also wanted to incorporate involvement of the audience with the animation. Some examples of animations we wanted to make is like cooking an egg, making toast, baking a cake. Below are some inspirations and drafts of our ideas.
partner: Jessica Nip, jknip
The first project that I have chosen to write about is “I want You to Want Me” by Jonathan Harris. It was created in 2008 and was installed in the Museum of Modern art during valentines day on 2008. It is an interactive exhibit where every balloon is a unique dating profile/story where the user can choose which story/profile to view as well as the background of the display. I Want You To Want Me aims to be a mirror, in which people see reflections of themselves as they glimpse the lives of others. Below is the link to the project.
Link to project 1
The second project that I have chosen to write about is Oily Stratum by Jared Tarbell. It was created in February 2003. It is a simple animation that is based on the laws of physics and tries to describe how to merge irregular objects based on cohesion and globual size.
The two projects are similar in that they both abide by certain physical rules, one is more based on data that is unrelated to physical rules while the other is based on physical properties, which is impressive.
]]>For this project, I simply just used a lot of randomization while trying to emulate the game of snakes with different colors for trails they leave. Below is an image of my draft
//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Assignment-10-A
//define line weight, starting positions of turtles, right angle,
//a unit of length for patterns, array of turtles, and max number of iterations
var line_weight = 10;
var r = 90;
var unit = 10;
var turtles = [];
var max_num = 34;
var cols = [];
function setup() {
//setup canvas and stroke properties
createCanvas(479, 479);
background(255);
stroke(0);
strokeJoin(MITER);
strokeCap(PROJECT);
cols = [color(60,186,84),color(244,194,13),color(219,50,54),color(72,133,237)];
//adds each turtle to its appropriate location, stroke weight
//color, and also initial orientation.
for (var i = 0; i < cols.length; i++){
turtles.push(makeTurtle(width/2,height/2));
turtles[i].setWeight(line_weight);
turtles[i].setColor(cols[i]);
for (var j = 0; j < i ; j++) {
turtles[i].left(r);
}
}
}
function draw() {
for (var i = 0; i < turtles.length; i++){
var k = random(10,30);
var dir = random([0,1]);
turtles[i].forward(k);
if (dir == 0){
turtles[i].left(r);
}
else {
turtles[i].right(r);
}
}
}
function mousePressed(){
turtles = [];
for (var i = 0; i < cols.length; i++){
turtles.push(makeTurtle(mouseX,mouseY));
turtles[i].setWeight(line_weight);
turtles[i].setColor(cols[i]);
for (var j = 0; j < i ; j++) {
turtles[i].left(r);
}
}
}
function turtleLeft(d) {
this.angle -= d;
}
function turtleRight(d) {
this.angle += d;
}
function turtleForward(p) {
var rad = radians(this.angle);
var newx = this.x + cos(rad) * p;
var newy = this.y + sin(rad) * p;
this.goto(newx, newy);
}
function turtleBack(p) {
this.forward(-p);
}
function turtlePenDown() {
this.penIsDown = true;
}
function turtlePenUp() {
this.penIsDown = false;
}
function turtleGoTo(x, y) {
if (this.penIsDown) {
stroke(this.color);
strokeWeight(this.weight);
line(this.x, this.y, x, y);
}
this.x = x;
this.y = y;
}
function turtleDistTo(x, y) {
return sqrt(sq(this.x - x) + sq(this.y - y));
}
function turtleAngleTo(x, y) {
var absAngle = degrees(atan2(y - this.y, x - this.x));
var angle = ((absAngle - this.angle) + 360) % 360.0;
return angle;
}
function turtleTurnToward(x, y, d) {
var angle = this.angleTo(x, y);
if (angle < 180) {
this.angle += d;
} else {
this.angle -= d;
}
}
function turtleSetColor(c) {
this.color = c;
}
function turtleSetWeight(w) {
this.weight = w;
}
function turtleFace(angle) {
this.angle = angle;
}
function makeTurtle(tx, ty) {
var turtle = {x: tx, y: ty,
angle: 0.0,
penIsDown: true,
color: color(128),
weight: 1,
left: turtleLeft, right: turtleRight,
forward: turtleForward, back: turtleBack,
penDown: turtlePenDown, penUp: turtlePenUp,
goto: turtleGoTo, angleto: turtleAngleTo,
turnToward: turtleTurnToward,
distanceTo: turtleDistTo, angleTo: turtleAngleTo,
setColor: turtleSetColor, setWeight: turtleSetWeight,
face: turtleFace};
return turtle;
}
]]>For week 11’s Looking Outwards, I have decided to write about “If vi was ix” by TRUMPIN or Gerhard Trimpin.
I have written about a project of his in a previous looking outwards. In this project, he created a sound sculpture as the center piece of the Seattle’s Experience Music Project. It is basically a 50 ft sculpture with seven hundred acoustic and electric guitars. He also programmed the guitars to play music from all different kinds of genre from Scottish ballads to punk rock. He also wrote it so that the guitar could tune itself to make sure that it is in tune and in sync. It is also called the guitar tornado because it resembles the shape of a tornado. It doesn’t describe specifically what algorithms are used to create the program that plays different genres of music. What TRUMPIN always seems to do with his work is not only involve music or sound, but also incorporate a very unique visual aesthetic. Attached below is the link to the piece of work.
]]>
For this week’s looking outwards, I have chosen to report on Nova Jiang’s project Landscape Abbreviated. It is a kinematic maze constructed with modular planters with the capability of rotation which forms new paths and routes, while being a beautiful garden.
The parts of the maze is rotated and reconstructs is maze is controlled a computer program that obeys and follows certain mathematical algorithms. This makes the maze dynamic and ever changing, which encourages the audience to appreciate it from different angles and perspectives. I really appreciate that this project combines both natural and mechanical components. Nova Jiang holds a masters at UCLA. She seems to be currently an independent artist who creates projects that encourages the tactile and creative participation of the audience, resulting in structurally open systems in which joy, disorder and improvisation can thrive. Attached below is a link to the project.
Link
Initially, I was going to make a generative landscape based on microscopic creatures. Such as what you would see under a microscope. However I later decided to go one layer more, and tried to portray the subatomic environment. For this project, I wanted to create a subatomic generative landscape. So the basis of in the subatomic environment, is the atom. And I had to decide how to create differing forms of atoms. Then I realized that atoms with different sizes also create different elements. I created 3 types of possible moving objects which are different sized atoms, with electrons wizzing around them. Below attached are some of my sketches.
//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Project 10
var atoms = [];
function setup() {
createCanvas(480, 480);
// create an initial collection of buildings
for (var i = 0; i < 10; i++){
var rx = random(width);
atoms[i] = makeAtom(rx);
}
frameRate(20);
}
function draw() {
background(0);
push();
stroke(0);
fill(0);
rect(0,0, width, height);
displayStatusString();
updateAndDisplayAtoms();
removeAtomsThatHaveSlippedOutOfView();
addNewAtomsWithSomeRandomProbability();
pop();
}
function updateAndDisplayAtoms(){
// Update the building's positions, and display them.
for (var i = 0; i < atoms.length; i++){
atoms[i].move();
atoms[i].display();
}
}
function removeAtomsThatHaveSlippedOutOfView(){
// If a building has dropped off the left edge,
// remove it from the array. This is quite tricky, but
// we've seen something like this before with particles.
// The easy part is scanning the array to find buildings
// to remove. The tricky part is if we remove them
// immediately, we'll alter the array, and our plan to
// step through each item in the array might not work.
// Our solution is to just copy all the buildings
// we want to keep into a new array.
var atomsToKeep = [];
for (var i = 0; i < atoms.length; i++){
if (atoms[i].x + atoms[i].breadth > 0) {
atomsToKeep.push(atoms[i]);
}
}
atoms = atomsToKeep; // remember the surviving buildings
}
function addNewAtomsWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newAtomLikelihood = 0.02;
if (random(0,1) < newAtomLikelihood) {
atoms.push(makeAtom(width));
}
}
// method to update position of building every frame
function atomMove() {
this.x += this.speed;
}
// draw the building and some windows
function objectDisplay() {
var floorHeight = 20;
var particle_size = 20;
var bHeight = this.nFloors * floorHeight;
fill(120);
noStroke(0);
push();
translate(this.x, this.y);
stroke(0);
if (this.breadth == 1){
fill(color(255,0,0));
ellipse(0, 0, particle_size, particle_size);
fill(color(0,0,255));
ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
}
else if (this.breadth == 2){
fill(color(255,0,0));
ellipse(-particle_size/4, -particle_size/4, particle_size, particle_size);
fill(color(0,0,255));
ellipse(particle_size/4, -particle_size/4 , particle_size, particle_size);
fill(color(255,0,0));
ellipse(-particle_size/4, particle_size/4, particle_size, particle_size);
fill(color(0,0,255));
ellipse(particle_size/4, particle_size/4 , particle_size, particle_size);
}
else{
fill(color(255,0,0));
ellipse(-particle_size/3, particle_size/3, particle_size, particle_size);
fill(color(0,0,255));
ellipse(0, -particle_size/3 , particle_size, particle_size);
ellipse(particle_size/3, particle_size/3, particle_size, particle_size);
}
noStroke();
fill(color(180,180,40));
for (var i = 0; i < this.nFloors; i++) {
ellipse(random(-particle_size,particle_size), random(-particle_size,particle_size), 5, 5);
}
pop();
}
function makeAtom(birthLocationX) {
var bldg = {x: birthLocationX,
y: round(random(0,height)),
breadth: random([1,2,3]),
speed: -1.0,
nFloors: round(random(2,8)),
move: atomMove,
display: objectDisplay}
return bldg;
}
function displayHorizon(){
stroke(0);
line (0,height-50, width, height-50);
}
function displayStatusString(){
noStroke();
fill(0);
var statusString = "# Atoms = " + atoms.length;
text(statusString, 5,20);
}
]]>The project that my peer and I have chosen to talk about is the Hexagonal Generative Game of Life by Charlotte Dann.
// Alvin Luk
// akluk@andrew.cmu.edu
// Section A
// Project 9
// variable to store the image
var img;
var cur_x;
var cur_y;
var rand_x;
var rand_y;
var rand_t;
var type_shape;
var pix;
var siz;
function preload(){
img = loadImage("https://i.imgur.com/z1yTE1v.jpg");
img.loadPixels();
}
function setup(){
createCanvas (477,478);
background(255);
noStroke();
//set ellispe mode to center
ellipseMode(CENTER);
frameRate(10000);
}
function draw(){
//Select random point on canvas to draw
rand_x = random(img.width);
rand_y = random(img.height);
cur_x = floor(rand_x);
cur_y = floor(rand_y);
//get the value at the position of the image
pix = img.get(cur_x, cur_y);
//generate a random size of the shape
siz = random(3,6);
//randomize which shape to draw
type_shape = random([0,1,2]);
fill(pix);
//depending on the random value of type shape: choose triangle circle or square
if (type_shape == 0){
triangle(cur_x, cur_y-(2/3)*siz, cur_x-(1/2)*siz, cur_y+(1/3)*siz, cur_x+(1/2)*siz, cur_y+(1/3)*siz);
}
else if (type_shape == 1){
ellipse(cur_x, cur_y,siz,siz);
}
else {
rect(cur_x-siz/2,cur_y-siz/2,siz,siz);
}
}
For this portrait, I asked if my sister if I could use one of her older photos. For the project, I just played around with what variables I could randomize to make it more interesting. I decided to incorporate the three elementary shapes, a square, a triangle, and a circle to reconstruct my image. I also varied the size of the shapes that were used to reconstruct the image. Below are just some screen shots of the program, at it’s initial, intermediate, and “final” reconstruction of the image.
Sarah William is a current assistant professor of Urban planning as well as a director of the Civic Data Design Lab at MIT’s School of Architecture and planning. The Civic Data Design Lab at MIT utilizes data visualization and mapping techniques to analyze and visualize patterns at an urban scale and also allows different audience members to be able to understand the data and communicates the policies issues from the data. Digital Matatus is a project that I really liked, since it has such a simple design and yet so effectively conveys so much information.Below you can find a link to the works.
Link to her work
Something very interesting about the work she does is that she utilizes a lot of real life and real time data to create these very informative visuals. She believes that data is very essential and very important aspect of life. She believes that data could be used for both good and bad. She believes that it is how we use data which is what makes data truly powerful and impactful.
Her presentation has a lot of logical flow to it, where she first explains the important concepts that enable her work, then explaining what some applications of those concepts. Finally establishing a baseline of what basic understanding of concepts, she explains her own project which at that point everyone will have clear understanding of. Below is a link to their presentation.