JavaScript холст движется прямоугольник назад и вперед - PullRequest
0 голосов
/ 10 ноября 2018

Сейчас я делаю 2D-платформерную игру на JavaScript, и пока все работает, за исключением того, что касается перемещения моей первой платформы

<!DOCTYPE html>
<html>

<body>

  <style>
    canvas {
      background: #eee;
    }
  </style>

  <canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>

  <script>
    var canvas = document.getElementById("ctx");
    var ctx = canvas.getContext("2d");
    canvas.setAttribute('tabindex', 0);
    canvas.focus();
    canvas.addEventListener("keydown", movePlayer);

    //Maybe I can get a class working?

    class Platform {
      constructor(x, y, xS, yS, moveBool) {
        this.xPos = x;
        this.yPos = y;
        this.xSize = xS;
        this.ySize = yS;

        ctx.fillStyle = "red";
        ctx.fillRect(this.xPos, this.yPos, this.xSize, this.ySize);

        this.moveable = moveBool;
      }

      get getX() {
        return this.xPos;
      }
      get getY() {
        return this.yPos;
      }
      get getxSize() {
        return this.xSize;
      }
      get getySize() {
        return this.ySize;
      }
      get getMoveable() {
        return this.moveable;
      }

      set moveRight(speed) {
        this.xPos = speed;
      }
    }

    //Platform array:
    platformArray = [];

    //Vars:

    var x_new = 50;
    var y_new = 50;

    var isJumping = false;
    var isColliding = false;

    var speed = 10;

    //Moving platform vars:
    var plat1X = 100;

    var keys = {
      up: false,
      right: false,
      left: false
    };

    function movePlayer(event) {
      switch (event.keyCode) {
        //Right key down:
        case 39:
          keys["right"] = true;
          break;
          //Left key down:
        case 37:
          keys["left"] = true;
          break;
          //Up key down:
        case 38:
          keys["up"] = true;
          isJumping = true;
          break;
      }
    }

    function keyUp(event) {
      switch (event.keyCode) {
        //Up key up:
        case 38:
          isJumping = false;
          keys["up"] = false;
          break;
          //Right key up:
        case 39:
          keys["right"] = false;
          break;
          //Left key up:
        case 37:
          keys["left"] = false;
          break;
      }

    }

    function boundsIntersect(x1, y1, x2, y2) {
      if (x1 > x2 - 50 && x1 < x2 + 200 && y1 < y2 && y1 > y2 - 55) {
        return true;
      }
      return false;
    }

    function update() {
      window.requestAnimationFrame(update);
      ctx.clearRect(0, 0, 900, 500);
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.fillRect(x_new, y_new, 50, 50);
      //Draw ground:
      ctx.beginPath();
      ctx.rect(0, 490, 900, 10);
      ctx.fillStyle = "green";
      ctx.fill();

      //PLayer movement:
      if (keys["up"] && !keys["right"] && !keys["left"]) {
        y_new -= speed;
      } else if (keys["right"] && !keys["up"]) {
        x_new += speed;
      } else if (keys["left"] && !keys["up"]) {
        x_new -= speed;
      } else if (keys["up"] && keys["right"]) {
        y_new -= speed;
        x_new += speed;
      } else if (keys["up"] && keys["left"]) {
        y_new -= speed;
        x_new -= speed;
      }

      if (y_new < 440 && isJumping == false && isColliding == false) {
        y_new += speed;
      }

      //Platforms:
      platform1 = new Platform(plat1X, 350, 200, 10, true);
      platformArray.push(platform1);

      platform2 = new Platform(300, 200, 200, 10, false);
      platformArray.push(platform2);

      platform3 = new Platform(400, 300, 200, 10, false);
      platformArray.push(platform3);

      //Platform intersections:
      platformArray.forEach(function(platform) {
        if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == false) {
          isColliding = true;
          y_new -= 0.5;
        } else if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == true) {
          isJumping = false;
          y_new += 11;
          isColliding = true;
        } else {
          isColliding = false;
        }
      });

      var platSpeed = 2;

      //Move platforms:
      platformArray.forEach(function(platform) {
        if (platform.getMoveable) {
          if (platform.getX > 0 && platform.getX < 400) {
            plat1X += 1;
          } else if (platform.getX > 0 && platform.getX > 400) {
            plat1X -= 1
          }
        }
      });

      ctx.save();
      ctx.restore();
    }

    window.requestAnimationFrame(update);
  </script>

</body>

</html>

Что происходит, так это визуальный эффект движения платформы, однако он оставляет след, который я не могу пройти. Я знаю, что это как-то связано с тем, что я не удаляю его, но я не знаю особенностей JavaScript.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Это небрежно, но я смог получить рабочую версию, поиграв с некоторыми другими вещами, вдохновленными предыдущим ответом:

<!DOCTYPE html>
<html>
<body>

<style>

canvas{
  background: #eee;
}

</style>

<canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>

<script>
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);

//Maybe I can get a class working?

class Platform {
  constructor(x, y, xS, yS, moveBool) {
    this.xPos = x;
    this.yPos = y;
    this.xSize = xS;
    this.ySize = yS;

    this.moveable = moveBool;
  }

  render() {
   ctx.save()
   ctx.fillStyle = "red";
   ctx.fillRect(this.xPos, this.yPos, this.xSize, this.ySize);
   ctx.restore()
 }

  get getX() {
    return this.xPos;
  }
  get getY() {
    return this.yPos;
  }
  get getxSize() {
    return this.xSize;
  }
  get getySize() {
    return this.ySize;
  }
  get getMoveable() {
    return this.moveable;
  }
}

//Platform array:
var platformArray = [];

//Vars:

var x_new = 50;
var y_new = 50;

var isJumping = false;
var isColliding = false;

var speed = 10;

//Moving platform vars:
var plat1X = 0;
var direction = '';

var keys = {
    up: false,
    right: false,
    left: false
};

function movePlayer(event) {
    switch(event.keyCode){
      //Right key down:
      case 39:
        keys["right"] = true;
        break;
      //Left key down:
      case 37:
        keys["left"] = true;
        break;
      //Up key down:
      case 38:
        keys["up"] = true;
        isJumping = true;
        break;
    }
}

function keyUp(event){
  switch(event.keyCode){
    //Up key up:
    case 38:
      isJumping = false;
      keys["up"] = false;
      break;
    //Right key up:
    case 39:
      keys["right"] = false;
      break;
    //Left key up:
    case 37:
      keys["left"] = false;
      break;
  }

}

function boundsIntersect(x1,y1,x2,y2){
  if(x1 > x2-50 && x1 < x2+200 && y1 < y2 && y1 > y2-55){
    return true;
  }
  return false;
}

function update(){

  window.requestAnimationFrame(update);
  ctx.clearRect(0,0,900,500);
  ctx.fillStyle = "black";
  ctx.beginPath();
  ctx.fillRect(x_new,y_new,50,50);
  //Draw ground:
  ctx.beginPath();
  ctx.rect(0,490,900,10);
  ctx.fillStyle = "green";
  ctx.fill();

  //PLayer movement:
  if(keys["up"] && !keys["right"] && !keys["left"]){
    y_new-=speed;
  } else if(keys["right"] && !keys["up"]){
    x_new+=speed;
  } else if(keys["left"] && !keys["up"]){
    x_new-=speed;
  } else if(keys["up"] && keys["right"]){
    y_new-=speed;
    x_new+=speed;
  } else if(keys["up"] && keys["left"]){
    y_new-=speed;
    x_new-=speed;
  }

  //Gravity
  if(y_new < 440 && isJumping == false && isColliding == false){
    y_new+=speed;
  }

  platformArray = [];

  //Platforms:
  platform1 = new Platform(plat1X,350,200,10, true);
  platformArray.push(platform1);

  platform2 = new Platform(300,200,200,10, false);
  platformArray.push(platform2);

  platform3 = new Platform(400,300,200,10, false);
  platformArray.push(platform3);

  //Move platforms:
  platformArray.forEach(function(platform) {
    if (platform.getMoveable) {
      if (platform.getX >= 400) {
        direction = 'left'
      } else if (platform.getX <= 0) {
        direction = 'right';
        plat1X += 1;
      }

      if(platform.getX > 0 && platform.getY < 400){
        if (direction == 'right') {
          plat1X += 10;
        } else if(direction == 'left'){
          plat1X -= 10;
        }
      }
    }
  });

  // render platforms
   platformArray.forEach(function (platform) {
     platform.render()
   });

  //Platform intersections:
  platformArray.forEach(function(platform){
    if(boundsIntersect(x_new,y_new,platform.getX, platform.getY) && isJumping == false){
      isColliding = true;
      y_new -= 10;
    } else if(boundsIntersect(x_new,y_new,platform.getX, platform.getY) && isJumping == true){
      isJumping = false;
      y_new += 50;
      isColliding = true;
    } else {
      isColliding = false;
    }
  });
}

window.requestAnimationFrame(update);

</script>

</body>
</html>
0 голосов
/ 10 ноября 2018

Причина, по которой игрок застревает в «следе», заключается в том, что каждый раз, когда вызывается ваша функция update(), она помещает 3 новых Platform объекта (1 из которых имеет обновленную позицию) в platformArray. Старые Platform объекты остаются там навсегда, поэтому всякий раз, когда вы проверяете наличие столкновений с platformArray, вы проверяете наличие столкновений с каждым Platform, который вы когда-либо создавали, поэтому отсюда и возникает «след».

Я сделал некоторые исправления в вашем коде, пытаясь быть менее агрессивным. Обратите внимание, как три Platform создаются только один раз и повторно визуализируются на каждом update(). Вы также заметите, что столкновения по-прежнему не работают должным образом, но это другая история (возможно, boundsIntersect() стоит проверить).

<!DOCTYPE html>
<html>

<body>

  <style>
    canvas {
      background: #eee;
    }
  </style>

  <canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>

  <script>
    var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);

//Maybe I can get a class working?

class Platform {
  constructor(x, y, xS, yS, moveBool) {
    this.xPos = x;
    this.yPos = y;
    this.xSize = xS;
    this.ySize = yS;
    this.moveable = moveBool;
    if (this.moveable) {
      this.setDirection('right')
    }
  }
  
  render() {
    ctx.save()
    ctx.fillStyle = "red";
    ctx.fillRect(this.xPos, this.yPos, this.xSize, this.ySize);
    ctx.restore()
  }

  get getX() {
    return this.xPos;
  }
  get getY() {
    return this.yPos;
  }
  get getxSize() {
    return this.xSize;
  }
  get getySize() {
    return this.ySize;
  }
  get getMoveable() {
    return this.moveable;
  }
  
  setDirection(direction) {
    this.direction = direction
  }

  moveX(speed) {
    this.xPos += speed;
  }
}

//Platform array:
platformArray = [];

//Platforms:
platform1 = new Platform(100, 350, 200, 10, true);
platformArray.push(platform1);

platform2 = new Platform(300, 200, 200, 10, false);
platformArray.push(platform2);

platform3 = new Platform(400, 300, 200, 10, false);
platformArray.push(platform3);

//Vars:

var x_new = 50;
var y_new = 50;

var isJumping = false;
var isColliding = false;

var speed = 10;

var keys = {
  up: false,
  right: false,
  left: false
};

function movePlayer(event) {
  switch (event.keyCode) {
    //Right key down:
    case 39:
      keys["right"] = true;
      break;
      //Left key down:
    case 37:
      keys["left"] = true;
      break;
      //Up key down:
    case 38:
      keys["up"] = true;
      isJumping = true;
      break;
  }
}

function keyUp(event) {
  switch (event.keyCode) {
    //Up key up:
    case 38:
      isJumping = false;
      keys["up"] = false;
      break;
      //Right key up:
    case 39:
      keys["right"] = false;
      break;
      //Left key up:
    case 37:
      keys["left"] = false;
      break;
  }

}

function boundsIntersect(x1, y1, x2, y2) {
  if (x1 > x2 - 50 && x1 < x2 + 200 && y1 < y2 && y1 > y2 - 55) {
    return true;
  }
  return false;
}

function update() {
  ctx.clearRect(0, 0, 900, 500);
  
  //Move platforms:
  platformArray.forEach(function(platform) {
    if (platform.getMoveable) {
      if (platform.getX > 0 && platform.getX < 400) {
        if (platform.direction === 'right') {
          platform.moveX(5);
        } else {
          platform.moveX(-5);
        }
      } else if (platform.getX >= 400) {
        platform.moveX(-5);
        platform.setDirection('left')
      } else if (platform.getX <= 0) {
        platform.moveX(5);
        platform.setDirection('right')
      }
    }
  });
  
  //PLayer movement:
  if (keys["up"] && !keys["right"] && !keys["left"]) {
    y_new -= speed;
  } else if (keys["right"] && !keys["up"]) {
    x_new += speed;
  } else if (keys["left"] && !keys["up"]) {
    x_new -= speed;
  } else if (keys["up"] && keys["right"]) {
    y_new -= speed;
    x_new += speed;
  } else if (keys["up"] && keys["left"]) {
    y_new -= speed;
    x_new -= speed;
  }

  //Platform intersections:
  platformArray.forEach(function(platform) {
    if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == false) {
      isColliding = true;
      y_new -= 10;
    } else if (boundsIntersect(x_new, y_new, platform.getX, platform.getY) && isJumping == true) {
      isJumping = false;
      y_new += 11;
      isColliding = true;
    } else {
      isColliding = false;
    }
  });
  
  if (y_new < 440 && isJumping == false && isColliding == false) {
    y_new += speed;
  }
  
  // render platforms
  platformArray.forEach(function (platform) {
    platform.render()
  })
  // render player
  ctx.save()
  ctx.fillStyle = "black";
  ctx.beginPath();
  ctx.fillRect(x_new, y_new, 50, 50);
  //Draw ground:
  ctx.beginPath();
  ctx.rect(0, 490, 900, 10);
  ctx.fillStyle = "green";
  ctx.fill();
  ctx.restore()
  
  window.requestAnimationFrame(update);

}

window.requestAnimationFrame(update);
  </script>

</body>

</html>
...