반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

이번주에도 Corona SDK 에서 금주의 SDK FAQ 5개를 올렸습니다.

이 내용 번역해서 같이 공유 합니다.


FAQ Wednesday

Posted by Tom Newman 

수요일 입니다. 오늘도 자주 들어오는 5개의 질문을 골라서 답변해 드리겠습니다.

Question 1

코로나에서는 PNG 나 JPG 어떤 이미지를 써야 하나요?

Answer

이미지의 화질이나 앱 패키지의 사이즈 등에 따라 다를 수 있습니다. 코로나는 32비트 PNG 와 32비트 JPGs를 지원합니다. PNG는 손실없이 압축하면서도 투명 효과를 지원하고 JPG는 압축되지만 약간 손실이 있고 장점은 광범위한 Color range를 지원합니다. 같은 해상도에서 PNG는 일반적으로 JPGs 보다 사이즈가 큽니다. 이건 여러분의 앱 용량 제한 조건에 영향을 줄 수 있습니다.

texture 메모리 사용량에 대해  PNG와 JPG는 모두 같은 용량의 openGL 메모리를 차지합니다. 왜냐하면 이미지는 메모리에 로드됐을 때는 압축되지 않기 때문이죠. 또 한가지 알아두셔야 할 것은 이미지는 openGL 메모리에 로드됐을 때는 2의 제곱으로 (2, 4, 8, 16, 32, 64, 128, 256, 512, etc.) 로드 됩니다. 만약 여러분이 320*480, 280*400 두개의 이미지가 있을 때 이 이미지는 모두 512*512 만큼의 texture memory를 소비한다는 겁니다. 769*1024 이미지는 1024*1024 byte를 소비할 겁니다.





Question 2

가끔 began touch 이벤트는 있는데 ended 이벤트는 없는 경우가 있는데 왜 그런가요?

Answer

그런 현상은 버그가 아닙니다. 이런 일이 어떻게해서 일어나는지 그리고 어떻게 처리해야 하는지 개발자로서 잘 알아 두실 필요가 있습니다. touch 에는 began과 ended 이벤트가 있습니다. display object에 touch 리스너를 생성하셨다면 그 object를 touch 하면 일반적으로 began, moved, ended 이벤트를 받게 됩니다. 그리고 그 리스너를 어떻게 구현했는지 그리고 유저가 그 object에 대해 touch를 어떻게 발생했는지에 따라 touch 시에 특정 이벤트가 missing 될 수 있습니다.

아래 코드는 circle object에 대해 간단한 방법으로 touch 리스너를 단 예제입니다.

local circle = display.newCircle( 100, 100, 50 )

-- Touch listener
local function myTouch( event )
    print( "Touch event = " .. event.phase )
end

circle:addEventListener( "touch", myTouch )


만약 유저가 원을 터치하고 손을 떼면 리스너는 began과 ended 이벤트를 call 할 겁니다. 또 만약 손가락을 떼지 않고 화면에서 움직이면 moved 이벤트가 나올 겁니다.

유저가 그 원을 터치하고 움직이다가 원을 벗어났다고 생각해 봅시다. 그럴 경우에는 began 과 moved 이벤트만 생성되고 ended 이벤트는 생성되지 않을 겁니다. 왜냐하면 손가락을 뗀 행위는 그 원안에서 일어나지 않았기 때문입니다.

그러면 ended 이벤트는 어디로 갔을 까요? 답은 다른 object 리스너로 갔다 입니다. Runtime touch 리스너나 원이 아닌 다른 object 의 리스너로 간거죠.

그러면 그 다른 object의 이벤트는 어떨까요? 그 object에는 moved와 ended는 있지만 began이 없겠죠? 왜냐하면 touch 이벤트가 한 object에서 시작해서 그 object 를 떠나서 다른 object에서 마감을 했기 때문입니다.

만약 한 object에서 이벤트가 시작됐을 경우 그 이벤트의 끝이 그 object에서 작동하게 하려면 setFocus 를 쓰시면 됩니다.

local circle = display.newCircle( 100, 100, 50 )

-- Touch listener
local function myTouch( event )
    print( "Touch event = " .. event.phase )
  
    if "began" == event.phase then
        display.getCurrentStage():setFocus( circle )  -- set touch focus on circle
        event.target.focus = true
    end
  
    if "ended" == event.phase or "cancelled" == event.phase then
        if event.target.focus ~= true then
            return false
        end
        print( "Ended found" )
        display.getCurrentStage():setFocus( nil ) -- clear touch focus
        event.target.focus = false
    end

    return true
end

circle:addEventListener( "touch", myTouch )


이 예제에서 setFocus는 began 일 경우에 설정을 했습니다. 그리고 ended에서 이 setFocus를 해제를 했죠. 이러한 방법으로 해당 객체에서 이벤트가 시작됐으면 그 이벤트가 그 객체 밖에서 종료하더라도 해당 객체에 ended 가 적용되도록 만들 수 있습니다.

아래 문구에 대해서 주의 깊게 살펴 보실 필요가 있습니다.

event.target.focus = true

이 코드가 began 에서 사용됐죠 그리고 ended 에서도 false로 할당 하느라고 사용했습니다. 바로 이 코드가 해당 object에서 리스너가 일어나고 끝날 수 있게 컨트롤 해 주는 겁니다.

좀 touch에 대해 좀 더 자세히 알고 싶으시면 Detecting Touches in Corona 튜토리얼을 보시기 바랍니다.

Question 3

코로나에서 하수를 정의하는 두가지 방법에 대해서 봤습니다. 어떤게 올바른 건가요? 그리고 그 둘의 차이점은 뭔가요?

Answer

함수는 두가지 방법으로 생성하실 수 있습니다.

local function myfunc1()
    print( "function = ", myfunc1 )
end

and
local myfunc2 = function()
    print( "function = ", myfunc2 )
end


두개 모두 대부분의 경우 잘 동작합니다. 그런데 두번째의 경우에는 이 함수 내부에서  function name을 참조하는것이 필요한 경우에는 작동하지 않습니다. 왜냐하면 이 함수 변수인 myfunc2는 이 함수가 정의 되기 전까지는 아직 생성된게 아니니까요. 첫번째의 경우에는 함수 변수 myfunc1은 이 함수가 정의되기 이전에 생성된 겁니다. 그러니까 이 함수 내부에서 참조될 수가 있습니다. 위 두개의 코드를 시뮬레이터에서 실행하시면 첫번째는 myfunc1 값을 보실수 있지만 두번째는 nil을 보시게 될 겁니다.

myfunc1 함수는 아래와 똑 같습니다.

local myfunc1
function myfunc1()
...
end


저는 myfunc1 방식으로 함수를 사용하는 편입니다. 왜냐하면 저한테는 이게 더 전통적이라고 느껴지거든요. 그리고 함수 안에서 그 함수를 참조할 때 nil 값을 받을 염려도 없구요. 하지만 글로벌 함수로 이용한다면 두 함수 모두 똑 같습니다.

Question 4

config.lua 에서 스크린 사이즈를 640*960 (iPhone 4) 로 설정했습니다. 그랬더니 iPhone 3 에서는 이미지가 작게 나와요. 왜 그럴까요?

Answer

만약 여러분이 디바이스의 표준 해상도보다 큰 이미지를 로드하기 위해 display.newImage를 사용하신다면 이 이미지들은 config.lua 파일에 세팅된 width/height 에 근거해서 dynamic 하게 scale이 조절되기 전에 screen에 맞게 먼저 조절 됩니다. 예를 들어 600*100 픽셀짜리 이미지를 iPhone3 (320*480) 에 표시한다고 합시다. 이 이미지는 dynamic하게 scale 되기 전에 화면에 맞게 먼저 이미지가 작아질 겁니다. 이래서 iPhone4에 맞추면 iPhone3에서 이미지가 작게 보이는 이유입니다. 이것을 해결하려면 display.newImageRect (위의 경우에는 이미지 사이즈를 600*100으로 하시면 되겠죠)나 display.newImage와 isFullResolution flag를 true로 세팅하시면 됩니다. 이렇게 하면 native screen size에 근거해서 이미지가 scaling 되는 것을 건너 뛰게 해 줍니다.

Note : iPhone4에서 scale down 하기 위해 320*480 보다 큰 이미지를 사용하면 display.newImage에서 에러가 발생하는 버그가 있었습니다. 이런 현상은 dynamic scaling이 적용 되던 안되던 발생했습니다. 이 버그는 Daily Build 2012.788 에서 해결 됐습니다.

좀 더 자세한 정보는 Dyamic Image Resolution 을 참조하세요.

Question 5

iOS5 환경에서 코로나는 audio 관련 버그가 좀 있었습니다. 왜 애플과 관련해서계속 버그가 나오죠?

Answer


가끔 코로나의 버그들은 operating system 에서 발견된 버그에 기인하는 경우가 있습니다. 그 문제와 관련해서 해결책을 찾기위해 노력중입니다. 일단 최선의 방법은 그 OS에서 버그를 해결하는게 되겠죠. iOS5에서는 해결하기 어려운 openAL audio 버그들이 좀 있습니다. 저희들은 포럼들에 버그 메세지가 올라오는 것을 보고 그 버그를 지속적으로 수정하고 있습니다. 그리고 그 버그 해결과 관련한 글을 그 포럼들에 댓글로 답해주고 있습니다. 그리고 그 버그들을 정리하고 있습니다. 또 애플에 report를 하고 있구요.  더 많은 유저들이 이 버그에 대해 레포트를 한다면 애플에서 이 버그를 근본적으로 해결할 가능성이 커 지겠죠. Ansca 말고는 아무도 이 버그 레포트를 하지 않는다면 이 문제는 근본적인 해결이 어렵겠죠.

좀 더 자세한 정보와 애플 버그와 관련된 정보는 Apple Bug Reporter 에서 보실 수 있습니다.


 
 

반응형


반응형

Working with classes in Sencha Touch 2.0

1. Declaration (선언)

1.1. The Old Way (옛날 방법)


만약 여러분이 Sencha Touch 1.x 버전을 사용하신다면 분명 클래스를 생성하기 위한 Ext.extend 를 잘 알고 계실겁니다.

var MyPanel = Ext.extend(Object, { ... });

이것은 다른 클래스를 상속받는 새로운 클래스를 생성할 때 손쉽게 이용할 수 있는 방법입니다. 상속하는 것 말고는 다른 클래스 생성 관점에서 보면은 그렇게 크게 유용하지는 않습니다. configuration이라던지 statics, mixins 같은 것들 말이죠. 간단하게 이런 아이템들과 관련한 사항들을 살펴보죠.

아래 샘플을 한번 보세요.

My.cool.Panel = Ext.extend(Ext.Panel, { ... });

여기서는 새로운 클래스의 네임스페이스를 사용했고 Ext.Panel을 extend 했습니다. 이 예제에서는 두가지 알아두어야 할 것들이 있습니다.

1. My.cool은 프로퍼티로서 Panel을 할당하기 전에 객체로서 존재해 있어야 합니다.
2. Ext.Panel은 이것이 참조되기 전에 존재하고 또 로드 되어 있어야 합니다.

첫번째 아이템은 대개 Ext.namespace (Ext.ns)를 사용해서 해결 합니다. 이 메소드는 object/property를 통해 재귀적으로 참조 되고 그것이 존재하지 않으면 생성합니다. 좀 성가신 일은 여러분이 Ext.extend를 사용할 때는 항상 이것을 사용해야 한다는 것이죠. 아래 예제가 있습니다.

Ext.ns('My.cool');
My.cool.Panel = Ext.extend(Ext.Panel, { ... });


두번째 이슈는 이것을 address 하기가 쉽지 않다는 것입니다. 왜냐하면 Ext.Panel 은 다른 많은 클래스들을 depend on  할 것이기 때문이죠. 다른 클래스들을 직접적이든 간접적이든 상속하니까요. 그러면 그 상속할 대상이 되는 클래스는 반드시 존재해 있어야 하겠죠. 이러한 이유 때문에 Sencha Touch 2 이전에는 ext-all.js의 모든 라이브러리의 일부분만 사용해도 이것을 통재로 include 했었습니다.

1.2. The New Way (새로운 방법)

센차 터치 2 는 클래스를 생성할 때 오직 한가지 메소드만 생각하면 되도록 부가적인 것들은 전부 제거했습니다. 그것은 Ext.define 입니다. 아주 간단한 신택스죠.

Ext.define(className, members, onClassCreated);

이 신택스의 각 부분별로 한번 살펴 보겠습니다.

- className 은 클래스의 이름입니다.
- members는 key-value 조합의 클래스 멤버 collection을 나타내는 객체입니다.
- onClassCreated는 옵션입니다. 모든 관계된 클래스가 ready 되면 invoke 하기 위한 callback 함수이죠. 또한 이 클래스 자체가 완전히 생성되면 invoke 되기도 합니다. 클래서 생성의 새로운 비동기적인 성격으로 인해  이 callback은 다양한 경우에 아주 유용하게 사용될 수 있습니다. 이 내용은 Sencha Touch 2 튜토리얼 4장에서 다시 자세하게 다뤄질 겁니다.


Example

Ext.define('My.sample.Person', {
    name: 'Unknown',

    constructor: function(name) {
        if (name) {
            this.name = name;
        }
    },

    eat: function(foodType) {
        alert(this.name + " is eating: " + foodType);
    }
});

var aaron = Ext.create('My.sample.Person', 'Aaron');
    aaron.eat("Salad"); // alert("Aaron is eating: Salad");

   
Ext.create() 메소드를 사용해서 My.sample.Person의 새로운 인스턴스를 생성했습니다. 그러려면 아마 (new My.sample.Person())을 사용해야 했겠죠. 하지만 다이나믹 로딩의 장점을 이용하기 위해서 위의 방법대로 하실것을 권장합니다. 다이나믹 로딩의 좀 더 자세한 사항은 Getting Started guide를 살펴 보세요.

2. Configuration

센차터치 2에서는 클래스가 생성되기 전에 강력한 Ext.Class 전처리 장치에 의해 진행되는 config property를 제공하고 있습니다.
이것은 아래와 같은 내용들을 제공합니다.

- configurations는 다른 클래스 멤버로부터 완전하게 캡슐화 되어있습니다.
- 각 config property의 getter와 setter 메소드들은 클래스가 생성되는 동안 이 메소드들이 따로 정의되어 있지 않으면 class prototype에 자동적으로 생성합니다.
- 각 config property에 대해 apply 메소드도 또한 생성됩니다. 자동으로 생성된 setter 메소드는 value를 setting 하기 전에 내부적으로 apply 메소드를 call 합니다.
그 value 를 세팅하기 전에 custom logic 을 run 할 필요가 있으면 config property에 apply 메소드를 override 합니다. 만약 apply가 어떤 값도 return 하지 않으면 setter는 value를 set 하지 않습니다.

아래에 예제가 있습니다.

Ext.define('My.own.WindowBottomBar', {});

Ext.define('My.own.Window', {

    /** @readonly */
    isWindow: true,

    config: {
        title: 'Title Here',

        bottomBar: {
            enabled: true,
            height: 50,
            resizable: false
        }
    },

    constructor: function(config) {
        this.initConfig(config);
    },

    applyTitle: function(title) {
        if (!Ext.isString(title) || title.length === 0) {
            console.log('Error: Title must be a valid non-empty string');
        }
        else {
            return title;
        }
    },

    applyBottomBar: function(bottomBar) {
        if (bottomBar && bottomBar.enabled) {
            if (!this.bottomBar) {
                return Ext.create('My.own.WindowBottomBar', bottomBar);
            }
            else {
                this.bottomBar.setConfig(bottomBar);
            }
        }
    }
});


아래 예제는 이것을 어떻게 사용하는지를 보여줍니다.

var myWindow = Ext.create('My.own.Window', {
    title: 'Hello World',
    bottomBar: {
        height: 60
    }
});

console.log(myWindow.getTitle()); // logs "Hello World"

myWindow.setTitle('Something New');
console.log(myWindow.getTitle()); // logs "Something New"

myWindow.setTitle(null); // logs "Error: Title must be a valid non-empty string"

myWindow.setBottomBar({ height: 100 }); // Bottom bar's height is changed to 100



3. Statics

static 멤버들은 static config를 사용해서 정의될 수 있습니다.

Ext.define('Computer', {
    statics: {
        instanceCount: 0,
        factory: function(brand) {
            // 'this' in static methods refer to the class itself
            return new this({brand: brand});
        }
    },

    config: {
        brand: null
    },

    constructor: function(config) {
        this.initConfig(config);

        // the 'self' property of an instance refers to its class
        this.self.instanceCount ++;
    }
});

var dellComputer = Computer.factory('Dell');
var appleComputer = Computer.factory('Mac');

alert(appleComputer.getBrand()); // using the auto-generated getter to get the value of a config property. Alerts "Mac"

alert(Computer.instanceCount); // Alerts "2"



Error Handling and debugging (에러 처리와 디버깅)


센차터치 2에는 디버깅과 에러 처리를 도와주는 유용한 기능이 있습니다.

메소드의 display name을 얻으려면 Ext.getDisplayName()을 사용하실 수 있습니다. 이것은 description 안에 클래스 이름과 메소드 이름을 가진 에러를 throw 할 때 유용하게 사용하실 수 있습니다.

throw new Error('['+ Ext.getDisplayName(arguments.callee) +'] Some message here');

에러가 Ext.define()을 사용해 정의된 클래스의 메소드내에서 던져졌을 때 여러분의 브라우저가 크롬(Chrome)이나 사파리(Safari) 같이 WebKit 을 사용하는 브라우저라면 call stack에 그 메소드와 클래스 이름이 표시될 겁니다.

아래에 크롬에서 보실 수 있는 에러 메세지들이 있습니다.


반응형

PhoneGap 설치하고 예제 실행하기

2012. 4. 26. 02:59 | Posted by 솔웅


반응형

오늘은 PhoneGap 을 한번 설치 해 보기로 했습니다.

저는 Hybrid App 을 Corona SDK, Sencha Touch, JQuery Mobile 을 위주로 한번 연구해 볼 생각이거든요.


거기다가 Kurogo 가 도움이 된다면 같이 한번 사용해 보고 싶고...

웹 서버쪽은 PHP 와 데이터베이스를 사용할 거고.


이런 구조로 Hybrid App 을 개발 툴 조합을 연구해 보고 있습니다.


그런데 디바이스의 Native 기능 등을 사용하기 위해 Corona SDK를 사용하느냐. PhoneGap을 사용하느냐 를 결정하려면 장단점을 알고 있어야 할 것 같아서요.


Corona SDK에 대해서는 잘 알지만 일반적으로 Hybrid App에 많이 사용되는 PhoneGap에 대해서는 전혀 몰라서 오늘 한번 설치해보고 감을 잡고자 합니다.


우선 eclipse 와 Android SDK, ADT Plugin, JAVA 등은 다 설치 되서 Native Android 앱 개발 환경은 다 완료 된 것으로 하고 PhoneGap 설치를 진행해 보겠습니다.


1. http://phonegap.com/start 로 접속을 합니다.


2. 아래 화면에서 해당 platform을 선택합니다. (저는 Android를 선택했습니다.)



3. 비디오 튜토리얼이 있네요. 이것부터 한번 볼까요?




보니까 PhoneGap 에 대해 많이 이해가 되네요.

이클립스 개발환경에서 폰갭을 설치하고 샘플 앱을 만드는 방법까지 자세히 설명을 했습니다.


4. 다음 단계는 Eclipse, Android SDK, ADT Plugin을 설치하는 단계입니다.



저는 ADT Plugin 까지 모두 설치 된 상태이기 때문에 PhoneGap 다운로드부터 하겠습니다.




이 글을 올리는 시점에는 PhoneGap 1.6.1 이 최신 버전이네요.


5. 다운받은 압축 파일을 푸니까 아래와 같은 구조네요.



lib 폴더에 android, bada, blackberry, ios, symbian, windows 같은 각 모바일 플랫폼 별 jar 파일과 js 파일이 들어있고 예제 파일도 들어있습니다.


6. 그 다음은 Android Native Language로 App을 만들 때 처럼 이클립스에서 New Android Projet를 만듭니다.


- 이클립스에서 File-New-Android Project를 선택합니다. 그리고 Project Name을 정합니다.



- 일단 버전은 2.2 를 선택하겠습니다.


- Package Name 이 빠졌으면 이 부분 넣고 Finish 버튼을 누릅니다.




7. 그 다음에는 project 폴더에 2개의 폴더를 더 추가해 넣습니다. (libs, assets/www)


8. 다음에 아까 받았던 PhoneGap 의 jar 파일을 libs에 js 파일을 www 에 복사해 넣습니다.

그리고 xml 폴더를 res 폴더 밑에 복사해 넛습니다.




9. 다음은 java 파일을 조금 수정하는데요.




위에 빨간 줄 친 부분을 바꾸시면 됩니다. (위에것 에서 아래 것으로요)


10. 다음에는 AndroidManifest.xml 파일을 수정합니다.

AndroidManifest.xml 안에서 <uses-sdk android:minSdkVersion="8" /> 코드를 찾으세요.

그리고 그 위에 아래 코드를 붙여 넣으세요.


<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />


그리고 <activity ..... > 태그에 아래 코드를 추가하세요.

android:configChanges="orientation|keyboardHidden"


그러면 대개 아래와 같은 형식이 될 겁니다.



10. 그 다음은 PhoneGap 프로그래밍을 하시면 됩니다.

www 폴더 밑에 index.html 파일을 생성하신후 아래와 같이 해 보세요.


<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap</title>
<script type="text/javascript" charset="utf-8" src="cordova-1.x.x.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>


11. 이제 실행하시면 됩니다. Ctrl + F11 을 누르시던지 프로젝트에서 오른쪽 마우스 버튼을 클릭한 후 Run As - Android Application을 실행 해 보세요.


아래 화면이 완성된 화면입니다.




처음엔 좀 복잡하네요..


하여간 이렇게 설치하고 예제를 하나 실행했더니 폰갭이 대강 이해가 갑니다.


자체적으로 jar 파일하고 js 파일을 제공해서 모바일 앱을 만들도록 하는 거네요.

각 플랫폼 마다 따로따로 개발해야 되는 번거로움이 좀 있구요.

(코로나 SDK 는 그냥 빌드만 따로 하면 되는데 말이죠.)

대신 기존 Android Native Programming 구도를 그대로 사용하는 거라서 Native 기능을 모두 사용할 수는 있겠네요.


폰갭 + JQuery, Sencha Touch를 하면 정말 많이 편리할 것 같습니다.


폰갭 공부도 좀 더 해서 폰갭 조합 하고 코로나 SDK 조합 Hybrid App 개발 둘 다 해야 겠습니다.


재밌네요...



반응형

Kurogo Platform Demo 체험기

2012. 4. 25. 00:55 | Posted by 솔웅


반응형

지난번에 Kurogo Mobile Middleware 문서를 하나 번역해서 소개해 드렸습니다.

Multi-Platform 모바일 환경에서 유용하게 사용될 기술 같아서 관심을 가졌는데요.


대충 감만 잡았지 잘 모르겠더라구요.


그래서 오늘은 해당 웹사이트에서 소개하는 5분만에 Kurogo Mobile Middleware 체험하기 가 있길래 한번 따라해 봤습니다.


우선 http://modolabs.com/ 로 가시던지 아니면 http://kurogo.org/home/ 로 가세요.


1. Kurogo Demo 체험해보기 시작

 위 첫번째 주소로 가시면 아래 화면이 나올겁니다.


두번째 주소로 가시면 아래 화면을 보세요.



첫번째 화면에서는 Try Our Demo Today를 누르시고 두번째 화면에서는 5-Minute Test Drive를 누르세요.


2. 다음은 sign up 화면 입니다. 필요한 정보 채우시고 Sign up 버튼을 누르세요.



3. 아래 화면이 나오면 Go to Quickstart Admin 을 누르세요.


4. 이제 아까 등록했던 Email 하고 패스워드를 누르고 sign in 하시면 됩니다.




5. 첫 화면에는 아래와 같이 Site 이름 등이 나오고 Optional Menu 로는 Contents가 들어있는 싸이트나 유튜브 아이디 등을 넣으라고 나옵니다. (저는 그냥 디폴트로 했어요.)



6. 다 입력하고 밑에 finish 버튼을 누르면 아래와 같은 화면을 보실 수 있습니다.

왼쪽 메뉴를 보시면 여러 configuration 메뉴를 보실 수 있습니다.

살펴 보시고 난 후 View Site를 누르세요.



7. 그러면 Site 가 나옵니다.

저는 회사 logo image에 제 사진을 넣었어요.

그리고 밑에 파란 아이콘들을 누르면 여러가지 contents들을 볼 수 있어요.

아마 이렇게 Kurogo Platform을 설치하면 저 아이콘을 누르면 들어가서 볼 수 있는 비디오나 맵, 도표, 뉴스, 주소록 등을 쉽게 이용할 수 있도록 하나봅니다.


저도 Kurogo 관련 문서 하나 보고 잘 이해가 안 가서 Demo를 한번 더 실행해 봤는데요.

조금 더 알것 같긴 하지만 좀 더 공부해야 할 것 같아요.


저는 지금 Corona SDK와 Sencha Touch, JQuery Mobile 쪽을 더 중심에 놓고 공부를 하고 있거든요.


이 Kurogo 관련 기술은 짬짬이 더 공부를 해야겠습니다.


좋은 기술인 것 같은데 많이 공부해야 할 것 같습니다.


반응형


반응형

큰 규모의 프로젝트를 진행하려면 OOP (객체지향) 개념을 사용하는 것이 좋습니다.

이 OOP를 사용하려면 클래스를 잘 이용해야 합니다.

이번글과 다음글은 Sencha Touch 2 에서 클래스를 어떻게 사용하는지에 대해 공부해 보겠습니다.

Sencha Touch2 에서는 나름의 class system을 제공하고 있네요.

클래스를 사용하는데 여러 간편한 방법을 제공하는 것 같습니다.


오늘은 여러 규칙과 개념 위주로 정리를 하고 다음 글에서 실제로 코딩하는 방법에 대해 주로 알아 보겠습니다.


먼저 이 글을 보시기 전에 아래 Sencha Touch 2 의 class system에 대해 설명하는 동영상을 보시면 도움이 되실 겁니다.




SenchaCon 2011: The Sencha Class System from Sencha on Vimeo.



How to use classes in Sencha Touch 2  - 1 -

센차터치 2는 Ext JS 4에서 개발된 art class system을 사용합니다. 이 시스템은 providing inheritance, dependency loading, mixins, 강력한 configuration 옵션들 그리고 더 다양한 것들을 위해 자바스크립트에서 새로운 클래스를 쉽게 생성하도록 해 줍니다.

이 시스템에서 클래스는 단지 어떤 함수의 객체일 뿐이고 거기에 프로퍼티들이 첨가 됩니다. 예를 들어 여기 animal 이란 클래스가 있습니다. 이 클래스의 이름과 함수는 아래와 같이 구성할 수 있습니다.

Ext.define('Animal', {
    config: {
        name: null
    },

    constructor: function(config) {
        this.initConfig(config);
    },

    speak: function() {
        alert('grunt');
    }
});


이제 Animal이라는 클래스가 생겼습니다. 이제 각각의 animal 객체를 만들 수 있고 그 객체들은 이름을 가질 수 있고 짖을 수 있습니다. animal의 새 instance를 만들기 위해 우리는 Ext.create 를 사용하면 됩니다.

var bob = Ext.create('Animal', {
    name: 'Bob'
});

bob.speak(); //alerts 'grunt'


여기 Bob이라는 Animal을 만들었습니다. 그리고 bob에게 말하라라고 시켰습니다. 우리가 클래스를 생성하고 그것을 초기화 했고 또 그것을 더 진화시킬 수도 있습니다. 여기까지는 우리는 아직 Bob이 어떤 종류인지를 모릅니다. 이제 우리가 Human 이라는 서브클래스가 있다고 해 봅시다.

Ext.define('Human', {
    extend: 'Animal',

    speak: function() {
        alert(this.getName());
    }
});


여기 Animal을 상속받은 새 클래스가 있습니다. 이 클래스는 Animal 클래스의 모든 함수와 configuration들을 사용할 수 있습니다. 이 Human 에서는 speak 함수를 overrode 했습니다. 왜냐하면 human은 똑똑하기 때문에 grunt 하는 대신에 자신의 이름을 말 할 수 있으니까요. Human은 grunt 하지 않고 자기 이름을 말하도록 하겠습니다.

var bob = Ext.create('Human', {
    name: 'Bob'
});

bob.speak(); //alerts 'Bob'


우리는 Human 서브클래스를 추가할 때 마법같은  함수를 사용했습니다. 느끼셨겠지만 Animal 클래스에서는 getName 함수를 정의하지 않았었습니다. 어디서 이게 왔을까요? 이 class system에서는 다음과 같은 것들을 자동으로 제공하고 있습니다.

- 현재 값을 return 하는 getter 함수, 위 경우에는 getName()
- 새 값을 세팅하는 setter 함수, 위 경우에는 setName()
- setter 에 의해 call 되는 applier 함수. 이 함수는 configuration 에 변경이 있을 때 함수를 실행할 수 있도록 해 줍니다. 위 역우에는 applyName()


getter와 setter 함수들은 자동으로 생성되고 클래스 안에서 데이터를 저장할 때 사용하시기에 좋을 겁니다. 센차터치의 모든 컴포넌트는 이 class system을 사용합니다. 그리고 이렇게 자동으로 함수들을 생성해 주니까 여러분이 config를 알면 자동으로 그 값의 get과 set을 어떻게 해야 하는지도 알게 되시는 겁니다.

이 기능은 여러분들의 코드를 더 간결하게 해 줄 겁니다. 예를 들어 만약에 유저가 Bob의 이름을 바꾸고 싶어한다면 여러분은 applyName 함수를 정의하시기만 하면 됩니다. 이 함수는 자동으로 call 되는 함수이니까요.

Ext.define('Human', {
    extend: 'Animal',

    applyName: function(newName, oldName) {
        return confirm('Are you sure you want to change name to ' + newName + '?')? newName : oldName;
    }
});


위 예제에서는 브라우저의 built in confirm 함수를 사용했습니다. 이 함수는 대화창을 보여주면서 Yes 와 No 를 선택하도록 할 겁니다. applier 함수에서 만약에 false를 return 하게 된다면 이름을 바꾸는 것을 cancel 하도록 할 수도 있습니다. 위 예제에서는 유저가 Yes나 No를 선택하게 되면 거기에 맞는 새 name 이나 기존 name 이 return 될 겁니다.

만약 No를 클릭하면 Bob의 이름은 바뀌지 않겠죠.

var bob = Ext.create('Person', {
    name: 'Bob'
});

bob.setName('Fred'); //opens a confirm box, but we click No

bob.speak(); //still alerts 'Bob'


여기까지 하면 아래와 같은 클래스에 대한 아주 중요한 부분을 이미 다 알게 되신겁니다.

- 여러분들이 만드는 클래스를 포함해 모든 클래스는 Ext.define 에서 정의합니다.
- 대부분의 클래스들은 extend 신택스를 이용해 다른 클래스를 extend 합니다.
- 클래스들은 Ext.create를 사용해서 생성됩니다. 예를 들어 Ext.create('클래스이름',{어떤:'configuration'}) 이런식입니다.
- 자동적으로 생성되는 getter와 setter를 사용하기 위해 config 신택스를 사용합니다. 그러면 코드도 한결 간결해 집니다.


이 정도 되면 여러분들은 여러분의 앱에 이미 클래스들을 생성할 수 있습니다. 그런데 class system에는 몇가지 더 주의해야 할 것들이 있습니다. class system의 유용한 다른 기능들을 사용할 수 있도록 도와주는 방법들이 몇개 더 있습니다.







Dependencies and Dynamic Loading

대부분 클래스들은 다른 클래스들에 depend on 합니다. Human 클래스는 위에서 Animal 클래스를 depend on 했죠. 왜냐하면 Human 클래스에서 Animal 클래스를 extend 했으니까요. Animal 이 Human을 정의할 수 있도록 도와 준 겁니다. 가끔 여러분들은 클래스 안에 클래스를 생성해야 될 때가 있을 겁니다. 이렇게 하려면 아래 신택스대로 하시면 됩니다.

Ext.define('Human', {
    extend: 'Animal',

    requires: 'Ext.MessageBox',

    speak: function() {
        Ext.Msg.alert(this.getName(), "Speaks...");
    }
});


이런 방법으로 클래스를 생성하면 센차 터치는 Ext.MessageBox가 이미 로드 됐는지 아닌지를 체크합니다. 그래서 로드되지 않았다면 즉시 그 파일을 AJAX를 이용해서 로드 합니다.

Ext.MessageBox는 그 안에 자신이 depend on 하는 클래스들을 가지고 있을 겁니다. 그것들은 background에서 자동적으로 로드될 겁니다. 일단 모든 required 클래스들이 로드 되면 Human 클래스는 정의된거고 여러분은 people를 instantiate 하기 위해 Ext.create를 사용하기 시작할 수 있습니다. 이것은 개발자 여러분이 개발 할 대 필요한 그런 클래스들을 직접 로드할 필요없이 다 자동적으로 문제없이 로드 된다는것을 의미합니다. 그런데 production 에서는 그렇지 않습니다. 왜냐하면 인터넷을 통해서 하나하나 로드되는것은 시간이 아주 길어질 수가 있으니까요.

production 에서는 단 1개의 JavaScript 파일만을 로드할 것을 원합니다. 단지 우리의 어플리케이션이 사용할 그 클래스만 포함되면 되죠. 이것은 JSBuilder 툴을 이용해 Sencha Touch2를 사용하면 아주 쉽게 할 수가 있습니다. 이 툴은 여러분의 앱을 분석해서 여러분이 만든 모든  클래스들과 오직 여러분의 앱이 실제로 사용하는 framework class 들만 모아서 single file build를 생성하거든요. JSBuilder를 어떻게 사용하는지 좀 더 자세하게 아시고 싶으면 Building guide를 보세요.

각각의 approach는 pros와 cons를 가집니다. 이 중에 나쁜것은 말고 그 둘의 좋은 부분만 가질 수 있을까요? 정답은 yes 입니다. Sencha Touch 2 에서는 그 solution을 implement 했습니다.

Naming Conventions

클래스와 네임스페이스 그리고 파일이름과 관련해 일관된 naming convention을 사용한다는 것은 여러분의 코드를 organize 하고 structure 하고 가독성있게 유지하는데 아주 유용합니다.

1) Classes


클래스 이름들은 오직 알파벳 글자만이 포함됩니다. 숫자도 가능하지만 그것이 어떤 전문 용어가 아닌 이상 대부분의 경우 권장되지는 않습니다. 밑줄이나 하이픈 또는 다른 알파벳이 아닌 특수문자들은 사용하지 마세요.

- MyCompany.useful_util.Debug_Toolbar 같은 형식은 추천하지 않습니다.
- MyCompany.util.Base64 같은 형식은 가능합니다.


클래스 이름들은 . (dot) 을 사용해서 관련된 것끼리 패키지를 만들어서 그룹화 해야 합니다. 최소한 거기에는 한개의 유니크한 top-level 네임스페이스가 있어야 하죠.

- MyCompany.data.CoolProxy
- MyCompany.Application


top-level 네임스페이스와 실제 클래스 이름은 CamelCase를 사용해야 합니다. 다른 것들은 소문자로 하시면 됩니다.

- MyCompany.form.action.AutoLoad

Sencha Touch에서 기본적으로 지원하는 클래스가 아니면 Ext 라는 top-level 네임스페이스를 절대 사용할 수 없습니다.

Acronyms(첫글자 이니셜)은 CamelCase convention 규칙을 따릅니다.

- Ext.data.JSONProxy 대신 Ext.data.JsonProxy 를 사용합니다.
- MyCompary.parser.HTMLParser 대신 MyCompany.util.HtmlParser 를 사용합니다.
- MyCompany.server.HTTP 대신 MyCompany.server.Http 를 사용합니다.


2) Source Files


클래스 맵의 이름은 그것이 저장돼 있는 곳의 file path를 가리킵니다. 그렇기 때문에 한 파일에 한개의 클래스만 있어야 합니다.

- Ext.mixin.Observable 는 path/to/src/Ext/mixin/Observable.js 에 저장돼 있습니다.
- Ext.form.action.Submit 는 path/to/src/Ext/form/action/Submit.js 에 저장돼 있습니다.
- MyCompany.chart.axis.Numeric 는 path/to/src/MyCompany/chart/axis/Numeric.js 에 저장돼 있습니다.


path/to/src는 여러분 애플리케이션의 클래스의 경로 입니다. 모든 클래스들은 이 경로 밑에 위치합니다. 그리고 개발과 운영,보수 등을 용이하게 하기 위해 이렇게 확실하게 네임스페이스를 따라 명명합니다.

3) 메소드(Methods)와 변수(Variables)


클래스 이름과 마찬가지로 메소드와 변수 이름들도 알파벳만을 사용합니다. 숫자를 사용할 수는 있지만 특정 용어가 아닌 이상은 권장하지 않습니다. 밑줄이나 하이픈 같은 다른 특수문자들은 사용하지 마세요.

메소드와 변수 이름들은 CamelCase를 사용합니다. acronyms 에도 마찬가지로 적용 됩니다.

아래 예제가 있습니다.

사용 가능한 메소드 이름들 :

- encodeUsingMd5()
- getHTML() 대신 getHtml() 를 사용합니다.
- getJSONResponse() 대신 getJsonResponse() 를 사용합니다.
- parseXMLContent() 대신 parseXmlContent() 를 사용합니다.


사용 가능한 변수 이름들 :

- var isGoodName
- var base64Encoder
- var xmlReader
- var httpServer


4) Properties

클래스 프로퍼티 이름은 그것이 static constant일 경우를 제외하고는 메소드나 변수이름과 같은 규칙을 따릅니다. static 클래스 프로퍼티는 모두 대분자로 표시되어야 합니다.

- Ext.MessageBox.YES = "Yes"
- Ext.MessageBox.NO = "No"
- MyCompany.alien.Math.PI = "4.13"

반응형


반응형

지난주에 이 블로그에 댓글에 올리신 몇분의 질문을 Corona SDK 측에 모아서 보냈었습니다.

아침에 올렸는데 바로 그날 저녁때 답변이 왔었죠?


이번주에도 여러분들이 보낸 질문을 정리해서 Corona SDK 측에 보냈습니다.


댓글로 올라온 질문도 있고 방명록을 통해서 받은 질문도 있고 메일로 받은 질문도 있습니다.


답변이 오는 대로 정리해서 올리겠습니다.


오늘 보낸 메일과 질문 내용은 아래와 같습니다.

제가 질문을 잘 이해 못해서 그리고 영어가 좀 짧아서 충분히 Corona SdK 측에 내용을 전달 못한것이 있을 수도 있습니다. 그점은 제가 능력이 부족해서 이오니 이해해 주시기 바랍니다.





========= Corona SDK 에 보낸 메일 ==========


Dear David

I am Changsoo park one of Corona SDK.

Thank you for your quick reply from my question last week.
The people who post the question on my blog said that they are very happy from your quick and helpful reply.

I've got a couple of questions from Corona Developer on my blog in last week also.

Please check it out and reply me if possible.

======= o ===== o ==== o=====

* dk 2012/04/17

Two graphic designers in my company applied for the Corona Level Editor Icon Contest.
I can not get any result and can not see the article also.
Do you have any result?


* ABIZZANG 2012/04/14

Can I set gravities for each objects seperately like Angry bird space with Corona SDK?


* CHOI HANNYONG 2012/04/23

I am developing book app. I have some difficulties to make that one.
(I attached zip file for your reference.)

1. I can not develop the slide transition function with Story board.
   There was 'book' class function in 'Director Class' in recent version.
   Could you provide Slide page transition and page flip function in Storyboard?
   You can see 'book' folder in attached zip file.
   I tried to do this job in storyboard.
   I hope if there are slide page transition and page flip function in storyboard then it will be very helpful for me.

2. It is difficult to develop Scroll fungtion in Storyboard
   You can see magazine_sample. Touch event make slide page transition so it is difficult to add scroll function on it.
   When the image is biger then the screen then I need to use the scroll function.
   If I use touch event for scroll then slide function can not get the touch event.
   You can check the Scroll folder in the zip file.
   So if Storyboard make scroll function automatically if the contents if bigger then the screen then it will be very helpful for the developers who develop book app with Storyboard.
   
3. It is difficult to use Zoom in/out function in the book app.
   Many apps allow zoom in/out of screen.   
   The PinchZoomGesture provide the code in main.lua.
   When I tried to use the code in Storyboard, it is very difficult to do that.
   And there should be page slide transition and scroll function with the Zoom in/out function.
   That make me so difficult to develop it.
   Could you advice please?
   
   There are a couple of things what I faced as difficulties.
   
   a. User tried to zoom in when text is too small, then the images and the buttons on the screen also should be zoom in.
      It is very diffucult to do the job in magazine_sample, director class.
  Can I develop page slide transition and scroll function with zoom in/out?
 
   b. When user zoom in the screen then scroll function should be provided automatically. If it comes nomal then the scroll function should be invisible.
 
   c. when scroll reached end of the contents then I'd like to show user the next page.
   
   So how can I develop these sort of functions? Please help me.

===== o ===== o ====== o =====

Thank you very much 

Changsoo (Douglas) park


========= 원래 질문 내용 ========

dk 2012/04/17
저희 회사 디자이너 두분이 응모했는데,
딱히 결과 발표 이야기가 없네요? 공모 원문은 사라진 것으로 보이는데
혹시 어떻게 되었는지 아시나요?


어비짱 2012/04/14
제가 많이 부족한 탓에 다시 들렀습니다. 헤헤~

궁금한게 있는데요. 물리엔진에서 중력을 설정할때 일정 구역만 다른 중력으로 코로나에서 설정이 가능한가요?

예를 들면 앵그리버드 스페이스에서처럼요.

물리엔진으로 게임을 하나 만들고 싶은데요 이게 가능하면 좋겠네요.



최한뇽 2012/04/23

1. StroryBoard에서는 swipe 기능이 지원되지 않는다. 지원필요합니다.

   그리고 API 모듈의 내부를 알 수 없어 접근이 용이하지 않습니다.

   Swipe 기능은 슬라이드 구조처럼 밀거나 당겨서 슬라이드 페이지를 넘기는 효과입니다.

   DirectorClass에서도 없다가 Book이란 Class 함수가 추가되면서 구현이 되었죠.

   요즘 전자책들은 Page flip 효과보다는 swipe기능을 많이 사용합니다. ibook Author에서도 사용합니다.

   혹시 몰라 첨부된파일에 Book이란 폴더를 실행해 보시면 알게 됩니다. ( magazine_sample 은 Storyboard 사용) 

  즉, StroryBoard에서는 swipe 기능 및 Page flip 기능이 추가되고,

   StroryBoard.lua 파일도 제공이 되었으면 좋겠다.(개발자 참조용, widget.lua 등)

 

2. StroryBoard에서는 Scroll 기능추가 적용이 어렵다. 

    이유는 제가 만든 magazine_sample 에는 이미 터치로 페이지전환을 시도합니다.

    그 부분에 스크롤 기능을 추가시 어려움이 많습니다. 

    우선 해당 페이지에 배경그림이 큰 경우에는 가로 세로 스크롤이 되어야 하며, 그럴 경우 스크롤영역으로 터치이벤트가 

    가 실행시에는 페이지전환에 대한 이벤트의 처리가 안먹게 됩니다. ScrollView를 만들때 이미 그룹으로 영역을 지정하게

    되므로 그 영역에 지정된 스크롤뷰의 이벤트를 먹게 됩니다. (첨부의  ScrollView 폴더 참조)

    또한 페이지에 중복으로 스크롤을 잡는경우도 아주 복잡합니다.

     즉, StroryBoard에서는 컨텐츠에 따라 자동으로 Scroll(가로,세로) 기능추가가 되어야 한다.

 

3. Zoom 기능을 책에 도입시 어려움이 많습니다.

   아이폰이나 안드로이드폰에서 인터넷을 사용해 보았을 것입니다. 즉, 글자가 적으면 Zoom 기능이 되어 확대,축소가 됩니다.  Corona 샘플은 main에 적용을 한것인데 이 부분을 스토리보드가 적용된      magazine_sample , director class 에 적용된 book 소스에 적용하는데 어렵습니다. 페이지 개념과 스크롤기능이 자동으로 추가가 되어야 하기 때문에 어렵습니다.

 

Zoom으로 확대 및 축소를 할 경우,

1) 페이지내에 글씨만 존재하지 않고 그림도 있을 수 있으며, 또한 버튼도 있을 수 있습니다. 그래서 그룹을 지정하여 

   확대 및 축소를 하려고 합니다. 그런데 그럴경우 Zoom의 영향을 받는 곳이 최상단좌측에서 부터 진행이 됩니다.

   (코로나 샘플은 배경만 확대축소 할 경우 가운데 지점부터 확대 축소됨) 

 

2) 확대가 되면서 자동으로 스크롤이 지정되어 상하좌우 이동이 가능해야하고, 원래 사이즈인 경우는 스크롤영역이

   없어져야 합니다. 즉, 자동 스크롤 영역이 되어야 합니다.

 

3) 확대가 된 페이지가 되었을때도 스크롤 영역이 한계에 갔을 경우 페이지 전환을 하는 터치 이벤트가 실행이 되어야 합니다.

 

 즉, StroryBoard에서는 기본으로 Zoom 기능이 내장되어야 하며, 자동으로 Scroll(가로,세로)이 반응해야 한다.


================================================================================


반응형

Sencha Touch 2 Tutorial - Layouts -

2012. 4. 24. 01:47 | Posted by 솔웅


반응형

Using Layouts in Sencha Touch 2

Intro and HBox

Layout은 컴포넌트들의 positioning과 sizing 을 정하는 겁니다. 예를 들어 이메일 클라이언트는 왼쪽에 메세지 리스트가 위치해 있어야 할 것입니다. 이것이 1/3을 차지한다고 합시다. 그 나머지 공간엔 메세지를 볼 수 있는 panel이 위치해 있을 겁니다.

이 구도라면 우리는 hbox layout을 사용해서 구현할 수 있습니다. 그 안에 flex라는 아이템을 넣어서 조절할 수도 있구요. Flexing 의 의미는 각각의 child component의 flex에 근거해서 공간을 나누겠다는 것입니다. 위의 조건을 만족하기 위해서 우리는 flex를 아래와 같이 나눌 수 있습니다.




코드는 아주 간단합니다. 그냥 컨테이너에 hbox 레이아웃을 정해주고나서 각 child 컴포넌트들에 flex를 지정해 주면 됩니다. (이 경우에는 panel이 됩니다.)

Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'hbox',
    items: [
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});


이 예제대로 하면 먼저 화면을 가득 채우는 container가 생성됩니다. 그 안에 메세지 리스트 panel 과 preview panel이 들어가게 됩니다. 두개의 아이템이 있는데요. 하나는 flex: 1 이고 다른 하나는 flex:2 입니다. 이 의미는 메세지 리스트는 전체 화면의 1/3차지하고 message preview 는 나머지 2/3 를 차지한다는 것입니다. 만약 이 콘테이너가 300 픽셀이라면 첫번째 것은 100 픽셀을 차지하고 나머지는 200픽셀을 차지하게 될 겁니다.

hbox는 가장 많이 사용되는 레이아웃 중 하나입니다. 이 레이아웃은 수평적으로 컴포넌트들을 배치하는데 사용할 수 있습니다. 더 자세한 사항은 HBox 문서를 봐 주세요.

VBox Layout

VBox는 HBox와 거의 비슷합니다. 좌우로 나누어지는 것이 아니라 상하로 나누어 지는것만 다릅니다.



이 레이아웃을 구현하는 코드는 hbox와 거의 비슷합니다. 단지 layout을 hbox 대신 vbox로 해 주시면 됩니다.

Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'vbox',
    items: [
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});


이 컨테이너 위 아래가 300 픽셀이라면 첫번째 패널은 100픽셀을 그리고 두번째 패널은 200 픽셀의 높이를 차지할 겁니다. 좀 더 자세한 사항은 VBox 문서를 보세요.

Card Layout

어떤 경우는 여러개의 스크린으로 정보를 보여줄 필요가 있습니다. 하지만 이 일을 하기에는 디바이스의 스크린 크기가 너무 작습니다. TabPanel 과 Carousels 는 한 스크린에 많은 정보를 보여줄 때 유용합니다. 이 두가지는 모두 Card layout 과 같이 쓰여 집니다.

Card layout은 현재 활성화 된 아이템의 전체 Container 크기를 차지합니다. 나머지 아이템들은 그 밑에 숨겨집니다. 그 숨겨진 아이템들 중에 한가지를 visible 하도록 만들 수 있습니다. 이 때 한번에 한 아이템만 visible 하도록 만들 수 있습니다.



여기 gray box가 Container 입니다. 그 안의 blue box 가 현재 활성화된 card 입니다. 나머지 세개는 비활성화 되서 모이지 않습니다. 하지만 이후에 swap 되서 활성화 될 수 있습니다. card layout을 direct 하게 생성하는 것은 아주 일반적이지는 않습니다. 아래와 같이 생성하시면 됩니다.

var panel = Ext.create('Ext.Panel', {
    layout: 'card',
    items: [
        {
            html: "First Item"
        },
        {
            html: "Second Item"
        },
        {
            html: "Third Item"
        },
        {
            html: "Fourth Item"
        }
    ]
});

panel.setActiveItem(1);


여기서는 card layout을 panel 과 같이 생성했습니다. 이 경우는 두번째 아이템이 활성화 될 겁니다. 왜냐하면 setActiveItem(1)을 했기 때문이죠. 첫번째 아이템은 0 으로 지정하면 활성화 될 수 있습니다. 일반적으로 이 card layout은 Tap Panel 이나 Carousel 을 사용하시는것이 좋습니다.

Fit Layout

Fit Layout 은 가장 간단한 레이아웃일 겁니다. 이 레이아웃이 하는 일은 그냥 parent Container의 크기만큼 child component를 꽉 차게 만드는 것입니다.



예를 들어 parent Container가 200X200 픽셀이고 한개의 child component와 fit layout을 사용한다면 이 child component는 200X200 픽셀이 될 겁니다.

var panel = Ext.create('Ext.Panel', {
    width: 200,
    height: 200,
    layout: 'fit',

    items: {
        xtype: 'panel',
        html: 'Also 200px by 200px'
    }
});

Ext.Viewport.add(panel);


fit layout을 사용하면서 container에 1개 이상의 아이템을 넣으면 첫번째 아이템만이 보여질 겁니다. 여러개의 아이템을 보이기를 원한다면 Card layout을 사용해야 합니다.

Docking

모든 레이아웃은 아이템들을 그 안에 탑재할 수가 있습니다. Docking은 parent Container의 위,아래,오른쪽,왼쪽 화면에 추가적인 Component를 넣을 수 있도록 해 줍니다.

예를들어, 처음에 다뤘던 hbox layout으로 돌아가서 화면 위에 다른 component를 탑재하기를 원한다고 가정해 봅시다.





이것은 툴바나 배너들을 사용할 때 자주 이용됩니다. 아래는 이것을 단지 dock: 'top' configuration을 함으로서 간단히 구현한 예제입니다.

Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'hbox',
    items: [
        {
            dock: 'top',
            xtype: 'panel',
            height: 20,
            html: 'This is docked to the top'
        },
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});


child component에 이 dock configuration을 사용해서 원하는 만큼의 아이템들을 간단하게 dock 할 수 있습니다. 그리고 방향을 어느쪽이든지 위치 시킬 수 있습니다. 우리가 위에서 사용했든 vbox 예제를 예로 들면 아래와 같이 할 수도 있습니다.



이것은 dock: 'left' 를 사용해서 구현하겠습니다.

Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'vbox',
    items: [
        {
            dock: 'left',
            xtype: 'panel',
            width: 100,
            html: 'This is docked to the left'
        },
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});


여러분은 사방에 여러개의 docked item들을 추가할 수 있습니다. (예를 들어 bottom 포지션에 여러개의 docking을 사용할 수 있습니다.)


반응형


반응형

코로나에서 지난 주부터 Corona SDK Ambassador 의 글을 하나씩 받아서 웹 싸이트 블로그에 올리겠다고 했습니다.

첫 글은 미국에서 코로나 SDK 책을 펴낸 Dr. Brian G. Burton 의 글입니다.

질문과 답변 형식으로 돼 있네요. 질문은 굳이 번역하지 않았습니다.

여러분들에게도 도움이 될 수 있을 것 같아 제 블로그에 올립니다.

==== o ==== o ==== o ==== o ====

Q&A with Dr. Brian G. Burton, Corona Ambassador

Dr. Brian G. Burton, Ed.D.은 Burton’s Media Group의 대표이고 Abilene Christian University의 교수이며 코로나 명예 대사 중 한명 입니다. 또한 그는 "코로나로 모바일 앱 개발하기 , Mobile App Development with Corona: Getting Started" 책의 저자이기도 합니다. 이 책은 코로나를 이용해서 모바일 앱과 게임을 개발하는 것을 도와주는 가이드죠.

Dr. Burton 당신의 얘기를 공유해 줘서 고맙습니다.

==== o ==== o ==== o ==== o ====




What is your background and experience in development?

몇몇의 코로나 개발자들 처럼 저는 1980년대에 시작했습니다. 고등학교 때 TRS-80(1977년에 발표된 Radio Shark 사의 개인용 컴퓨터)이 나왔습니다. 완전 매료 됐죠. 그 컴퓨터가 완전 유행이라는 말을 계속 듣긴 했지만 저는 안정적인 GM의 공장 일을 하는 직업을 선택해야만 했습니다. 그러다가 Ball State University 에서 Computer Science과 Management Information Systems을 공부하기로 결심했죠. 그러면서 저는 원래 계획했던 실리콘 밸리로 가는 것보다 진짜로 제가 가르치는것을 좋아하고 있다는 것을 깨달았습니다. 나는 중고등 학교때 computer science를 생각 했었습니다. 재가 그것을 석사 과정을 할 때 우리 가족들은 미주리주로 이사했습니다. 그리고 Ozark Mountains 와 사랑에 빠졌죠.

제 석사와 박사 과정을 할 때 computing을 할지 education을 할 지 정말 고민이 많이 됐었습니다. 그래 둘 다 같이하자! 컴퓨터 쪽을 가르치면 둘 다 만족할 수 있을 것 같았습니다. 석사 과정을 할 때 Freshman level 컴퓨터 코스를 가르치라는 제의를 받았습니다. 동시에 당시 제가 약간 인기가 있어서 college level에서 full time으로 가르치지 않겠느냐는 제의도 받았습니다. 제가 박사과정을 마쳤을 때 당시 14살이던 제 아들이 게임 디자인과 개발을 공부하고 싶다고 얘기하더라구요. 그게 2004년 이었습니다. 그 당시에는 그렇게 명망있는 게임이 없었습니다. 미주리 주립대학에서 Jeff Huff와 같이 일하는 동안 우리는 game level design 전공을 시작했습니다. 거기서는 프로그래밍과 그래픽 디자인을 가르쳤습니다. 그 강좌는 중부 미주리에서 인기있는 강좌가 됐습니다.

How and why did you become interested in developing mobile apps?

2007년 그 게임 개발 강좌가 성공했다는 것이 알려져 Alma Mater가 텍사스로 옮겨서 그런 강좌를 시작하는게 어떻냐고 제의를 했습니다. 이 시기는 애플 (Apple) 이 iPod Touch와 첫번째 세대 iPhone을 내 놓은 시기였습니다. 저도 어얼리 어답터 중의 한명이었습니다. 그래서 2009년 모바일 앱 개발 강좌를 가르치기 시작했습니다. (스탠포드가 그들의 첫번쨰 코스를 가르친 후 단 몇 주 후의 일이었습니다). 그 코스는 아주 성공적이었습니다. 그래서 그 강좌는 곧바로 정규 강좌로 채택 됐습니다.

2010년대 초 저는 제 학생들과 첫번 째 앱을 개발했습니다. iPad에서 학교 신문을 보여주는 앱이었습니다. (iPad 는 토요일에 나왔고 그 앱은 바로 다음 월요일에 선보였습니다) 그 프로젝트 이후로 학급에서는 꾸준히 다른 앱을 개발하자는 요구가 이어졌습니다.

How did you learn about Corona and what do you like about it?

2010년 초 앱을 개발하는데 좀 더 좋은 방법이 있다는 것을 알게 됐습니다. 저는 iOS 와 안드로이드에서 동시에 동작하는 모바일 앱이나 게임을 만들고 싶었거든요. 그렇게 할 수 있는 툴이 없을까 찾다가 보니까 그런 방법을 고민하는 그룹들이 별로 안 된다는 것을 알았습니다. iOS와 안드로이드 앱이나 게임 개발을 동시에 지원하는 회사는 오직 Ansca Mobile의 Corona 뿐이었습니다. 그래서 이 코로나를 한번 배워보자고 생각했습니다. 금방 매료가 됐죠. 여름 방학동안 제 블로그에 이 툴을 어떻게 사용하는지에 대한 정보를 올렸습니다. 그리고 그해 가을 그것을 거의 1/3 학기 동안 가르쳤습니다. 학생들은 코로나에 대해서 좀 더 보여주길 바랬죠. 그래서 금요일 수업은 코로나에 대해서만 공부하기로 했습니다. 그 클래스 프로젝트로 우리는 Space Explorer 의 초기 버전을 개발했습니다. (이 앱에 대한 내용은 제 책 9장과 10장에 있습니다.)

지금은 코로나로 인해서 컴퓨터 관련 학과 이에의 곳에서도 모바일 앱과 게임 개발 클래스를 해 달라는 제의를 받고 있습니다. 저는 코로나가 누구에게나 앱과 게임 개발을 가능하게 할 거라고 믿습니다.

What interesting projects have you worked on (Corona and non-Corona related)?

작년에 저는 제 클래스에서 사용할 코로나에 대한 책이 하나도 없다는 것이 문제라는 생각을 했습니다. 그래서 책을 쓰기로 작정했죠. 결과적으로 저는 두개의 책을 썼습니다. 하나는 학과 수업을 위한 것이구요. (Beginning Mobile App Development with Corona) 다른 하나는 제 학부 학생 뿐만 아니라 모든 분들을 위한 책입니다. (Mobile App Development with Corona: Getting Started)

말씀드리고 싶은 것은 이 책을 쓰기 시작했을 때는 단지 제가 가르치는 강좌를 위해서 였습니다. 처음에는 일반인을 대상으로 한 책은 염두에 두지 않았습니다. 그런데 하루는 학부 교재를 출판하는 회사의 영업사원이 제 사무실에 들렀습니다. 그 때 제가 그 책을 썼다고 말했죠. 48시간 만에 저는 계약 제안을 받았습니다. 그 책을 쓰고 그것을 지원할 웹 사이트를 만들고 그리고 몇가지 더 일을 해 달라는 것이었습니다. 그들은 책 판매의 10%를 주겠다고 했습니다. 그리고 다른 몇몇개의 출판사에서 비슷한 제의를 받았습니다. 그 때 저는 제가 쓴 책이 다른 사람들이 읽고 싶어 하는 내용일 수도 있겠구나 라는 생각을 했습니다.

그러다가 이런 생각이 들었습니다. 애플이나 아마존이나 구글에 앱을 출판하면 70%를 받는데 왜 이 책을 쓰고 70%보다 훨씬 못한 돈을 받아야 하나? 그래서 별도로 독립적인 루트를 통해서 출판을 하기로 결심했습니다. 출판사랑 같이 하면 훨씬 더 많은 광고를 할 수 있다는 걸 압니다. 하지만 저는 인디 작가, 인대 앱 개발자가 되는것이 훨씬 행복합니다. 그리고 또 가격도 낮출 수 있구요. 여러분이 제 책을 구매해 주시면 저의 indie work를 도와 주실 수 있습니다.

What projects are you working on next?

Beginning Mobile App Development with Corona를 집필하고 있을 때 몇가지 중요한 일들이 일어났습니다.

1) 모바일 앱 개발이 몇개 주에서 고등학교 수업 과정이 되었습니다.
2) 아주 많은 사람들로부터 모바일 앱과 게임을 개발하고 싶다는 말을 많이 들었는데 어떻게 해야 하는지를 모르고 있었습니다.
3) 제 웹사이트에 단지 코딩 하는 법만 올리는 대신 게임을 만들기 위한 전체 개발 과정에 대해서 알려달라는 요청을 많이 받았습니다.
4) Beginning Mobile App Development with Corona를 다른 나라 말로도 출판 해 달라는 부탁을 많이 받았습니다.

이러한 것들은 저를 지금 현재 하고 있는 몇가지 아주 신나는 프로젝트로 안내했습니다. 첫번째로 새로운 책을 시작했습니다. Learning Mobile Application Development 이 책은 모바일 앱과 게임 프록래밍을 배우기 원하는 프로그래밍 경험이 전혀 없는 사람을 위한 책입니다. 이 책은 고등학생이나 대학을 준비하는 혹은 프로그래밍 경험이 전혀 없는 사람들에게 맞도록 만들고 있습니다. 이 책은 2012년 여름에 나올 겁니다.

두번쨰로 저는 게임을 개발하기 위한 전체 과정에 대해 가르칠 수 있는 책 시리즈를 만들기 위해 몇명의 게임과 그래픽 아티스트 (14살 밖에 안 된 내 아들도 포함해서) 들과 일을 하고 있습니다. 이 시리즈 중 첫번째 책은 2012년 봄에 나올 겁니다.

마지막으로 저는 중국어,한국어,이탈리아어, 포르투갈어, 러시아어 그리고 스패니쉬어로 Beginning Mobile App Development with Corona를 번역하는 작업을 몇몇의 코로나 개발자들과 하고 있습니다.

그리고 제 여가시간에는 개인적으로 앱을 개발하고 있기도 합니다.


반응형


반응형

일단 센차터치에서 그동안 버전업이 됐길래 저는 최신버전으로 새로 받아서 작업하고 있습니다.


제가 받은 버전은 sencha-touch-2.0.0-gpl 입니다.


제가 센차터치 (Sencha Touch) 튜토리얼을 몇개 번역 했는데요.

Component 까지 번역을 했군요.


그런데 실습을 하지 않으면서 계속 번역만 하니까 제가 잘 이해를 못하겠더라구요.

제일 모르겠는건 어떻게 MVC 모델을 적용해서 앱을 만드는지 입니다.


그래서 지난 시간에 했었던 Component 글의 첫번째 예제를 MVC 모델을 적용해서 고쳐 보겠습니다.


먼저 원래 소스는 아래와 같습니다.


var panel = Ext.create('Ext.Panel', {
    layout: 'hbox',

    items: [
        {
            xtype: 'panel',
            flex: 1,
            html: 'Left Panel, 1/3rd of total size',
            style: 'background-color: #5E99CC;'
        },
        {
            xtype: 'panel',
            flex: 2,
            html: 'Right Panel, 2/3rds of total size',
            style: 'background-color: #759E60;'
        }
    ]
});

Ext.Viewport.add(panel);


이것을 app.js에 넣어서 직접 실행해 보려면 아래와 같이 하면 됩니다.


Ext.application({
    name: 'Panel',

    launch: function() {

        var panel = Ext.create('Ext.Panel', {
        layout: 'hbox',

        items: [
            {
                xtype: 'panel',
                flex: 1,
                html: 'Left Panel, 1/3rd of total size aaa ',
                style: 'background-color: #5E99CC;'
            },
            {
                xtype: 'panel',
                flex: 2,
                html: 'Right Panel, 2/3rds of total sizeaaa',
                style: 'background-color: #759E60;'
            }
            ]
        });

        Ext.Viewport.add(panel);
    }
});


보시면 아시겠지만 튜토리얼에 있는 코드를 복사해서 Ext.application 안의 launch:function() 안에 넣으시면 됩니다.


문제는 이 소스를 어떻게 MVC 모델에 맞게 수정하느냐 입니다.


이 소스는 view 만 있는 간단한 소스 입니다. 그러니까 폴더 구조를 아래와 같이 가져가겠습니다.


Panel 폴더가 프로젝트 폴더입니다.

그 안에 index.html과 app.js 가 있습니다. 그리고 sencha-touch.css 와 sencha-touch-all.js는 다운받은 Sencha Touch 소스 파일에서 복사해 넣습니다.


그리고 MVC 패턴을 적용하려면 app 폴더를 만들어야 하는 것 같습니다.

그 app 폴더에 view,controller,model,store 등의 폴더를 만드는데 이 소스에서는 view 만 있으면 되니까 view를 만들었습니다.

저 view 안에 panel.js 파일을 만들어서 그 안에 실제 view 를 담당하는 코드를 넣겠습니다.


일단 index.html 코드를 볼께요.


<!DOCTYPE html>
<html>
<head>
    <title>MVC Sample with Panel</title>
    <link rel="stylesheet" href="sencha-touch.css" type="text/css">
    <script type="text/javascript" src="sencha-touch-all.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>


소스는 간단합니다. html 파일에서는 단지 css와 js 파일을 불러왔습니다.

sencha-touch.css와 sencha-touch-all.js 파일을 Panel 폴더 밑에 복사해 넣었기 때문에 위와 같이 불러왔는데요. 서버에서 동작 시키려면 해당 경로를 써 주셔야 합니다.


그 다음은 app.js 파일을 보겠습니다.


Ext.application({
    name: 'Panel',


    launch: function() {
        Ext.create('Panel.view.panel');
    }
});


소스 코드가 아주 간단해 졌죠?

MVC 모델을 쓰는 이유가 이렇게 app.js를 간단하게 만들고 각 기능별로 폴더와 js 파일을 나눠서 코드를 관리하기 위해서 입니다.

여기서는 launch:function() 안에 Ext.create 함수를 사용해서 Panel.view.panel 을 불러왔습니다.

처음 Panel 은 위에서 설정한 이 애플리케이션의 name 이고 view는 app 폴더 밑에 있는 view 폴더를 가르킵니다. 그리고 맨 마지막 panel 은 view 폴더 밑에 있는 panel.js를 말합니다.


이렇게 하면 app/view/panel.js 파일을 불러올겁니다.


다 하고 나니까 이렇게 간단한데 몰랐을 때는 이것 맞추느라고 엄청 헤맸습니다.


다음은 panel.js 파일을 보겠습니다.


Ext.define('Panel.view.panel', {
    extend: 'Ext.Container',

    config: {
            fullscreen: true,
            layout: 'hbox',
            items: [
            {
                xtype: 'panel',
                flex: 1,
                html: 'Left Panel, 1/3rd of total size',
                style: 'background-color: #5E99CC;'
            },
            {
                xtype: 'panel',
                flex: 2,
                html: 'Right Panel, 2/3rds of total size',
                style: 'background-color: #759E60;'
            }
            ]
    }
});


우선 Ext.define 함수를 사용합니다. 곧바로 이 파일의 경로를 표시하구요.

다음으로는 Ext.Container 를 extend 합니다. 이 부분을 extend 하지 않으면 에러가 납니다.

Container 부분 튜토리얼을 번역 했는데 왜 그런지 아직 딱 떠오르지 않네요. 다시 한번 봐야겠습니다.


그 다음은 config 를 사용하고 그 안에서 화면을 full 로 해 준 다음에 원래 튜토리얼에 있던 소스를 위와 같이 해 주면 됩니다.


여기까지 하느라고 많이 헤맸습니다.


아래 제가 완료한 소스파일 올려 놓습니다. 혹시 저처럼 MVC 패턴 적용이 많이 헛갈리시는 분들은 이 소스가 도움이 되실겁니다.


Panel.zip


다음 글은 계속 센차터치의 튜토리얼을 다루겠습니다.

될 수 있는대로 소스코드를 이것 저것 변경해 보고 적용해 봐야 완전히 제것이 될 것 같군요.


다음에는 각 디바이스별로 화면을 달리 하는 Profile 을 한번 적용해 볼까 합니다.

반응형

Corona SDK 수요일의 FAQ

2012. 4. 22. 01:12 | Posted by 솔웅


반응형

지난주부터 코로나에서는 새로운 블로그 코너를 만들었습니다.


매주 Corona SDK 웹사이트의 포럼이나 댓글에 달린 질문 중에 자주 질문되는 것 몇가지를 골라서  답을 주는 그런 코너입니다.


지난주 수요일에는 5가지가 올라와 있는데요.


저나 여러분한테도 도움이 될 것 같아 이렇게 번역해서 글을 올립니다.


====== o ==== o ==== o =====


FAQ Wednesday  

Posted by Tom Newman

이 블로그 포스트는 새로운 시리즈인데요. 매주 수요일 코로나 댓글이나 포럼등에서 자주 나오는 질문들 (FAQ)을 모아서 이에 대한 답을 올리려고 합니다. 그 질문들은 코로나를 사용하고 계신분들도 있고 아니면 처음 접하시는 분들도 계실 겁니다.

이제 시작하겠습니다.






Question 1

코로나 시뮬레이터를 돌릴 때 코로나 터미널에 print 메세지를 볼 수가 있는데요. Xcode iOS 시뮬레이터나 iOS 디바이스에서 돌릴 때는 print로 찍은 메세지를 볼 수 없습니다. 뭐가 잘못 된 것일까요?

Answer

만약 Xcode를 사용해서 앱을 로드하거나 iOS 디바이스를 테스트 한다면 Xcode 콘솔에서 print 메세지가 display 될 겁니다. Xcode iOS 시뮬레이터를 사용하고 계신다면 Mac의 콘솔앱을 start 하시면 그 메세지를 보실 수 있을 겁니다. 만약 안드로이드 디바이스를 테스트 하신다면 안드로이드 SDK를 다운받아서 adb logcat을 사용하셔야 print 메세지를 보실 수 있습니다.

Tip: 만약 print 메세지를 즉각즉각 확인하시지 못하신다면 main.lua 파일 맨 위에 아래 코드를 붙여 주세요.
io.output():setvbuf('no')


Question 2


display object의 x,y 위치를 세팅하는게 헛갈립니다. 제가 생성할 때의 값이 생성된 이후에도 똑 같은 건가요?

Answer


대부분의 객체들이 x,y 포지션으로 위치를 정의하면 top-left 를 기준으로 위치를 잡습니다 그리고 생성된 다음에는 객체의 중심으로 바꿉니다. 예외 적인 경우는 display.newCircle, display.newLine, display.newGroup 입니다. display.newCircle 객체는 원의 중심을 기준으로 생성됩니다. 그리고 display.newLine은 start와 end 포인트를 사용합니다. display.newGroup은 top-left 포인트를 기준으로 생성되고 생성 된 이후에도 x,y 레퍼런스 포인트가 바뀌지 않습니다. 다른 모든 display object 들은 생성되고 나서 center 기준점을 사용합니다. 이 말은 display 객체의 x,y  파라미터를 변경한다면 그 객체는 객체의 중심을 기준으로 해서 움직일 거라는 겁니다. object:setReferencePoint API 생성 후에 어떤 기준점을 사용할 것인지 정할 수 있도록 해 줍니다.

이런 혼란을 피하기 위해서 프로그래머들은 객체를 처음 생성할 때 (top-left 가 기준일 때) 0,0을 만들어 놓고 나서 생성된 후에 그 객체의 x,y 값을 세팅해 줍니다. 이렇게 하면 그 객체의 x,y 포지션은 (별도로 reference point를 변경하지 않는 이상) center를 기준으로 삼게 된다는 얘기입니다.


Question 3


멀티플 터치 객체들을 사용할 때, 스크린에서 그 객체들이 겹쳐질 때 touch 이벤트가 사용되는 것을 볼 때가 있습니다. 이런 경우 어떻게 stop 시켜야 하죠?

Answer

터치 리스너를 call 하게 되면 그 터치가 일어난 곳의 최상위 객체 (top-most object) 에 그 이벤트가 전달 됩니다. 만약 리스너가 true를 리턴한다면 그 event dispatcher는 그 touch event를 stop 시킬 겁니다. 만약에 리스너가 false를 return 하면 dispatcher는 터치된 위치에 있는 그  다음 객체의 touch listener를 볼겁니다. 이러한 작업은 계속 그 밑으로 밑으로 똑 같이 적용 됩니다. 리스너가 true를 return 할 때까지요. 일반적인 실수로는 return 값을 아예 주지 않는 경우인데요. 그렇게 되면 디폴트로 false가 return 됩니다. 그러니까 그 이벤트를 밑의 object에도 적용시키지 않으려면 항상 이벤트 리스너 마지막 줄에 return true를 해 주셔야 합니다.

Question 4

I’m getting build errors saying the code signing was wrong or invalid entitlements. What can cause this?
빌드할 때 code signing 이 틀리거나 invalid 하다고 나옵니다. 왜 그럴까요?

Answer

빌드할 때 에러가 난다면 코드의 syntax 에러는 아닙니다. build.settings를 지우고 한번 빌드를 해 보세요 그래도 에러가 나는지요. build.settings file이 없을 때 에러가 나지 않으면 build.setting 파일쪽이 문제가 있는 겁니다. 그리고 코로나의 샘플 앱을 한번 빌드 해 보세요. (Hello World 같은...) 그러면 여러분의 프로젝트에 문제가 있는지 없는지 알 수 있을 겁니다. 애플리케이션 이름(폴더 이름)을 test 같은 간단한 이름으로 한번 해 보세요. 그럼 애플리케이션 이름에서 문제가 있는지 없는지 알 수가 있을 겁니다.

Question 5

서브디렉토리에 있는 저의 Lua 코드를 로드하기 위해 require를 사용 합니다. 그리고 코로나 시뮬레이터에서는 잘 돌아 갑니다. 그런데 이것을 제 디바이스에서 돌리면 충돌이 일어납니다. 코로나에서는 서브디렉토리로부터 코드를 로딩하는 것을 지원하나요?

Answer

예 서브디렉토리안에 Lua 코드를 만드실 수 있습니다. 하지만 주의하셔야 할 부분이 있습니다. 코로나 시뮬레이터와 디바이스 사이에는 약간 다른 부분이 있습니다. 첫번째로 require 구문에 있는 파일 이름은 실제 파일 이름이어야 합니다. 일반적인 에러는 실제 파일 이름은 testlib 인데 그 구문에서는 require("Testlib") 이라고 하면 에러가 납니다. 코로나 시뮬레이터에서는 둘 다 작동을 하지만 디바이스에서는 작동하지 않을 겁니다.

두번째로는 subdirectory를 어떻게 표기 했는가 입니다. 맞는 표기는 . 을 사용하는 겁니다. 만약 여러분의 라이브러리 파일이 test.lua 이고 그것이 library 서브디렉토리에 있다면 test = require("library.test") 라고 해야 합니다.

코로나 시뮬레이터에서는 디렉토리 구분자로 . (마침표) 뿐만 아니라 / (슬래시)도 허용합니다. 하지만 디바이스에서는 / 를 사용하면 에러가 날 겁니다. 디바이스에서는 항상 구분자로 . 을 사용해야 합니다. 그러므로 루아 파일의 이름에는 . 가 들어갈 수 없습니다.

한가지 더 말씀 드리자면, 가끔 require 구문을 괄호 없이 사용하는 경우가 있습니다. 이것은 오직 한개의 함수 파라미터만 존재하고 그것이 스트링이거나 테이블일 경우에만 허용됩니다. 그래서 위에 썼던 예제를 이 형식으로 사용한다면 test = require "library.test" 가 될 겁니다.


여기까지가 오늘의 FAQ 입니다. 오늘의 FAQ를 통해서 뭔가 새로운 것을 배우셨기를 바랍니다. 만약 질문이 있으시면 forum들에 올려 주세요. 아니면 댓글에 올려 주시던가요. 여기에 짧게 댓글을 다셔도 됩니다. 하지만 되도록 forum 을 이용해 주실것을 부탁드립니다.

반응형