Как рефакторинг моего кода в игровой цикл? - PullRequest
0 голосов
/ 14 мая 2018

Теперь у меня есть простой код без основного игрового цикла. Я рендерил спрайты на холсте, используя конструктор Loader и его функцию image.onload (потому что без image.onload я не вижу никаких спрайтов). Теперь я хочу анимировать свои спрайты, и для этого мне нужно создать нарисовать петлю. К сожалению, на этом мои знания заканчиваются. Я попытался создать функцию рендеринга и просто скопировать мои методы ship.drawimage(boat, boatPosX, boatPosY, 50, 50);, но это не работает, потому что мне нужна функция image.onload, которая находится внутри Loader. И я не могу поместить конструктор Loader в мою функцию render(), потому что тогда var background = new Loader("ground.png"); var boat = new Loader("ship.png"); не может получить доступ к переменной конструктора, чтобы инициировать новый объект.

Итак, на данный момент я довольно растерян, как мне лучше провести рефакторинг своего кода?

Вот полный код:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var mapArray = [
  [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],
  [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]
]


var StyleSheet = function(image, width, height) {
  this.image = image;
  this.width = width;
  this.height = height;


  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 = 230;
var boatPosY = 200;

var Loader = function(src) {
  this.image = new Image();
  this.image.src = src;
  this.image.onload = function() {
  var sprite = new StyleSheet(background, 36, 36);
  var ship = new StyleSheet(boat, 90, 100);
  for (let i = 0; i < mapArray.length; i++) {
    for (let j = 0; j < mapArray[i].length; j++) {
      if (mapArray[i][j] == 0) {
        sprite.draw(background, 190, 230, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
      if (mapArray[i][j] == 1) {
        sprite.draw(background, 30, 30, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
      if (mapArray[i][j] == 2) {
        sprite.draw(background, 200, 20, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
    }
  }
  ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
}
  return this.image;
}

function render() {

}

setInterval(render, 10);

/* Sprite controls */

function move(e) {
  if (e.keyCode == 39) {
    boatPosX += 2;
    console.log("works");

  }
  if (e.keyCode == 37) {
    boatPosX -= 2;
  }
}

  document.onkeydown = move;

var background = new Loader("ground.png");
var boat = new Loader("ship.png");

console.log(background);

UPDATE:

Поэтому, следуя моим старым вопросам, я решил внести некоторые изменения в свой код, чтобы мне было разрешено вызывать requestAnimationFrame для моей функции onload и постоянно рисовать спрайт на холсте. Для этого я разделил конструктор Loader и мой метод onload, поместив onload в новую функцию и присвоив эту функцию прототипу Loader. Тогда я делаю var background = new Loader("ground.png"); и background.render();, но я получаю Uncaught TypeError: background.render is not a function ошибку. Не уверен, что я делаю не так?

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var mapArray = [
  [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],
  [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]
]


var StyleSheet = function(image, width, height) {
  this.image = image;
  this.width = width;
  this.height = height;


  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 = 230;
var boatPosY = 200;

var Loader = function(src) {
  this.image = new Image();
  this.image.src = src;
  return this.image;
}

Loader.prototype.render = function() {
  this.image.onload = function() {
  var sprite = new StyleSheet(background, 36, 36);
  var ship = new StyleSheet(boat, 90, 100);
  for (let i = 0; i < mapArray.length; i++) {
    for (let j = 0; j < mapArray[i].length; j++) {
      if (mapArray[i][j] == 0) {
        sprite.draw(background, 190, 230, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
      if (mapArray[i][j] == 1) {
        sprite.draw(background, 30, 30, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
      if (mapArray[i][j] == 2) {
        sprite.draw(background, 200, 20, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
      }
    }
  }
  ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
}
}



/* Sprite controls */

function move(e) {
  if (e.keyCode == 39) {
    boatPosX += 2;
    console.log("works");

  }
  if (e.keyCode == 37) {
    boatPosX -= 2;
  }
}

  document.onkeydown = move;

var background = new Loader("ground.png");
var boat = new Loader("ship.png");
background.render();
console.log(background);

Пример кодекса: https://codepen.io/Limpuls/pen/dejVpR

1 Ответ

0 голосов
/ 14 мая 2018

Я сделал форк из твоего пера и реорганизовал твой код.Теперь у вас есть игровой цикл с использованием requestAnimationFrame: https://codepen.io/DonKarlssonSan/pen/rvrGvL/

Редактировать , добавив то, что я изменил:

  • Я удалил загрузчик и вместо этого простоиспользуйте обычный Image и img.src = url, которые я затем передаю в качестве параметров конструктору в StyleSheet.

  • Я извлек цикл по mapArray в метод рендеринга, который также функционирует как основной("игра") петля.

Код:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var mapArray = [
  [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],
  [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]
];

var StyleSheet = function(image, width, height) {
  this.image = image;
  this.width = width;
  this.height = height;

  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 = 230;
var boatPosY = 200;

function render() {
  requestAnimationFrame(render);

  for (let i = 0; i < mapArray.length; i++) {
    for (let j = 0; j < mapArray[i].length; j++) {
      if (mapArray[i][j] == 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[i][j] == 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[i][j] == 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);
};

function move(e) {
  if (e.keyCode == 39) {
    boatPosX += 2;
    console.log("right");
  }
  if (e.keyCode == 37) {
    boatPosX -= 2;
    console.log("left");
  }
}

document.onkeydown = move;

var background = new Image();
background.src = "http://i67.tinypic.com/35lx8y0.png";
var sprite = new StyleSheet(background, 36, 36);

var boat = new Image();
boat.src = "http://i66.tinypic.com/b7b9tc.png";
var ship = new StyleSheet(boat, 90, 100);

render();
...