Iso Metric은 View 관점에서 x, y, z 축이 120도를 이루는 좌표계를 말합니다.


저는 편의상 Flash의 좌표계를 x, y Iso 상의 좌표를 u, v, z라고 합니다.


이때 xy 좌표를 uvz로 변환하는 공식은 다음과 같습니다.


(z는 기본적으로 추가되야합니다. 기본값은 0이겠죠)


u =  x + y + z

v = -x + y + z

z = z


반대로 uvz를 xy로 변환하는 공식입니다.


x = u - v

y = ( ( u + v ) / 2 ) - z


제가 유틸로 쓰고 있는 메소드입니다.


static public function toUVZ( $x: int, $y: int, $z: int = 0, $target: UVZPoint = null ): UVZPoint
{
     var point: UVZPoint = $target;
     
     if( point == null )
          point= new UVZPoint;
     
     point.u = $y + ( $x >> 1 ) + $z;
     point.v = $y - ( $x >> 1 ) + $z;
     point.z = $z;
     
     return point;
}


uvz를 xy 로 변환하는 메소드입니다.


static public function toXY( $u: int, $v: int, $z: int = 0, $target: XYPoint = null ): XYPoint
{
     var point: XYPoint = $target;
     
     if( point == null )
          point = new XYPoint;
     
     point.x = $u - $v;
     point.y = ( ( $u + $v ) >> 1 ) - $z;
     
     return point;
}


여기서 $target으로 받는 파라미터는 팁입니다.


연산이 많아질 경우 매번 새로운 객체를 생성하는 것은 상당한 cpu 부하가 필요합니다.


재사용을 위해서 결과값을 받을 객체를 전달받아서 퍼포먼스 향상을 꾀하는 것이죠.


Iso 엔진의 기본인 좌표계 연산이었습니다~


(뭐 꼭 제가 삽질 많이해서 올리는건 아닙니다 -_-a)





for the Better.

[ Starling Download : http://gamua.com/starling/ ]


Starling은 Full-source 로 제공됩니다.


그렇기 때문에 자신에게 맞춰서 소스를 수정하여 쓸 수 있습니다.


현재 Starling 기반의 IsoMetric 엔진이 제대로된게 없어서


저는 DisplayObject를 고쳐서 Iso Engine으로 사용하고 있습니다.


swc로 감싸져있다면 불가능한 일이겠죠.


확대/축소가 가능한 Iso엔진을 60fps 돌리는 날이 올줄이야 ㅠㅠ


하지만 개발하다보니까


Hit Area로 쓰기가 어렵더군요


반드시 Texture로 만들어서 Image로 붙여야 touch가 가능하기 때문에


터치만 반응하고 실제 렌더링은 되지 않는 객체를 만들어야 했습니다.


그래서 DisplayObject를 살펴보다 보니까 다음과 같은 부분을 찾았습니다.


/** @private */
internal function get hasVisibleArea():Boolean
{
return mAlpha != 0.0 && mVisible && mScaleX != 0.0 && mScaleY != 0.0;
}


아마도 렌더러가 이 객체를 렌더링할지 말지를 결정하는 메소드인거 같네요.


그래서 다음과 같이 property를 하나 더 추가해봤습니다.


public var hitArea: Boolean = false;

/** @private */
internal function get hasVisibleArea():Boolean
{
return mAlpha != 0.0 && mVisible && mScaleX != 0.0 && mScaleY != 0.0 && !hitArea;
}


hitArea라는 속성이 true 면 렌더링에서 제외시켜라 라는거죠.


이렇게하면 렌더링에서 스스로 제외될 수 있게 되었습니다.


게다가 실제 객체는 addChild가 되어 있기 때문에


Touch 이벤트에서는 그대로 영역이 계산되어 터치가 됩니다.


즉 눈에는 안보이는 Hit 전용 객체를 만들 수 있게 된거죠.


실제로 테스트해보면 draw call이 증가하지 않는것을 볼 수 있습니다.


-_-)b 굿~




for the Better.

이전 강좌에서는 ane 파일까지 개발을 해봤습니다.

사실 Flash Builder 4.6 이상을 사용한다면 ane 파일만 있어도 개발이 가능합니다.


하지만 이번 강좌에서는 ANT 빌드를 통해서


직접 컴파일하여 디바이스에 설치까지 시켜보는 (아이튠즈 없이) 과정을 배워보게습니다. (단, 아이튠즈가 깔려는 있어야합니다.)




1. 프로젝트 만들기


AlertApp 이라는 모바일 액션스크립트 프로젝트를 생성해보겠습니다.



앱 이름은 AlertApp 이라고 지어줍니다.



Mobile Settings 에서는 Apple iOS만 선택해주고 나머지는 해제해줍니다.



Build Paths 에서는 우리가 만든 AlertExtension 라이브러리를 추가해줍니다.



다음과 같이 프로젝트 셋팅이 다 되었습니다.



이제 우리가 만들 앱은 간단합니다.


TextField 두 개를 두고


하나는 Title을 입력받고


다른 하나는 Message를 입력받아


Extension의 alert 메소드를 호출할 겁니다.


먼저 간단하게 TextField를 생성하는 부분부터 코딩합니다.


package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.KeyboardEvent; import flash.text.TextField; import flash.text.TextFieldType; import flash.text.TextFormat; import flash.ui.Keyboard; /** * AlertApp * * author: Yun Jinsang (a.k.a. Wooyaggo, http://www.as3.kr, victim4 at gmail.com) * created: Aug 13, 2012 * */ [SWF (widthPercent="100%", heightPercent="100%", frameRate="60")] public class AlertApp extends Sprite { private var txtTitle: TextField; private var txtMessage: TextField; public function AlertApp() { initTextField(); } private function initTextField(): void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; txtTitle = createTextField(); txtTitle.x = 5; txtTitle.y = 5; txtMessage = createTextField(); txtMessage.x = 5; txtMessage.y = 60; txtMessage.addEventListener( KeyboardEvent.KEY_DOWN, showAlertListener ); } private function showAlertListener( $e: KeyboardEvent ): void { } private function createTextField(): TextField { var txt: TextField = new TextField; txt.type = TextFieldType.INPUT; txt.border = true; txt.defaultTextFormat = new TextFormat( null, 48 ); txt.width = stage.stageWidth - 10; txt.height = 50; addChild( txt ); return txt; } } }


TextField 두 개 만들어서 배치를 해놓고


마지막 TextField에는 KeyboardEvent를 받습니다.


엔터 즉, 확인 버튼을 누르면


바로 팝업을 띄우도록 하기 위함입니다.


먼저 Extension 객체를 생성해보겠습니다.


package
{
	... 생략 ...

	public class AlertApp extends Sprite
	{
		private var txtTitle: TextField;
		private var txtMessage: TextField;
		
		public function AlertApp()
		{
			initTextField();
			initExtension();
		}
		
		... 생략 ...
		
		private var _extension: AlertExtension;
		private function initExtension(): void
		{
			_extension = new AlertExtension;
		}
		
		... 생략 ...
	}
}


간단합니다. 


AlertExtension 객체를 생성해놓습니다.


이제 두 번째 TextField 에서 엔터를 눌렀을 때를 처리해봅시다.


package
{
	... 생략 ...

	public class AlertApp extends Sprite
	{
		... 생략 ...
		
		private function showAlertListener( $e: KeyboardEvent ): void
		{
			if( $e.keyCode != Keyboard.ENTER )
				return;
			
			var title: String = txtTitle.text || "";
			var message: String = txtMessage.text || "";
			
			_extension.alert( title, message );
		}
		
		... 생략 ...
	}
}


키보드 입력이 엔터일 때


title과 message를 가져옵니다.


그리고 만들어진 _extension.alert 에 파라미터를 전달하여 호출하게 됩니다.


앱은 여기가 끝입니다.




2. Extension 선언하기


AlertApp-app.xml 파일을 열어 다음과 같이 Extension을 선언해줍니다.



코드로 적어드리면 다음과 같습니다.




	... 생략 ...

	AlertApp
	
	
		wooyaggo.extension.Alert
	
	
	... 생략 ...

자 이제 코드는 끝이 났습니다.


이제 ipa 빌드로 넘어가보겠습니다.




3. ipa 빌드하기


앞서와 마찬가지로 ANT빌드를 이용하겠습니다.


먼저 build.xml 파일을 생성합니다.


그리고 ane 파일을 만들때 사용했던 변수들을 복사하여 적어놓습니다.



	
	
	
		
		
		
	
	


그 밖에 필요한 정보들이 더 있습니다.


인증서와 ane 파일의 경로입니다.


아래와 같이 변수들을 설정해주고 정확한 값을 입력해줍니다.



	
	
	
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	

자 변수 설정이 끝났다면


먼저 빌드하기 전에 bin-debug 폴더에 ane 파일을 복사해와야합니다.


<copy> 명령어로 다음과 같이 추가 합니다.



	
	
	
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	


빌드를 돌려보고 파일이 제대로 복사되는지 확인합니다.



이제 ipa 빌드를 할 차례입니다.


adt 커맨드는 다음과 같습니다.


adt -package -target ( ipa-test | ipa-debug | ipa-app-store | ipa-ad-hoc | ipa-test-interpreter | ipa-debug-interpreter | ipa-test-interpreter-simulator | ipa-debug-interpreter-simulator ) ( CONNECT_OPTIONS? | LISTEN_OPTIONS? ) ( -sampler )? SIGNING_OPTIONS ( PLATFORM-SDK-OPTION? FILE-AND-PATH-OPTIONS | PLATFORM-SDK-OPTION? )


복잡해보이지만 단순하게 나타내면 다음과 같습니다.


adt -package -target (패키지옵션) (인증서옵션) (생성할 ipa명) (-app.xml 파일) (swf 파일)


입니다.


인증서 옵션은 다음과 같이 줄 수 있습니다.


-storetype pkcs12 -keystore (cer파일) -storepass (비밀번호) -provisioning-profile (provisioning파일)


이 파라미터들을 다 합쳐서


ant 빌드를 추가해보겠습니다.



	
	
	
		... 생략 ...
		
		
		
		
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
			
		
		
	
	


각 변수를 잘 할당하였다면 다음과 같이 ipa 가 생성이 되었을 것입니다.



만약 에러가 났다면 build.log 파일의 에러 로그를 보고 어디가 잘못된 것인지 살펴봐야합니다.


이제 빌드는 모두 끝났고


아이튠즈 없이 직접 설치하는 방법을 보겠습니다.


마찬가지로 adt 커맨드이고


사용방법은 다음과 같습니다.


adt -uninstallApp PLATFORM-OPTION PLATFORM-SDK-OPTION? DEVICE-OPTION? -appid


app id 만 알면됩니다.


주의할 점은 adt 로 컴파일 한 앱에는 패키지명이 air.wooyaggo~~~ 이렇게 시작한다는 것입니다.


그리고 지금처럼 bin-debug 로 빌드한 파일의 경우에는 뒤에 .debug가 더 붙습니다.


앱 아이디가 AlertApp이라면 실제 App ID는


air.AlertApp.debug 가 됩니다.


ant 빌드에서는 다음과 같이 적용됩니다.



	
	
	
	
	
	
	

앱을 설치시키는 것은 ipa 파일만 있으면 됩니다.


adt 사용법은 다음과 같습니다.


adt -installApp PLATFORM-OPTION PLATFORM-SDK-OPTION? DEVICE-OPTION? -package


ant 빌드에서는 다음과 같이 적용됩니다.



	
	
	
	
	
	
	



자 이제 다 됐습니다.


ant 컴파일을 command + F11로 실행해봅니다.




위 그림과 같이 잘 설치되었는지 확인하고 실행을 해봅니다.



타이틀과 메세지를 적은 후에 


엔터를 치면


!!!!!!!!!!!



짠~


위와 같이 팝업이 뜨게 됩니다.




드디어 완성입니다!!






4. 자동화


Native Extension 은 자동화가 무척 중요합니다.


빌드 과정도 복잡하고 여러 프로젝트가 한데 묶이다보니


체계화를 잘 해야합니다.


그냥 한번 따라하는거는 터미널에서 하고 넘어갈 수 있지만


실제 개발을 위해서는 자동화하는게 중요합니다.


인증서도 그렇고 build property 들도 파일로 따로 관리하는 것이 좋습니다.


ant 빌드를 잘 짜놓고 재사용할 수 있게 잘 관리하시길 바랍니다.




AlertApp 다운로드 :


AlertApp.zip


  1. 초보개발자 2014.07.29 14:33

    매우 잘 읽었습니다.
    그런데 제가 여러차례 시도를 해도 createExtensionContext하는 부분에서 자꾸 null 이 반환되어 아무것도 되지 않는데요..
    원인을 모르겠어요. .a 파일 만들 때에도 잘 호출이 되었고 extensionID도 동일하게 사용했는데.. 도통 어디가 잘못된건지 모르겠어요..
    도와주세요.

    • Favicon of https://wooyaggo.tistory.com 우야꼬  2014.08.04 10:55 신고

      .a 파일 만드실 때 빌드를 iOS Devices 로 놓고 빌드하셔야되요.
      만약에 Simulator로 잡고 빌드하시면 그런 현상이 나올 수 있어여

  2. Favicon of http://imincheol.blog.me imincheol 2015.12.15 10:51

    Source 부분이 안보이는 곳이 있네요

    맥북에어/사파리 입니다.

+ Recent posts