You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Canvas绘制瓦片图时为何出现Type Error且无法显示图像?

问题分析与修复方案

错误原因

  1. 异步函数处理不当:createImageBitmap()是异步方法,返回的是Promise对象,你直接将其存入tiles字典,导致调用ctx.drawImage()时传入的是Promise而非可绘制的图像资源,触发TypeError。
  2. 索引计算错误:原代码中i+8*u的索引逻辑会导致重复键名(比如第1行第1个tile和第0行第9个tile索引都是8),应该按行号×每行数量 + 列号的方式计算。

修复后的代码

JavaScript部分

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

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var tileSize = 32;
var tilex = Math.ceil(canvas.width / tileSize);
var tiley = Math.ceil(canvas.height / tileSize);
var tiles = {};
var images = ['performanceTask Assets/Grass.png', 'performanceTask Assets/Plant.png', 'performanceTask Assets/Stone Ground.png', 'performanceTask Assets/Struct.png', 'performanceTask Assets/Wall.png', 'performanceTask Assets/Props.png', 'performanceTask Assets/Shadow Plant.png', 'performanceTask Assets/Shadow.png', 'performanceTask Assets/player.png'];

var atlasImage = new Image();
var tilesReady = false; // 标记瓦片是否全部加载完成

atlasImage.src = images[0];
atlasImage.onload = async function() {
    let x = 0
    let y = 0
    // 外层循环处理行(共8行)
    for (let row = 0; row < 8; row++) {
        // 内层循环处理每行的9个tile
        for (let col = 0; col < 9; col++) {
            // 等待异步操作完成,拿到实际的位图对象
            const tileBitmap = await createImageBitmap(atlasImage, x, y, tileSize, tileSize);
            // 用行×9+列生成唯一索引
            tiles["tiles" + (row * 9 + col)] = tileBitmap;
            x += tileSize;
        }
        y += tileSize;
        x = 0;
    }
    tilesReady = true;
    grassScreen(); // 加载完成后立即绘制
};

function grassScreen() {
    // 瓦片未加载完成时直接返回,避免报错
    if (!tilesReady) return;
    ctx.drawImage(tiles['tiles1'], 100, 100);
};

// 如果需要实时刷新画面可以保留,否则无需定时调用
// setInterval(grassScreen, 1000);

HTML部分(无需修改)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Work in Progress</title>
        <style>
            * {
                overflow: hidden;
            }
            html, body {
                margin: 0 !important;
                padding: 0 !important;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas"></canvas>
        <script src="performanceTask.js"></script>
    </body>
</html>

额外说明

  • 使用async/await确保异步生成的位图正确存入字典,避免Promise对象导致的绘制错误。
  • 添加tilesReady状态判断,防止在资源未加载完成时执行绘制逻辑。
  • 调整索引计算方式,保证每个tile的键名唯一,避免覆盖问题。

内容的提问来源于stack exchange,提问作者user16581612

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:10:22