Sprites and Box2D

I've recently been attempting to make a game as a project but when I place the the sprites and the platforms under the same void display(). It just want the sprite to display for player 1. Ever since I started doing this its been spawning a sprite and a rectangle for every box. I was wondering if anyone knew how to make the sprite only appear for 1 box and rectangles appear for the rest?

Sprite 1: Sprite1

//Minim
//import ddf.minim.analysis.*;
 //import ddf.minim.*;
 //Minim minim;
 //AudioPlayer Tune;


//Sprites
PImage sprite1;//, sprite2;

//Box2D
import shiffman.box2d.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
// A list for all of our rectangles
ArrayList<Box> boxes;
Box2DProcessing box2d;

//Variables
float x=0.0;
float y=0.0;
float frame=0;
int direction=0;
int fchange=0;
int jump=0;
int spawn=0;

float left=0;
float right=0;

//Controls
int w = 0;
int a = 0;
int s = 0;
int d = 0;
int q = 0;

void setup()
{
  //Base Setup
  size(1280, 720, P2D);
  frameRate(60);
  smooth();

  //Music Loading

 //minim = new Minim(this);
   //Tune = minim.loadFile("Tune.wav");
   //Tune.loop();


  //Image Loading
  //sprite1 = loadImage("Sprite1.jpg");
  //sprite2 = loadImage("Sprite2.jpg");

  textureMode(NORMAL);
  blendMode(BLEND);
  noStroke();

  // Initialize and create the Box2D world
  box2d = new Box2DProcessing(this);

  box2d.createWorld();

  // Turn on collision listening!
  box2d.listenForCollisions();

  // Create ArrayLists
  boxes = new ArrayList<Box>();

  //Top Platform
  Box p = new Box(640, 325, 300, 30, 1);
  boxes.add(p);

  //Middle Platform Left
  Box b = new Box(150, 515, 300, 30, 1);
  boxes.add(b);

  //Middle Platform Middle
  Box c = new Box(640, 515, 100, 30, 1);
  boxes.add(c);

  //Middle Platform Right
  Box e = new Box(1130, 515, 300, 30, 1);
  boxes.add(e);

  //Middle Colum
  Box f = new Box(640, 420, 30, 160, 1);
  boxes.add(f);

  //Bottom Platform
  Box g = new Box(640, 705, 1280, 30, 1);
  boxes.add(g);

  //Player 1
  Box h = new Box(x+25, y+37.5, 50, 75, 0);
  boxes.add(h);
  if (jump==1)
  {
    p.body.setAngularVelocity(1);
    p.body.setLinearVelocity(new Vec2(0, 10));
    jump=0;
  }
}
void draw()
{
  background(0, 200, 255);

  //Sun
  fill(255, 255, 0);
  ellipse(100, 100, 100, 100);

  // We must always step through time!
  box2d.step();
  // Display all the boxes
  for (Box b : boxes)
  {
    b.display();
  }

  //Player
  left = frame/2;
  right = (frame+1)/2;

  if (direction==1)
  {
    float temp = left;
    left = right;
    right = temp;
  }
  //Draw Player
  /*
  pushMatrix();
   translate(x,y);
   beginShape();
   texture(sprite1);
   vertex(0,0,right, 0);
   vertex(50,0,left,0);
   vertex(50,75,left,1);
   vertex(0,75,right,1);
   endShape(CENTER);
   popMatrix();  
   */

  //Controls
  if (w==1)
  {
    jump = 1;
    y=y-10;
  }

  if ((a==1)&(x!=0))
  {
    direction = 0;
    x-=10;
    if (fchange == 10)
    {
      frame++;
      if (frame==2) frame=0;
      fchange=fchange-10;
    }
    fchange++;
  }

  if ((d==1)&(x!=1280-50))
  {
    direction=1;
    x+=10;
    if (fchange == 10)
    {
      frame++;
      if (frame==2) frame=0;
      fchange=fchange-10;
    }
    fchange++;
  }

  if (s==1)
  {
    y=y+10;
  }
}

// A rectangular box
class Box
{
  // Instead of any of the usual variables,
  // we will store a reference to a Box2D Body
  Body body;
  float w, h;
  Box(float x, float y, float w_, float h_, int type)
  {
    w = w_;
    h = h_;
    // Build Body
    BodyDef bd = new BodyDef();
    if (type==0)
    {
      bd.type = BodyType.DYNAMIC; // Was DYNAMIC
    } else
    {
      bd.type = BodyType.STATIC;
    }
    bd.position.set(box2d.coordPixelsToWorld(x, y));
    body = box2d.createBody(bd);
    // Define a polygon (this is what we use for a rectangle)
    PolygonShape sd = new PolygonShape();
    // Box2D considers the width and height of a
    // rectangle to be the distance from the
    // center to the edge (so half of what we
    // normally think of as width or height.)
    float box2dW = box2d.scalarPixelsToWorld(w/2);
    float box2dH = box2d.scalarPixelsToWorld(h/2);
    sd.setAsBox(box2dW, box2dH);

    // Define a fixture
    FixtureDef fd = new FixtureDef();
    fd.shape = sd;
    // Parameters that affect physics
    fd.density = 1;
    fd.friction = 1;
    fd.restitution = 0;
    // Attach Fixture to Body
    body.createFixture(fd);
  }
  void display()
  {
    // We need the Body’s location and angle
    Vec2 pos = box2d.getBodyPixelCoord(body);
    //float a = body.getAngle();
    // Using the Vec2 position and float angle to
    // translate and rotate the rectangle
    pushMatrix();
    translate(pos.x, pos.y);
    //rotate(-a);
    fill(255, 0, 0);
    //stroke(0);
    rectMode(CENTER);
    rect(0, 0, w, h);
    popMatrix();

    float mx = pos.x +x-25;
    float my = pos.y +y-37.5;
    pushMatrix();
    translate(mx, my);
    beginShape();
    image(loadImage("Sprite1.jpg"), mx, my);

    vertex(0, 0, right, 0);
    vertex(50, 0, left, 0);
    vertex(50, 75, left, 1);
    vertex(0, 75, right, 1);

    endShape();
    popMatrix();
  }
} // End of the Box Class description

void keyPressed()
{
  if (key=='w')
  {
    w = 1;
  }

  if (key=='d')
  {
    d = 1;
  }

  if (key=='a')
  {
    a = 1;
  }

  if (key=='s')
  {
    s = 1;
  }

  if ((key=='q')&&(direction==1))
  {
    Box i = new Box(x+25, y+35, 10, 10, 0);
    boxes.add(i);
    i.body.setAngularVelocity(1);
    i.body.setLinearVelocity(new Vec2(1280, 0));
  }
  if ((key=='q')&&(direction==0))
  {
    Box i = new Box(x-25, y+35, 10, 10, 0);
    boxes.add(i);
    i.body.setAngularVelocity(1);
    i.body.setLinearVelocity(new Vec2(-1280, 0));
  }
}

void keyReleased()
{
  if (key=='w')
  {
    w = 0;
  }

  if (key=='d')
  {
    d = 0;
  }

  if (key=='a')
  {
    a = 0;
  }

  if (key=='s')
  {
    s = 0;
  }
}

Answers

  • You should edit your Box class so that there is a new boolean variable, is_player. Default it to false for all Boxes, but set it for true for the Box that represents your player. Then draw the sprite in display() only if that boolean is true.

  • The boxes are located in void setup() which is above class Box. So if I declare the boolean in class Box it isn't recoginised in void setup. If I make the boolean global it doesn't work.

  • It doesn't matter where the class is - only that it is defined at the global scope. You can add the boolean to the class below setup() and still access it inside setup().

  • located in void setup() which is above class Box

    Processing doesn't read a sketch from top to bottom -- it only reads individual functions (more or less) top-to-bottom. Here is a better (very simplified) simple way of thinking about what happens:

    1. It reads the definitions of everything (so it knows what a Box is, and what setup does, and what draw does) without doing anything. If you defined Box mybox outside any function, it is global.
    2. Now the sketch starts running, and executes setup first -- no matter where it is, we just put it first by convention.
    3. setup assigns a new Box to mybox. It knows what a Box is because of step 1 -- it read everything already, no matter what order your defined the functions, classes, and variables in.
    4. draw runs after setup -- no matter where it is, we just put it second by convention. refers to mybox.
    5. if draw refers to mybox, and if mybox was declared in global scope (in step 1), then draw can "see' mybox and knows what it is. If mybox was declared inside a function (like setup, or myfunction) then draw can't see it, and doesn't know what it is.
  • Ah ok thanks. I'm sort of confused on how to execute your instructions though.
    So I setup the variable is_player = false in class Box();. Then how do I differentiate between the boxes that is the player and isn't the player? Sorry if I'm getting annoying, I'm sort of new to programming.

  • edited December 3 Answer ✓

    Set the variable in the class by passing an argument to the Constructor, e.g. when you call new Box(true). See is this example helps you to understand some of the principles involved.

    void draw(){
      Square e = new Square(false);
      e.render(20, 20);
      e.render(80, 30);
      e.render(60, 80);
      Square p = new Square(true); 
      p.render(width/2, height/2);
      noLoop();
    }
    
    class Square {
      boolean player;
      Square (boolean player){
        this.player = player;
      }
      void render(float x, float y){
        if(player){
          fill(0,255,0);
        } else {
          fill(255,0,0);
        }
        rect(x-10,y-10,20,20);
      }
    }
    

    Screen Shot 2017-12-02 at 8.38.56 PM

Sign In or Register to comment.