안녕하세요, 명랑늑대입니다. 이 카페에 가입한 후 첫 글을 남기게 되네요.
저는 최근에 Sprite을 상속한 클래스를 구현하다가 width, height(Sprite 클래스에 정의된 프라퍼티들)의 값을 생성자에서 변경하는 것이 잘 안 되는 문제를 겪었습니다.
카페를 검색해보니, 거친마루 님께서도 같은 문제를 겪으션던지 질문을 올리셨더군요.
http://cafe.naver.com/flexcomponent/2034
그런데 아직 해결되지 않은 의문인 건 같아서, 제가 좀더 파고 들어봤습니다.
Sprite 객체의 width/height 값을 변경하면 내부적으로 어떤 일이 일어나는가?
var aSprite:Sprite = new Sprite();
....
aSprite.width = 100;
위와 같이 Sprite 객체의 width 프라퍼티에 새 값을 대입하면, width의 값이 바뀌는 것으로 끝나지 않습니다.
Sprite
에 정의된 scaleX, scaleY도 함께 변합니다(사실은 그 외에도 함께 바뀌는 프라퍼티들이 여럿 더 있습니다만, 이번
논의와는 직접적인 관련이 없으므로 언급하지 않겠습니다). 아시다시피 scaleX, scaleY는 스케일링에 관련된 놈들이죠.
그렇다면 width 값을 바꾸려고 했을 뿐인데, 왜 스케일링에 관련된 프라퍼티들이 *자동으로* 바뀌는가?
이는 전형적인 GUI 컴포넌트의 크기를 바꾸는 것과 Sprite의 크기를 바꾸는 행위가 전혀 다른 의미를 내포하고 있기 때문이라고 할 수 있습니다.
예를 들어, 여러 개의 하위 컴포넌트가 들어있는 컨테이너의 크기를 바꾸면 어떤 일이 일어나나요?
하위 컴포넌트들의 크기도 함께 변할 것입니다(아닐 수도 있지만). 심지어는 컴포넌트들의 배치가 달라지기도 합니다. 그래서
레이아웃의 개념이 들어가죠. 즉, 컨테이너의 크기가 바뀐 비율과는 상관없이 레이아웃 정책에 의해 너비만 늘어나거나 위치가
바뀌거나 합니다.
그러나 Sprite은 전통적인 의미에서의 GUI 컴포넌트가 아닙니다. 레퍼런스 문서에도 설명되어 있듯이 일종의 MovieClip이죠.
동영상 재생기의 윈도우 크기를 바꾸면 어떻게 됩니까? 재생하고 있는 동영상의 화면 크기가 그에 맞춰 스케일링 됩니다. 이건 상식적으로도 당연한 행동입니다.
Sprite
의 행동도 이와 마찬가지입니다. Sprite의 크기를 바꾸면 그 자신이 화면에 그리는 내용은 물론이고 그 Sprite에
속해있는(아시다시피 Sprite은 DisplayObjectContainer입니다) 하위 DisplayObject들까지도 스케일링
됩니다.
즉, Sprite의 크기가 바뀌면 그 Sprite은 물론이고 다른 DisplayObject들의 스케일링까지 바꿔야 하므로,
크기가 얼마나 변했는지를 기억하고 있어야 합니다. 따라서 해당 프라퍼티인 scaleX, scaleY가 크기 변화와 함께 바뀌는
것이 당연하겠죠?
따라서 Sprite을 상속받은 클래스의 생성자에서 width/height의 값을 바꾸면 아무 소용이 없습니다.
왜냐하면, width/height의 초기값은 0이기 때문입니다.
예를 들어, width에 100을 대입하려고 하면 scaleX = newWidth / oldWidth이므로(정확한 공식은
아닙니다. scaleX의 이전 값을 고려해야 하죠 원래는) 100 / 0 = NaN, 즉 scaleX가 0이 됩니다.
그리고 width 값은 scaleX가 계산된 후에 scaleX * oldWidth가 되는 것 같습니다.
따라서 또한 0이 될 수 밖에 없죠.
(이 부분은 Sprite의 소스 코드가 없어서 확실하진 않습니다만, 개인적으로는 이렇게 추측합니다. 왜 그렇게 하는지는 모르겠구요. ㅎㅎ)
그리고 우리를 더 힘들게 만드는 문제점은 위와 같이 생성자에서 width/height에 값을 대입하고 나면, 이후에 무슨 짓을 해도 해당 Sprite이 화면에 나타나지 않는다는 점입니다.
scaleX 또는 scaleY가 0이 되므로 화면에 나타나지 않는게 당연합니다.
아시다시피 Sprite에 다른 DisplayObject를 add하거나 graphics에 뭔가를 그리면 Sprite의 width/height이 자동으로 바뀌지만, 스케일 팩터가 0이므로, 곱하고 나면 그릴 영역이 없습니다.
그렇다면 Sprite의 width/height 값은 언제 세팅하면 되는 것일까?
물론 width/height가 0이 아닐 때 세팅하면 되겠습니다. 즉, Sprite을 상속해서 만든 객체의 크기를 세팅하고
싶을 때에는 좀 귀찮지만 그 Sprite의 내용(하위 DisplayObject 또는 graphics에 직접 그린 내용)이 완성된
후에 하는 것이 가장 좋을 듯 합니다.
** 글을 쓰다보니 좀 길어졌네요.
혹시 UIComponent가 아니라 Sprite을 상대하다가 이런 비슷한 문제를 겪으신 분들께 조금이나마 도움이 됐으면 좋겠습니다.
댓글 정보
인민군 :
width는 html에서도 흔히 사용하는 픽셀단위의 고정값이라고 한다면
scale은 0~1까지의 백분율 값입니다.
이 두 속성의 차이는 단지 단위의 차위라고 생각하시는게 편하지 않을까 하는데요. |