× Haoshu #1 The Lost PenBox #2 STAR TREE Generator #3 Match Clock #4 Lonely Universe Monster #5 Chinese Name Mondrian Encoder #6 Put your mask on! #7 A Day with Tech #8 Put your mask on! v2.0 #9 Daily Laughter #10 Apple Global Suppliers #11 Nested For Loop Visualizer
☰ Menu

Project #4 Exquisite Corpse | Lonely Universe Monster


Move your mouse and click on the canvas :)

Designed by Haoshu Yang.
Partner: Nishra, Yumeng

Background Stories

Background Story 1 by Haoshu:

Monster

It’s a monster. It terrifies us. It makes our life aberrant. It could be Thanos with his ambition of eliminating half of the life in the universe. It could be a catastrophe causing millions of tragedies. It could also be the COVID-19 that changes our everyday patterns, hurts people and ruins families.

But it is not a portrait of a fierce evil who plays with human life. It is a monster but it is not inevitable. It scares us at the beginning. But after people’s rebounding together with careful researches and works day and night, the monster could just be like what I draw on the canvas—a controlled plush object.

Background Story 2 by Nishra:

Meet Anonymous!

They are everyone! They are you and I at some point in our lives! They are battling for the well being of their mental health. They have anxiety that knots up their mind and ties up their gut; and depression that makes them weak in their knees. They are afraid to face the world that is often too harsh. They are fading from within trying to fit in. They’re Anonymous, because some do not want too recognize them. They’re resting waiting to get back up.

Background Story 3 by Yumeng:

I get the inspiration from my favorite book, the Little Prince. He is not in that story, and he comes from my imagination.

Each person is composed of abstract geometric figures in that space, and each person is an independent and unique individual. They have their planet. Just as each of us is unique in reality, the communication between people is like the exploration between stars.

I created this character because I believe that people should respect others' uniqueness while remaining themselves.

Design Process

A lot of fun in redesigning this monster!

First, I got the upper body from Nishra’s drawing and the lower body from Yumeng’s. I tried to integrate the 2 parts with my monster’s head in Photoshop and it’s shown below.

Next, I thought about how to unify the style so that the 3 parts looks harmonious. I tried to use curves but the filled colors are rather too simple or complicated. Therefore, I found a intermediate way that is to use the triangles to divide the character and create the low-poly style.

Adobe Illustrator was used to set the triangles and the shapes as shown above. Then, I declared every triangle’s position and color in p5.js manually that requires a great deal of patience. After finishing all the still part of the character, I attempted to add some motion. Finally, with stars moving in the background, the monster could move the eyes with the mouse, so it is with the flower pattern. The lower “plate” also giggles like a seesaw. (But actually it ends up rotating counterclockwise if you let it move. XD) One more thing, press the mouse and the monster spew up a rainbow. It doesn’t mean anything, but it brings a spark of fun.

New story

It’s a monster.
It’s a lonely monster.
It’s a lonely monster traveling across the universe.
It has a terrifying appearance and the ability to destroy a planet.
It leaps millions of light year but couldn’t meet a single creature.
It is filled with power that cannot be shown to the outside world.
It feels nothing but lonely.
All it can do is to spew up a rainbow.
It is controlled in a micro universe.
It can never escape.

Reflection

The exquisite corpse brings a lot of fun and surprises. Before, drawing is a process of visualizing the image in the mind on a canvas. But this being is a total mystery until you finish the puzzle at the end. Unlike the computer generated random pattern, each piece of it is a part of the creation of a real person. It introduces stories, thoughts, as well as reflections, which make the surreal narrative.

Code

function setup() {

createCanvas(400, 600);

noStroke();

angleMode(DEGREES);

}

 

function tri(x1, y1, x2, y2, x3, y3, color) {

push();

fill(color);

triangle(x1, y1, x2, y2, x3, y3);

pop();

}

 

function Eye(x, y) {

push();

fill('#7D0D05');

let tx = map(mouseX, 0, 400, -6, 8, true);

let ty = map(mouseY, 0, 600, -6, 8, true);

translate(tx, ty);

beginShape();

for (let a = 0; a < 360; a += 360 / 6) {

let sx = x + cos(a) * 8;

let sy = y + sin(a) * 8;

vertex(sx, sy);

}

endShape(CLOSE);

 

stroke('ffffffaF');

strokeWeight(3);

point(x - 2, y - 2);

pop();

}

 

function Head() {

push();

fill('#231D0F');

rect(136, 110, 70, 50);

fill('#F3CC84');

rect(140, 60, 70, 40);

Eye(150, 77);

Eye(195, 85);

pop();

tri(120, 136, 152, 152, 136, 160, '#35EDA0');

tri(176, 160, 152, 152, 136, 160, '#0DDC6D');

tri(256, 160, 184, 176, 136, 160, '#07BF47');

tri(176, 160, 200, 128, 256, 160, '#1FE47A');

tri(200, 96, 200, 128, 256, 160, '#29EBA5');

tri(200, 96, 264, 104, 256, 160, '#43F1C0');

tri(200, 96, 208, 88, 264, 104, '#47EDBE');

tri(200, 96, 208, 88, 264, 104, '#47EDBE');

tri(264, 88, 208, 88, 264, 104, '#67F0CB');

tri(264, 88, 208, 88, 208, 80, '#47EDBE');

tri(264, 88, 256, 72, 208, 80, '#5CF2E5');

tri(200, 72, 256, 72, 208, 80, '#48F1D9');

tri(200, 72, 256, 72, 240, 48, '#4CF5F5');

tri(200, 72, 224, 32, 240, 48, '#45F3DC');

tri(200, 72, 224, 32, 160, 72, '#33EFBE');

tri(200, 24, 224, 32, 160, 72, '#40F1D7');

tri(200, 24, 168, 32, 160, 72, '#3EEFD2');

tri(144, 40, 168, 32, 160, 72, '#3EF0BD');

tri(144, 40, 152, 64, 160, 72, '#2EEDB6');

tri(144, 40, 152, 64, 128, 64, '#32EC9C');

tri(144, 72, 152, 64, 128, 64, '#2EF0D1');

tri(144, 72, 120, 88, 128, 64, '#2DF0B2');

tri(144, 72, 120, 88, 144, 80, '#30FFBD');

tri(152, 88, 120, 88, 144, 80, '#2BE2B2');

tri(152, 88, 160, 80, 192, 88, '#3BEFC3');

tri(192, 80, 160, 80, 192, 88, '#38EF9B');

tri(192, 80, 160, 80, 160, 72, '#3BFFC5');

tri(192, 80, 200, 72, 160, 72, '#35E6B2');

tri(192, 88, 120, 88, 120, 96, '#24F0B9');

tri(192, 88, 200, 96, 120, 96, '#35EDBC');

tri(112, 128, 200, 96, 120, 96, '#22F091');

tri(112, 128, 200, 96, 120, 136, '#24FF9A');

tri(152, 120, 200, 96, 200, 128, '#45F3A8');

tri(120, 136, 136, 128, 152, 152, '#29E795');

tri(184, 176, 256, 160, 256, 168, '#09810D');

tri(288, 168, 256, 160, 256, 168, '#33A865');

tri(272, 128, 256, 160, 264, 104, '#16DD7D');

tri(264, 88, 272, 104, 264, 104, '#0FC574');

tri(264, 88, 272, 72, 256, 72, '#37EBBF');

tri(240, 48, 264, 48, 256, 72, '#2CF0D6');

tri(240, 48, 240, 24, 224, 32, '#3BF1DE');

tri(136, 128, 152, 128, 152, 120, 'DEF5E5');

tri(152, 120, 200, 128, 160, 128, 'DDF4E2');

tri(136, 128, 152, 144, 152, 152, 'DFECDC');

push();

beginShape();

fill('EDE9D8');

vertex(152, 152);

vertex(166, 140);

vertex(168, 152);

vertex(173, 144);

vertex(176, 160);

endShape();

beginShape();

fill('ECE9D5');

vertex(180, 137);

vertex(190, 136);

vertex(200, 128);

vertex(176, 160);

endShape();

pop();

}

 

function UpperBody() {

tri(136, 160, 72, 192, 104, 168, '#EFECF5');

tri(136, 160, 72, 192, 152, 168, '#E4E6F2');

tri(136, 160, 184, 176, 152, 168, '#B4C1DE');

tri(200, 216, 184, 176, 152, 168, '#929DB4');

tri(256, 168, 184, 176, 208, 184, '#E6F2E8');

tri(200, 216, 184, 176, 208, 184, '#EBECF1');

tri(200, 216, 256, 168, 208, 184, '#E8F7F0');

tri(200, 216, 256, 168, 288, 168, '#B9D0E3');

tri(200, 216, 304, 200, 288, 168, '#E4EAED');

tri(312, 184, 304, 200, 288, 168, '#DCE9F1');

tri(312, 184, 304, 200, 328, 248, '#809DC9');

tri(312, 184, 328, 200, 328, 248, '#E8E9EB');

tri(360, 304, 328, 200, 328, 248, '#D4E0E9');

tri(280, 272, 304, 200, 328, 248, '#B9CBE1');

tri(280, 272, 304, 200, 272, 240, '#C1DBF3');

tri(200, 216, 304, 200, 272, 240, '#E2E9EF');

tri(272, 240, 280, 272, 200, 216, '#D5E6F3');

tri(288, 320, 280, 272, 200, 216, '#E1EBF2');

tri(288, 320, 168, 240, 200, 216, '#DCE9F1');

tri(160, 208, 152, 168, 200, 216, '#4A5E7B');

tri(160, 208, 152, 168, 72, 192, '#CCCED9');

tri(160, 208, 168, 240, 200, 216, '#50637C');

tri(160, 208, 168, 240, 72, 192, '#E1EAF3');

tri(328, 248, 280, 272, 288, 320, '#BED0E5');

tri(328, 248, 360, 304, 288, 320, '#84B0DF');

tri(72, 192, 168, 240, 56, 216, '#DBE4ED');

tri(128, 240, 168, 240, 56, 216, '#799AC9');

tri(128, 240, 48, 272, 56, 216, '#B0CAE7');

tri(128, 240, 48, 272, 120, 304, '#9AAECB');

tri(56, 304, 48, 272, 120, 304, '#CCDCF0');

tri(168, 240, 128, 240, 288, 320, '#ACCEEE');

tri(120, 304, 128, 240, 288, 320, '#2B62AC');

tri(120, 304, 240, 400, 288, 320, '#367DD5');

tri(120, 304, 240, 400, 168, 408, '#6A9FE0');

tri(120, 304, 144, 408, 168, 408, '#2A62AC');

tri(200, 416, 240, 400, 168, 408, '#557FBA');

tri(200, 416, 240, 400, 256, 408, '#1D284B');

tri(256, 408, 240, 400, 288, 320, '#719DD8');

//right arm

tri(120, 304, 56, 304, 112, 456, '#E8F2F9');

tri(120, 304, 144, 408, 112, 456, '#DAEDF5');

tri(168, 440, 144, 408, 112, 456, '#EAEBED');

tri(168, 440, 136, 480, 112, 456, '#F3F3F5');

tri(168, 440, 136, 480, 168, 472, '#E5E4EA');

tri(168, 440, 176, 448, 168, 472, '#8E949E');

tri(168, 440, 176, 448, 176, 440, '#CFE0ED');

tri(152, 480, 136, 480, 168, 472, '#C5CAD8');

//left arm

tri(288, 320, 256, 408, 296, 432, '#D2E4F2');

tri(288, 320, 360, 304, 296, 432, '#E4ECF9');

tri(224, 432, 256, 408, 296, 432, '#EEEFEE');

tri(224, 432, 224, 456, 296, 432, '#D3D8E4');

tri(224, 456, 280, 480, 296, 432, '#ECEDEE');

tri(224, 456, 280, 480, 256, 480, '#8696A9');

tri(304, 464, 280, 480, 296, 432, '#E7E8EB');

}

 

function UpperBodyPattern() {

push();

let tx = map(mouseX, 0, 400, -8, 10, true);

let ty = map(mouseY, 0, 600, -5, 5, true);

translate(tx, ty);

blendMode(MULTIPLY);

tri(152, 304, 176, 320, 168, 328, '#25416C');

tri(192, 328, 176, 320, 168, 328, '#33517D');

tri(192, 328, 176, 296, 176, 320, '#233A64');

tri(192, 328, 200, 296, 200, 328, '#1E3662');

tri(240, 304, 200, 328, 216, 328, '#425983');

tri(240, 328, 256, 312, 216, 328, '#2D4770');

tri(240, 328, 240, 336, 264, 328, '#26446C');

tri(240, 328, 240, 336, 216, 328, '#86A3CE');

tri(232, 344, 240, 336, 216, 328, '#7899C6');

tri(232, 344, 240, 336, 256, 350, '#325EA3');

tri(232, 344, 232, 360, 248, 368, '#3F638F');

tri(232, 344, 232, 360, 216, 328, '#84A1CB');

tri(216, 352, 232, 360, 216, 328, '#657EA7');

tri(216, 352, 232, 360, 232, 376, '#2D4465');

tri(216, 328, 216, 352, 200, 344, '#486795');

tri(216, 328, 192, 328, 200, 344, '#2E4B73');

tri(168, 328, 192, 328, 200, 344, '#42659C');

tri(168, 328, 144, 344, 200, 344, '#223A68');

tri(184, 352, 176, 344, 200, 344, '#324E7B');

tri(184, 352, 176, 344, 160, 368, '#224170');

tri(184, 352, 176, 376, 200, 352, '#43618F');

tri(184, 352, 200, 344, 200, 352, '#617EA4');

tri(216, 352, 200, 344, 200, 352, '#6983AD');

tri(208, 360, 216, 352, 200, 352, '#506C93');

tri(200, 376, 200, 352, 208, 360, '#28405F');

tri(208, 360, 216, 352, 216, 376, '#445E80');

pop();

}

 

function LowerBody1() {

tri(144, 408, 168, 408, 160, 488, '#EFE03E');

tri(200, 416, 168, 408, 160, 488, '#E8D940');

tri(200, 416, 272, 472, 160, 488, '#EED93E');

tri(200, 416, 272, 472, 240, 400, '#E4CE34');

tri(216, 504, 272, 472, 160, 488, '#E4B40D');

tri(216, 504, 192, 504, 160, 488, '#BF9605');

}

 

let angle = 20;

 

function LowerBody2() {

push();

let tx = 205,

ty = 496;

translate(tx, ty);

let add = int(millis() / 1000) % 2 ? 1 : -1;

let pa = (millis() / 1000 - int(millis() / 1000));

angle = angle + add * pa;

rotate(angle);

tri(192 - tx, 360 - ty, -120 - tx, 576 - ty, 544 - tx, 520 - ty, '#EDEBF8c8');

strokeWeight(3);

stroke('#3B5093');

tri(6 - tx, 496 - ty, 272 - tx, 536 - ty, 336 - tx, 448 - ty, '#E6ECF364');

strokeWeight(2);

tri(112 - tx, 504 - ty, 285 - tx, 464 - ty, 256 - tx, 520 - ty, '#F0EFF464');

strokeWeight(1);

tri(208 - tx, 488 - ty, 144 - tx, 504 - ty, 256 - tx, 504 - ty, '#F2F2E064');

pop();

}

 

let rainbow_color = ["#F80000", "#F8A000", "#F8F800", "#007C00", "#0000F8", "#49007E", "#E77EE7"];

 

function rainbow(num) {

let tx = map(mouseX, 0, 400, -5, 5, true);

let ty = map(mouseY, 0, 600, -400, 0);

let a = int((millis() / 1000 - int(millis() / 1000)) * 10) % 2 ? 1 : -1;

let step = 6;

let jmax = 472 + ty;

push();

fill(rainbow_color[num]);

beginShape();

let x = 146 + num * step + tx;

let y = 128;

for (let j = 0; j < jmax; j += 3) {

let i = j % 2 ? a : -a;

vertex(x + i, y + j);

}

vertex(x + step, y + jmax);

for (let j = 0; j < jmax; j += 3) {

let i = j % 2 ? -a : a;

vertex(x + step + i, y + jmax - j);

}

endShape();

pop();

}

 

function Slow() {

let num = 50;

while (num--) {

push();

strokeWeight(random(1, 5));

stroke(255, 255, 255, random(50, 205));

point(random(0, 400), random(0, 600));

pop();

}

}

 

let spew = false;

 

function draw() {

background('#3B5093');

Slow();

Head();

LowerBody2();

LowerBody1();

UpperBody();

UpperBodyPattern();

if (spew)

for (let i = 0; i < 7; i++)

rainbow(i);

}

 

function mousePressed() {

spew = !spew

}