hannahk2-Final Project

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
//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

    //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()));
        //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
        //add spider sprites

//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];
            //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() {
    //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."
        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."
        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") {
        //counts down from timer once game state goes into "looking" and
        //at 0 the game state changes to "gameOver"
        if (gameState == "looking") {
            if (timer <= 0) {
                gameState = "gameOver";
        //sets up the game over state with text and background
        if (gameState == "gameOver") {
            s3 = "You were seen and banished by the spiders before you could reach the human realm. Better luck next time!"
            fill(156, 183, 226)
            text(s3, 10, 10, 400, 400);
            //if game state is not "gameOver" display normal background
        } else {
            //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") {
                s4 = "You reached successfully the portal and returned to the human realm! Congrats!"
                fill(156, 183, 226)
                text(s4, 10, 10, 400, 400);
            //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
//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

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.


For my final project I would like to create a 2D platformer exploration game. I want to create an interactive game where a character has to navigate through an environment and either click on certain objects or come into contact with a portal to reach the next phase or environment. I want there to ultimately be some type of end environment in which the character is trying to reach. I am really inspired by the games, “Loved”, and “Limbo”, and would be interested in making the landscapes/environments slightly dangerous and contain traps. I would like to incorporate sounds in my game as well, and really focus on the art that goes into the environments and of course, the coding. I will be implementing gravity in the game/code so that my character can move around the environment, jump on top of things, etc. The game will also probably include animations in the environment and for the character.

This is a photoshop sketch of the type of environment I want to create. The character will interact with the background and jump, move, etc.


Loved is a browser based platform game by Alex Ocias, a graphic designer and artist. Written in Adobe Flash and released in June 2010, the game is a slightly sadistic exploration game where the player moves through a pixellated world and chooses to obey or disobey commands from a mysterious abusive narrator on the screen. The game is psychological in nature and thought provoking, and features a minimal landscape which becomes more and more complex as commands are disobeyed (the world gets more colorful). The other project I chose to write about is Limbo, a puzzle-platform video game developed by independent studio “Playdead” and released in July 2010. The game is a 2D side-scroller, and contains a physics system which controls objects in the environment and the character. The players job is to guide a mysterious little boy through dangerous environments and traps as he searches for his sister. The game was built with the expectation that the player would fail many times before finding the correct solution. The art in the game is made in black and white, and uses many effects including sound to create the eerie atmosphere of the world. I seriously admire these projects for their ability to immerse the player in the world built by the artists. Both of the games contain a sort of sadistic aspect which interests me, and Loved touches on really interesting themes of power and control, and abuse. What is really amazing is that both of these games turn games into a sort of art form, through both sophisticated visuals and complex concepts. People complain that limbo, however, could have had a more complex story line, and while I partly agree, I think the game suffices as one that paints a convincing environment and forces the player to overcome puzzles to survive.



Limbo gameplay

loved gameplay

limbo wiki

loved wiki



//Hannah Kim
//Section A

//creates variable to be mapped
var move=500

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

function draw() {
	//maps value to be used in right command
	var m = map(move, 0, mouseX, 200, 400);

    //draws darkest circular turtle which moves according to mouse
    var turtle4 = makeTurtle(mouseX, mouseY); //150
    turtle4.setColor(color(20, 36, 62));
        for (var i = 0; i < 2000; i++) {

    //draws middle colored circular turtle which moves according to mouse
    var turtle5 = makeTurtle(mouseX+200, mouseY+200); //150
    turtle5.setColor(color(85, 108, 122));
        for (var i = 0; i < 2000; i++) {

    //draws lightest colored circular turtle which moves according to mouse
    var turtle6 = makeTurtle(mouseX-200, mouseY-200); //150
    turtle6.setColor(color(139, 202, 191));
        for (var i = 0; i < 2000; i++) {

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){
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,
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;}

I did not make any sketches for this, but here are images of some compositions I liked.

For this project, I wanted to create a simple turtle collage which interacted with the mouse and created interesting compositions with eachother with every movement of the mouse. I am pretty happy with my results, and how the tiniest movement can create a different composition and pattern.


For this week’s Looking Outwards, I chose Maxime Causeret’s computer generated video and music work, “Order from Chaos”. The work is a blend of computationally generated biological forms and simulations, and computer generated music. Causeret aimed to represent the idea of emergence in the audio and visuals in his video, and even generated the rhythm of the track in an emergent manner. He took audio samples of rain falling, and mapped the transients for the drips, and forced the mapped points towards the nearest drumming grid positions using the computer. The result was that a steady rhythm emerged, and over this audio he added layers and layers of different instruments. He used computer animation to simulate complex biological processes such as endosymbiosis, flocking behavior, etc. The creators artistic sensibilities are clearly manifested in the final work, seeing his other works and his fascination with biological processes on the microscopic scale, and his use of bright, thin lines. I admire this project because of its consistency in the theme of emergence, in all aspects of the video including visuals, sound, etc. The forms displayed are simply mesmerizing and morph into each other beautifully, and the music is enchanting. The whole video seems otherworldly to me, and I really admire that.


Max Cooper – Order from Chaos – Official Video by Maxime Causeret from Max Cooper on Vimeo.



//Hannah Kim
//Section A

var gemboy; 
var terrainSpeed = 0.0075;
var terrainDetail = 0.06;
var gemY;

//preload image of spaceship
function preload(){
	gemboy = loadImage("https://i.imgur.com/OBAJ0Kb.png");

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

function draw() {

    //background layer 1 farthest layer back
    //uses noise to create randomized terrain
    fill(1, 100, 167, 100);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail/20) + (millis() * terrainSpeed/20);
        var y = map(noise(t), 0, 1, height/10, height);
        vertex(x, y); 
    vertex(width, height);

    //bg layer 2
    fill(1, 83, 130);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail/5) + (millis() * terrainSpeed/2);
        var y = map(noise(t), 0, 1, height/5, height);
        vertex(x, y); 
    vertex(width, height);

    //bg layer 3
    fill(250, 230, 162);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail/50) + (millis() * terrainSpeed/2);
        var y = map(noise(t), 0, 1, height/2, height);
        vertex(x, y); 
    vertex(width, height);

	image(gemboy, 100, 60, 280, 300);

    //closest layer
    fill(25, 176, 186);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail*1.5) + (millis() * terrainSpeed*20);
        var y = map(noise(t), 0, 1, height-200, height*1.2);
        vertex(x, y); 
    vertex(width, height);

    //calling stars to be drawn

//function to create star object with randomized opacity
//and randomized size
function makeStar() {
  var starX = random(5, width); 
  var starY = random(5, 200);
  var starW = random(2, 5);

  fill(255, random(10, 255)); 
  ellipse(starX, starY, starW, starW);

I wanted to create a cave landscape of a character in a gem spaceship. This was a very frustrating project for me as manipulating the different terrains and their speeds, heights, etc. was confusing. I did, however, have fun creating the drawing of the spaceship and choosing the colors. The object that I chose to include in my landscape was randomized stars. I wish I had more time so I could really create a more complex landscape with more objects, that I was happy with.

above is an image of my drawing.


The project I chose for this week is Camille Utterback’s “Dances of the Sacred and Profane”, an hour-long dance and computer generated video collaborative work shown at the Cowell Theater in San Francisco. The project is inspired by the music and art of the impressionist period, and mimics timing, memory, and angles of dancers using a motion graphics projection and real-time particle system. Camille manipulates the dancers movements on screen using onstage cameras projected onto large screens behind the dancers. I think this project is ambitious and extremely successful because the projected and manipulated graphics aesthetically augment and play with the details of the reflected choreography. I really admire the pure viscerality in the concept and the artwork, and the painterly quality of the art. It really does a convincing job of bringing me back to the impressionist era. Camille is an incredibly successful and internationally acclaimed artist and pioneer in digital and interactive art. Her work explores the aesthetic and experimental possibilities of connecting computational systems to human bodies, and has been displayed in galleries, festivals, and museums internationally. She is currently an assistant professor in Art at Stanford University, and a co-director of the Stanford Graduate Design program. She has a BA in Art from Williams College, and a Masters from NYU’s Tisch School of the Arts.

Link to the work: http://camilleutterback.com/projects/dances-of-the-sacred-and-profane/


Dances of the Sacred & Profane from Camille Utterback on Vimeo.



//Hannah Kim
//Section A

var img;
var small, big;

function preload() {
  var myImageURL = "https://i.imgur.com/7sW6Was.jpg";
	img = loadImage(myImageURL);

function setup() {
  createCanvas(500, 400);
  small = 4;
  big = 30;

function draw() {
  var pointCircle = map(mouseX, 0, 250, small, big);
  var pointSquare = map(mouseX, 250, width, small, big);
  var x = floor(random(img.width));
  var y = floor(random(img.height));
  var pix = img.get(x, y);
  fill(pix, 100);
  ellipse(x, y, pointCircle, pointCircle);
  ellipse(x, y, pointCircle-5, pointCircle-5);

  } else {
  fill(pix, 100);
  rect(x, y, pointSquare, pointSquare);



There were a few versions I messed around with before coming to my final version. I chose to create a portrait of my sister.

Below is an image of the final result which I felt was the most visually interesting.


Below are my other iterations.

The first one on the bottom was personally my favorite, however I felt it wasnt as interesting as the image above.


I chose Clarisa’s looking outwards from week 2, because I can relate to her fascination with virtual reality after experiencing it for the first time recently. I think the project she chose, Memo Akten’s Fight (2017), is really amazing and I agree with Clarisa in that the most interesting aspect is its variability- no two people will see and interpret the visuals in their brains the same way, though the images stay constant with each showing. I think it is important, however, to highlight how the artist achieved this effect by utilizing his knowledge of psychology and the binocular rivalry phenomenon. While looking around, the viewer’s brain chooses which aspects of the two images shown become dominant or suppressed, presenting the viewer with an animated patchwork of the two images. Even more amazing is the message that the picture we see in our minds is not a clear representation of the outside world, but of simulated world constructed based on our expectations and prior experiences.


(the link to the work)

cespinoz-Looking Outwards 02

(the original looking outwards post)

(the simulation of the mixing of the two images within the brain)

fight_snippet_4 from Memo Akten on Vimeo. (a clip of the two images shown in the VR)


Elliot Woods is a digital media artist and technologist from Manchester based in Seoul. He fosters interactions between humans and socio-visual design technologies, more specifically involving projectors, cameras, and graphical computation. He co-founded Kimchi and Chips, an art and technology studio with Mimi Son. They display the realms of material and immaterial, creating speculative visual objects which poke at the unpredictable attributes of things when they are touched with technology. I admire the groups’ success in encouraging the dialogue between digital and modern art cultures, and playing with the illusion of reality and immateriality. I really was amazed by their light projections project, and even wrote on it for my first looking outwards. It is a project in which they create intangible shapes and forms by gathering light projection beams. They present their work effectively by first showing the concept and digital mock ups, then the implementation and actual technical process of creating the work, and the final product. I think this would be a great way for me to clearly present future technology related artworks.

Eyeo 2014 – Mimi Son and Elliot Woods from Eyeo Festival // INSTINT on Vimeo.

A video of my favorite project from this group.

Light Barrier, 2014 from Mimi Son on Vimeo.