Hitbox detection?

image

the terrain is a 2d array, and thre player can move just a tiny but so how do i do it? i dont wanna use a pgraphics with get()

a collision detection algorithm might be appropriate. take a look at this website for examples and explanations for code

interactive examples on this website

and a point shape collision detection on this website

3 Likes

Do you want to detect if the player is inside this area?

Then you can use the above mentioned collision detection.

When it’s a point p inside a rectangle rect you can just say:

if (pX > rectX &&
   pX < rectX + rectwidth &&
   pY > rectY && 
   pY < rectY + rectHeight) {
       ...
}

(adjust to your variable names)

Chrisir

2 Likes

Slight modification to @Chrisirs code

if (pX >= rectX && pX < rectX + rectwidth 
            && pY >= rectY && pY < rectY + rectHeight) {
  // …
}

It is probable that the tile’s position and size are stored as integers but the players position [pX, pY] are stored in floats. If that is the case then there are values of pX and pY which will not ‘hit’ any tile. Genrally it is better to use a half-open range to avoid this problem.

2 Likes

so i wanted to make it so if the player is not touching any blocks, they fall.
here is my code:

for (int ix = -2; ix < resolution+4; ix++) {
        for (int iy = 0; iy < height/(width/resolution)+4; iy++) {
          if (terrainbase[playerxpos+ix][playerypos+iy] == 0) {
            rect(visxpos+ix+width/resolution*(ix-1), visypos+iy+width/resolution*(iy-1), width/resolution+1, width/resolution+1);
            if (visxpos+ix+width/resolution*(ix-1)-50 < mouseX-25 && visxpos+ix+width/resolution*(ix-1)+50 > mouseX+50
            && visypos+iy+width/resolution*(iy-1) < mouseY && visypos+iy+width/resolution*(iy-1)+50 > mouseY) {
              visypos -= (width/resolution)/10;
              //println(frameCount);
            }
          }
        }
      }

the first & second for loops just loop through the area the player can see.

terrainbase is the array, that saves the world

“width/resolution” is the width of a tile in the world

the first if() statement checks if a tile is air

the first rectangle int the loop draws rectangles on the screen where also the tiles are

the second if() statement tries to check if the player is touching only air.

“visxpos+ix+width/resolution*(ix-1)” and the others that look very alike, are the current tile of the terrain that is air

mouseX and mouseY represent the postion of the player on screen

“visypos -= (width/resolution)/10” moves the player down.

image
that big black box is the player.

problem is sometimes the player isnt moved down or it is beeing moved down even when they are touching something.

im trying to do this kind of collision:

image
image
image
image

blue means fall, green means stay.

i hope this kinda helps.

1 Like

also the game is a side view, not top down!

I am not sure I understand your code, because I don’t know your entire code.


But basically you need to detect the cell the player is in.

Then you check whether the cell underneath it is not air.

Set a boolean marker falling

  • to true when it’s air
  • to false when it’s solid

Where you move the player check falling :

if(falling) 
    playerY++; // or what your variable name is called 

make falling a global variable: boolean falling = false;

Chrisir

1 Like

here is an example… without the marker

I am not too happy with it

PVector player=new PVector(800, 400);
boolean jump=false;

String mapPattern =
  "111110111111111111111101111111111111111111111111111111111111111111111111111111111111111111111111111";
ArrayList<Cell>map=new ArrayList();

// ----------------------------------------------------------------------------------

void setup() {
  size(900, 900);

  int i=0;
  for (char c : mapPattern.toCharArray()) {
    if (c=='1')
      map.add(new Cell(i*27, 500, true)) ;
    else map.add(new Cell(i*27, 500, false )) ;

    i++;
  }//for
  //
}//func

void draw() {
  background (0, 0, 211);

  //display player
  fill(255, 0, 0);
  stroke(0);
  ellipse(player.x, player.y, 10, 20);

  //display map
  for (Cell c : map) {
    c.display();
  }

  managePlayer();

  keysPlayer();
}//func

// -------------------------------------------------------------------------------

void managePlayer() {
  // fall/lift
  for (Cell c : map) {
    // are we inside the cell (in x)
    if (player.x-5 >= c.cell.x &&
      player.x+5   <  c.cell.x+c.w ) {
      // hit x
      if (player.y+10 < c.cell.y || c.air)
        player.y++; // fall
      else jump=false; // stop jump

      // we can lift the player when it's too low
      if (!c.air) {
        if (player.y+10 > c.cell.y) {
          player.y--;
        }
      }
    }//if
  }//for
}

void keysPlayer() {
  // player keys
  if (!keyPressed)
    return;

  if (keyCode==LEFT)
    player.x-=2;
  else if (keyCode==RIGHT)
    player.x+=2;
  else if (key==' ') {
    if (!jump)
      player.y-=32; // jump
    jump=true;
  }
}

// ====================================================================================================================

class Cell {

  PVector cell=new PVector(800, 400);
  float w=27, h=27;
  boolean air=true;

  // constr
  Cell(float x, float y,
    boolean full ) {
    cell=new PVector(x, y);
    if (full)
      air=false;
  }//constr

  void display() {
    if (air) {
      noFill();
      noStroke();
    } else {
      fill(0, 255, 0);
      stroke(0);
    }

    rect(cell.x, cell.y,
      w, h);
  }//method
  //
}//class
//

1 Like

The world is a 2-D array. Just compute the left, right, top, and bottom array indexes that the player overlaps and only check the rectangle of cells in the grid that the player could possibly touch.

3 Likes

guys i actually did it! it works now! thank youuu!!!

3 Likes