JS Tile Map - 用图像替换彩色图块

时间:2017-10-23 22:46:32

标签: javascript canvas

我正在尝试做一个Tilemap系统,所以我经历了一个教程。这是代码:

// Possible tile types
const TILE_TYPES = {
  0: { name: 'Sea', color: 'lightBlue'},
  1: { name: 'Land', color: 'wheat' },
  2: { name: 'House', color: 'black'}
}

// Map tile data
let mapData = <?php echo $mapData ?>

/**
Tile class
*/
class Tile {
  constructor (size, type, ctx) {
    this.size = size
    this.type = type
    this.ctx = ctx
  }

  draw (x, y) {
    // Store positions
    const xPos = x * this.size
    const yPos = y * this.size

    // Draw tile
    this.ctx.fillStyle = this.type.color
    this.ctx.fillRect(xPos, yPos, this.size, this.size)
  }
}

/**
Map class
*/
class Map {
  constructor (selector, data, opts) {
    this.canvas = document.getElementById(selector)
    this.ctx = this.canvas.getContext('2d')
    this.data = data
    this.tileSize = opts.tileSize
  }
}

/**
OrthogonalMap class
*/
class OrthogonalMap extends Map {
  constructor (selector, data, opts) {
    super(selector, data, opts)
    this.draw()
  }

  draw () {
    const numCols = this.data[0].length
    const numRows = this.data.length

    // Iterate through map data and draw each tile
    for (let y = 0; y < numRows; y++) {
      for (let x = 0; x < numCols; x++) {
        // Get tile ID from map data
        const tileId = this.data[y][x]

        // Use tile ID to determine tile type from TILE_TYPES (i.e. Sea or Land)
        const tileType = TILE_TYPES[tileId]

        // Create tile instance and draw to our canvas
        new Tile(this.tileSize, tileType, this.ctx).draw(x, y)
      }
    }
  }
}

// Init canvas tile map on document ready
document.addEventListener('DOMContentLoaded', function () {
  // Init orthogonal map
  const map = new OrthogonalMap('orthogonal-map', mapData, { tileSize: 64 })
})

这是电话:

<?php
  $mapData = '[
    [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2],
    [1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1],
    [1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0],
    [1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
    [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  ]';

  include "" . $_SERVER['DOCUMENT_ROOT'] . "/includes/maptiles.php";
?>
<canvas id="orthogonal-map" class="canvas-map" width="704" height="576"> </canvas>

这是我的问题:如何用图像替换颜色?

我的第一个赌注是将“color”属性替换为TILE_TYPES常量,并将this.ctx.fillStyle替换为this.ctx.drawimage之类的内容。

我是Javascript的初学者,所以如果你有时间,我会很乐意为你的过程解释一下。谢谢!

1 个答案:

答案 0 :(得分:1)

在画布上绘制图像非常简单,但是,在需要解释之前,您需要执行一个步骤。在开始执行Javascript代码之前,您需要加载图像并等待它们准备就绪。我将向您展示实现此目的的最简单方法,但还有其他方法,这个方法有几个问题。所以,现在还可以,但在某些时候你会学到其他的方法。

首先,我们将添加html图像标记来加载图像:

<img id="Sea" src="Sea.jpg">
<img id="Land" src="Land.jpg">
<img id="House" src="House.jpg">
<script>
...

<script>是您当前代码的开头,...我的意思是代码会继续存在,您不能在代码中写下这些点。

如果您检查结果,您会看到它们出现在页面顶部的画布顶部。我们现在告诉Javascript等待它们加载并从画布顶部删除它们:

首先让我们改变一下:

document.addEventListener('DOMContentLoaded', function () {

由此:

window.addEventListener('load', function () {

根据您所拥有的,您正在等待加载DOM内容以开始执行。使用新代码,它将等待加载所有内容,包括DOM内容和图像。

所以,现在让我们为图像创建一些参考:

const images = {};
window.addEventListener('load', function () {
    images.Sea = document.getElementById("Sea");
    images.Land = document.getElementById("Land");
    images.House = document.getElementById("House");
...

现在,让我们从画布顶部删除它们:

const images = {};
window.addEventListener('load', function () {
    images.Sea = document.getElementById("Sea");
    images.Land = document.getElementById("Land");
    images.House = document.getElementById("House");
    images.Sea.parentNode.removeChild(images.Sea);
    images.Land.parentNode.removeChild(images.Land);
    images.House.parentNode.removeChild(images.House);
...

现在唯一缺少的部分是在画布上绘制它们。所以,让我们替换它:

// Draw tile
this.ctx.fillStyle = this.type.color
this.ctx.fillRect(xPos, yPos, this.size, this.size)

由此:

// Draw tile
this.ctx.drawImage(images[this.type.name], xPos, yPos);