My project is a spot-the-difference game with three levels. To relate the project to 2020, I based my game loosely around the concept of isolation and distance.
My game is based off of online spot-the-difference games I used to play by a developer with the screen name “Ivory.” I was inspired by the moody atmosphere that Ivory was able to create using melancholy images and ambient music.
To play the game, simply click on the differences you find. Try to click precisely when making your guess. The number of remaining differences is shown in the top right corner. If you get stuck you can use the hint button for help, which has a short cooldown of 20 seconds. Try to win without any hints though!
var count = 0; //counter for effects timing
var hint; //variable to hold the "hint" object
var hintcooldown = 0;
var hinttimer = 0;
var scene1bg;
var scene1; //variable to hold scene images
var scene2;
var scene3;
var scene = 1; //which scene (level) the player is currently on
var margin = 5; //tolerence for guess clicks
var scene1DifferencesLinks = ["https://i.imgur.com/ohzNdw0.jpg", "https://i.imgur.com/I33D4yq.png", "https://i.imgur.com/4NeqeQR.png", "https://i.imgur.com/awJOkKc.png", "https://i.imgur.com/qLzzqz7.png", "https://i.imgur.com/QbUGoQQ.png", "https://i.imgur.com/a1iMYvd.png"]; //the "differences" are small .jpgs of edited pieces of the image. They will be placed on top of the image to create the "difference"
var scene2DifferencesLinks = ["https://i.imgur.com/f6goqZk.png", "https://i.imgur.com/YdMfKCs.png", "https://i.imgur.com/n3I5MAl.png", "https://i.imgur.com/EYIHAZV.png", "https://i.imgur.com/uu3811U.png", "https://i.imgur.com/e7dqm0J.png", "https://i.imgur.com/V4bhJe8.png"];
var scene3DifferencesLinks = ["https://i.imgur.com/tvCjM0d.png", "https://i.imgur.com/OhlyeMv.png", "https://i.imgur.com/Cr3qy7U.png", "https://i.imgur.com/RttUtn3.png", "https://i.imgur.com/y9AJnzC.png", "https://i.imgur.com/XqaebA2.png", "https://i.imgur.com/wF5Jwgm.png"];
var scene1Differences = [];
var scene2Differences = [];
var scene3Differences = [];
var scene1DifObjs = [];
var scene2DifObjs = [];
var scene3DifObjs = [];
var bgmusic;
var successnoise;
var difsremaining = 7; //tests how many difs left
function preload() {
scene1bg = loadImage("https://i.imgur.com/oibVoIs.jpg");
scene1 = loadImage("https://i.imgur.com/oehMn23.png"); //main images for the 3 scenes
scene2 = loadImage("https://i.imgur.com/PsOlXha.png");
scene3 = loadImage("https://i.imgur.com/lVsD9Nu.png");
for(i=0; i<scene1DifferencesLinks.length; i++){
scene1Differences[i] = loadImage(scene1DifferencesLinks[i]);
}
for(i=0; i<scene2DifferencesLinks.length; i++){
scene2Differences[i] = loadImage(scene2DifferencesLinks[i]);
}
for(i=0; i<scene3DifferencesLinks.length; i++){
scene3Differences[i] = loadImage(scene3DifferencesLinks[i]);
}
scene1DifObjs.push(makeDifference(scene1Differences[0], 467, 115, 12, 9)); //make the differences. Each difference object contains the x, y, w, and h of the difference. this is the information the rest of the program functions will need to figure out where to place the difference and when the difference is discovered
scene1DifObjs.push(makeDifference(scene1Differences[1], 213, 15, 2, 11));
scene1DifObjs.push(makeDifference(scene1Differences[2], 81, 26, 27, 13));
scene1DifObjs.push(makeDifference(scene1Differences[3], 12, 211, 14, 20));
scene1DifObjs.push(makeDifference(scene1Differences[4], 281, 329, 25, 26));
scene1DifObjs.push(makeDifference(scene1Differences[5], 491, 250, 99, 6));
scene1DifObjs.push(makeDifference(scene1Differences[6], 317, 195, 15, 11));
scene2DifObjs.push(makeDifference(scene2Differences[0], 527, 219, 47, 8));
scene2DifObjs.push(makeDifference(scene2Differences[1], 319, 252, 24, 17));
scene2DifObjs.push(makeDifference(scene2Differences[2], 388, 185, 12, 43));
scene2DifObjs.push(makeDifference(scene2Differences[3], 47, 339, 82, 33));
scene2DifObjs.push(makeDifference(scene2Differences[4], 573, 81, 34, 40));
scene2DifObjs.push(makeDifference(scene2Differences[5], 211, 158, 8, 93));
scene2DifObjs.push(makeDifference(scene2Differences[6], 413, 352, 19, 16));
scene3DifObjs.push(makeDifference(scene3Differences[0], 328, 209, 19, 21));
scene3DifObjs.push(makeDifference(scene3Differences[1], 475, 30, 17, 41));
scene3DifObjs.push(makeDifference(scene3Differences[2], 262, 293, 12, 53));
scene3DifObjs.push(makeDifference(scene3Differences[3], -16, 155, 56, 64));
scene3DifObjs.push(makeDifference(scene3Differences[4], 284, 183, 15, 13));
scene3DifObjs.push(makeDifference(scene3Differences[5], 172, 298, 56, 60));
scene3DifObjs.push(makeDifference(scene3Differences[6], 73, 274, 29, 21));
bgmusic = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/104music.mp3");
successnoise = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/success.wav");
}
function setup() {
createCanvas(600, 800);
useSound();
scene1bg.resize(600, 400);
frameRate(12);
hint = {x: 0, y: 0, w: 1, h: 1, alph: 0, drawit: hintDraw, stepit: hintStep};
}
function soundSetup() { // setup for audio generation
bgmusic.setVolume(0.3);
successnoise.setVolume(1);
}
function draw() {
// you can replace any of this with your own code:
background(255);
bgmusic.play();
print(difsremaining);
print(count);
if(count % 3000 == 0){
bgmusic.play();
}
if(difsremaining == 0){
difsremaining = 7;
if (scene == 1) {
scene = 2;
} else if (scene == 2){
scene = 3;
} else {
scene = 4;
count = 1;
}
}
if (scene == 1){
image(scene1bg, 0, 0);
image(scene1bg, 0, height/2);
push();
fill(255, 255, 255, 20);
rect(0, 0, 600, 800);
pop();
image(scene1, 0, 0);
image(scene1, 0, height/2); //draw two base scene images
push();
fill(255, 255, 255, 150);
textSize(10);
text("Differences remaining: " + difsremaining, 470, 15);
//text("Differences remaining: " + difsremaining, 470, 415);
pop();
for(i=0; i<scene1DifObjs.length; i++){
if(scene1DifObjs[i].found == false){
scene1DifObjs[i].drawit();
}
}
}
if (scene == 2){
image(scene2, 0, 0);
image(scene2, 0, height/2);
push();
fill(255, 255, 255, 150);
textSize(10);
text("Differences remaining: " + difsremaining, 470, 15);
//text("Differences remaining: " + difsremaining, 470, 415);
pop();
for(i=0; i<scene2DifObjs.length; i++){
if(scene2DifObjs[i].found == false){
scene2DifObjs[i].drawit();
}
}
}
if (scene == 3){
image(scene3, 0, 0);
image(scene3, 0, height/2);
push();
fill(255, 255, 255, 150);
textSize(10);
text("Differences remaining: " + difsremaining, 470, 15);
//text("Differences remaining: " + difsremaining, 470, 415);
pop();
for(i=0; i<scene3DifObjs.length; i++){
if(scene3DifObjs[i].found == false){
scene3DifObjs[i].drawit();
}
}
}
if (hintcooldown > 0){
push();
textSize(10);
fill(255, 255, 255, 150);
text(hintcooldown, 540, 31);
}
if (hinttimer % 12 == 0){
hintcooldown --;
}
hint.drawit(); //hint functions
hint.stepit();
drawhintbutton();
if (scene == 4){
push();
image(scene3, 0, 0);
image(scene3, 0, height/2);
fill(0, 0, 0, count*2.5);
rect(0, 0, width, height);
fill(255, 255, 255, count*2.5);
textSize(50);
text("END", width/2-50, height/2-10);
textSize(15);
text("THANK YOU FOR PLAYING", 205, 450);
pop();
}
if(scene != 4){
fill(0, 0, 0, 255-count*2.5); //fades in from black
rect(0, 0, width, height);
}
count++;
hinttimer++;
}
function mousePressed() {
if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
givehint();
}
if(scene == 1) {
for(i=0; i<scene1DifObjs.length; i++){
if((scene1DifObjs[i].found == false) & (mouseX >= scene1DifObjs[i].x - margin && mouseX <= scene1DifObjs[i].x + scene1DifObjs[i].w + margin) && (mouseY >= scene1DifObjs[i].y - margin && mouseY <= scene1DifObjs[i].y + scene1DifObjs[i].h + margin)) {
scene1DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene1Differences[i], scene1DifObjs[i].x, scene1DifObjs[i].y);
}
if((scene1DifObjs[i].found == false) & (mouseX >= scene1DifObjs[i].x - margin && mouseX <= scene1DifObjs[i].x + scene1DifObjs[i].w + margin) && (mouseY >= scene1DifObjs[i].y + 400 - margin && mouseY <= scene1DifObjs[i].y + 400 + scene1DifObjs[i].h + margin)) {
scene1DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene1Differences[i], scene1DifObjs[i].x, scene1DifObjs[i].y);
}
}
}
print(scene1DifObjs[0].found);
if(scene == 2) {
for(i=0; i<scene2DifObjs.length; i++){
if((scene2DifObjs[i].found == false) & (mouseX >= scene2DifObjs[i].x - margin && mouseX <= scene2DifObjs[i].x + scene2DifObjs[i].w + margin) && (mouseY >= scene2DifObjs[i].y - margin && mouseY <= scene2DifObjs[i].y + scene2DifObjs[i].h + margin)) {
scene2DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene2Differences[i], scene2DifObjs[i].x, scene2DifObjs[i].y);
}
if((scene2DifObjs[i].found == false) & (mouseX >= scene2DifObjs[i].x - margin && mouseX <= scene2DifObjs[i].x + scene2DifObjs[i].w + margin) && (mouseY >= scene2DifObjs[i].y + 400 - margin && mouseY <= scene2DifObjs[i].y + 400 + scene2DifObjs[i].h + margin)) {
scene2DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene2Differences[i], scene2DifObjs[i].x, scene2DifObjs[i].y);
}
}
}
if(scene == 3) {
for(i=0; i<scene3DifObjs.length; i++){
if((scene3DifObjs[i].found == false) & (mouseX >= scene3DifObjs[i].x - margin && mouseX <= scene3DifObjs[i].x + scene3DifObjs[i].w + margin) && (mouseY >= scene3DifObjs[i].y - margin && mouseY <= scene3DifObjs[i].y + scene3DifObjs[i].h + margin)) {
scene3DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene3Differences[i], scene3DifObjs[i].x, scene3DifObjs[i].y);
}
if((scene3DifObjs[i].found == false) & (mouseX >= scene3DifObjs[i].x - margin && mouseX <= scene3DifObjs[i].x + scene3DifObjs[i].w + margin) && (mouseY >= scene3DifObjs[i].y + 400 - margin && mouseY <= scene3DifObjs[i].y + 400 + scene3DifObjs[i].h + margin)) {
scene3DifObjs[i].found = true;
successnoise.play();
difsremaining--;
flashDif(scene3Differences[i], scene3DifObjs[i].x, scene3DifObjs[i].y);
}
}
}
}
function flashDif(img, x, y){ //difference flashes when found
image(img, x, y);
image(img, x, y + 400);
img.style.visibility = 'visible';
img.style.visibility = 'hidden';
}
function makeDifference(img, dx, dy, dw, dh) { //create the difference image as an object
var difFound = false; //keeps track of whether or not the difference has been found
var dif = {difimage: img, x: dx, y: dy, w: dw, h: dh, drawit: differenceDraw, found: difFound}
return dif;
}
function differenceDraw() { //place the difference image on the screen
image(this.difimage, this.x, this.y);
}
function drawhintbutton() {
push();
noStroke();
if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
fill(255, 255, 0, 40);
} else {
fill(255, 255, 255, 40);
}
rect(470, 20, 62, 16);
push();
if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
fill(255, 255, 0, 170);
} else {
fill(255, 255, 255, 170);
}
textSize(10);
text("Hint please!", 474, 31);
pop();
pop();
}
function givehint(){ //gives the player a hint based on which differences are not found
if(scene == 1){
for(i=0; i<=scene1DifObjs.length; i++){
if(scene1DifObjs[i].found == false){
hint.x = scene1DifObjs[i].x + random(-60, 60);
hint.y = scene1DifObjs[i].y + random(-60, 60);
hint.alph = 200;
hintcooldown = 20;
counttimer = 0;
return;
}
}
}
}
function hintDraw(){
push();
strokeWeight(2);
fill(255, 255, 0, 0);
stroke(255, 255, 0, this.alph);
ellipse(this.x, this.y, 220, 220);
pop();
}
function hintStep(){
this.alph-= 2;
}