RUN! PENGUIN!
made by Zhixuan Gu(Grace)
instructed by Andy Garcia
CONCEPTION AND DESIGN:
Because of global warming, the melting of the polar glaciers is becoming a more and more serious threat to the survival of polar animals. Based on this environmental issue, I started my project and mainly want players to understand the seriousness of climate change to raise their awareness of protecting the environment and do more to ease the climate problem. My project’s name is “Run! Penguin!”It focused on penguins. Players can experience the penguin’s life in the game, they will use the joystick to control the penguin’s location. There will be a big circle shown on the screen, which is the glacier. Everytime the circle touches the edge of the screen, it will become smaller, which is the process when the glacier is melting. Players need to make sure the penguin always stays inside the circle or the penguin will die in the cold ocean. Because the player’s movement on the joystick will directly reflect on the screen to influence the penguin’s location and it will change the final result of the game, I think this is the interaction part and players can have more fun and be aware of the horrible consequences of global warming.
During the user testing, most of the players reflect it is a fun game but they can not get fulfillment because this game only has the failing ending when the penguin falls from the ice. Also, they hope I can add more instructions on how to play this game. Finally, they think just using a joystick is too easy and can’t feel the excitement of playing the game. So according to these suggestions, I add an opening introduction stage to explain the game, a success stage and a fail stage. Once the penguin insists on the ice for 15 seconds, the player wins the game. Also, I add a roundel on the joystick to make the operation way more complex and more challenging. These changes are all successful in the practical game, especially the win condition which can make the players more excited and nervous.
this is the picture of my note during the user testing.
the three stages I add to the code
FABRICATION AND PRODUCTION:
First, the code is connected to the keyboard and then I want to add four buttons to control the penguin’s movement, like my first design draft.
But then I found that the penguin’s movement is not very smooth so it’s hard to play with four buttons. Professor Andy suggested I should try the joystick. It will make the movement smoother and more interesting to play. After the user testing, according to others advice, I added a roundel to the joystick to make the playing experience more interesting.
The button on the joystick didn’t work, so I added another button to start the game. But I think it is a better choice, because it can separate the gaming period and the starting and restarting action. Also, I didn’t choose to use the wood to make the box. Instead, I chose acrylic. (This part was made by laser cutting) Because I think the transparent box is prettier and we can see the colorful circuits inside and I think it is more interesting. Moreover, it is easier to draw on the acrylic and it will make the box more like in the Antarctic Pole and help players immerse themselves in the gaming world and experience the lives of penguins.
Finally, I used 3D printing to make a little penguin and ice mountain which will be stuck on the box to decorate the box to become prettier.
CONCLUSIONS:
I think my goals for this project have been achieved. The players use the joystick to control the penguin’s movement on the scream. When the ice becomes smaller, it becomes harder to keep the penguin on the ice. Everytime the penguin dies, the player will feel sad and regretful. So players can understand the harmful impact global warming has brought on the polar animals. If I have more time to finish this project, I may add more elements to the games. For example, I will think about solutions or ways to ease global warming, and once the player controls the penguin to achieve some actions, the penguin will be rewarded like the ice will become bigger. During the process, I have met some difficulties, like the coding problem. I try to review the course Powerpoint or ask professors and LAs to seek help. I understand that I shouldn’t give up or change my ideas quickly. Instead, we have to always have a positive attitude to solve the problem. Also, before my presentation, my roundel fell out of the joystick and I had to restick quickly in a short time. It reminds me to examine my project before and do more preparations to solve the urgent problem.
After these setbacks, I finally achieved my project and from this experience, I feel so satisfied because I made this project all by myself and I understand the importance of persistence and reinforcing past knowledge through real practice which will be more meaningful.
This is the video of the project:
DISASSEMBLY:
APPENDIX:
-
The image of the penguin comes from KOUPEN CHAN https://kawaii-republic.com/blog/entry_37.html
- The model of the penguin’s 3D cutting:https://www.tinkercad.com/learn/overview/OZE6V3PL1W5N53H?collectionId=OSZ5W2BL1W5N51F&type=TKCD
- The model of the box: https://cuttle.xyz/@cuttle/Closed-Box-with-Finger-Joints-blQZfaiFfZvv
- The background music of the success stage: https://youtu.be/BukCo9ebcSc?si=4b2QNE5LqqR1xfrD
- The background music of the success stage: https://youtu.be/WcYfsUOu3fk?si=pj2ehMPSnBbSgD7E
- The code of the Arduino:
void setup() {
Serial.begin(9600);
}
void loop() {
// to send values to Processing assign the values you want to send
// this is an example:
int sensor0 = analogRead(A0);
int sensor1 = analogRead(A1);
int button = digitalRead(9);
// send the values keeping this format
Serial.print(sensor0);
Serial.print(","); // put comma between sensor values
Serial.print(sensor1);
Serial.print(","); // put comma between sensor values
Serial.print(button);
Serial.println(); // add linefeed after sending the last sensor value
// too fast communication might cause some latency in Processing
// this delay resolves the issue
delay(20);
// end of example sending values
}
- The code of the Processing:
PImage photo; PImage photo2; float x ; float y ; float x1 ; // penguin float y1 ; float size ; float d = 10; float xspeed; float yspeed; float xspeed1; float yspeed1; int stage = 0 ; float button ; long time; boolean soundFailNotStarted = true; boolean soundWinNotStarted = true; import processing.serial.*; import processing.sound.*; Serial serialPort; SoundFile soundWin; SoundFile soundFail; int NUM_OF_VALUES_FROM_ARDUINO = 3; /* CHANGE THIS ACCORDING TO YOUR PROJECT */ /* This array stores values from Arduino */ int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO]; void
setup() { size (1167, 792); photo = loadImage("Antarctic.png"); photo2=loadImage("Penguin.png"); stage =0; x = width/2; y = height/2; x1 = width/2; y1 = height/2; size=400; xspeed = 2; yspeed = 2; printArray(Serial.list()); // put the name of the serial port your Arduino is connected // to in the line below - this should be the same as you're // using in the "Port" menu in the Arduino IDE serialPort = new Serial(this, "/dev/cu.usbmodem2101", 9600); soundFail = new SoundFile(this, "Failed.aiff"); soundWin = new SoundFile(this, "winning.mp3"); } void draw() { button = arduino_values[2]; if (stage == 0) { size (1167, 792); background(#A6CFF2); textSize(150); fill(#FFFFFF); text("Run Penguin!", 200, 250); textSize(30); fill(#FFFFFF); text("Because of global warming, the ice is becoming smaller and smaller!", 200, 500); text("You need to make sure the penguin always stay in the ice", 200, 540); text("If you are ready for the game, press the button!", 200, 580); fill(#F0EC83); noStroke(); circle( 900, 590, 30); if (button== 1 ) { time=millis(); stage=1; } } if (stage == 1) { xspeed1 = map(arduino_values[1], 0, 1023, -10, 10); yspeed1 = map(arduino_values[0], 1023, 0, -10, 10); imageMode(CORNERS); image(photo, 0, 0); noStroke(); fill(255); circle(x, y, size); x = x + xspeed; y = y + yspeed; if (y+size/2>height) { yspeed=yspeed *-1; size=size-d; } if (x+size/2>width) { xspeed=xspeed *-1; size=size-d; } if (y-size/2<0) { yspeed =yspeed *-1; size=size-d; } if (x-size/2<0) { xspeed=xspeed *-1; size=size-d; } //if (millis() >= 3000 && size <= 200) { // size = 0; // // suceess //} push(); translate(x1, y1); fill(0); imageMode(CENTER); image(photo2, 0, 0, 100, 100); pop(); x1 += xspeed1; y1 += yspeed1; // if (dist(x1, y1, x, y) < size/2) { // background(#FFFFFF); // fill(#FF0505); // text("SUCCESS", 350, 400); //} if (dist(x1, y1, x, y) > size/2) { stage=2; x1 = -100; y1 = -100; } if (dist(x1, y1, x, y) < size/2 && millis()-time >30000) { stage=3; x1 = -100; y1 = -100; } } if (stage == 2) { background(0); textSize(250); fill(#FF0505); text("FAIL", 350, 400); textSize(50); fill(#FFFFFF); text("if you want to start again,", 300, 600); text("The little penguin died in the ocean (O_O)", 150, 500); text(" press the button!", 400, 700); if (soundFailNotStarted == true) { soundFail.play(); soundFailNotStarted = false; } if (button == 1 ) { stage = 1; x1 = width/2; y1 = height/2; x = width/2; y = height/2; size = 400; time = millis(); soundFail.stop(); soundFailNotStarted = true; } } if (stage == 3) { background(0); textSize(200); fill(#F0EC83); text("SUCCESS", 225, 400); textSize(50); fill(#FFFFFF); text("if you want to start again,", 300, 600); text("You successfully save the penguin o(^▽^)o!", 150, 500); text(" press the button!", 400, 700); if (soundWinNotStarted == true) { soundWin.play(); soundWinNotStarted = false; } if (button == 1 ) { stage = 1; x1 = width/2; y1 = height/2; x = width/2; y = height/2; size = 400; time = millis(); soundWin.stop(); soundWinNotStarted = true; } } // receive the values from Arduino getSerialData(); } // the helper function below receives the values from Arduino // in the "arduino_values" array from a connected Arduino // running the "serial_AtoP_arduino" sketch // (You won't need to change this code.) void getSerialData() { while (serialPort.available() > 0) { String in = serialPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII if (in != null) { print("From Arduino: " + in); String[] serialInArray = split(trim(in), ","); if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) { for (int i=0; i<serialInArray.length; i++) { arduino_values[i] = int(serialInArray[i]); } } } } }