繁体   English   中英

从画布精灵获取图像像素数据

[英]Getting image pixel data from a canvas sprite

我正在尝试在我的画布游戏中实现像素完美碰撞检测,但是我似乎无法从精灵中获取像素信息。

我需要为子画面的每个像素设置x和y值,从我读到的内容中,我使用getImageData()方法来实现。

但是,这不起作用:

this.sprite = new Image();
this.sprite.src = 'img/player.png';
console.log(this.sprite.getImageData());

我可能使用了错误类型的Sprite吗? 因为我在控制台中收到此错误:

未捕获的TypeError:对象#没有方法'getImageData'

这是使用精灵的像素数据进行像素完美命中测试的方法

首先,通常在可见的画布上绘制精灵。

在此处输入图片说明

在隐藏的画布上创建该精灵的红色蒙版副本 此副本的大小与精灵相同,但包含透明或红色像素。

在此处输入图片说明

跟踪可见的精灵的边界框。 单击边界框时,请相对于精灵的边界框 (而不是相对于画布)计算mouseclick的X / Y。

然后,参考红色蒙版精灵,查看该X / Y处的相应像素是红色还是透明的。 如果像素为红色,则表示像素完美匹配。 如果像素是透明的,则不会命中。

在此插图中,假设蓝点是X / Y单击位置。 由于红色蒙版画布中对应的X / Y像素为“红色”,因此这是HIT。

在此处输入图片说明

这是创建红色蒙版精灵的代码。 我在这里没有显示用于命中测试的代码,但是如果您尝试并且无法对命中测试进行编码,我也会花时间来编写命中测试。

重要说明:要使此代码运行,必须避免跨域安全限制。 确保您的图像源位于您的本地域上,否则您将遇到跨域安全冲突,并且将不会绘制遮罩图像……因此,您不能对您的sprite源执行此操作: http : //otherDomain.com/ picture.jpg

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:10px; }
    canvas{border:1px solid blue;}
</style>

<script>
    $(function(){

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

        var img=new Image();
        img.onload=function(){
          ctx.drawImage(this,100,25);

          // make a red-masked copy of just the sprite
          // on a separate canvas
          var canvasCopy=document.getElementById("canvasCopy");
          var ctxCopy=canvasCopy.getContext("2d");
          canvasCopy.width=this.width;
          canvasCopy.height=this.height;
          ctxCopy.drawImage(img,0,0);

          // make a red-masked copy of the sprite on a separate canvas
          var imgData=ctxCopy.getImageData(0,0,c.width,c.height);
          for (var i=0;i<imgData.data.length;i+=4)
            {
                if(imgData.data[i+3]>0){
                    imgData.data[i]=255;
                    imgData.data[i+1]=0;
                    imgData.data[i+2]=0;
                    imgData.data[i+3]=255;
                }
            }
          ctxCopy.putImageData(imgData,0,0);         

        }
        img.src = "houseIcon.png";

    }); // end $(function(){});
</script>

</head>

<body>
    <p>Original sprite drawn on canvas at XY:100/25</p>
    <canvas id="canvas" width="400" height="300"></canvas>
    <p>Red-masked on canvas used for hit-testing</p>
    <canvas id="canvasCopy" width="300" height="300"></canvas>

</body>
</html>

要在2个精灵之间进行像素完美的碰撞测试,您需要:

为sprite#1和sprite#2创建一个红色蒙版的画布。

首先测试两个精灵的边界框是否碰撞。 如果边界框不碰撞,则两个精灵不碰撞,因此您可以在此处停止命中测试。

如果使用边界框测试可能会碰撞2个精灵,请为碰撞测试创建第三个画布。

您将使用画布的合成方法通过将sprite#1和sprite#2都绘制到第三张画布上来测试sprite#1和sprite#2之间的冲突。 使用合成时,只有两个Sprite的COLLIDING像素将绘制在第三个画布上。

这是“目标插入”合成的工作方式:现有画布内容保留在新形状(sprite#2)和现有形状(sprite#1)内容重叠的位置。 其他一切都变得透明。

所以…

将Sprite#1 以其转换后的状态绘制到第三个画布中(转换可以是移动,旋转,缩放,倾斜等等)。

将globalCompositeOperation设置为destination-in。

context.globalCompositeOperation = 'destination-over';

将处于转换状态的 sprite#2绘制到第三个画布中。

在绘制之后,第三幅画布包含sprite#1和sprite#2的碰撞部分

测试第三个画布中的每个像素是否有非透明像素。 如果发现任何不透明的像素,则说明这2个精灵在收集中。

根据要在碰撞时采取的操作,找到第一个碰撞像素后,您可能会纾困。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM