[ActionScript] Array의 원소 추가/삭제

배열의 탈을 쓴 액션스크립트의 Array에 원소를 추가하고  삭제하는 매서드가 바로 splice라는 녀석인데.. 이 놈의 성질을 보다 명확히 파악하고 작업을 진행해야겠기에.. 정리를 해봅니다.

배열의 탈을 썼다는 의미는.. 아무리 봐도 이 Array는 배열이라고 하기 어려운 놈이라고 생각되기 때문입니다. 이 부분에 대해서는 다음 기회에 더 논하기로 하고… 이 Array에 원소를 중간에 추가하거나 중간의 원소를 삭제하는 매서드가 바로 splice입니다.

이 Array의 splice를 이용해 이떤 기능을 개발하고 있는데… 뭔가 작동이 제대로 의도하는 바대로 되지 않습니다.. Array에 대한 기본이 부족한 탓이기에 이 Array의 splice에 대해 살펴봅니다. 먼저 Array 타입의 변수에 다음과 같은 원소들이 담겨져 있다고 해 보겠습니다.

사용자 삽입 이미지
즉, 총 6개의 원소로 구성되어져 있으며 첫번째 원소는 배열 인덱스 0부터입니다. 이 초기 상태에서 다음과 같은 매서드를 호출하면…

v.splice(0, 0, 'a');

결과는 다음과 같습니다..

사용자 삽입 이미지
즉, 첫번째 자리에 a 값을 추가할 수 있습니다. 그리고 다시 초기 상태로 돌아가서… 다시 다음 코드를 호출하면..

v.splice(99, 0, 'a');

결과는 다음과 같습니다.

사용자 삽입 이미지
99번째 인자는 너무 커서 존재하지 않는 인자임에도 불구하고 인자하게도.. 가장 마지막에 a 값을 추가해 줍니다.. 그리도 또 다시 초기 상태로 돌아가서.. 다음 코드를 호출하면..

v.splice(2, 0, 'a');

결과는 다음과 같습니다.

사용자 삽입 이미지
2번째 인덱스 바로 앞에서 a 값이 추가됩니다..

이제.. 다시 초기 상태로 돌아가서 원소를 삭제하는 다음 코드를 실행해보면..

v.splice(2, 1);

결과는 다음과 같습니다..

사용자 삽입 이미지
정확히 지정한 2번 인덱스를 제거합니다.. 인덱스가 옳바르지 않을 경우 어떠한 에러도 발생하지 않고 원소들을 변경시키지 않습니다..

이제 정리가 끝났으니… 다시 코딩단으로……

[ActionScript] Event 클래스의 target과 currentTarget 속성

플래시의 기능을 최대한 할용하고는 있지만… 플래시가 자동으로 처리해주는 것보다는… 퍼포먼스 향상을 목표로 부하를 최소화하기 위해.. 수동으로 처리해주는 기능들이 있습니다..

예를 들어서 Sprite 클래스가 가지고 있는 자식들 각각에 대해 클릭 이벤트를 받아 오기 위해.. 각 자식들에 대해 마우스 이벤트를 등록(addEventListener)를 하지 않고… 부모 Sprite에만 마우스 이벤트를 등록해 놓고.. 이 부모의 이벤트에서 자식들의 클릭 여부(hitTestPoint 매서드를 사용)를 가려내고자 함입니다..

이때… 클릭한 지점에 대한 좌표가 여러 모로 혼란스럽습니다… 플래시 자체가 DisplayObject라는 레이어로 첩첩히 쌓여져 있어서… 말입니다.. 여담이지만.. GIS의 지도 레이어 개념과 플래시의 DisplayObject의 대응은 마치 플래시를 맵엔진을 위해 만들어지 개발환경이 아닌가할 정도로… 뛰어납니다…

다시 본론으로 돌아와서… 부모 Sprite에서 받은 마우스 클릭 위치에 대해서 자식 Sprite의 hit 여부를 알아내기 위해서는 마우스 이벤트의 인자인 Event 클래스의 target를 제대로 이해하고 있어야 합니다.. target와 함께 currentTarget 속성이 존재하는데.. 간단히 정리하면 다음과 같습니다..

  • target : 이벤트를 dispatch한 객체
  • currentTarget : 이벤트 핸들러 함수가 등록된 객체

다음 코드는 진행중인 플래시 기반의 맵엔진의 코드중.. 이와 관련된 부분입니다..

public function mouseClick(e:MouseEvent):void
{
    ....

    if(_targetLyr != null)
    {
        var pt:Point = new Point(e.localX, e.localY);
        pt = (e.target as DisplayObject).localToGlobal(pt);

        // 내부적으로 Sprite의 hitTestPoint(pt.x, pt.y)가 사용됨
        _sketch = _targetLyr.getIdByPoint(pt.x, pt.y);
        if(_sketch != null)
        {
            _sketch.draw(_map.coordMapper);

           ....
        }
    }

    ....
}

보시면… 위의 mouseClick 매서드는 이벤트가 아닙니다.. 단지 mouseDown과 mouseUp 이벤트를 조합해서 클릭 여부에 대해 형성된 이벤트 성격의 매서드입니다.. 여튼.. 이벤트라고 생각하셔도 무방합니다..

이 mouseClick 매서드는 부모 Sprite의 소유입니다.. 즉, 달리 말해 부모 Sprite에 등록된 이벤트입니다. 이때 받은 e 매개변수에 localX과 localY 좌표는 클릭된 위치이고… 클릭된 위치는.. 부모 Sprite일수도 있고… 자식 Sprite일수도 있습니다.. 즉, 이 이벤트가 등록된 부모에 대한 좌표가 아니라는 점입니다..

문제는 Sprite의 hitTestPoint가 받는 x, y 좌표입니다.. 받는 x, y 좌표는 부모 Sprite의 좌표여야 하는데.. e를 통해 넘어온 좌표는 부모의 좌표일수도.. 자식의 좌표일 수도 있다는 점입니다.. 이를 부모의 좌표로 통일해줘야 하는데.. 그 방법이 바로 8번 코드의 target를 속성을 사용하는 것입니다.

플래시의 DisplayObject의 개념과 target 속성에 대한 기본적인 부분을 알면 매우 당연한 내용이겠지만…. 저처럼.. 플래시에 대한 개념이 얕은 사람은.. 매우 혼돈스러운 부분이 아닐까 싶습니다..

플래시로 만들어본 간단한 파티클 시스템

이제 곧.. RIA 기반의 GIS 엔진 개발을 시작하게 됩니다.. 몇가지 RIA 기술중(JavaFX, SilverLight, Flash)에 Flash를 선택하였고.. 이 선택에 있어서 여러가지 고민도 많았지만.. 이제 RIA 기술에 대한 선택의 고민은 더 이상한 불필요할듯하고.. 본격적으로 개발에 들어갑니다.

아마도 이 제품에 대한 개발을 위해 기본적인 설계와 자료 수집을 위해 대략 어느 정도의 시간이 소요될 것이고.. 3~4개월 정도의 시간을 들여 기본적인 형태의 RIA 기반의 지도 솔루션(코드명, FingerEyes-Xr)을 개발할테구요..

시작에 앞서 플래시를 이용하여 간단한 파티클 시스템을 만들어 보았습니다. 그다지 멋지지는 않지만.. 그냥 머리속에 간단한 생각을 만들어 보았습니다..

[Flash] /attachment/1286715815.swf 

참고로 비트맵에 대한 백버퍼를 사용하여 메모리의 증가에 대한 문제를 고려치 않아… 장시간 실행시켜 놓으면 메모리 폭주가 발생성과 속도가 점점 느려질 소지가 다분합니다만.. 걍 가볍게 봐주시기 바랍니다..