Нарисуйте изображение на холсте из свойства объекта - PullRequest
0 голосов
/ 24 января 2019

Я хочу рисовать изображение на холсте на каждой итерации, изображение, полученное от объекта.Либо я получаю "не формат HTML ..." в консоли, либо ничего, и это блокирует цикл.

Есть ли способ нарисовать изображение на холсте, не помещая его сначала в index.htmlили без загрузки с URL?

Я попробовал два стандартных решения, и они не сработали.

Я не нашел подобной проблемы, используя свойство объекта, содержащее изображение, чтобынарисуйте его на холсте.

function Board(width, height) {
    this.width = width;
    this.height = height;
    this.chartBoard = [];

    // Création du plateau logique
    for (var i = 0; i < this.width; i++) {
        const row = [];
        this.chartBoard.push(row);
        for (var j = 0; j < this.height; j++) {
            const col = {};
            row.push(col);
        }
    }
}
let board = new Board(10, 10);
console.log(board);

// CONTEXT OF THE CANVAS
const ctx = $('#board').get(0).getContext('2d');

Board.prototype.drawBoard = function () {
    for (var i = 0; i < this.width; i++) {
        for (var j = 0; j < this.height; j++) {
            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.strokeRect(j * 64, i * 64, 64, 64);
            ctx.closePath();
        }
    }
};

board.drawBoard();



Board.prototype.test = test;

function test() {
    console.log(this);
}


// OBJECT TO DRAW
function Obstacle(name, sprite) {
    this.name = name;
    this.sprite = sprite;
}

const lava = new Obstacle("Lave", "assets/lave.png");
const lava1 = new Obstacle("Lave1", "assets/lave.png");
const lava2 = new Obstacle("Lave2", "assets/lave.png");
const lava3 = new Obstacle("Lave3", "assets/lave.png");
const lava4 = new Obstacle("Lave4", "assets/lave.png");
const lava5 = new Obstacle("Lave5", "assets/lave.png");
const lava6 = new Obstacle("Lave6", "assets/lave.png");
const lava7 = new Obstacle("Lave7", "assets/lave.png");
const lava8 = new Obstacle("Lave8", "assets/lave.png");
const lava9 = new Obstacle("Lave9", "assets/lave.png");
const lavaArray = [lava, lava1, lava2, lava3, lava4, lava5, lava6, lava7, lava8, lava9];


// FUNCTION TO DRAW

Board.prototype.setPiece = function (piece) {

    let randomX = Math.floor(Math.random() * board.width);
    let randomY = Math.floor(Math.random() * board.height);

    let drawX = randomX * 64;
    let drawY = randomY * 64;


    if (randomX >= this.width || randomY >= this.height) {
        throw new Error('Pièce hors limite');
    }

    if (piece instanceof Obstacle) {

        if (!(this.chartBoard[randomY][randomX] instanceof Obstacle)) {
            this.chartBoard[randomY][randomX] = piece;

            // CODE TO DRAW, BUG DOESN'T WORK
            ctx.fillRect(drawX, drawY,64,64);
            let image = Obstacle.sprite;
            ctx.drawImage = (image, drawX, drawY);
        }
    } 

    } else {
        throw new Error('Pièce non valide');
    }
};

Board.prototype.setObstacles = function () {
    for (let lava of lavaArray) {

        const obstacle = board.setPiece(lava);
    }
};
board.setObstacles();

Факт: Изображение не нарисовано.И если я попробую fillRect, он будет работать хорошо.Так что цикл работает.

Ожидается: Уметь рисовать изображение на холсте из свойства объекта.

1 Ответ

0 голосов
/ 24 января 2019

Не совсем понятно, что вы пытаетесь сделать.

Код, который вы прокомментировали

ctx.drawImage = (image, drawX, drawY);

, должен быть таким

ctx.drawImage(image, drawX, drawY);

Выглядит немногов более широком смысле это

let image = Obstacle.sprite;
ctx.drawImage(image, drawX, drawY);  // assume this was fixed

Но Obstacle - это класс, а не экземпляр этого класса.Вы хотите

let image = piece.sprite;
ctx.drawImage(image, drawX, drawY);

Но это приводит к следующей проблеме.глядя на остальную часть кода piece.sprite это строка, а не изображение.См. Этот код.

// OBJECT TO DRAW
function Obstacle(name, sprite) {
    this.name = name;
    this.sprite = sprite;
}

const lava = new Obstacle("Lave", "assets/lave.png");

Существует несколько способов рисования изображений на холсте.Если они приходят из файла, вам придется ждать их загрузки.В противном случае вы можете сгенерировать их из другого холста.Вы также можете использовать createImageData и putImageData в качестве другого способа создания изображений.

Давайте изменим код для загрузки нескольких изображений и затем запустим

Я переместил весь код класса вверх и код запуска снизу.

Внутри Board методов было несколько мест, где вместо this использовалась глобальная переменная board, поэтому я исправил их.

Здесь есть функция, которая загружает изображение и возвращает Обещание

function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => { resolve(img); };
    img.onerror = reject;
    img.crossOrigin = 'anonymous';  // REMOVE IF SAME DOMAIN!
    img.src = url;
  });
}

Вы можете использовать это для загрузки одного изображения, как это

loadImage(urlOfImage).then(function(img) {
  // use the loaded img
});

Я использовал эту функцию, чтобы написать эту функциюон принимает объект имен в URL и возвращает объект имен загруженным изображениям.

function loadImages(images) {
  return new Promise((resolve) => {
    const loadedImages = {};
    const imagePromises = Object.entries(images).map((keyValue) => {
      const [name, url] = keyValue;
      return loadImage(url).then((img) => {
         loadedImages[name] = img;
      });
    });
    Promise.all(imagePromises).then(() => {
      resolve(loadedImages);
    });
  });
}

Затем я вызываю его и передаю объект имен загруженным изображениям в функцию start.На данный момент загружено только одно изображение, но вы можете добавить еще.

const images = {
  lave: 'https://i.imgur.com/enx5Xc8.png',
  // player: 'foo/player.png',
  // enemy: 'foo/enemny.png',
};
loadImages(images).then(start);

// CONTEXT OF THE CANVAS
const ctx = $('#board').get(0).getContext('2d');

function Board(width, height) {
    this.width = width;
    this.height = height;
    this.chartBoard = [];

    // Création du plateau logique
    for (var i = 0; i < this.width; i++) {
        const row = [];
        this.chartBoard.push(row);
        for (var j = 0; j < this.height; j++) {
            const col = {};
            row.push(col);
        }
    }
}

Board.prototype.drawBoard = function () {
    for (var i = 0; i < this.width; i++) {
        for (var j = 0; j < this.height; j++) {
            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.strokeRect(j * 64, i * 64, 64, 64);
            ctx.closePath();
        }
    }
};

// OBJECT TO DRAW
function Obstacle(name, sprite) {
    this.name = name;
    this.sprite = sprite;
}


// FUNCTION TO DRAW

Board.prototype.setPiece = function (piece) {

    let randomX = Math.floor(Math.random() * this.width);
    let randomY = Math.floor(Math.random() * this.height);

    let drawX = randomX * 64;
    let drawY = randomY * 64;


    if (randomX >= this.width || randomY >= this.height) {
        throw new Error('Pièce hors limite');
    }

    if (piece instanceof Obstacle) {

        if (!(this.chartBoard[randomY][randomX] instanceof Obstacle)) {
            this.chartBoard[randomY][randomX] = piece;

            // CODE TO DRAW, BUG DOESN'T WORK
            ctx.fillRect(drawX, drawY,64,64);
            let image = piece.sprite;
            ctx.drawImage(image, drawX, drawY);
        }
    } else {
        throw new Error('Pièce non valide');
    }
};

Board.prototype.setObstacles = function (lavaArray) {
    for (let lava of lavaArray) {

        const obstacle = this.setPiece(lava);
    }
};

function start(images) {
  let board = new Board(10, 10);
//  console.log(board);

  const lava = new Obstacle("Lave", images.lave);
  const lava1 = new Obstacle("Lave1", images.lave);
  const lava2 = new Obstacle("Lave2", images.lave);
  const lava3 = new Obstacle("Lave3", images.lave);
  const lava4 = new Obstacle("Lave4", images.lave);
  const lava5 = new Obstacle("Lave5", images.lave);
  const lava6 = new Obstacle("Lave6", images.lave);
  const lava7 = new Obstacle("Lave7", images.lave);
  const lava8 = new Obstacle("Lave8", images.lave);
  const lava9 = new Obstacle("Lave9", images.lave);
  const lavaArray = [lava, lava1, lava2, lava3, lava4, lava5, lava6, lava7, lava8, lava9];

  board.drawBoard();


  board.setObstacles(lavaArray);
}

function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => { resolve(img); };
    img.onerror = reject;
    img.crossOrigin = 'anonymous';  // REMOVE IF SAME DOMAIN!
    img.src = url;
  });
}

function loadImages(images) {
  return new Promise((resolve) => {
    const loadedImages = {};
    // for each name/url pair in image make a promise to load the image
    // by calling loadImage
    const imagePromises = Object.entries(images).map((keyValue) => {
      const [name, url] = keyValue;
      // load the image and when it's finished loading add the name/image
      // pair to loadedImages
      return loadImage(url).then((img) => {
         loadedImages[name] = img;
      });
    });
    // wait for all the images to load then pass the name/image object
    Promise.all(imagePromises).then(() => {
      resolve(loadedImages);
    });
  });
}

const images = {
  lave: 'https://i.imgur.com/enx5Xc8.png',
  // player: 'foo/player.png',
  // enemy: 'foo/enemny.png',
};
loadImages(images).then(start);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="board" width="640" height="640"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...