【问题标题】:How to detect if the area was 100% painted in as3如何检测该区域是否在 as3 中 100% 绘制
【发布时间】:2013-02-27 11:52:22
【问题描述】:

我正在制作一款模拟泛行业的游戏,其中一个过程是绘画。

我想做的是让玩家画平底锅,但我不希望使用 FILL 很容易,我希望玩家用刷子画平底锅,然后游戏检测是否所有区域被画了,让玩家前进。

对于这幅画我打算使用那个库:http://www.nocircleno.com/graffiti/

但我不知道如何检测是否所有区域都已涂漆。有人可以告诉我一些方法吗?

【问题讨论】:

    标签: actionscript-3 flash bitmap paint bitmapdata


    【解决方案1】:

    您可以遍历BitmapData 上的像素并使用getPixel() 检查所有这些像素的颜色是否不是白色。如果找到一个白色的,则图像未完全绘制。

    类似这样的:

    function containsWhite(bitmapData:BitmapData):Boolean
    {
        for(var c:int = 0; c < bitmapData.width; c++)
        {
            for(var r:int = 0; r < bitmapData.height; r++)
            {
                // Check if pixel is white.
                if(bitmapData.getPixel(c, r) >= 0xFFFFFF)
                {
                    return true;
                }
            }
        }
    
        return false;
    }
    

    【讨论】:

    • 值得注意的是,虽然这是正确的过程,但它在处理器上也是一个非常繁重的过程,并且可能非常慢,具体取决于位图的大小。
    • 确实如此 - 您可以将较大的图像分解成块,然后分别对每个块执行检查。评估完所有块后,您可以实施回调以接受真/假响应。这是异步方法的一个很好的候选:)
    • 老实说,这是一个很好的卸载到工人或 PixelBender 的候选者。不过,显然您只能使用工作人员来处理非移动项目。
    • @user2159322 您可以接受答案,这也会提高您的声誉。
    • @Apocalyptic0n3 我不知道这是否可以卸载到 Pixel Bender,因为 PB 着色器根据提供的图像数据返回每个像素的值,这里只需要一个合并值。不过,PB 可以为您简化图像,例如为每个非白色像素返回一个黑色像素,这样您就可以更安全地使用 histogram()
    【解决方案2】:

    您本质上是在处理碰撞检测问题。通过查看他们的 API,您可以尝试使用 getColorAtPoint 进行 for 循环之类的操作,并尝试确定它们已在每个像素处绘制。

    如果所有其他方法都失败,请查看库使用对象的 .hitTestObject 方法生成的对象之间的冲突。

    看到这个:http://sierakowski.eu/list-of-tips/39-collision-detection-methods-hittest-and-hittestobject-alternatives.html

    看看有人如何处理与像素的碰撞:http://www.emanueleferonato.com/2010/08/05/worms-like-destructible-terrain-in-flash-part-2/

    【讨论】:

      【解决方案3】:

      其中一种方法是 - 您制作一个具有透明性且不透明的屏蔽 BitmapData,您需要您的播放器进行绘制。 (根据需要着色,但确保颜色完全不透明)。然后收集histogram() 然后查询 alpha 向量的第 255 个值,这将是填充百分比为零的初始值。这些范围为 0-255,因此您不能使用 100 或任何其他固定值。然后,当玩家在绘画时,您在该 BitmapData 上绘制画笔,并将 blendMode 参数设置为 BlendMode.ERASE,这将使您的 BitmapData 获得画笔绘制位置的透明度。在您的播放器以任何方式完成绘制后(例如,油漆用完),您在 BitmapData 上运行另一个 histogram(),并查询 alpha 通道向量的第 255 个值。 0 表示位图是完全透明的(或者至少,只有少量像素不透明),因此您可以将零算作 100% 填充,如果更大,请使用该比例。

      var bd:BitmapData=new BitmapData(w,h,true,0x0); // fully transparent initial bitmap
      bd.draw(yourPaintBase); // a shape that designates area to be painted. Must be fully opaque
      var bm:Bitmap=new Bitmap(bd);
      // position it as needed, so the area which should be painted is aligned to wherever you need
      addChild(bm);
      addEventListener(Event.ENTER_FRAME,doPaint);
      var baseValue:int=bd.histogram()[3][255]; // Vector #3 contains alpha, #255 contains 
      // percentage of those pixels that have alpha of 255 = fully opaque
      function doPaint(e:Event):void {
          if (!areWePainting) return;
          var sh:Shape=getBrush(); // shuold return an existing Shape object reference for performance
          sh.x=e.localX;
          sh.y=e.localY; // we are drawing where the mouse is
          bd.draw(sh,null,null,BlendMode.ERASE);
          decreasePaint(); // we have used some paint
          if (noMorePaint()) {
              e.target.removeEventListener(Event.ENTER_FRAME,doPaint);
              var endValue:int=Math.floor(100*(1-bd.histogram()[3][255]/baseValue));
              // aligning to percentage. This is the value you seek
              reportFilledPercentage(endValue);
          }
      }
      

      【讨论】:

      • 你的答案对我来说比另一个难一点。 .但如果我掌握了你的做法,我可以将我想要的图像放在盾牌后面。我会先尝试您的答案,如果它对我来说太复杂,我会尝试另一个。我不能投票给你的答案。我会尽力帮助一些人,当我有 15 名声望时,我肯定会支持你。
      猜你喜欢
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 2021-06-08
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多