HTML-холст оставляет следы на горизонтальном переводе - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь понять, как работает HTML canvas.Я знаю основы и пишу 2D-игру, но у меня так много вопросов относительно ее и странного поведения.У меня разные версии кода, и каждая из них дает разные результаты при перемещении символа вправо или влево на холсте.

Основная проблема заключается в том, что когда translate() для холста вызывается, персонаж перемещается вправо, он начинает покидать следы спрайтов.Я пытаюсь исправить это с помощью clearRect(), но если я использую clearRect, то при движении вправо он просто дает мне белый пустой фон для функции translate().Почему нет следов персонажа при движении по центру, но как только я выхожу за пределы центра больше вправо, это либо спрайт-символ, либо наборы спрайтов, которые тянутся?

Мне действительно нужна помощь в этом,поэтому, если вопрос слишком широкий или недостаточно ясный, дайте мне знать, и я его исправлю.

объясните мне, что происходит с холстом и как это исправить, чтобы, когда translate() происходит при перемещении персонажа в сторону, не было белого фона или следов спрайтов, а просто хороший рендер как он естьonload.

https://codepen.io/Limpuls/pen/deEGXX оставляет следы для наборов плиток на ход персонажа.Вы можете видеть, что это происходит, когда происходит translate () для canvas.Если я попытаюсь clearRect в цикле прорисовки перед рисованием, то при перемещении персонажа фон обрезается, и появляется только белый фон.Почему и как это исправить?Внутри функции render() попробуйте комментировать и раскомментировать clearRect(), чтобы понять, о чем я говорю.

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var view = {x: 0, y: 0};
var questionsArray = [];
var moveCount = 0;
var moveCharacter = false;
var theArray = [];
/*var mapArray = [
  [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
  [0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
  [0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
  [0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
  [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
  [0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
  [0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
  [0, 0, 0, 1, 1, 0, 0, 0, 0, 0]
];
*/
var mapArray = [
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
  [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],
  [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
function isPositionWall(ptX, ptY) {
  var gridX = Math.floor(ptX / 36);
  var gridY = Math.floor(ptY / 36);
  /*if(gridX > 0 || gridX >= mapArray[0].length)*/
  if(mapArray[gridX][gridY] === 1) {
    return true;
  /*if(gridY < 0 || gridY >= mapArray.length)
    return true;
    return mapArray[gridX][gridY];*/
  }
}


var Question = function(question, answer1, answer2, correctAnswer) {
  this.question = question;
  this.answer1 = answer1;
  this.answer2 = answer2;
  this.correctAnswer = correctAnswer;

  this.addToArray = function(){
     theArray.push(this);
 };
  this.addToArray();
}

Question.prototype.checkAnswer = function(answer1, answer2) {
  if (answer1.innerHTML  == this.correctAnswer) {
    console.log("correct");
    moveCharacter = true;
  } else {
    console.log("nope")
  }
}

var question1 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question2 = new Question("Jo ar ne?", "Ne", "Jo", "Ne");
var question3 = new Question("Aha ar ne?", "Aha", "Ne", "Aha");
var question4 = new Question("Ja ar ne?", "Taip", "Ne", "Taip");
var question5 = new Question("Jojo ar ne?", "Jojo", "Ne", "Jojo");
var question6 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");

var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var StyleSheet = function(image, width, height, x, y) {
  this.image = image;
  this.width = width;
  this.height = height;
  this.x = x;
  this.y = y
  this.draw = function(image, sx, sy, swidth, sheight, x, y, width, height) {
    context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
  };
  this.drawimage = function(image, x, y, width, height) {
    context.drawImage(image, x, y, width, height);
  };
};

/* Initial Sprite Position */


var boatPosX = canvas.height/2 - 50;
var boatPosY = canvas.height/2 - 50;

function render(viewport) {

  context.save();
  context.translate(view.x, view.y);
  context.clearRect(0, 0, canvas.width, canvas.height)
  requestAnimationFrame(render);
  var oldPosX = boatPosX;
  var oldPosY = boatPosY;


  for (let i = 0; i < mapArray.length; i++) {
    for (let j = 0; j < mapArray[i].length; j++) {

      if (mapArray[j][i] == 0) {
        this.sprite.draw(
          background,
          190,
          230,
          26,
          26,
          i * this.sprite.width,
          j * this.sprite.height,
          this.sprite.width,
          this.sprite.height
        );
      }
      if (mapArray[j][i] == 1) {
        this.sprite.draw(
          background,
          30,
          30,
          26,
          26,
          i * this.sprite.width,
          j * this.sprite.height,
          this.sprite.width,
          this.sprite.height
        );

      }
      if (mapArray[j][i] == 2) {
        this.sprite.draw(
          background,
          200,
          20,
          26,
          26,
          i * this.sprite.width,
          j * this.sprite.height,
          this.sprite.width,
          this.sprite.height
        );
      }
    }
  }
  this.ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
  /*var lineHeight = 16 * 2.286;
  var textWidth = context.measureText(theArray[moveCount].question).width * 3;
  context.textAlign = 'left';
  context.textBaseline = 'top';
  context.font="14px Verdana";
  context.fillStyle = 'rgba(0, 0, 0 ,0.9)';
  context.fillRect(boatPosX + ship.width / 2, boatPosY - ship.height / 2, textWidth, lineHeight);
  context.fillStyle = 'white';
  context.fillText(theArray[moveCount].question, boatPosX + ship.width / 2, boatPosY - ship.height / 2);

  answerBtn1.innerHTML = theArray[moveCount].answer1;
  answerBtn2.innerHTML = theArray[moveCount].answer2;*/
  if(isPositionWall(boatPosX + 36, boatPosY)) {
    //boatPosX = oldPosY;
    //console.log("collision");
  }
  //console.log(mapArray[Math.floor(boatPosX / 36)]);
  //console.log(mapArray[Math.floor(boatPosX / 36)][Math.floor(boatPosX / 36)]);
  context.restore();

};


var btn1 = document.getElementsByClassName("button1")[0];
var btn2 = document.getElementsByClassName("button2")[0];
var btn3 = document.getElementsByClassName("button3")[0];
var btn4 = document.getElementsByClassName("button4")[0];
var answerBtn1 = document.getElementsByClassName("answer1")[0];
var answerBtn2 = document.getElementsByClassName("answer2")[0];

console.log(theArray);

answerBtn1.addEventListener("click", function(e) {
  theArray[moveCount].checkAnswer(answerBtn1, answerBtn2);
});

answerBtn2.addEventListener("click", function(e) {
  question1.checkAnswer(answerBtn2, answerBtn2);
});

btn1.addEventListener("click", function(e) {
  if (moveCharacter == true) {
    moveCount++;
    boatPosX -= 5;
    view.x += 5
    moveCharacter = false;
  }
});
btn2.addEventListener("click", function(e) {
  boatPosX += 5;
  view.x -= 5
  moveCount++;
});
btn3.addEventListener("click", function(e) {
  boatPosY += 5;
  view.Y += 5
  moveCount++;
});
btn4.addEventListener("click", function(e) {
  boatPosY -= 5;
  view.Y += 5
  moveCount++;
});


function move(e) {
  if (e.keyCode == 39) {
    boatPosX += 5;
    //canvas.width += 2;
    view.x -= 5
    moveCount++;
    console.log(moveCount);
    console.log("right");
  }
  if (e.keyCode == 37) {
    boatPosX -= 5;
    view.x += 5
    moveCount++;
    console.log(moveCount);
    console.log("left");
  }
  if (e.keyCode == 38) {
    boatPosY -= 5;
    view.Y += 5
    moveCount++;
    console.log(moveCount);
    console.log("up");
  }
  if (e.keyCode == 40) {
    boatPosY += 5;
    view.Y += 5
    moveCount++;
    console.log(moveCount);
    console.log("down");
  }
}

document.onkeydown = move;

var background = new Image();
background.src = "ground.png";
var sprite = new StyleSheet(background, 36, 36, 16, 16);

var boat = new Image();
boat.src = "ship.png";
var ship = new StyleSheet(boat, 36, 36, 16, 16);

console.log(mapArray[Math.floor(boatPosX / 36)]);
//console.log(mapArray[Math.floor(boatPosX / 36)][Math.floor(boatPosX / 36)]);
render();
...