매트릭스는 인접한 스프라이트에서 변형되어 서브 픽셀 간격을 유발합니다
-
13-09-2019 - |
문제
나는 서로 위에 쌓인 3 개의 스프라이트가 있습니다.
나는 그들의 변형을 수정하여 그들이 일제히 성장하는 외관을 제공하기 위해 matrix를 수정합니다.
그러나 스케일링 계수에 따라 타일 사이에 작은 균열이 나타납니다.
스프라이트 사이의 균열 http://img21.imageshack.us/img21/7518/cracks.png
이것을 고치는 방법이 궁금합니다.
나는 그것을 알고있다 AS3의 텍스트 개체에는 서브 픽셀 렌더링 옵션이 있습니다. 아마도 모든 AS3에 대해 비슷한 설정이 존재합니까? 다른 아이디어?
작동하지 않는 전술 : Cacheasbitmap.
package
{
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import mx.core.UIComponent;
public class tmpa extends UIComponent
{
private var _scale:Number;
private var _s1:Sprite;
private var _s2:Sprite;
private var _s3:Sprite;
private var _s1Pt:Point;
private var _s2Pt:Point;
private var _s3Pt:Point;
private var _tileDim:int;
public function tmpa( ):void
{
_scale = 1;
_tileDim = 100;
_s1 = new Sprite();
_s2 = new Sprite();
_s3 = new Sprite();
paintSprite( _s1, _tileDim );
paintSprite( _s2, _tileDim );
paintSprite( _s3, _tileDim );
_s1Pt = new Point( 100, _tileDim );
_s1.x = _s1Pt.x;
_s1.y = _s1Pt.y;
_s2Pt = new Point( 100, _tileDim*2 );
_s2.x = _s2Pt.x;
_s2.y = _s2Pt.y;
_s3Pt = new Point( 100, _tileDim*3 );
_s3.x = _s3Pt.x;
_s3.y = _s3Pt.y;
addChild( _s1 );
addChild( _s2 );
addChild( _s3 );
scale = 1.0394; //cracks
//scale = 1.0306; // nocracks
}
private function paintSprite( s:Sprite, dim:int, color:int=0xFF0000 ):void
{ s.graphics.beginFill( color, .5 );
s.graphics.drawRect( 0, 0, dim, dim );
s.graphics.endFill( );
}
public function set scale( s:Number ):void
{ _scale = s;
var scaleFromPt:Point = new Point( 20, 20 );
updateSpriteMatrix( _s1, _s1.globalToLocal(scaleFromPt), _s1Pt );
updateSpriteMatrix( _s2, _s2.globalToLocal(scaleFromPt), _s2Pt );
updateSpriteMatrix( _s3, _s3.globalToLocal(scaleFromPt), _s3Pt );
}
public function get scale( ):Number
{ return _scale;
}
private function updateSpriteMatrix( t:Sprite, ctrPt:Point, regPt:Point ):void
{ var mx:Matrix = t.transform.matrix;
mx.identity();
mx.scale( _scale, _scale );
mx.translate( ctrPt.x*(1-_scale), ctrPt.y*(1-_scale));
mx.translate( regPt.x, regPt.y );
t.transform.matrix = mx;
}
}
}
그리고 MXML :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:a="*"
width="100%" height="100%"
paddingTop="0" paddingBottom="0" paddingLeft="0" paddingRight="0"
backgroundColor="0x000000"
backgroundGradientAlphas="undefined">
<a:tmpa id="t" width="100%" height="100%" x="0" y="0" left="0" top="0"/>
</mx:Application>
해결책
간격이있는 이유는 반올림 오류 때문입니다. 플래시는 요소 만 픽셀 (TWIP)의 20 개로 배치 할 수 있습니다. 당신은 y 위치를 설정하고있었습니다
- 3.152000000000008
- 7.092000000000018
- 11.032000000000028
각기. 분명히 이것은 20 대보다 훨씬 정확합니다. 반올림이 발생하면 오류가 발생하기 쉽습니다.
제 생각에는 모든 품목을 다른 컨테이너 내부에 넣은 다음 컨테이너를 스케일링해야합니다. 하나의 변환 만 수행하는 방식이지만 동일한 결과를 얻습니다.
그러나 어떤 상황에서는이 방법이 필요할 수 있음을 이해합니다. 이것을 반올림하는 방식은 먼저 모든 척도 변환을 수행하는 것입니다. 그런 다음 이전 스프라이트에 대한 번역을 수행하십시오. 그렇게하면 항상 이전에 둥근 물약을 기반으로합니다. 다음은 수업에서 해킹 된 빠른 예입니다. 분명히 이것을 정리하는 방법에는 여러 가지가 있지만 단순성을 위해 일하는 방식으로 장난감을 붙잡 으려고 노력했습니다.
package
{
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import mx.core.UIComponent;
public class tmpa extends UIComponent
{
private var _scale:Number;
private var _s1:Sprite;
private var _s2:Sprite;
private var _s3:Sprite;
private var _s1Pt:Point;
private var _s2Pt:Point;
private var _s3Pt:Point;
private var _tileDim:int;
public function tmpa( ):void
{
_scale = 1;
_tileDim = 100;
_s1 = new Sprite();
_s2 = new Sprite();
_s3 = new Sprite();
paintSprite( _s1, _tileDim );
paintSprite( _s2, _tileDim );
paintSprite( _s3, _tileDim );
_s1Pt = new Point( 100, _tileDim );
_s1.x = _s1Pt.x;
_s1.y = _s1Pt.y;
_s2Pt = new Point( 100, _tileDim*2 );
_s2.x = _s2Pt.x;
_s2.y = _s2Pt.y;
_s3Pt = new Point( 100, _tileDim*3 );
_s3.x = _s3Pt.x;
_s3.y = _s3Pt.y;
_s1.transform.matrix = new Matrix();
_s2.transform.matrix = new Matrix();
_s3.transform.matrix = new Matrix();
addChild( _s1 );
addChild( _s2 );
addChild( _s3 );
scale = 1.0394; //cracks
//scale = 1.0306; // nocracks
}
private function paintSprite( s:Sprite, dim:int, color:int=0xFF0000 ):void
{ s.graphics.beginFill( color, .5 );
s.graphics.drawRect( 0, 0, dim, dim );
s.graphics.endFill( );
}
public function set scale( s:Number ):void
{ _scale = s;
scaleSpriteMatrix( _s1 );
scaleSpriteMatrix( _s2 );
scaleSpriteMatrix( _s3 );
translateSprite(_s2, _s1);
translateSprite(_s3, _s2);
}
public function get scale( ):Number
{ return _scale;
}
private function scaleSpriteMatrix( targetSprite:Sprite):void
{ var mx:Matrix = targetSprite.transform.matrix;
mx.scale( _scale, _scale );
targetSprite.transform.matrix = mx;
}
private function translateSprite( targetSprite:Sprite, basedOnSprite:Sprite):void
{ var mx:Matrix = targetSprite.transform.matrix;
mx.translate( basedOnSprite.x, basedOnSprite.y + basedOnSprite.height);
targetSprite.transform.matrix = mx;
}
}
}
도움이되기를 바랍니다
제임스