Processing memory card game

Hi,
I have to make this memory card game in processing and Im a little stuck somewhere. I have three screens and on the third screen the game is displayed based on the selected number of cards in the second screen. This is what I have so far for the memory game:

PImage backing;
PImage memory;
PImage[] voorkant;

int aantalKaarten = 32;
float kaartenX = windowX+10;
float kaartenY= windowY + 10;
float breedteKaarten = 75;
float kaartenHoogte = 100;
int arrayNummer;
int kaarten[][] = new int[0][0];

boolean one_showing = false;
boolean two_showing = false;
int aantalKlikken = 0;

boolean beurtSpelerEen;
boolean beurtSpelerTwee;
boolean gelijkeKaarten = false;
int kaartAchterkant = 0;
    
String[] afbeeldingen;
      
void drawHetSpel(){ 
  
 background(#BFBFBF); 
 fill(#FF8C00);
 stroke(0);
 rect(windowX, windowY, windowBreedte, windowHoogte);
 backing = loadImage( "kaart0.jpg");
          
 spelerInformatie();
 kaartenMaken(); 

}
      
void kaartenMaken(){
 float kaartenX = windowX + 25;
 float kaartenY= windowY + 10;
 float reset = kaartenX;
 aantalKaarten = sliderPositie + 12;
 voorkant = new PImage[aantalKaarten];  
 int afbeelding;
 kaarten = new int [aantalKaarten][2];
 
 afbeeldingen = new String[]  {
      "kaart1.jpg",
      "kaart2.jpg",
      "kaart3.jpg",
      "kaart4.jpg",
      "kaart5.jpg",
      "kaart6.jpg",
      "kaart7.jpg",
      "kaart8.jpg",
      "kaart9.jpg",
      "kaart10.jpg",
      "kaart11.jpg",
      "kaart12.jpg",
      "kaart13.jpg",
      "kaart14.jpg",
      "kaart15.jpg",
      "kaart16.jpg"};

for(int n = 0; n < 2; n++) {
for(int i = 0; i < kaarten.length/2; i++) {
  afbeelding = int(random(1,kaarten.length/2-i) - 1);
  voorkant[i + kaarten.length/2 * n] = loadImage(afbeeldingen[afbeelding]);
  afbeeldingen[afbeelding] = afbeeldingen[kaarten.length/2 -1- i];
}
}

 if (aantalKaarten%2==0 && kaartAchterkant == 0) {   
   gelijkeKaarten = true;
 for(int i = 0; i < aantalKaarten; i++){
      image(backing, kaartenX, kaartenY,75,100);
      kaarten[i][0] = int(kaartenX);
      kaarten[i][1] = int(kaartenY);
      
      kaartenX+=85;
        
    if(kaartenX>=windowBreedte){
       kaartenY+=110; 
       kaartenX= reset;
      }
    if(kaartenY >= windowHoogte && kaartenX >= windowBreedte){
      
      }
  }   
  if(mouseX > kaartenX && mouseX <= kaartenX + 75 && mouseY > kaartenY && mouseY <= kaartenY + 100){
    
    noFill();
    stroke(0,0,255);
    strokeWeight(5);
    rect(kaartenX, kaartenY, 75, 100);
    
  }else{
    stroke(0);
  }
}
 
else{
  gelijkeKaarten = false;
  fill(#BFBFBF);
  rect(width/2-100, height/2, 200, 100);
  fill(0);
  text("Oneven Kaarten, ", width / 2 - 75, height / 2 + 30);
  text("Ga terug! ", width / 2 - 50, height / 2 + 50);
  if(mousePressed && mouseX > width/2-100 && mouseX <= width/2 +100 && mouseY > height/2 && mouseY <= height/2 + 100){
    drawInstellingen();
    level = 1;
  }
 }

}  

void spelerInformatie(){
  float spelerEenX =windowX+( windowX * 2);
  float spelerY = windowHoogte - 110;
  float spelerBreedte = 200;
  float spelerHoogte = 100;
  float spelerTweeX = spelerEenX + (windowBreedte / 2);
  
  
  fill(#BFBFBF);
  noStroke();
  rect(spelerEenX, spelerY, spelerBreedte,spelerHoogte);
  rect(spelerTweeX, spelerY, spelerBreedte,spelerHoogte);
  
  fill(0);
  textSize(20);
  text("Speler 1: ", spelerEenX, spelerY);
  text("Speler 2: ", spelerTweeX, spelerY);
  text("Paren: ", spelerEenX, spelerY+50);
  text("Paren: ", spelerTweeX, spelerY+50);
}

void mouseClicked(){
  boolean kaartDraaien = false; 
  
  for(int i = 0; i < kaarten.length; i++){
    if(mouseX > kaarten[i][0] && mouseX < kaarten[i][0] + breedteKaarten && mouseY > kaarten[i][1] && mouseY < kaarten[i][1] + kaartenHoogte){
      image(voorkant[i], kaarten[i][0],kaarten[i][1], breedteKaarten, kaartenHoogte);
      kaartDraaien = true;
    }
  }
  println(kaartDraaien);
}

The problem is that the images of the front side of a card change on a same position.
I hope someone can help me out in here

1 Like

This is my first tab:

float windowBreedte;
float windowHoogte;
float windowX;
float windowY;
      
boolean homeScreen = false;
boolean SchermEenClick = false;
int startHoogte = 100;
int startBreedte = 200;
int startX;
int startY;
int level;
int marge = 100;
   
    
void setup(){
 size(800,800);
 windowBreedte = (width / 100) * 90;
 windowHoogte = (height / 100) * 90;
 windowX = (width / 100) * 5;
 windowY = (height / 100) * 5;
 memory = loadImage("memory.jpg");
}
    
void draw(){
 rect(windowX, windowX, windowBreedte, windowHoogte);
      
  if(level == 0) {
    drawHomeScreen();
  } else if(level == 1) {
    drawInstellingen();
  } else{
    drawHetSpel();  
  }
}
    

void mousePressed(){
  if (homeScreen == false) {
    homeScreenClick();
  } else {
    //SchermEenClick();
  }
  
}


void tekenStartKnop(){
 //Instellingen voor de uiterlijk van de "verder" knop
 fill(#BFBFBF);
 rect((windowBreedte/3)+50,windowHoogte-60,startBreedte,startHoogte); 
 fill(0);
 textSize(35);
 strokeWeight(4);
 text("Verder", (windowBreedte/3)+90, windowHoogte);
 
 if( mouseX >= (windowBreedte/3)+20
     && mouseX <= (windowBreedte/3)+20 + startBreedte
     && mouseY >= windowHoogte-60
     && mouseY <= windowHoogte-60 + startHoogte)
     { 
       stroke(0);
     }
}

My second tab:

void drawHomeScreen(){
  //Instellingen voor het beginscherm, zoals achtergrond en welkomstekst

  background(#BFBFBF);
  image(memory,windowX, windowX, windowBreedte, windowHoogte);

  tekenStartKnop();
}

//De functies voor de startknoppen.
void homeScreenClick() {
   
     if( mouseX >= (windowBreedte/3)+20
     && mouseX <= (windowBreedte/3)+20 + startBreedte
     && mouseY >= windowHoogte-60
     && mouseY <= windowHoogte-60 + startHoogte)
     {
       level += 1;
     }else{
     homeScreen = false;
    } 
}

My third tab:

  float sliderX = 150;
  float sliderEenY = 100;
  float sliderBreedte = 500;
  float sliderHoogte = 30;

  int margeSliderTekst = 5;
  int tekstMargeTien = 10;

  int minimaleMarge = 12;

  boolean sliderKlik1 = false;

  int sliderPositie;

  int nPosities = 21;

  float blokjeBreedte = sliderBreedte / nPosities;
  
void drawInstellingen(){
  background(#BFBFBF);
  stroke(0);
  tekenStartKnop();
  tekenSliders();
}

// in deze methode wordt het klikken op de knop bepaald
void schermEenClick() {
  if(mouseX >= startX-startHoogte
     && mouseX <= startX + startBreedte
     && mouseY >= startY
     && mouseY <= mouseY + startHoogte)
     {
       drawHetSpel();
     }

}

void tekenSliders(){
  
  if(mouseX>sliderX
    && mouseX <= sliderX+sliderBreedte
    && mouseY > sliderEenY
    && mouseY <= sliderEenY + sliderHoogte)
    {
      sliderPositie = bepaalPositie(sliderX, sliderBreedte, nPosities);
    }
 tekenSlider(sliderX,sliderEenY,sliderBreedte,sliderHoogte,sliderPositie, nPosities);
 text("Hoeveelheid Kaarten: "+ (sliderPositie + minimaleMarge), sliderX, sliderEenY-margeSliderTekst); 

}

// Hier worden de positie in de slider bepaald
int bepaalPositie(float x, float breedte, int nPosities){
 
  float blokjeBreedte = breedte / nPosities ;
 
 if (mouseX < x){
  return 0;
 }
 else if ( mouseX >= breedte + x){
   return nPosities - 1;
 }
 else{
   return floor((mouseX - x) / blokjeBreedte);
 }
}
 // hier worden de sliders getekend 
void tekenSlider(float x, float y, float breedte, float hoogte, int positie, int nPosities){
 float blokjeBreedte = breedte / nPosities;
 

 fill(255);
 rect(x,y, breedte, hoogte);
 
 fill(255,0,0);
 rect(x + positie * blokjeBreedte + 2, y, blokjeBreedte, hoogte);

}

my fourth tab is my memory game code above.

It’s hard to run your code without your images. It’s a pain to copy your code when it is in four chunks. It is near impossible to use your code it you don’t post it formatted like code.

Put all your code together in one chunk. Then select it and hit the </> formatting button which will make it be formatted like code:

Or surround it in three tildes: ``` <your code> ```

Better yet, since you are using images, either load them from URLs or host your entire sketch on a code-sharing site. Perhaps github?


That said, what problems are you having? You haven;t really describe what you are trying to do, what works, and what doesn’t. What have you tried?

1 Like
float windowBreedte;
float windowHoogte;
float windowX;
float windowY;
      
boolean homeScreen = false;
boolean SchermEenClick = false;
int startHoogte = 100;
int startBreedte = 200;
int startX;
int startY;
int level;
int marge = 100;
   
    
void setup(){
 size(800,800);
 windowBreedte = (width / 100) * 90;
 windowHoogte = (height / 100) * 90;
 windowX = (width / 100) * 5;
 windowY = (height / 100) * 5;
 memory = loadImage("memory.jpg");
}
    
void draw(){
 rect(windowX, windowX, windowBreedte, windowHoogte);
      
  if(level == 0) {
    drawHomeScreen();
  } else if(level == 1) {
    drawInstellingen();
  } else{
    drawHetSpel();  
  }
}
    

void mousePressed(){
  if (homeScreen == false) {
    homeScreenClick();
  } else {
    //SchermEenClick();
  }
  
}


void tekenStartKnop(){
 //Instellingen voor de uiterlijk van de "verder" knop
 fill(#BFBFBF);
 rect((windowBreedte/3)+50,windowHoogte-60,startBreedte,startHoogte); 
 fill(0);
 textSize(35);
 strokeWeight(4);
 text("Verder", (windowBreedte/3)+90, windowHoogte);
 
 if( mouseX >= (windowBreedte/3)+20
     && mouseX <= (windowBreedte/3)+20 + startBreedte
     && mouseY >= windowHoogte-60
     && mouseY <= windowHoogte-60 + startHoogte)
     { 
       stroke(0);
     }
} 

void drawHomeScreen(){
//Instellingen voor het beginscherm, zoals achtergrond en welkomstekst

background(#BFBFBF);
image(memory,windowX, windowX, windowBreedte, windowHoogte);

tekenStartKnop();

}

 
 //De functies voor de startknoppen.
void homeScreenClick() {
   
     if( mouseX >= (windowBreedte/3)+20
     && mouseX <= (windowBreedte/3)+20 + startBreedte
     && mouseY >= windowHoogte-60
     && mouseY <= windowHoogte-60 + startHoogte)
     {
       level += 1;
     }else{
     homeScreen = false;
    } 
}

  float sliderX = 150;
  float sliderEenY = 100;
  float sliderBreedte = 500;
  float sliderHoogte = 30;

  int margeSliderTekst = 5;
  int tekstMargeTien = 10;

  int minimaleMarge = 12;

  boolean sliderKlik1 = false;

  int sliderPositie;

  int nPosities = 21;

  float blokjeBreedte = sliderBreedte / nPosities;
  
void drawInstellingen(){
  background(#BFBFBF);
  stroke(0);
  tekenStartKnop();
  tekenSliders();
}

// in deze methode wordt het klikken op de knop bepaald
void schermEenClick() {
  if(mouseX >= startX-startHoogte
     && mouseX <= startX + startBreedte
     && mouseY >= startY
     && mouseY <= mouseY + startHoogte)
     {
       drawHetSpel();
     }

}

void tekenSliders(){
  
  if(mouseX>sliderX
    && mouseX <= sliderX+sliderBreedte
    && mouseY > sliderEenY
    && mouseY <= sliderEenY + sliderHoogte)
    {
      sliderPositie = bepaalPositie(sliderX, sliderBreedte, nPosities);
    }
 tekenSlider(sliderX,sliderEenY,sliderBreedte,sliderHoogte,sliderPositie, nPosities);
 text("Hoeveelheid Kaarten: "+ (sliderPositie + minimaleMarge), sliderX, sliderEenY-margeSliderTekst); 

}

// Hier worden de positie in de slider bepaald
int bepaalPositie(float x, float breedte, int nPosities){
 
  float blokjeBreedte = breedte / nPosities ;
 
 if (mouseX < x){
  return 0;
 }
 else if ( mouseX >= breedte + x){
   return nPosities - 1;
 }
 else{
   return floor((mouseX - x) / blokjeBreedte);
 }
}
 // hier worden de sliders getekend 
void tekenSlider(float x, float y, float breedte, float hoogte, int positie, int nPosities){
 float blokjeBreedte = breedte / nPosities;
 

 fill(255);
 rect(x,y, breedte, hoogte);
 
 fill(255,0,0);
 rect(x + positie * blokjeBreedte + 2, y, blokjeBreedte, hoogte);

}

PImage backing;
PImage memory;
PImage[] voorkant;

int aantalKaarten = 32;
float kaartenX = windowX+10;
float kaartenY= windowY + 10;
float breedteKaarten = 75;
float kaartenHoogte = 100;
int arrayNummer;
int kaarten[][] = new int[0][0];

boolean one_showing = false;
boolean two_showing = false;
int aantalKlikken = 0;

boolean beurtSpelerEen;
boolean beurtSpelerTwee;
boolean gelijkeKaarten = false;
int kaartAchterkant = 0;
    
String[] afbeeldingen;
      
void drawHetSpel(){ 
  
 background(#BFBFBF); 
 fill(#FF8C00);
 stroke(0);
 rect(windowX, windowY, windowBreedte, windowHoogte);
 backing = loadImage( "kaart0.jpg");
          
 spelerInformatie();
 kaartenMaken(); 

}
      
void kaartenMaken(){
 float kaartenX = windowX + 25;
 float kaartenY= windowY + 10;
 float reset = kaartenX;
 aantalKaarten = sliderPositie + 12;
 voorkant = new PImage[aantalKaarten];  
 int afbeelding;
 kaarten = new int [aantalKaarten][2];
 
 afbeeldingen = new String[]  {
      "kaart1.jpg",
      "kaart2.jpg",
      "kaart3.jpg",
      "kaart4.jpg",
      "kaart5.jpg",
      "kaart6.jpg",
      "kaart7.jpg",
      "kaart8.jpg",
      "kaart9.jpg",
      "kaart10.jpg",
      "kaart11.jpg",
      "kaart12.jpg",
      "kaart13.jpg",
      "kaart14.jpg",
      "kaart15.jpg",
      "kaart16.jpg"};

for(int n = 0; n < 2; n++) {
for(int i = 0; i < kaarten.length/2; i++) {
  afbeelding = int(random(1,kaarten.length/2-i) - 1);
  voorkant[i + kaarten.length/2 * n] = loadImage(afbeeldingen[afbeelding]);
  afbeeldingen[afbeelding] = afbeeldingen[kaarten.length/2 -1- i];
}
}

 if (aantalKaarten%2==0 && kaartAchterkant == 0) {   
   gelijkeKaarten = true;
 for(int i = 0; i < aantalKaarten; i++){
      image(backing, kaartenX, kaartenY,75,100);
      kaarten[i][0] = int(kaartenX);
      kaarten[i][1] = int(kaartenY);
      
      kaartenX+=85;
        
    if(kaartenX>=windowBreedte){
       kaartenY+=110; 
       kaartenX= reset;
      }
    if(kaartenY >= windowHoogte && kaartenX >= windowBreedte){
      
      }
  }   
  if(mouseX > kaartenX && mouseX <= kaartenX + 75 && mouseY > kaartenY && mouseY <= kaartenY + 100){
    
    noFill();
    stroke(0,0,255);
    strokeWeight(5);
    rect(kaartenX, kaartenY, 75, 100);
    
  }else{
    stroke(0);
  }
}
 
else{
  gelijkeKaarten = false;
  fill(#BFBFBF);
  rect(width/2-100, height/2, 200, 100);
  fill(0);
  text("Oneven Kaarten, ", width / 2 - 75, height / 2 + 30);
  text("Ga terug! ", width / 2 - 50, height / 2 + 50);
  if(mousePressed && mouseX > width/2-100 && mouseX <= width/2 +100 && mouseY > height/2 && mouseY <= height/2 + 100){
    drawInstellingen();
    level = 1;
  }
 }

}  

void spelerInformatie(){
  float spelerEenX =windowX+( windowX * 2);
  float spelerY = windowHoogte - 110;
  float spelerBreedte = 200;
  float spelerHoogte = 100;
  float spelerTweeX = spelerEenX + (windowBreedte / 2);
  
  
  fill(#BFBFBF);
  noStroke();
  rect(spelerEenX, spelerY, spelerBreedte,spelerHoogte);
  rect(spelerTweeX, spelerY, spelerBreedte,spelerHoogte);
  
  fill(0);
  textSize(20);
  text("Speler 1: ", spelerEenX, spelerY);
  text("Speler 2: ", spelerTweeX, spelerY);
  text("Paren: ", spelerEenX, spelerY+50);
  text("Paren: ", spelerTweeX, spelerY+50);
}

void mouseClicked(){
  boolean kaartDraaien = false; 
  
  for(int i = 0; i < kaarten.length; i++){
    if(mouseX > kaarten[i][0] && mouseX < kaarten[i][0] + breedteKaarten && mouseY > kaarten[i][1] && mouseY < kaarten[i][1] + kaartenHoogte){
      image(voorkant[i], kaarten[i][0],kaarten[i][1], breedteKaarten, kaartenHoogte);
      kaartDraaien = true;
    }
  }
  println(kaartDraaien);
}

/*

     
*/

I hope this is what you mean with the code

https://github.com/roeludh/Processing

and in here there are all the files with image, i hope you can get them.

The problem is that the images are randomly placed and don’t stick to one place. e.a. when i click on the back of a card, the card turns and show the front for a second, when i click on the same card again it turns and another card image appears.

I hope this makes it a little more clear

1 Like

Great. The thing about card games is that - right away - you know you’re going to want a Card class to help you work with card objects.

So usually people writing card games start by defining what a card is.

A Card has a suit, and a value.
A Card can be face up or face down.
A Card has some position on the screen.
A Card can start to exist, be drawn, or be turned over.
There is no need for your Cards to move.

With just those simple definitions about what a card is, we can start to create our class:

// What is a Card?
class Card {
  // A card has a suit and a value.
  int suit, value;
  // A card can be face up or face down.
  boolean is_faceup;
  // A Card has some position.
  float x, y;
  // A Card can stat to exist.
  Card(){
    x = 20;
    y = 20;
  }
  // A Card can be drawn.
  void draw_card(){
    rect(x,y,20,30);
  }
  // A card can be turned over.
  void flip(){
    is_faceup = !is_faceup;
  }
}

So that’s a basic, blank Card. Can we see it? Yes, if we add:

Card test_card;

void setup(){
  size(600,400);
  test_card = new Card();
}

void draw(){
  background(0,100,0);
  test_card.draw_card();
}

Notice that a card appears. Since it is only drawn as a simple rectangle, only a simple rectangle appears. For now, this is fine, because what we really want is a lot of them:

class Card {
  int suit, value;
  boolean is_faceup;
  float x, y;
  Card(float ix, float iy, int iv, int is){
    x = ix;
    y = iy;
    suit = is;
    value = iv;
  }
  void draw_card(){
    fill(255);
    rect(x,y,20,30);
    fill(0);
    text(suit, x+5, y+15);
    text(value, x+5, y+25);    
  }
  void flip(){
    is_faceup = !is_faceup;
  }
}

Card[] cards = new Card[52];

void setup(){
  size(600,400);
  int t = 0;
  for( int y = 0; y<4; y++){
    for( int x = 0; x<13; x++){
      cards[t++] = new Card(20 + 30 * x, 20 + 40 * y, x, y);
    }
  }
}

void draw(){
  background(0,100,0);
  int t = 0;
  for( int y = 0; y<4; y++){
    for( int x = 0; x<13; x++){
      cards[t++].draw_card();
    }
  }
}

Notice that there is now an array of cards, and each card gets a position, suit, and value as parameters. These are then used in a fancier draw_card() function, to draw the card a bit better.

2 Likes

Next we add variables for the size of the card, and the logic to determine if a card should flip over. Notice also that the draw_card() function just keeps getting fancier - it now draws cards face up AND face down, depending on the state of the card. Try clicking a few Cards!

class Card {
  int suit, value;
  boolean is_faceup;
  float x, y, w, h;
  Card(float ix, float iy, int iv, int is) {
    x = ix;
    y = iy;
    w = 20;
    h = 30;
    suit = is;
    value = iv;
  }
  void draw_card() {
    if ( is_faceup ) {
      fill(255);
      rect(x, y, w, h);
      fill(0);
      text(suit, x+5, y+15);
      text(value, x+5, y+25);
    } else {
      fill(100, 0, 0);
      rect(x, y, w, h);
    }
  }
  void flip() {
    is_faceup = !is_faceup;
  }
  void clicked(){
    if( over() ){
      flip();
    }
  }
  boolean over(){
    return( x < mouseX && mouseX < x+w && y < mouseY && mouseY < y+h );
  }
}

Card[] cards = new Card[52];

void setup() {
  size(600, 400);
  int t = 0;
  for ( int y = 0; y<4; y++) {
    for ( int x = 0; x<13; x++) {
      cards[t++] = new Card(20 + 30 * x, 20 + 40 * y, x, y);
    }
  }
}

void draw() {
  background(0, 100, 0);
  int t = 0;
  for ( int y = 0; y<4; y++) {
    for ( int x = 0; x<13; x++) {
      cards[t++].draw_card();
    }
  }
}

void mousePressed() {
  for( Card c : cards ) c.clicked();
}
1 Like

Thank you for your response and the clear information!
The annyoing thing is: that this is for a school project and in this project we are not allowed tot use classes…

You can turn each field within a class into an array. Read more about it below: :stuck_out_tongue:

1 Like