使用JavaScript和canvas做精确的像素碰撞检测

作者:Benjamin Horn

原文地址:Pixel accurate collision detection with Javascript and Canvas

我正在开发一个又要使用碰撞检测的游戏。我通常会使用简单高效的盒模型碰撞检测。盒子模型的主要原则就是把所有的物体都抽象成正方形,如果两个正方形有重叠,就认为是一次碰撞。这通常是一个简单的游戏所需要的。但是因为这种模型我之前用过多次,我想尝试一些更深刻更准确的方法。

我选择从像素级层面来看是否发生了碰撞。首先我要了解“像素是什么”。我尝试的元素透明度都不为0,换句话说,所有的可见像素都被看做一个碰撞点。为了提高算法效率,我预先创建了一张图片的像素映射图。换句话说,就是一个数组内包含了屏幕上的所有可见像素。

    /* 描述像素图的伪代码 */
    var pixelMap = [];
    for( var y = 0; y < image.width; y++ ) {
        for( var x = 0; x < image.height; x++ ) {
            // 获取当前位置的元素
            var pixel = ctx.getImageData( x, y, 1, 1 );
            // 检查透明度不为0
            if( pixel.data[3] != 0 ) {
                pixelMap.push( { x:x, y:y } );
            }
        }
    }
    return pixelMap;

用这种方法,一张小图片会变得很大。一张40X40的图片会有1600像素,所以如果我在一个很大的canvas上做碰撞检测将会非常缓慢。测试之前我先将盒子模型重叠起来,如果点击测试返回true,我会进一步测试是否有像素重叠。这意味着我们只需要测试一次。

    /* 盒模型测试, 碰撞返回 true */
    function hitBox( source, target ) {
        /* 源物体和目标物体都包含 x, y 以及 width, height */
        return !(
            ( ( source.y + source.height ) < ( target.y ) ) ||
            ( source.y > ( target.y + target.height ) ) ||
            ( ( source.x + source.width ) < target.x ) ||
            ( source.x > ( target.x + target.width ) )
        );
    }

如果hitBox函数返回true,我们需要比较两个物体的预渲染像素图。然后我们需要测试源物体的每一个像素是否与目标物体的像素有重叠。这是一个非常耗时耗能的函数。

。。。

    /* 像素碰撞检测的伪代码 */
    function pixelHitTest( source, target ) {
        // 循环源图像的所有像素
        for( var s = 0; s < source.pixelMap.length; s++ ) {
            var sourcePixel = source.pixelMap[s];
            // 添加位置偏移
            var sourceArea = {
                x: sourcePixel.x + source.x,
                y: sourcePixel.y + source.y,
                width: 1,
                height: 1
            };

            // 循环目标图像的所有像素
            for( var t = 0; t < target.pixelMap.length; t++ ) {
                var targetPixel = target.pixelMap[t];
                // 添加位置偏移
                var targetArea = {
                    x: targetPixel.x + target.x,
                    y: targetPixel.y + target.y,
                    width: 1,
                    height: 1
                };

                /* 使用之前提到的 hitbox 函数 */
                if( hitBox( sourceArea, targetArea ) ) {
                    return true;
                }
            }
        }
    }

未完

时间: 2024-10-17 02:31:07

使用JavaScript和canvas做精确的像素碰撞检测的相关文章

JavaScript之Canvas画布

canvas可以在页面中设定一个区域,再利用JavaScript动态地绘制图像. 基本用法 使用canvas元素,首先设置width和height属性,为其设置绘制区域的大小,   如果没有设置宽度和高度,是看不到元素的,不能在其区域画图,在开始标签和结束标签之间的信息是后备信息,当用户的浏览器不支持canvas元素时会显示,用于友好地提示用户. <canvas id="canvas" width="400" height="300">

html5 canvas做的图表插件

用highchart的时候发现它是用svg来画图的,那么用canvas来做怎么样的. 以前做AS图表插件的时候,绘制图画主要用容器的Graphics对象来绘制,而canvas的context和Graphics一样,都可以用来绘制图形. 然后就试着用canvas做了这样一个东西. 具体实现如下,个人表达能力有问题,各位看官还是看源码吧,如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-T

HTML5 canvas 做画板画图 可以做电子白板

HTML5 canvas 做画板画图 可以做电子白板 <html> <head> <meta charset="utf-8"> <title>HTML5 canvas 做画板画图 可以做电子白板</title> <style type="text/css"> <!-- #container { position: relative;} #imageView { border: 1px so

canvas做的时钟,学习下

canvas标签只是图形容器,您必须使用脚本来绘制图形. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性.——获取上下文对象. getContext("2d") 对象属性和方法,可用于在画布上绘制文本.线条.矩形.圆形等等. fillRect(l,t,w,h):默认颜色是黑色 strokeRect(l,t,w,h):带边框的方块.默认一像素黑色边框 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. beginP

使用JavaScript和Canvas打造真实的雨滴效果

使用JavaScript和Canvas打造真实的雨滴效果 寸志 · 1 年前 我最近搞了一个有趣的项目——rainyday.js .我认为这个项目并不怎么样,而且,事实上这是我第一次尝试接触一些比弹窗更复杂的JavaScript.幸好,你们觉得它还有点意思.rainyday.js想创建一个轻量的JavaScript类库,利用HTML5的canvas,来实现雨滴在玻璃上滑落的效果.很简单,不过有时候还是很有挑战的,尤其是在我们既要尽力避免动画区别于通常JavaScript的动画,又要保证动画流畅运

我们能用canvas做什么?

什么是Canvas? Canvas元素是HTML5的一部分,允许脚本语言动态渲染位图像.Canvas由一个可绘制地区HTML代码中的属性定义决定高度和宽度.JavaScript代码可以访问该地区,通过一套完整的绘图功能类似于其他通用二维的API,从而生成动态的图形. 我们能用Canvas做些什么? 1. 游戏:毫无疑问,游戏在HTML5领域具有举足轻重的地位.HTML5在基于Web的图像显示方面比Flash更加立体.更加精巧,我认为运用Canvas制作的图像能够令HTML5游戏在流畅度和跨平台方

HTML5 Canvas 获取网页的像素值。

我之前在网上看过一个插件叫做出JScolor   颜色拾取器  说白了就是通过1*1PX的DOM设置颜色值通过JS来获取当前鼠标点击位置DOM的颜色值. 自从HTML5 画布出来之后.就有更好的方法来获取了,比如郭阿里巴巴ICON矢量库 用的SVG和渐变来进行绘制: 我昨天用Canvas来绘制了一下,因为Canvas有现成的方法getImageData(x,y,width,height);这个方法返回一个属性data数组,也就是CanvasPixelArray 1个像素分别有四个值rgba(红,

除了Web和Node,JavaScript还能做什么

前言 提起JavaScript,我们也许经常会想到的是,可以用来写Web页面嘛,又或者,会想起Node.js 这个服务端环境,搞前后端同构. 那么,除此之外, JavaScript还可以做什么? JavaScript可以 通过electron.js建设跨平台电脑桌面应用 通过树莓派和Node.js,沟通硬件 做电视机机顶盒应用,例如借助ntv.js 从Hybird到React-Native,编写跨平台的混合APP,或者原生APP 通过Cocos2d-x 框架或白鹭引擎,JS可以开发流行游戏 JS

用H5的canvas做时钟

<!doctype html><html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <canvas id="can1" width="500px" height="500px"></canvas> <scr