Idea
When I was a child, I used to play this memory game that comes by default on every Windows 7 machine:
Hence the inspiration for my project.
Process
October 13, 2020.
Today marks the first day of my *official* work on the midterm project. I came up with an idea last week – the Card Memory Game. For now, I am doing some UI research to see what type of interface I would like to create for my staring page. I haven’t started my work yet, but I know for sure that I want to include some buttons and sounds. Today I also implemented a function for my button to check if it is being hovered over:
// check if the mouse is over the button boolean isHover(){ if(mouseX <= rectX+rectWidth/2 && mouseX >= rectX - rectWidth/2 && mouseY <= rectY + rectHeight/2 && mouseY >= rectY - rectHeight/2) return true; else return false; }
October 14, 2020.
Keeping up the consistency! Worked on the Welcome UI scene, included some text instruction placeholders, built the button, and figured out how to move between the scenes (has some bugs, will improve next time).
October 16, 2020.
Fixed the function to switch between the scenes, designed the cards and made the cover for them. Created a function to load the card images into the array and display them in the second scene.
October 17, 2020
D e b u g g i n g
<…>
October 26th, 2020.
Well, a lot of time has passed since my last update, but I was fixing the code here and there in the meanwhile. A few challenges during those few days was fixing the score to display on the screen properly (which I got fixed, yay!), displaying and shuffling the card deck properly (resolved!), storing the card flips (not resolved), and working out the complete logic of the game.
Final Notes
I believe it is worth mentioning that I got tremendous help along the way from Professor Aaron (thank you!), Professor Discord and Professor Google (xD). There were many things that I had to look up online, for example, the list shuffle method.
Does my program work perfectly now? No. Did I learn something new in the meanwhile? YES. Before embarking on this assignment, I had no clue how to switch between the game scenes, use lists and manipulate Java arrays dynamically. While my game still cannot count the score and flip the cards the way it is supposed to, I have learned that asking for help and needing some time to build a good code is normal and does not equal failing.
Demo
I have done the majority of the code, but have a tiny hidden bug somewhere that crashes the whole game. I suspect that happens somewhere between passing each card’s value and comparing selected cards, but I will investigate this further and am determined to make it work! Unfortunately, this might not happen on time for the showcase, but it will happen in the next few steps. For now, enjoy the code & demo:
// v0.4 24.10.2020 // importing sound import processing.sound.*; SoundFile click; // v0.3 21.10.2020 // moving everything into class int margin = 3; IntList imageIndex = new IntList(); int[] flippedCard; // v0.2 17.10.2020 // Outputting the card deck // v0.1 16.10.2020 // Creating different scenes + images // set the scene int scene, score; int numCards = 20; //PImage[] cards = new PImage[numCards]; Card[] cards = new Card[numCards]; PImage[] images = new PImage[numCards]; PImage cardCover; // v0.1 14.10.2020 // Creating the text instructions PFont font; String instructions_1, instructions_2, instructions_3, instructions_4, btn_start, btn_quit; int fontSize = 50; // v0. 13.10.2020 // Creating a button // defining colors as [r,g,b] arrays int[] pink = {242, 170, 224}; int[] green = {51, 225, 142}; int[] orange = {248, 163, 15}; int[] blue = {103, 212, 239}; int[] yellow = {255, 244, 108}; // defining shape coordinates float rectX, rectY, rectWidth, rectHeight; void setup(){ size(1100, 800); rectMode(CENTER); click = new SoundFile(this, "clickSound.wav"); scene = 0; // setting the button coordinates rectX = width/2; rectY = height/2; rectWidth = 170; rectHeight = 80; // setting the text push(); fontSize = 40; instructions_1 = "Welcome!"; instructions_2 = "You are presented a deck of cards."; instructions_3 = "Your task is to flip and match every one of them."; pop(); btn_start = "START"; btn_quit = "QUIT"; font = createFont("VT323-Regular", fontSize); textFont(font); // setting flipped cards to null flippedCard = new int[2]; score = 0; // load cards once loadCards(); } void draw(){ background(green[0], green[1], green[2]); // display scenes if (scene == 0){ displayMenu(); } if (scene == 1){ playScene(); //displayScore(); } if (scene == 2){ playWin(); } } // display the UI scene void displayMenu(){ // create a button push(); noStroke(); if(isHover()) fill(yellow[0]-20,yellow[1]-20,yellow[2]-20); else fill(yellow[0],yellow[1],yellow[2]); rect(rectX, rectY, rectWidth, rectHeight); pop(); // place instructions textAlign(CENTER); fill(0); text(instructions_1, width/2, height/6); text(instructions_2, width/2, height/6+80); text(instructions_3, width/2, height/6+120); text(btn_start, width/2, height/2+12.5); push(); textSize(22); text("Intro to IM, Fall 2020", width/2, 3*height/4); pop(); } // check if the mouse is over the button boolean isHover(){ if(mouseX <= rectX+rectWidth/2 && mouseX >= rectX - rectWidth/2 && mouseY <= rectY + rectHeight/2 && mouseY >= rectY - rectHeight/2 && mousePressed){ scene = 1; return true; } else return false; } // display scene 1 void playScene(){ background(blue[0], blue[1], blue[2]); // show the cards for (int i =0; i<numCards; i++){ cards[i].displayCards(); } push(); textSize(60); text("Score: " + score, width-200, height/2); pop(); } // load cards void loadCards(){ // store all the cards in the image array for (int i = 0; i < numCards; i ++) { images[i] = loadImage(i+".png"); imageIndex.append(i); } // initialize counters int counter = 0; int index; // initialize a deck matrix for (int i = 0; i < 5; i++) { //i = x for (int j = 0; j < 4; j++) {//j = y index = i + j * 5; // width is 5 cards[index] = new Card(i*(margin+images[i].width), j*(margin+images[i].height), images[imageIndex.get(counter)], index); counter++; } } // shuffle images imageIndex.shuffle(); } // flip the cards void mousePressed(){ // add sound click.play(); for (int i = 0; i<numCards; i++){ cards[i].flipCard(); if (flippedCard[0] == -1){ flippedCard[0] = cards[i].value; } else{ flippedCard[1] = cards[i].value; } // compare flipped cards if (flippedCard[0] != -1 && flippedCard[1] != -1){ if (flippedCard[0] == (flippedCard[1] - 10) || flippedCard[0] == (flippedCard[1] + 10)){ score++; // check for win if (score == numCards/2){ scene = 2; } // flip cards back if they don't match else { cards[i].isFlipped = false; } // reset the storage array flippedCard[0] = -1; flippedCard[1] = -1; } } } } // display the win scene void playWin(){ background(pink[0], pink[1], pink[2]); text("You have matched them all!", width/2, height/2-200); push(); noStroke(); if(isHover()) fill(yellow[0]-20,yellow[1]-20,yellow[2]-20); else fill(yellow[0],yellow[1],yellow[2]); rect(rectX, rectY, 2*rectWidth, rectHeight); pop(); text("Play Again?", rectX, rectY+10); score = 0; // reset the cards for (int i = 0; i < numCards; i++){ cards[i].isFlipped = false; } } class Card { PImage card; PImage cover; int locX, locY, value; int cardWidth = 135; int cardHeight = 200; boolean isFlipped = false; int numFlipped = 0; boolean isMatched = false; Card(int _locX, int _locY, PImage _card, int _value){ locX = _locX; locY = _locY; card = _card; cover = loadImage("cover.png"); value = _value; } void displayCards() { // display cover if not flipped if (!isFlipped && !isMatched){ image(cover, locX, locY); } else { image(card, locX, locY); } } // debugging void displayValue(){ print(value); } void flipCard(){ if(mouseX <= locX+card.width && mouseX >= locX && mouseY <= locY + card.height && mouseY >= locY){ isFlipped = !isFlipped; // count every time the card is flipped numFlipped++; // reset the counter when 2 cards are selected if (numFlipped == 3){ isFlipped = !isFlipped; numFlipped = 0; } } } }
Zip file: amina_midterm