Pinball Poker box2d help please

Hello my group is creating a pinball combined with poker game within processing using the box2d library as our main physics library. The idea of the game is to create obstacles that represent different card values (A,K,Q,J,10). Each time the ball hits an obstacle, the respective card would be generated. If players get a certain sequence of cards hit (based on texas hold 'em hands), they will get more points. The way we want to distribute points is that the game will store data for 5 obstacles that are hit. Every 5 obstacles hit, if there is a texas hold 'em hand within those five cards (royal straight, four of a kind, full house, four of a kind, three of a kind, pair), a certain amount of points will be rewarded. For example, if a player hits the “A” obstacle 4 times and the K once, they get the point value for getting four of a kind.

This is our question. How do we code it so that the game tracks five obstacle collisions and then notices that a certain combination of cards is within those 5 cards? Once the game distributes those points, we want the game to erase that stored data to prep for the next five cards to be stored. The first chunk of code is what our main tab looks like. The second chunk of code is what our obstacle tab looks like. The game cannot be run with these tabs alone, there are about 14 tabs of code but I would be happy to send the full file to anyone who asks.

We had an idea of creating a counter function which is the third chunk of code, but we were not sure on where to put it into processing and how to convert it to fit the syntax of box2d as we are still not too sure on how to use box2d.

Also the code is adopted from Anthony Zalar’s interactive pinball game which he uploaded a youtube video of. The full source code can also be found in the description of the video but we changed a lot of it because we needed it to fit our design.

Any help would be greatly appreciated and I would be willing to use any other messaging apps besides the forum if that would be easier.

import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
import ddf.minim.*;
import ddf.minim.signals.*; 
import ddf.minim.analysis.*; 
import ddf.minim.effects.*; 

// A reference to our box2d world
Box2DProcessing box2d;

//for the music
AudioPlayer[] player = new AudioPlayer[5]; //for number of tracks
Minim minim;


//for Background
PImage backDrop;
PFont font;

//for displaying the score
int score = 0;
int lives = 3;

//for the flippers
Flipper fl;
Flipper fr;
Flipper ft;
Flipper ff;

//launcher objects
Bumpers bumper;
Spring spring;
ArrayList<Pair> pairs;

//bumpers
LeftBumper lbump;
ArrayList<Bumper> bumpers;
ArrayList<Circle> circ;

//Chain Shapes
Level a;
LeftSiding ls;
Pinball pb;
RightSiding rs;

//turning flippers on/off
boolean lflip;
boolean rflip;
boolean tflip;
boolean fflip;

void setup()
{
  //required to create
  size(1200,800 );
  box2d = new Box2DProcessing(this);
  box2d.createWorld();  
  box2d.listenForCollisions();  
  box2d.setGravity(0, -25);
  
  a = new Level();
  ls = new LeftSiding();
  rs = new RightSiding();
  pb = new Pinball(width/2 - 15, height - 220, 8);
  bumpers = new ArrayList<Bumper>();
  pairs = new ArrayList<Pair>();
  circ = new ArrayList<Circle>();
  Pair p = new Pair(width/2,height/2, new Particle(width/2+15, height-200), new Box(width/2-10, height-200, 30, 30));
  pairs.add(p);
  bumpers.add(new Bumper(width/2, height, 100, 210));
  bumpers.add(new Bumper(width/2-40, height, 13, 1000));
  bumpers.add(new Bumper(width/2, height, 13, 2000));
  minim = new Minim(this);
  lbump = new LeftBumper(width/2/2 -200, height - 225);
  bumper = new Bumpers(width/2/2 + 150, height - 225);
  
  //create flippers
  fr = new Flipper(width/2/2 + 70, height - 120, 25, -QUARTER_PI/2, QUARTER_PI, false, 15, 10, 60);
  fl = new Flipper(width/2/2 - 120, height - 120, 25, -QUARTER_PI/2 - radians(15), QUARTER_PI - radians(20), true, 15, 10, 60); //have no idea why they don't match up but this works
  ft = new Flipper(10, 500, 25, -QUARTER_PI, HALF_PI - QUARTER_PI, true, 10,5,30); 
  ff = new Flipper(width/2-60, 500, 25, -QUARTER_PI, HALF_PI - QUARTER_PI, false, 10, 5, 30);
  
  //load music
  //player[0] = minim.loadFile("Streamline.mp3");
  player[1] = minim.loadFile("laun.wav");
  player[2] = minim.loadFile("flip.wav");
  player[3] = minim.loadFile("bump.wav");
  player[4] = minim.loadFile("final.wav");
  
  //player[0].play(); 
  //player[0].loop();
  
  //load background
  backDrop = loadImage("13.png");
  spring = new Spring();
  
  //creates circle bumpers
  Circle c1 = new Circle(width/2/2 + 90, height/2 - 100, 30);
  Circle c2 = new Circle(width/2/2 - 115, height/2 - 100, 30);
  Circle c3 = new Circle(width/2/2 - 5, 50, 25);
  Circle c4 = new Circle(-5, 200, 20);
  Circle c5 = new Circle(width/2/2 - 60, 130, 25);
  Circle c6 = new Circle(width/2/2 + 50, 130, 25);
  Circle c7 = new Circle(width/2/2 - 15, 345, 20);
  circ.add(c1);
  circ.add(c2);
  circ.add(c3);
  circ.add(c4);
  circ.add(c5);
  circ.add(c6);
  circ.add(c7);
  
  //resets flippers 
  rflip = false;
  fflip = false;
  lflip = false;
  tflip = false;
  
  //loads font
  font = createFont("CARDC___.TTF",10);
  textFont(font, 20 );
  textAlign(CENTER);
  
}

void draw()
{
  background(backDrop); //set background
  box2d.step();
  //displayAudio(player[0], height- 50, color(249,237,45)); //displays music at bottom of screen
  pb.display();
  spring.update(mouseX,mouseY);
  
  for(Bumper b: bumpers)
  {
   b.display();
  }
  bumper.display();
  lbump.display();
  
  //display chain shapes
  a.display();
  ls.display();
  rs.display();
  
  //display flippers
  fr.display();
  fl.display(); 
  ft.display();
  ff.display();
  
  //display circle bumpers
  for(Circle c: circ)
  {
   c.display(); 
  }
  
  //checks lives left
  if(lives >= 0)
  {
    //displays score and lives
    fill(255);
    text("Score ", 50, 35);
    text(score, 45, 65);
    text("Lives ",560, 35);
    text(lives,555,65);

    //resets game when player loses a ball
    if(pb.done())
    {
     minim.stop(); 
     setup();
     --lives; 
    }
  }
  else
  {
   //resets game variables
   score = 0;
   lives = 3;
   minim.stop();
   setup();
  }
  
  // Display all the boxes
  for(Pair p: pairs) {
    p.display();
  }
  
  //keeps flippers in correct position
  rflip = true;
  lflip = true;
  tflip = false;
  fflip = false;
}

//creates audio waves
//void displayAudio(AudioPlayer player, int playerHeight, color c) 
//{
//     stroke(c);
//    for(int i=0; i<player.left.size()-1; i++) {
//    line(i, playerHeight + player.left.get(i)*50, i+1, playerHeight + player.left.get(i+1)*50);
//    line(i, playerHeight + 25 + player.right.get(i)*50, i+1, playerHeight + 25 + player.right.get(i+1)*50);
//  }
//}

//plays spring noise and destroys spring
void mouseReleased() {
  player[1].play();
  player[1].rewind();
  spring.destroy();
}

//checks for press on launcher
void mousePressed() 
{
    if (pairs.get(0).p2.contains(mouseX, mouseY))
    {
    // And if so, bind the mouse location to the box with a spring
    spring.bind(mouseX,mouseY,pairs.get(0).p2);
    }
}

//checks for flipper presses, plays flipper sounds
void keyPressed( )
{
  if(keyCode == RIGHT && rflip)
  {
    fr.reverseSpeed();
    ff.reverseSpeed();
    player[2].play();
    player[2].rewind();
    rflip = false;
    fflip = false;
  }
  if(keyCode == LEFT && lflip)
  {
    fl.reverseSpeed();
    ft.reverseSpeed();
    player[2].play();
    player[2].rewind();
    lflip = false;
    tflip = false;
  }
}

//resets flippers
void keyReleased( )
{
  if(keyCode == RIGHT && rflip)
  {
    fr.reverseSpeed();
    ff.reverseSpeed();
    rflip = true;
    fflip = true;

  }
  if(keyCode == LEFT && lflip)
  {
    fl.reverseSpeed();
    ft.reverseSpeed();
    lflip = true;
    tflip = true;
  }
}

//for collisions: applyingImpulses, playing sounds, incrementing the score
void beginContact(Contact cp)
{
// Get both fixtures
  Fixture f1 = cp.getFixtureA();
  Fixture f2 = cp.getFixtureB();
  // Get both bodies
  Body b1 = f1.getBody();
  Body b2 = f2.getBody();

  // Get our objects that reference these bodies
  Object o1 = b1.getUserData();
  Object o2 = b2.getUserData();

  if (o1 instanceof Circle && o2 instanceof Pinball)
  {
    Pinball p2 = (Pinball) o2;
    p2.change();
    p2.body.applyAngularImpulse(500000);
    player[3].play();
    player[3].rewind();
    score += 10;
  }

  if (o1 instanceof Pinball && o2 instanceof Circle)
  {
    Pinball p1 = (Pinball) o1;
    p1.change();
    p1.body.applyAngularImpulse(500000);
    player[3].play();
    player[3].rewind();
    score += 10;
  }
  
  if (o1 instanceof Pinball && o2 instanceof Bumpers)
  {
    Pinball p1 = (Pinball) o1;
    p1.change();
    p1.body.applyAngularImpulse(1000000);
    player[4].play();
    player[4].rewind();
    score += 5;
  }
  
   if (o1 instanceof Bumpers && o2 instanceof Pinball)
   {
    Bumpers p1 = (Bumpers) o1;
    p1.change();
    player[4].play();
    player[4].rewind();
    Pinball p2 = (Pinball) o2;
    p2.change();
    p2.body.applyAngularImpulse(1000000);
    score += 5;
   }
  
   if (o1 instanceof Pinball && o2 instanceof LeftBumper) 
   {  
    LeftBumper p2 = (LeftBumper) o1;
    p2.change();
    player[4].play();
    player[4].rewind();
    Pinball p1 = (Pinball) o1;
    p1.change();
    p1.body.applyAngularImpulse(1000000);
    score += 5;
   }
  
   if (o1 instanceof LeftBumper && o2 instanceof Pinball) 
   {
    LeftBumper p1 = (LeftBumper) o1;
    p1.change();
    player[4].play();
    player[4].rewind();
    Pinball p2 = (Pinball) o2;
    p2.change();
    p2.body.applyAngularImpulse(1000000);
    score += 5;
   }
}

// Objects stop touching each other
void endContact(Contact cp) {
}
//creates the circle bumpers
class Circle
{

  Body body;
  float rad;
  
  Circle(float x, float y, float r) {
    rad = r;
    makeBody(x,y,r);
    body.setUserData(this); //for collision detection
  }

  
  void display()
  {
    
    Vec2 pos = box2d.getBodyPixelCoord(body);
    float a = body.getAngle();
    
    pushMatrix();
    translate(pos.x,pos.y);
    fill(20,74,46);
    stroke(0);
    noFill();
    noStroke();

    rotate(a);
    ellipse(0,0,rad,rad);
    popMatrix();
  }

  void makeBody(float x, float y, float r) {
    BodyDef bd = new BodyDef();
    bd.position = box2d.coordPixelsToWorld(x,y);
    bd.type = BodyType.STATIC;
    bd.bullet = true;
    body = box2d.world.createBody(bd);

    CircleShape cs = new CircleShape();
    cs.m_radius = box2d.scalarPixelsToWorld(rad);
    
    FixtureDef fd = new FixtureDef();
    fd.shape = cs;
    fd.density = 1;
    fd.friction = 0.01;
    fd.restitution = .99;
    
    body.createFixture(fd);
  }

}
if (combi.size() < 5) {
      combi.add(c.getName());
      for (int i = 0; i < combi.size(); i++) {
        for (int j = 0; j < letters.size(); j++) {
          if (char(combi.get(i)) == letters.get(j)) {
            //counter of specific letter increases
            //score increases
            //increaseScore(score, counter);
          }
        }
      }
      combi.clear();
    }
1 Like

Well, i don‘t know what you mean by track 5 obstacle collissions (since i think you‘re already checking for collission, right?), but i might be able to help you with how to read the cards value, since i made a small texas holdem Game (a year ago or so).

You‘ll have to check for each combination of cards for that. Start out by checking for a straight flush, then 4 pair, Full house and so on, until you only check for the additive value if nothing else is there.

Also, you‘d want to stop the method if you found a result with return, to save iterating even though all results could only be less than the one you already found.

As for how to get points for the cards, you‘ll have to take a look online, or think a while.

Lets say a 4 pair of 8 with a 3 Kicker gives 10405 points (just a random number, the actual value should be a lot higher), then you‘d want a 4 pair of 8 with a 4 kicker be 10406.

But if you have a pair of 2 3’s with 4,5,6 as kicker, you‘d want to have 258, while a pair of 2 4’ with the same kickers would be 283.

Also, 2,4,5,7,8 would be 83, and 2,4,5,7,9 is
101, but 3,4,5,7,8 would be 100. So the lowest number counts one point, the second lowest counts ~13 and then it‘s 13^n from lowest. But that only goes for kickers. A pair of 2 is ~ 2000 less than a pair of 3… it’s not that hard, just a bit annoying to deal with…

I think you get the point…

At least that‘s how i made it… there might be an easier way to solve this…

1 Like