2011-04-09 59 views
1

所以我创建使用按钮引擎的经典侧滚轮艺术资产(http://www.pushbuttonengine.com),我想在“世界”位是任意给定的大小,当然,重复/瓦片我的艺术资产。我有以下渲染设置的代码作为开始:按钮引擎 - 重复/平铺整个精灵

var Render:SpriteRenderer = new SpriteRenderer();                    
Render.positionProperty = new PropertyReference("@Spatial.position"); 
Render.sizeProperty = new PropertyReference("@Spatial.size"); 
Render.fileName = "./media/brick.png"; 
Render.scene = PBE.scene; 
Render.layerIndex = 1; 

然而,这只是需要brick.png和伸展/收缩以填充物的大小。瘸。 :)我花了一堆时间试图谷歌如何做到这一点,但我可能没有得到正确的条款或一些诸如我没有提出任何东西。主要是关于使用PBE构建基于瓦片的游戏的文章。

虽然我敢肯定我能砍在一起的东西,会做的伎俩,我要确保我在做正确的方式,这样我获得最佳的性能,什么不是。任何提示我应该在哪里寻找这个标准效应?

感谢, 布拉德

回答

1

一些flubbing约并将该溶液是合适地微不足道的。

public class TiledBitmapRenderer extends BitmapRenderer 
{  
    public function TiledBitmapRenderer(bitmap:Bitmap, width:int, height:int) 
    { 
     super(); 

     positionOffset = new Point(width/-2,height/-2); 

     var cx:int = Math.ceil(width/bitmap.width); 
     var cy:int = Math.ceil(height/bitmap.height); 
     bitmapData = new BitmapData(width, height, false, 0x000000); 

     // fill the bitmapData object with all display info with the provided bitmap 
     for (var ix:int = 0; ix<cx; ix++) { 
      for (var iy:int = 0; iy<cy; iy++) 
       bitmapData.copyPixels(bitmap.bitmapData,bitmap.bitmapData.rect, new Point(ix*bitmap.width,iy*bitmap.height)); 
     } 
    } 
} 
1

颜色我brad在这方面做了一个很好的尝试 - 它让我想到了这个问题。

重写BitmapRenderer以允许因为由渲染器组件所做的更改与矩阵执行平铺是棘手的。我写了一个忽略缩放的类,而是根据需要创建一个具有更大物理尺寸的新位图。

下面的解决方案确实带来了一些小的限制:我已经四舍五入缩放变化并在1位小数检查变化,以(试验证明了这有时是特定的比例比机构有必要)。

其次,因为我们重绘每次尺度的变化,它可能不是A S以及优化的,好像我们刚刚更新矩阵规模。

但是 - 它仍然是非常快的,真正到了PBE“哲学”,而我高兴地在游戏中现在使用它。

package render 
{ 
    import com.pblabs.engine.PBUtil; 
    import com.pblabs.rendering2D.BitmapRenderer; 
    import com.pblabs.rendering2D.SpriteRenderer; 

    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Graphics; 
    import flash.display.Sprite; 
    import flash.geom.Matrix; 
    import flash.geom.Point; 
    import flash.geom.Rectangle; 
    import flash.geom.Vector3D; 

    /** 
    * Creates a tiles bitmap. The tile is identified as the first bitmap parameter set when this component is created. 
    */ 
    public class TileRenderer extends BitmapRenderer 
    { 
     public function TileRenderer() 
     { 

      super(); 
     } 

     protected var lastScaleX:Number = undefined; 
     protected var lastScaleY:Number = undefined; 

     // the original bitmap contains the single tile we will reuse to fill out the bitmap 
     protected var originalBitmapData:BitmapData; 


     /** 
     * Just set this to the tile you want to reuse. It will automatically figure out tile width and height. 
     */ 
     override public function set bitmapData(value:BitmapData):void{ 


      if (value === bitmapData) 
       return; 

      originalBitmapData = value; 

      bitmap.bitmapData = advanceRender(value.width, value.height); 

      // Due to a bug, this has to be reset after setting bitmapData. 
      smoothing = _smoothing; 

      // set registration point to get spritesheet-component-style centering 
      registrationPoint = new Point(value.width/2,value.height/2);  

      _transformDirty = true; 


     } 

     /** 
     * tile the original bitmap across a new bitmap area 
     * the following is adapted from http://stackoverflow.com/users/102373/colour-me-brad: 
     */ 
     protected function advanceRender(targetWidth:Number, targetHeight:Number):BitmapData{ 

      var target:BitmapData = new BitmapData(targetWidth,targetHeight, true,0x00000000); 

      var cx:int = Math.ceil(target.width/originalBitmapData.width); 
      var cy:int = Math.ceil(target.height/originalBitmapData.height); 

      target = new BitmapData(target.width, target.height, true, 0x000000); 


      // fill the bitmapData object with all display info with the provided bitmap 
      for (var ix:int = 0; ix<cx; ix++) { 
       for (var iy:int = 0; iy<cy; iy++) 
        target.copyPixels(originalBitmapData,originalBitmapData.rect, new Point(ix*originalBitmapData.width,iy*originalBitmapData.height)); 
      } 
      return target; 
     } 


     /** 
     * heavily override this function to avoid changing scale. We instead redraw the 
     * bitmap to the correct width and height. 
     */ 
     override public function updateTransform(updateProps:Boolean = false):void 
     { 

      if(!displayObject) 
       return; 

      if(updateProps) 
       updateProperties(); 

      // If size is active, it always takes precedence over scale. 
      var tmpScaleX:Number = _scale.x; 
      var tmpScaleY:Number = _scale.y; 
      if(_size) 
      { 
       var localDimensions:Rectangle = displayObject.getBounds(displayObject); 
       tmpScaleX = _scale.x * (_size.x/localDimensions.width); 
       tmpScaleY = _scale.y * (_size.y/localDimensions.height); 
      } 


      _transformMatrix.identity(); 
      //_transformMatrix.scale(tmpScaleX, tmpScaleY); 
      _transformMatrix.translate(-_registrationPoint.x * tmpScaleX, -_registrationPoint.y * tmpScaleY); 
      _transformMatrix.rotate(PBUtil.getRadiansFromDegrees(_rotation) + _rotationOffset); 
      _transformMatrix.translate(_position.x + _positionOffset.x, _position.y + _positionOffset.y); 


      if (getRoundDecimal(tmpScaleX,1) != 1 || getRoundDecimal(tmpScaleY,1) != 1) { 


       bitmap.bitmapData = advanceRender(originalBitmapData.width*tmpScaleX, originalBitmapData.height * tmpScaleY); 
       smoothing = _smoothing; 

       // set registration point to get spritesheet-component-style centering 
       registrationPoint = new Point(bitmap.bitmapData.width/2,bitmap.bitmapData.height/2); 

      } 

      displayObject.transform.matrix = _transformMatrix; 
      displayObject.alpha = _alpha; 
      displayObject.blendMode = _blendMode; 
      displayObject.visible = (alpha > 0); 


      _transformDirty = false; 

     } 


     /** 
     * taken from: http://swordfish1987.wordpress.com/2009/07/10/decimal-rounding-in-actionscript-3/ 
     */ 
     public static function getRoundDecimal(num:Number, precision:int):Number{ 

      var decimal:Number = Math.pow(10, precision); 

      return Math.round(decimal* num)/decimal; 

     } 

     override protected function onRemove():void{ 
      originalBitmapData = null; 
      super.onRemove(); 
     } 
    } 
}