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
