2

I am currently debugging a game im making in p5.js and have found that i stick to walls that are on the right of my player but not on my left. i have tried turning up the number of pixels away it checks but it doesn't look good and only will work with 5. here is the code:

move(){
  let wallcheckL = get(this.x - 1, this.y);
  let wallcheckR = get(this.x + (this.scale + 1), this.y);
  let wallcheckLB = get(this.x - 1, this.y + this.scale - 5);
  let wallcheckRB = get(this.x + (this.scale + 1), this.y + this.scale - 5);
  
  if(wallcheckL[0] == 0 && wallcheckL[1] == 0 && wallcheckL[2] == 255 ||
     this.x == 0 ||
     wallcheckLB[0] == 0 && wallcheckLB[1] == 0 && wallcheckLB[2] == 255 ||
     wallcheckL[0] == 0 && wallcheckL[1] == 128 && wallcheckL[2] == 0) {
    
    this.wallL = true;
  }
  else{
    this.wallL = false;
  }
  
  if(wallcheckR[0] == 0 && wallcheckR[1] == 0 && wallcheckR[2] == 255 ||
     this.x == 400 - this.scale ||
     wallcheckRB[0] == 0 && wallcheckRB[1] == 0 && wallcheckRB[2] == 255 ||
     wallcheckR[0] == 0 && wallcheckR[1] == 128 && wallcheckR[2] == 0) {

    this.wallR = true;
  }
  else{
    this.wallR = false;
  }
  
  if(this.moveR == true && this.wallR == false){
    this.x += this.speed;
  }
  else if(this.moveL == true && this.wallL == false){
    this.x -= this.speed;
  }
}

also here is the gravity:

gravity(){
  let gc = get(this.x, this.y + 21);
  let gc2 = get(this.x + this.scale, this.y + 21);
  if(gc[0] == 0 && gc[1] == 0 && gc[2] == 255 && gc[3] == 255 ||
     this.y >= 400 - this.scale ||
     gc2[0] == 0 && gc2[1] == 0 && gc2[2] == 255 && gc2[3] == 255 ||
     gc[0] == 255 && gc[1] == 255 && gc[2] == 0 && gc[3] == 255 ||
     gc2[0] == 255 && gc2[1] == 255 && gc2[2] == 0 && gc2[3] == 255){

    this.gravSpeed = this.dgrav;
    this.isOnGround = true;
    return;
  }
  else{
    this.y += this.gravSpeed;
    if(this.gravSpeed < this.tv){ 
      this.gravSpeed += this.ac;
    }
    else{
      this.gravSpeed = this.tv;
    }

    this.isOnGround = false;
  }
}
Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41
Maddox Fox
  • 111
  • 7
  • The right wall check uses `this.scale`, the left wall check doesn't. I have no idea what `this.scale` is or how it relates to absolute coordinate values but I suspect that's the reason for the inconsistency. –  Oct 29 '21 at 18:30
  • Using pixel colors for collision detection in `p5.js` is definitely not the ideal way to do it. There could potentially be issues with antialiasing, sub pixel position, and high DPI sampling that cause issues. I'm not seeing an obvious bug in your code, but it would be easier to test given a fully working sample (preferably as a runnable snippet) https://stackoverflow.com/questions/67410651/how-do-i-include-a-runnable-p5-js-sketch-in-a-stackoverflow-question – Paul Wheeler Oct 29 '21 at 18:30
  • @ChrisG presumably `this.scale` is the size of the collision detection bounding box which is square and has it's top left corner anchored at `this.x, this.y` – Paul Wheeler Oct 29 '21 at 18:38
  • I can see some issues with the code (like checking for `this.x == 0` rather than `this.x <= 0`), but I can't see anything that would cause the "sticking" behavior. I think the issue is probably in some other part of the code. – Paul Wheeler Oct 29 '21 at 18:39
  • no sure if this works for you guys to see the code or edit it but here is the link https://editor.p5js.org/25foxm/sketches/9BgIeb9v1 – Maddox Fox Oct 30 '21 at 13:17

2 Answers2

2

Your main problem is in your gravity method, particularly this block of code:

if(gc[0] == 0 && gc[1] == 0 && gc[2] == 255 && gc[3] == 255 ||
     this.y >= 400 - this.scale ||
     gc2[0] == 0 && gc2[1] == 0 && gc2[2] == 255 && gc2[3] == 255 ||
     gc[0] == 255 && gc[1] == 255 && gc[2] == 0 && gc[3] == 255 ||
     gc2[0] == 255 && gc2[1] == 255 && gc2[2] == 0 && gc2[3] == 255){

    this.gravSpeed = this.dgrav;
    this.isOnGround = true;
    return;
  }

This evaluates irrespective of whether the player is actually on the ground, which results in the issue where the player is getting stuck on the right-hand block.

A potential way to solve it is with actually using code you already have tucked within that condition:

if (this.y >= height - this.scale) {
    this.y = height - this.scale; // ensure the player's height is properly constrained
    this.gravSpeed = this.dgrav;
    this.isOnGround = true;
} 

This prevents the sticking as it doesn't set the player variable isOnGround = true when it's not.

Here's a working example:

class player {
  constructor(x, y, scale, grav, ac, speed) {
    this.x = x;
    this.y = y;
    this.dtime = 20;
    this.jumpTimer = 20;
    this.jumpLimit = 12;
    this.jumpedHeight = 0;
    this.jumping = false;
    this.wallR = false;
    this.wallL = false;
    this.moveR = false;
    this.moveL = false;
    this.tv = 10;
    this.dgrav = grav;
    this.ac = ac;
    this.speed = speed;
    this.gravSpeed = grav;
    this.canGravity = true;
    this.isOnGround = false;
    this.scale = scale;
  }

  draw() {
    fill("red");
    rect(this.x, this.y, this.scale, this.scale);
  }

  gravity() {
    let gc = get(this.x, this.y + 21);
    let gc2 = get(this.x + this.scale, this.y + 21);
    if (this.y >= height - this.scale) {
      this.y = height - this.scale;
      this.gravSpeed = this.dgrav;
      this.isOnGround = true;
    } else {
      this.y += this.gravSpeed;
      if (this.gravSpeed < this.tv) {
        this.gravSpeed += this.ac;
      } else {
        this.gravSpeed = this.tv;
      }
      this.isOnGround = false;
    }
  }

  move() {
    let wallcheckL = get(this.x - 1, this.y);
    let wallcheckR = get(this.x + this.scale + 2, this.y);
    let wallcheckLB = get(this.x - 1, this.y + this.scale - 5);
    let wallcheckRB = get(this.x + this.scale + 2, this.y + this.scale - 5);

    if (
      (wallcheckL[0] == 0 && wallcheckL[1] == 0 && wallcheckL[2] == 255) ||
      this.x == 0 ||
      (wallcheckLB[0] == 0 && wallcheckLB[1] == 0 && wallcheckLB[2] == 255) ||
      (wallcheckL[0] == 0 && wallcheckL[1] == 128 && wallcheckL[2] == 0)
    ) {
      this.wallL = true;
    } else {
      this.wallL = false;
    }

    if (
      (wallcheckR[0] == 0 && wallcheckR[1] == 0 && wallcheckR[2] == 255) ||
      this.x >= 400 - this.scale ||
      (wallcheckRB[0] == 0 && wallcheckRB[1] == 0 && wallcheckRB[2] == 255) ||
      (wallcheckR[0] == 0 && wallcheckR[1] == 128 && wallcheckR[2] == 0)
    ) {
      this.wallR = true;
    } else {
      this.wallR = false;
    }

    if (this.moveR == true && this.wallR == false) {
      this.x += this.speed;
    } else if (this.moveL == true && this.wallL == false) {
      this.x -= this.speed;
    }
  }

  jump() {
    let uc = get(this.x, this.y - 2);
    let ucr = get(this.x + this.scale, this.y - 2);
    if (
      uc[0] == 255 &&
      uc[1] == 255 &&
      uc[2] == 0 &&
      ucr[0] == 255 &&
      ucr[1] == 255 &&
      ucr[2] == 0
    ) {
      this.y -= 5;
      this.jumpedHeight += 1;
    } else {
      if (
        (this.jumpedHeight < this.jumpLimit &&
          this.isOnGround == true &&
          uc[0] == 255 &&
          uc[1] == 255 &&
          uc[2] == 255 &&
          ucr[0] == 255 &&
          ucr[1] == 255 &&
          ucr[2] == 255) ||
        (this.jumpedHeight < this.jumpLimit &&
          this.isOnGround == true &&
          uc[0] == 255 &&
          uc[1] == 255 &&
          uc[2] == 0 &&
          ucr[0] == 255 &&
          ucr[1] == 255 &&
          ucr[2] == 0) ||
        (this.jumpedHeight < this.jumpLimit &&
          this.isOnGround == true &&
          uc[0] == 255 &&
          uc[1] == 255 &&
          uc[2] == 0 &&
          ucr[0] == 255 &&
          ucr[1] == 255 &&
          ucr[2] == 255)
      ) {
        this.y -= 5;
        this.jumpedHeight += 1;
      } else {
        this.gravSpeed = this.dgrav;
        this.jumping = false;
      }
    }
  }
}

class ground{
  constructor(x, y, color){
    this.x = x;
    this.color = color;
    this.y = y;
  }
  
  draw(){
    fill(this.color);
    rect(this.x, this.y, 40, 40);
  }
}

var groundArray = [];
groundArray[0] = [0];
groundArray[1] = [0];
groundArray[2] = [0];
groundArray[3] = [0];
groundArray[4] = [0];
groundArray[5] = [0];
groundArray[6] = [1,0,0,0,0,0,0,1];
groundArray[7] = [1,0,0,0,0,0,0,1];
groundArray[8] = [1,0,0,0,0,0,0,1];
groundArray[9] = [1,0,0,0,0,0,0,1];

function setup() {
  noStroke();
  createCanvas(400, 400);
  for(let y = 0; y < groundArray.length; y++){
    for(let x = 0; x < groundArray[y].length; x++){
        if(groundArray[y][x] == 1){
          groundArray[y][x] = new ground(x * 40, y * 40, "blue");
        }
      else if(groundArray[y][x] == 2){
          groundArray[y][x] = new ground(x * 40, y * 40, "yellow");
      }
      else if(groundArray[y][x] == 3){
          groundArray[y][x] = new ground(x * 40, y * 40, "green");
      }
    }
  }
}

var play = new player(200, 0, 20, 3, 0.06, 4);

function draw() {
  background(255);
  for(let y = 0; y < groundArray.length; y++){
    for(let x = 0; x < groundArray[y].length; x++){
        if(groundArray[y][x] != 0){
          groundArray[y][x].draw();
        }
    }
  }
  play.move();
  if(play.jumping == true){
    play.jump();
  }
  else{
    play.gravity();
  }
  play.draw();
}

function keyPressed(){
  if(keyCode == RIGHT_ARROW){
    play.moveL = false;
    play.moveR = true;
  }
  else if(keyCode == LEFT_ARROW){
    play.moveR = false;
    play.moveL = true;
  }
  
  if(keyCode == UP_ARROW){
    play.jumping = true;
  }
}

function keyReleased(){
  if(keyCode == RIGHT_ARROW){
    play.moveR = false;
  }
  if(keyCode == LEFT_ARROW){
    play.moveL = false;
  }
  if(keyCode == UP_ARROW){
    play.jumping = false;
    play.gravSpeed = play.dgrav;
    play.jumpedHeight = 0;
  }
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>
Luke Garrigan
  • 4,571
  • 1
  • 21
  • 29
-1

I have fixed my problem. i found that in my gravity script it was checking too far to the right where it would collide with the wall so i changed it to this and it now works

gravity(){
      let gc = get(this.x, this.y + 21);
  let gc2 = get(this.x + this.scale - 2, this.y + 21);
  if(gc[0] == 0 && gc[1] == 0 && gc[2] == 255 && gc[3] == 255 ||
     this.y >= 400 - this.scale ||
     gc2[0] == 0 && gc2[1] == 0 && gc2[2] == 255 && gc2[3] == 255 ||
     gc[0] == 255 && gc[1] == 255 && gc[2] == 0 && gc[3] == 255 ||
     gc2[0] == 255 && gc2[1] == 255 && gc2[2] == 0 && gc2[3] == 255){

    this.gravSpeed = this.dgrav;
    this.isOnGround = true;
    return;
  }
  else{
    this.y += this.gravSpeed;
    if(this.gravSpeed < this.tv){ 
      this.gravSpeed += this.ac;
    }
    else{
      this.gravSpeed = this.tv;
    }

    this.isOnGround = false;
  }
  }
Maddox Fox
  • 111
  • 7