// Xiaoyu Kang & Xu (Claire) Xu
// Section B
// xkang@andrew.cmu.edu & xux1@andrew.cmu.edu
// Final Project
var hatShapeX = 130; //BY BOTH XIAOYU AND XU
var hatShapeY = 128;
var heartShapeX = 205;
var heartShapeY = 128;
var moneyShapeX = 270;
var moneyShapeY = 140;
var textboxShapeX = 330;
var textboxShapeY = 128;
var backgroundColor = 0;
var gameStart = false;
var badEnd = false;
var goodEnd = false;
var img1 = [];
var imageCount = 0;
var testLinks = ["https://i.imgur.com/VWoGtbO.jpg",
"https://i.imgur.com/OpLGpha.jpg",
"https://i.imgur.com/1Ik4bPx.jpg",
"https://i.imgur.com/vM6ZK9c.jpg",
"https://i.imgur.com/8J6Gxdo.jpg",
"https://i.imgur.com/yk3tV27.jpg",
"https://i.imgur.com/FH9qhm4.jpg",
"https://i.imgur.com/E7a5TDu.jpg",
"https://i.imgur.com/9vRGrKE.jpg",
"https://i.imgur.com/C4XhQaI.jpg",
"https://i.imgur.com/NgIAvpS.jpg",
"https://i.imgur.com/QRXsh9S.jpg",
"https://i.imgur.com/04EkVKf.jpg",
"https://i.imgur.com/0dOYwZv.jpg",
"https://i.imgur.com/xc56D6n.jpg",
"https://i.imgur.com/0sk94O3.jpg"];
var questionCount = 0;
let testQuestions = ["I can't code for life,", " but do you want to collaborate on this 15104 project?",
"Did you hear about the history exam tomorrow?", "I can’t believe it’s on EVERYTHING!",
"I heard Vivian got a 104/100", " on the recent physics test!",
"I really need to get some sleep,", "will you sign me in for lecture today?",
"There’s a frat party tonight,", "do you want to go and hang out?",
"OMG I heard there’s a new pho place downtown,", "are you interested??",
"There’s a library part time job on Handshake", "let’s apply together!",
"Let’s play","League of Legends tonight!",
"<Introduction to Javascript> is a required textbook,", "please get it by next class.",
"Re: Please see the HW attached,", "submit all to autolab by tonight at midnight.",
"I noticed that you have not paid attention in class.", "Is there something wrong?",
"Class, this project", "will be due in a week’s time.",
"Re: Would you like to be a generous supporter", "of the CMU community by becoming a donor?",
"The total amount of your food will be $15.76.", "Paid in card or cash?",
"New: Pittsburgh popcorn & smokey barbeque", "flavored mac and cheese",
"It’s 2am in the mornin’,","why are y’all still workin’?"]
var imageposX = 115;
var imageposY = 80;
var questionposY = 380;
var answerCount = 0;
let answerX = ["Um… Sure?",
"What exam?",
"Ha, I can do better",
"Sure, go sleep",
"Sure, I’ll go!",
"YES LET’S GO",
"Sure I’ll join",
"I'll grab my laptop",
"I’ll buy it",
"Grinds through HW",
"It won’t happen again",
"Complete the task",
"Fine I’ll donate",
"Takes out debit card",
"Gives it a try",
"We have a deadline"];
let answerY = ["I prefer someone better",
"Ya I studied all night",
"She must’ve worked hard",
"I’m also not going",
"Nah, I’ll pass",
"No I’m broke",
"I’m too lazy",
"My heart is in the work",
"I’ll find a fake one",
"Ignores this email",
"Your class is boring",
"Request for extension",
"I’m not generous",
"Gets something cheaper",
"Gets something normal",
"Cries hysterically"];
var answerposX = 90;
var answerposY = 430;
var timeTracker = 0;
var choices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var choices_A = [];
var academicsHP = 50;
var sanityHP = 50;
var financeHP = 50;
var socialHP = 50;
var HPposX = 35;
var HPposY = 40;
var logoPosX = 15;
var logoPosY = 30;
var subtract = true;
var monthCount = 0;
var star = [];
var cloud = [];
var crow = [];
function preload(){ //BY XU
for (var i = 0; i < testLinks.length; i++){
img1[i] = loadImage(testLinks[i]);
}
}
function setup(){ //BY XIAOYU
createCanvas(480,480);
frameRate(10);
//setup stars that will display at night
for (var i = 0; i < 50; i ++) {
var starX = random(width);
var starY = random (0, height/2);
star[i] = makeStar(starX, starY);
}
//setup clouds that will display at morning
for (var i = 0; i < 10; i ++) {
var cloudX = random(width);
var cloudY = random (0, height/2);
cloud[i] = makeCloud(cloudX, cloudY);
}
//setup crows that will display at afternoon
for (var i = 0; i < 20; i ++) {
var crowX = random(width);
var crowY = random (0, height/2);
crow[i] = makeCrow(crowX, crowY);
}
}
function draw(){ //BY XU
//starting page text
background(0);
fill("yellow");
textSize(70);
textFont('Courier');
textAlign(CENTER);
text('REIGNS', width/2, height/2);
fill("white");
textSize(20);
text('- CMU EDITION -', width/2, height/2 + 50);
textSize(15);
text('Press Mouse To Start', width/2, height - 70);
//starting page logo
fill("yellow");
rectMode(CENTER);
rect(width/2, 130, 250, 60);
//academics logo
noStroke();
fill(0);
beginShape();
vertex(hatShapeX, hatShapeY);
vertex(hatShapeX + 20, hatShapeY - 5);
vertex(hatShapeX + 40, hatShapeY);
vertex(hatShapeX + 20, hatShapeY + 5);
vertex(hatShapeX, hatShapeY);
endShape();
rectMode(CORNER);
rect(hatShapeX, hatShapeY, 1, 10);
rect(hatShapeX + 10, hatShapeY, 20, 10);
//sanity logo
circle(heartShapeX, heartShapeY, 15);
circle(heartShapeX + 10, heartShapeY, 15);
triangle(heartShapeX - 8, heartShapeY, heartShapeX + 18, heartShapeY, heartShapeX + 6, heartShapeY + 15);
//finance logo
textSize(33);
text('S', moneyShapeX, moneyShapeY);
rect(moneyShapeX - 1.5, moneyShapeY - 22, 3, 25);
//social life logo
ellipse(textboxShapeX, textboxShapeY, 30, 20);
triangle(textboxShapeX, textboxShapeY, textboxShapeX + 10, textboxShapeY, textboxShapeX + 10, textboxShapeY + 15);
if(gameStart){
backgroundChange();
fill(backgroundColor);
rectMode(CENTER);
rect(width/2, height/2, 480, 480);
//display clouds when background is light gray
if (timeTracker == 0) {
displayCloud();
}
//display crows when background is dark gray
if (timeTracker == 1) {
displayCrow();
addCrow();
removeCrow();
}
//display stars when background is black
if (timeTracker == 2) {
displayStars();
}
gameInterface();
}
//check if the game has ended
checkStatus();
//bad end
if (badEnd){
gameStart = false;
background(0);
fill("yellow");
textSize(70);
textFont('Courier');
textAlign(CENTER);
text('GAME OVER', width/2, height/2);
fill("white");
textSize(20);
text('- SADLY YOU DIDNT GRADUATE -', width/2, height/2 + 50);
textSize(15);
text('Refresh Page to Start Over', width/2, height - 70);
}
//goodEnd
if (goodEnd){
gameStart = false;
background(0);
fill("yellow");
textSize(50);
textFont('Courier');
textAlign(CENTER);
text('CONGRATULATIONS', width/2, height/2);
fill("white");
textSize(20);
text('- YOU SUCCESFULLY GRADUATED CMU -', width/2, height/2 + 50);
textSize(15);
text('Refresh Page to Play Again', width/2, height - 70);
}
}
function mouseClicked(){ //BY XU
gameStart = true;
}
function gameInterface(){ //BY XU
//frame
fill("yellow");
rectMode(CENTER);
rect(width/2, height/2 - 35, 280, 280);
//implement images
putImage();
//implement question
putQuestion();
//implement answers
putAnswers();
putDate();
hpTracker();
}
function putImage(){ //BY XIAOYU
image(img1[imageCount], imageposX, imageposY);
}
function putQuestion(){ //BY XIAOYU
fill("white");
textFont('Courier');
textAlign(CENTER);
textSize(12.5);
text(testQuestions[questionCount], width/2, questionposY);
text(testQuestions[questionCount + 1], width/2, questionposY + 15);
}
function putAnswers(){ //BY XIAOYU
//left side
fill("yellow");
textFont('Courier');
textSize(12.5);
text("A. " + answerX[answerCount], answerposX, answerposY);
text("B. " + answerY[answerCount], answerposX + 280, answerposY);
}
function putDate(){ //BY XIAOYU
fill("yellow");
textFont('Courier');
textAlign(CENTER);
textSize(12.5);
text(monthCount*2 + " months survived", width/2, 460);
}
function keyTyped(){ //BY XU
if (key === 'a'){
//time passes
timeTracker ++;
imageCount = floor(random(choices));
questionCount = imageCount *2;
answerCount = imageCount;
subtractHP();
monthCount ++;
} else if (key === 'b'){
//time passes
timeTracker ++;
imageCount = floor(random(choices));
questionCount = imageCount *2;
answerCount = imageCount;
subtractHP();
monthCount ++;
}
if (timeTracker >= 3){
timeTracker = 0;
}
}
function notRepeat(){ //BY XU
while (choices_A.includes(imageCount)){
imageCount = floor(random(choices));
}
if(choices_A.length < 6){
choices_A.push(imageCount);
}else {
choices_A.shift();
choices_A.push(imageCount);
}
}
function hpTracker(){ //BY XIAOYU
//academics logo
noStroke();
fill("yellow");
beginShape();
vertex(logoPosX, logoPosY);
vertex(logoPosX + 20, logoPosY - 5);
vertex(logoPosX + 40, logoPosY);
vertex(logoPosX + 20, logoPosY + 5);
vertex(logoPosX, logoPosY);
endShape();
rectMode(CORNER);
rect(logoPosX, logoPosY, 1, 10);
rect(logoPosX + 10, logoPosY, 20, 10);
//academics hp
fill("white");
textFont('Courier');
textAlign(CENTER);
textSize(12.5);
text(academicsHP + "/100", HPposX + 50, HPposY);
//sanity logo
fill("yellow");
circle(logoPosX + 130, logoPosY, 15);
circle(logoPosX + 130+ 10, logoPosY, 15);
triangle(logoPosX + 130 - 8, logoPosY, logoPosX + 130 + 18, logoPosY, logoPosX + 130 + 6, logoPosY + 15);
//sanity hp
fill("white");
text(sanityHP + "/100", HPposX + 130 + 30, HPposY);
//finance logo
fill("yellow");
textSize(33);
text('S', logoPosX + 250, logoPosY + 10);
rect(logoPosX - 1.5 + 250, logoPosY + 10 - 22, 3, 25);
//finance hp
fill("white");
textSize(12.5);
text(financeHP + "/100", HPposX + 250 + 25, HPposY);
//social life logo
fill("yellow");
ellipse(logoPosX + 370, logoPosY, 30, 20);
triangle(logoPosX + 370, logoPosY, logoPosX + 370 + 10, logoPosY, logoPosX + 370 + 10, logoPosY + 15);
//social hp
fill("white");
text(socialHP + "/100", HPposX + 400, HPposY);
}
function subtractHP(){ //BY XU
//subtract hp
if (imageCount <= 3){
var randomNum = random(0, 1);
if (randomNum < 0.5){
academicsHP -= 10;
sanityHP += 10;
}else{
academicsHP += 10;
sanityHP -= 10;
}
}
if (imageCount >= 4 || imageCount <= 7){
var randomNum = random(0, 1);
if (randomNum < 0.5){
financeHP -= 10;
socialHP += 10;
}else{
financeHP += 10;
socialHP -= 10;
}
}
if (imageCount >= 8 || imageCount <= 11){
var randomNum = random(0, 1);
if (randomNum < 0.5){
academicsHP += 10;
sanityHP -= 10;
}else{
academicsHP -= 10;
sanityHP += 10;
}
}
if (imageCount >= 12 || imageCount <= 15){
var randomNum = random(0, 1);
if (randomNum < 0.5){
financeHP += 10;
socialHP -= 10;
}else{
financeHP -= 10;
socialHP += 10;
}
}
}
function checkStatus(){ //BY XU
if (academicsHP == 100 || sanityHP == 100 || financeHP == 100 || socialHP == 100){
badEnd = true;
}
if (academicsHP == 0 || sanityHP == 0 || financeHP == 0 || socialHP == 0){
badEnd = true;
}
if (monthCount >= 24){
goodEnd = true;
}
}
function backgroundChange(){ //BY XIAOYU
if (timeTracker == 0) {
backgroundColor = 130;
}
if (timeTracker == 1) {
backgroundColor = 95;
}
if (timeTracker == 2) {
backgroundColor = 0;
}
}
function drawStar(){ //BY XIAOYU
noStroke();
fill("yellow");
push();
translate(this.x, this.y);
ellipse(20, 20, random(1,5), random(1,5));
pop();
}
function makeStar(starX, starY){ //BY XIAOYU
var makeStar = {x: starX,
y: starY,
draw: drawStar}
return makeStar;
}
function displayStars(){ //BY XIAOYU
for (i = 0; i < star.length; i++){
star[i].draw();
}
}
function drawCloud(){ //BY XU
noStroke();
fill(185);
push();
translate(this.x2, this.y2);
ellipse(15, 26, 34, 20);
ellipse(45, 30, 22, 25);
ellipse(15, 35, 15, 16);
ellipse(30, 28, 28, 26);
pop();
}
function makeCloud(cloudX, cloudY){ //BY XU
var makeCloud = {x2: cloudX,
y2: cloudY,
speed: -6,
move: moveCloud,
draw: drawCloud}
return makeCloud;
}
function moveCloud(){ //BY XU
this.x2 += this.speed;
if(this.x2 <= -10){
this.x2 += width;
}
}
function displayCloud(){ //BY XU
for (i = 0; i < cloud.length; i++){
cloud[i].move();
cloud[i].draw();
}
}
function drawCrow(){ //BY XIAOYU
strokeWeight(1);
stroke(0);
noFill();
arc(this.x3, this.y3, this.size, this.size/2, PI, TWO_PI);
arc(this.x3 + this.size, this.y3, this.size, this.size/2, PI, TWO_PI);
}
function makeCrow(crowX, crowY){ //BY XIAOYU
var makeCrow = {x3: crowX,
y3: crowY,
speed2: random(3, 10),
size: random(5, 10),
move2: moveCrow,
draw2: drawCrow}
return makeCrow;
}
function moveCrow(){ //BY XIAOYU
this.x3 -= this.speed2;
this.y3 -= this.speed2 / random(5, 10);
}
function displayCrow(){ //BY XIAOYU
for (i = 0; i < crow.length; i++){
crow[i].move2();
crow[i].draw2();
}
}
function addCrow(){ //BY XU
if (random(0,1) < 0.1) {
var crowX = width;
var crowY = random(0, height/2);
crow.push(makeCrow(crowX, crowY));
}
}
function removeCrow() { //BY XU
var keep = [];
for (i = 0; i < crow.length; i++) {
if (crow[i].x3 + crow[i].size > 0) {
keep.push(crow[i]);
}
}
crow = keep;
}
For this final project, Xiaoyu and I collaborated to use p5js to create a CMU version of Reigns (a phone game). The game starts by pressing the mouse, then a series of questions will be presented, and the player uses ‘a’ key and ‘b’ key to make choices. There are four HP counters at the top of the screen, and they will fluctuate based on the choices the player makes. Once any of the four HPs reach 0/100 or 100/100, the game will present the bad end. If the player survives until 48 months (4 years), the game presents the good end.
We used things we learned in the past semester to give the game some particular features, such as the background changes, making sure the characters don’t repeat themselves, etc. We drew the characters ourselves in illustrator, and created the gamestart/end pages with p5js.