프로그래밍/Corona SDK2014. 2. 19. 15:21

http://docs.coronalabs.com/guide/graphics/migration_g20.html


Graphics 2.0: Migrating from Graphics 1.0 to 2.0

Graphics 2.0: Graphics 1.0을 2.0으로 업그레이드 하기


Updated: 2013.11.18


Overview

개관


This guide explains the changes required to modify existing Graphics 1.0 code to handle some behavioral changes introduced in Graphics 2.0. By migrating your projects, you'll be able to take advantage of all the new graphics features which are not actively supported in Graphics 1.0 Compatibility Mode.

이 가이드는 이미 만들어진 1.0 코드를 2.0 코드로 변경하기 위해 필요한 작업에 대해 설명한다. 이 변경 작업에 의해 1.0 호환 모드에서 완벽하게 지원되지 않는 새 그래픽 기능들을 제대로 활용할 수 있다.


Guides for the new Graphics 2.0 features are available in Corona University. For a list of tutorials, see the Graphics 2.0 Tutorial Roundup.

Corona University에도 새 2.0 그래픽 기능들에 대한 가이드가 있다. 2.0 그래픽 튜토리얼 라운드업에서 튜토리얼들을 체크해 보기 바란다.


Display Objects

디스플레이 오브젝트


The following are behavioral changes to Graphics 2.0 APIs:

2.0 API에서는 이런 부분들이 바뀌었다. 


Constructors

컨스트럭터


In Graphics 1.0, display object constructors had a top/left parameter. These have been reinterpreted as x and y values that specify the object's center point. The original behavior of interpreting the x and y parameter as top/left is available if using V1 Compatibility Mode. You can see the difference by comparing the HelloWorld_v1 and HelloWorld_v2 samples.

1.0 그래픽에서는 디스클레이 오브젝트가 좌측 상단 위치의 파라미터를 가지고 있었는데 이것이 오브젝트의 중심점을 정의하는 x, y 값으로 바뀌었다. 만약 1.0 호환 모드를 사용한다면 이 x, y 파라미터를 예전처럼 좌측 상단 위치값으로 사용 가능하다. HelloWorld_v1과 HelloWorld_v2 샘플에서 차이점을 비교해 볼 수 있다.


Reference points → Anchor Points


The following methods and properties have been removed:

다음 메소드와 프로퍼티는 없어졌다.


setReferencePoint

xReference

yReference

xOrigin

yOrigin


These have been replaced by anchor points, set via object.anchorX and object.anchorY. Anchors have some behavioral differences ? see Understanding Transforms and Anchors for details.

이것들은 object.anchorX와 object.anchorY로 정해줄 수 있는 앵커 포인트로 대체되었다. 앵커 포인트는 예전의 기준점에 비해서 몇 가지 차이점이 있는데 Understanding Transforms와 Anchors for details을 보고 확인하자.


Note that groups do not have anchor points. All operations are based around the group's fixed origin point.

이제 그룹은 앵커 포인트를 갖지 않게 된다는 것을 주목하라. 그룹에 관한 모든 동작은 origin point가 기준이 되어 동작한다. 


Color Definition

색상 정의


For properties like object:setFillColor() and object:setStrokeColor(), RGBA color settings range between 0.0 and 1.0, not between 0 and 255. In addition, APIs that were available in Graphics 1.0 will adopt the new range by default, unless you enable V1 Compatibility Mode.

object:setFillColor()나 object:setStrokeColor(), RGBA 컬러 세팅과 같은 프로퍼티는 이제 0~255가 아니라 0.0~1.0 사이의 값으로 지정하게 된다. 참고로, 1.0에서 사용할 수 있었던 API들은 v1 호환 모드에서 별도로 지정하지 않아도 새 값을 디폴트로 갖는다.


Also note that object:setTextColor() has been deprecated. You should use object:setFillColor() on text objects instead.

그리고 object:setTextColor()가 없어진 것에 주의하라. 이제는 그 대신 텍스트 오브젝트에 object:setFillColor() 를 사용해야 한다.


Widgets

위젯


This section aims to ease the migration of projects containing widgets.

이 부분에서는 위젯을 포함하는 프로젝트의 업그레이드에 대해 설명한다.


Widget Alignment

위젯 정렬


In Graphics 1.0, all widgets were top-left aligned, except for newPickerWheel().

1.0 그래픽에서, 모든 위젯은 newPickerWheel()를 제외하고는 전부 왼쪽 위 정렬이었다.


In Graphics 2.0, all widgets are center aligned for consistency. The default anchoring for all widgets is 0.5 for both the x and y coordinates.

2.0 그래픽에서, 모든 위젯은 일관성을 위해 가운데 정렬이 되었다. 모든 위젯의 중심점 기본값은 가로/세로 중심을 취하기 위해 0.5가 되었다.


TableView

테이블 뷰


The following changes relate to widget.newTableView():

widget.newTableView()에 관한 변경점


* Widget Positioning

위젯 좌표


In Graphics 2.0, the x and y properties of the table view refer to the center of the widget. This is a change from Graphics 1.0 in which the x and y properties were aligned to the top left.

2.0 그래픽에서는, 테이블 뷰의 x, y 값은 위젯의 중심을 참조하게 된다. 1.0에서는 x, y 값이 왼쪽 위로 정렬되어 있었는데 이제 바뀌었다.


* Row Positioning

열 정렬


In Graphics 2.0, the x and y position of the rows ? when inserting objects into a row via the onRowRender method ? will refer to the center of the row.

2.0 그래픽에서, 열의 x, y값은 onRowRender 메소드로 열에 오브젝트를 넣을 때 중심점을 참조하게 된다.


* Example

예제


The following example shows how your Graphics 1.0 code might look, followed by what it should look like in Graphics 2.0:

다음 예제는 1.0 코드에서 변경하는 방법을 보여준다. 


-- Graphics 1.0

local function onRowRender( event )

    local phase = event.phase

    local row = event.row


    -- We cache the row contentWidth and contentHeight because the row bounds can change as we add children

    -- 열의 contentWidth와 contentHeight를 캐쉬한다. 

    local rowHeight = row.contentHeight

    local rowWidth = row.contentWidth


    local rowTitle = display.newText( row, "Row " .. row.index, 0, 0, nil, 14 )


    -- Left-align the label

    -- 라벨을 왼쪽정렬한다

    rowTitle.x = row.x - ( rowWidth * 0.5 ) + ( rowTitle.contentWidth * 0.5 )


    rowTitle.y = rowHeight * 0.5

    rowTitle:setTextColor( 0 )

end


-- Graphics 2.0 (even in V1 Compatibility Mode)

-- 2.0 그래픽(v1 호환 모드도 포함)

local function onRowRender( event )

    local phase = event.phase

    local row = event.row


    -- We cache the row contentWidth and contentHeight because the row bounds can change as we add children

    -- 열 바꿈은 자식을 넣는 것과 같이 바뀔 수 있기 때문에 contentWidth와 contentHeight를 캐쉬한다

    local rowHeight = row.contentHeight

    local rowWidth = row.contentWidth


    local rowTitle = display.newText( row, "Row " .. row.index, 0, 0, nil, 14 )


    -- Left-align the label

    -- 라벨을 왼쪽 정렬

    rowTitle.x = 0

    rowTitle.anchorX = 0


    rowTitle.y = rowHeight * 0.5

    rowTitle:setFillColor( 0 )

end


Removed Libraries and APIs

없어진 라이브러리와 API들


The following libraries and APIs have been removed in Graphics 2.0 and are not available, even in V1 Compatibility Mode:

다음 라이브러리와 API들은 2.0 그래픽스에서 없어졌으므로 사용 불가능하다(v1 호환 모드 포함).


* sprite library

* 스프라이트 라이브러리

  - The legacy sprite library has been removed. Use display.newSprite() instead.

  - 예전의 스프라이트 라이브러리는 없어졌다. display.newSprite()를 대신 사용하자. 

  - If you rely on the old sprite library, a legacy sprite module is available here.

  - 예전의 스프라이트 라이브러리에 의존하고 있었다면, 여기에서 스프라이트 모듈을 구할 수 있다.

  - Update: Particle Candy has been updated to support Corona Graphics 2.0. If your project uses and older version of Particle Candy, you must download and require() this legacy sprite module.

  - Particle Candy가 코로나 2.0 그래픽스를 지원하도록 업데이트 되었다. 만약 여러분의 프로젝트가 Particle Candy의 구버전을 사용하고 있다면, 반드시 이 스프라이트 모듈을 다운로드해야 한다.


* display.newImageGroup()

Use display.newGroup() instead.

 display.newGroup()를 대신 사용한다.


* setReferencePoint() / xReference / yReference / xOrigin / yOrigin

Use object.anchorX and object.anchorY instead.

 object.anchorX와  object.anchorY를 대신 사용한다.



Deprecated APIs

없어진 API들


* textObject:setTextColor()

Use object:setFillColor() on text objects.

 object:setFillColor()를 텍스트 오브젝트에 사용한다.


* line.width

Use line.strokeWidth instead.

line.strokeWidth를 대신 사용한다.


* line:setColor

Use line:setStrokeColor() instead.

line:setStrokeColor()를 대신 사용한다.


* graphics.newGradient()

Create a table of parameters instead. Please see object:setFillColor() for an example.

파라미터의 테이블을 만들어 대신 사용한다. object:setFillColor()의 예제를 확인하라.



2.0 Graphics Features

그래픽스 2.0의 기능들


To learn about the new Graphics 2.0 features, please read the guides in Corona University or see the Graphics 2.0 Tutorial Roundup.

그래픽스 2,0의 새로운 기능들에 대해서는, Corona University에 있는 가이드를 보거나 그래픽스 2.0 튜토리얼 라운드업을 보자.


Posted by windship
프로그래밍/Corona SDK2013. 8. 29. 14:33

* 복합형 스프라이트란


 각각 다른 크기의 이미지를 사용하여 여백의 데이터를 절약하는 비균일 스프라이트에 이어, 그림의 각 부분을 더 작은 그림으로 쪼개서 그걸 조합하는 형식으로 만들어지는 스프라이트이다. 그림을 바꾸어가며 보여주는 일반적인 애니메이션 방식에 더해, 부분의 작은 그림만을 조금씩 이동시키거나 회전시키는 등으로 애니메이션을 줄 수 있다. 작은 동작은 그림 리소스를 바꾸지 않은 채 이런 식의 좌표 이동만으로도 표현할 수 있으므로 용량을 최대한으로 아낄 수 있으며, 무기를 든 인간 캐릭터의 부분별로 이미지를 바꾼다거나 하는 복잡한 처리도 가능하므로 2D 스프라이트 처리에서는 가장 진보된 방식이자 가장 어려운 방식이기도 하다.



* sequenceData 문으로 애니메이션 동작을 관리


 복합 스프라이트를 만들려면 부분별로 나누어진 각각의 파츠에 애니메이션이 있어야 한다. 결론적으로 여러 개의 단일 애니메이션들을 조합하는 것이기 때문이다. 이를 위해 우선 sequenceData 문으로 애니메이션 데이터(이미지 시트)를 다루는 방법에 대해 알아두어야 한다. 시퀀스의 종류는 다음과 같이 4가지가 있다.


1. 단일 시퀀스 (순차 프레임)


이 형식의 시퀀스는 이미지 시트에 있는 애니메이션 프레임들을 순서에 맞게 차례대로 보여준다. 모든 예제들은 graphics.newImageSheet() 항목에서 만들었던 "imageSheet"를 사용한다. (참고 : http://docs.coronalabs.com/api/library/display/newSprite.html#format-for-sequencedata)


local sequenceData =

{

    name="walking",

    start=3,

    count=6,

    time=100,        -- 선택옵션. 단위는 ms. 만약 이 옵션이 주어지지 않으면 스프라이트는 프레임 기반이 된다.

    loopCount = 0    -- 선택옵션. 디폴트는 0. 0으로 세팅되면 무한히 반복된다.

    loopDirection = "bounce"    -- 선택옵션. 값은 "forward"나 "bounce" 중의 하나가 된다.

}


local character = display.newSprite( imageSheet, sequenceData )



2. 단일 시퀀스 (비순차 프레임)


이 형식은 위의 순차 프레임 샘플과 같지만, 대신 애니메이션에 사용할 프레임 인덱스를 열거함으로써 사용하고 싶지 않은 프레임을 빼고 재생할 수가 있다.


local sequenceData =

{

    name="walking",

    frames= { 3, 4, 5, 6, 7, 8 }, -- 애니메이션의 이미지 시트에서의 프레임 인덱스

    time = 50,           -- 선택옵션. 단위는 ms. 만약 이 옵션이 주어지지 않으면 스프라이트는 프레임 기반이 된다.

    loopCount = 0        -- 선택옵션. 디폴트는 0. 0으로 세팅되면 무한히 반복된다.

}


local character = display.newSprite( imageSheet, sequenceData )



3. 다중 시퀀스 


이 형식은 하나의 스프라이트에 여러 개의 애니메이션 시퀀스를 넣는다. sequenceData 배열 안에 순차 시퀀스와 비순차 시퀀스를 다 넣을 수 있다는 사실에 주목하라. 


local sequenceData =

{

    { name="walking", start=1, count=3 },    --> 순차 시퀀스 애니메이션

    { name="running", frames={ 3, 4, 5, 6, 7, 8 }, time=50, loopCount=4 },    --> 비순차 시퀀스 애니메이션

    { name="jumping", start=9, count=13, time=300 }

}


local character = display.newSprite( imageSheet, sequenceData )



4. 다중이미지 시퀀스


이 형식은 하나의 스프라이트에 여러 개의 이미지 시트를 사용한다. 각각의 시퀀스 설정에 이미지 시트의 파라미터(정보)를 넣어서, 그 프레임들이 어느 이미지 시트에서 오는 것인지 알 수 있게 한다.


-- 1번 이미지 시트


local sheetData1 = { width=64, height=64, numFrames=6, sheetContentWidth=384, sheetContentHeight=64 }

local sheet1 = graphics.newImageSheet( "mySheet1.png",sheetData1 )



-- 2번 이미지 시트


local sheetData2 = { width=64, height=64, numFrames=6, sheetContentWidth=384, sheetContentHeight=64 }

local sheet2 = graphics.newImageSheet( "mySheet2.png", sheetData2 )



-- 시퀀스에서, 사용되어야 하는 이미지 시트를 파라미터 'sheet='로 참조하고, 각각의 이미지 시트에 이름을 부여해 놓는다.

-- 처음에는 1번, 즉 seq1 이미지 시트의 애니메이션만 재생된다.


local sequenceData = {                                                                                --> 즉 여기는 초기에 sequenceData로 설정하는 부분

                { name="seq1", sheet=sheet1, start=1, count=6, time=220, loopCount=0 },

                { name="seq2", sheet=sheet2, start=1, count=6, time=220, loopCount=0 }

                }


local myAnimation = display.newSprite( sheet1, sequenceData )

myAnimation.x = display.contentWidth/2 ; myAnimation.y = display.contentHeight/2

myAnimation:play()            --> 애니메이션을 재생시킨다



-- 잠시 딜레이를 둔 뒤, 시퀀스를 'seq2'로 교체한다.


local function swapSheet()

        myAnimation:setSequence( "seq2" )    --> setSequence("이미지시트명") 으로 시퀀스를 교체하는 부분

        myAnimation:play()            --> 애니메이션을 다시 재생시킨다

end


timer.performWithDelay( 2000, swapSheet )  --> 타이머로 시간을 잰 뒤 2000ms가 지나면 swapSheet 함수를 실행한다




* 스프라이트들을 묶어서 큰 스프라이트로 만들기


sequenceData 문으로 각각의 애니메이션 동작을 다루는 방법을 알았다면, 이제 다음 예제 소스를 보자. 이 소스는 시퀀스 데이터들을 그룹으로 묶어서 오브젝트화 시키고 조합된 애니메이션을 만든다.

(원본 출처는 http://www.coronalabs.com/blog/2012/10/09/dynamically-optimized-sprite-sheets/)


-- 스프라이트 파일로부터 데이터를 읽어온다.


local 변수1 = 

{

frames = require("스프라이트파일명").frames   --> *.lua 스프라이트 파일로부터 파라미터를 읽어온다.

}


local sheetData1 = { width=가로크기, height=세로크기, numFrames=6, sheetContentWidth=384, sheetContentHeight=64 }

local sheet = graphics.newImageSheet( "이미지파일",sheetData1 )



-- 시퀀스데이터 내에 이름과 프레임을 분류해서 설정해 넣는다. 


local sequenceData = {

  { name="beachboy_hat_yellow", frames={1} },      --> 단일 비순차 시퀀스지만. 1번 그림 하나만 쓴다. 즉 애니메이션이 없다

  { name="beachboy_body_dark", frames={34} },

  { name="beachboy_shorts_red", frames={42} },

  { name="beachboy_arm_dark", frames={ 5,12,15,19,23,26 }, loopDirection="bounce" },  

--> 단일 비순차 시퀀스. frames={} 안에 설정된 번호의 그림들을 사용. loopDirecrion으로 왔다갔다 재생을 하게 한다.

  { name="beachboy_foot_dark", frames={47} }

}



-- 읽어온 시퀀스데이터 역시도 테이블(배열)로 저장되므로, 내부의 어떤 요소든지 읽어내 참조하거나 값을 변경해 넣을 수 있다. 


local sequenceData =

{

    { name="walking", start=1, count=3 },    --> 순차 시퀀스 애니메이션

    { name="running", frames={ 3, 4, 5, 6, 7, 8 }, time=50, loopCount=4 },    --> 비순차 시퀀스 애니메이션

    { name="jumping", start=9, count=13, time=300 }

}


sequenceData[1].name = "test"   --> 시퀀스데이터 안의 3개의 애니메이션 데이터 중 첫번째 데이터의 name 값을 walking

   에서 test로 바꿔넣는다


print(sequenceData[1].name)  --> name값을 출력해본다. 방금 변경해넣은 test가 출력된다.

print(sequenceData[1].start)  --> start 값을 출력해본다. 1이 출력된다.

print(sequenceData[2].frames[2])  --> 2번째 애니메이션의 frames 데이터 중 2번째를 출력한다. 2번째인 4가 출력된다.


sequenceData[1].start = 25  --> start값을 25로 변경한다.

sequenceData[2].frames = { 22, 33, 44 }  --> 2번째 애니메이션의 frames 데이터 배열을 아예 바꿔버렸다.


print(sequenceData[1].start)  --> 다시 한번 start값을 출력한다. 이번엔 1이 아닌 25가 출력된다.

print(sequenceData[2].frames[2])  --> 2번째 애니메이션의 frames 데이터 중 2번째를 다시 출력해본다. 4가 아니라 33이 

     출력된다.



-- 캐릭터를 위한 디스플레이 그룹을 만든다. 보통의 display.newSprite 함수로 만들어지는 하나의 스프라이트들을 이 그룹으로 묶게 된다. 


local beachboy = display.newGroup()



-- 스프라이트로 각 몸의 파츠를 만든다.


local hat = display.newSprite( sheet, sequenceData )    

      hat : setSequence( "beachboy_hat_yellow" )

                    --> 보통 단일 스프라이트를 만들때 쓰는 것과 같은 구문이다. 다만 setSequence 문을 이용해 beachboy_hat_yellow의 

  내용으로 애니메이션 시퀀스를 교체한다.

local body = display.newSprite( sheet, sequenceData )

      body : setSequence( "beachboy_body_dark" )

local shorts = display.newSprite( sheet, sequenceData )

      shorts : setSequence( "beachboy_shorts_red" )

local rightArm = display.newSprite( sheet, sequenceData )

      rightArm : setSequence( "beachboy_arm_dark" )

local leftArm = display.newSprite( sheet, sequenceData )

      leftArm : setSequence( "beachboy_arm_dark" )

local rightFoot = display.newSprite( sheet, sequenceData )

      rightFoot : setSequence( "beachboy_foot_dark" )

local leftFoot = display.newSprite( sheet, sequenceData )

      leftFoot : setSequence( "beachboy_foot_dark" )



-- 각 파츠의 위치 설정 및 왼쪽/오른쪽 팔의 위치, 확대축소 비율. 팔은 하나의 그림을 뒤집어 사용하기 때문에 .xScale = -1 을 준다.


shorts.x, shorts.y = 0, 15

leftArm.x, leftArm.y = -20, -18

leftArm.xScale = -1  --> 애니메이션 leftArm을 가로로 뒤집는 부분



-- 각 파츠들을 아래에서부터 위의 순서대로 디스플레이 그룹에 넣는다. 


beachboy:insert(leftFoot)

beachboy:insert(rightFoot)

beachboy:insert(shorts)

-- etc...



-- STORE REFERENCES TO EACH ELEMENT

-- 각 파츠에 대한 레퍼런스를 설정한다.


beachboy["feet"] = {leftFoot, rightFoot}

beachboy["shorts"] = shorts

beachboy["body"] = body

-- etc...





Posted by windship
프로그래밍/Corona SDK2013. 8. 28. 16:24
번역 : windship (windship@gmail.com)



graphics.newImageSheet()

타입

라이브러리graphics.*
리턴값ImageSheet
버전Current Public Release (2013.1137)
키워드sprite sheet, texture atlas, texture memory, images
참고Image Sheets (Sprite Sheets)

ImageSheet objects allow you to load multiple graphics from a single image file (also known as a spritesheet). Image sheets can be used for static images (useful for preloading many static images) and animated sprites.

ImageSheet 오브젝트는 하나의 이미지 파일로부터 여러 장의 조각 그림을 얻어낸다(spritesheet라고도 불리운다). 이미지 시트는 정적인 이미지들을 미리 로드하거나, 애니메이션 스프라이트를 만드는 데에 사용된다.

텍스처 샘플링

By default, new image sheets will use a linear sampling filter, so that the image will look smooth when the actual rendered region is larger or smaller than the pixel dimensions of the loaded texture.

기본적으로, 이미지 시트는 linear 샘플링 필터를 사용하게 되며, 로딩된 텍스처의 실제 크기보다 렌더링되는 크기가 크거나 작으면 이미지가 부드럽게 필터링되어 보이게 된다.

You can change the default texture filter by callingdisplay.setDefault(). Once an image is loaded the first time, the same sampling filter will be applied for any subsequent loads of the same file. This is because textures are loaded once per file.

텍스처의 필터링 방식은 display.setDefault() 함수를 호출함으로써 바꿀 수 있다. 처음 이미지 하나가 로드되면, 같은 파일을 여러번 로드하더라도 같은 필터가 계속 적용된다. 이것은 텍스처가 파일당 한번만 로드되기 때문이다.

Gotchas

Image sheet packing tools such as Texture Packer will output thesourceXsourceYsourceWidth, and sourceHeight parameters fortrimmed frames. When displaying these frames on the screen, the image will be positioned in respect to the center point of the untrimmed frame size.

Texture Packer와 같은 툴을 사용해 만든 이미지 시트는 조각그림을 자르는 데 필요한 sourceX, sourceY, sourceWidth, sourceHeight과 같은 파라미터 정보를 포함시킨다. 스크린에 이 그림들을 표시할 때, 이미지는 잘리지 않은 프레임 사이즈의 중점을 참고하여 표시된다.

graphics.newImageSheet( filename, [baseDir, ] options )
filename (필수)

String. This is the filename of the image file that includes all frames of the image sheet. This file is also called a spritesheet image.

문자열. 이미지 시트의 모든 프레임이 들어있는 이미지 파일의 파일명이다. 이 파일은 spritesheet 이미지라고도 불린다.

baseDir (선택)

Constant. Specifies the base directory where filename is located. Options include system.ResourceDirectory,system.DocumentsDirectorysystem.TemporaryDirectory andsystem.CachesDirectory. Default is system.ResourceDirectory.

상수. 위의 이미지 파일이 있는 디렉토리명이다. system.ResourceDirectory,system.DocumentsDirectorysystem.TemporaryDirectory 그리고 system.CachesDirectory 를 옵션으로 선택할 수 있으며, 디폴트는 system.ResourceDirectory이다.

options (필수)

Table. Table with keys that represent specific options related to the resulting image sheet. There are two different formats for this table: Simple and Complex. See 'Formats for options' below.

테이블. 키를 가진 테이블로써 이미지 시트에 관련된 특정 옵션들을 제공한다. 이 테이블에는 간단한 것과 복합적인 것 2가지 형식이 있다. 아래의 옵션 형식 항목을 보라.

options에 사용되는 형식들

단 타입

This configuration assumes all frames in the image sheet texture share identical properties.

이 형식은 동일 프로퍼티를 공유하는 이미지 시트 텍스처의 모든 프레임을 포함한다.

local options =
{
    width = 50,
    height = 50,
    numFrames = 3
}
width (필수)

Number. Width of all images (frames) in the image sheet texture.

수치값. 이미지 시트 텍스처에 있는 모든 이미지들(프레임들)의 가로폭.

height (필수)

Number. Height of all images (frames) in the image sheet texture.

수치값. 이미지 시트 텍스처에 있는 모든 이미지들(프레임들)의 세로폭.

numFrames (필수)

Number. Total number of images (frames) in the image sheet.

수치값. 이미지 시트에 있는 모든 이미지들(프레임들)의 총 갯수.

border (선택)

Number. The border around each frame, typically used for tiles whose edges are extruded to eliminate seam artifacts. Default is 0. When > 0, this overrides the trimming options for cropping the frame.

수치값. 각 프레임 사이의 경계선. 보통 타일 경계선이 흐려지거나 할 때를 위해서 쓴다. 디폴트값은 0. 만약 0보다 큰 값이 설정되면, 프레임을 자를 때 자르는 옵션이 된다.

합 타입

This configuration is required if the image sheet has frames of varying sizes. In this configuration, options consists of an array of tables within a parent frames table. Each table in the array represents a single frame in the image sheet.

이 설정은 크기가 제각각인 프레임을 가진 이미지 시트가 필요할 경우 사용한다. 이 설정에서, options는 부모 frames 테이블 안에 있는 테이블 배열을 상속받는다. 배열 안의 각 테이블들은 이미지 시트 안의 하나씩의 프레임을 되돌린다.

local options =
{
    frames =
    {
        -- FRAME 1:
        {
            x = 0,
            y = 70,
            width = 50,
            height = 50
        },

        -- FRAME 2:
        {    
            x = 50,
            y = 70,
            width = 45,
            height = 55
        },

        -- FRAME 3 and so on...
    }
}
(필수)

Number. x-location of the frame in the texture.

수치값. 텍스처 내에서 프레임의 가로 위치.

(필수)

Number. y-location of the frame in the texture.

수치값. 텍스처 내에서 프레임의 세로 위치.

width (필수)

Number. Width of the frame (if cropping, specify cropped width here).

수치값. 프레임의 가로 크기. (만약 잘린다면 여기에 잘릴 가로 크기를 명시한다)

height (필수)

Number. Height of the frame (if cropping, specify cropped height here).

수치값. 프레임의 세로 크기. (만약 잘린다면 여기에 잘릴 세로 크기를 명시한다)

sourceWidth (선택)

Number. Width of the original uncropped frame. Default: same as width (required parameter).

수치값. 잘리지 않은 프레임의 원래 가로 크기. 기본값은 width와 같다.

sourceHeight (선택)

Number. Height of the original uncropped frame. Default: same as height (required parameter).

수치값. 잘리지 않은 프레임의 원래 세로 크기. 기본값은 height와 같다.

sourceX (선택)

Number. The x-origin of the crop rect relative to the uncropped image. Default: 0.

수치값. 잘리지 않은 이미지에 대응하는 잘린 사각형 영역의 가로 기준점. 디폴트값은 0.

sourceY (선택)

Number. The y-origin of the crop rect relative to the uncropped image. Default: 0.

수치값. 잘리지 않은 이미지에 대응하는 잘린 사각형 영역의 세로 기준점. 디폴트값은 0.

border (선택)

Number. The amount of pixels around each individual frame. This is necessary for scaling image sheets without getting blending artifacts around the edges. Default: 0.

수치값. 각각의 프레임 둘레의 픽셀의 양. 이미지 시트가 확대/축소될 때 외곽선에 필터가 영향을 끼치는 것을 막기 위해 사용된다. 디폴트값은 0.

간단 타입 예제:

local options =
{
    -- 아래 파라미터는 필수

    width = 70,
    height = 41,
    numFrames = 2,

    -- 아래 파라미터는 선택적이다. 동적 해상도 지원에 사용된다

    sheetContentWidth = 70,  -- 전체 시트의 원래 100% 가로 사이즈
    sheetContentHeight = 82  -- 전체 시트의 원래 100% 세로 사이즈
}

local imageSheet = graphics.newImageSheet( "fishies.png", options )

복합 타입 예제:

local options =
{
    -- 각각의 프레임을 되돌려 주는 배열 테이블 (필수)
    frames =
    {
        -- 프레임  1:
        {
            -- 각각의 프레임마다 이하의 파라미터는 전부 필요하다
            x = 2,
            y = 70,
            width = 50,
            height = 50
        },

        -- 프레임 2:
        {
            x = 2,
            y = 242,
            width = 50,
            height = 52
        },
    },

    -- 선택 파라미터 : 동적 해상도 지원에 필요하다
    sheetContentWidth = 1024,
    sheetContentHeight = 1024
}

local imageSheet = graphics.newImageSheet( "imageframes.png", options )


Posted by windship
프로그래밍/Corona SDK2013. 8. 28. 15:34

Understanding Lua tables in Corona SDK

Corona SDK의 루아 테이블 이해하기


 Posted on June 21, 2011. Written by  Jonathan Beebe

원문 : http://www.coronalabs.com/blog/2011/06/21/understanding-lua-tables-in-corona-sdk/

번역 : windship (windship@gmail.com)




What Are Tables?

테이블이란 무엇인가?


If you’re familiar with other programming languages, then most likely, you’re already familiar with arrays and dictionaries. In Lua, a table is a mixture of both (which is why they are so flexible and powerful).

당신이 다른 프로그램 언어에 익숙하다면, 아마 당신은 이미 딕셔너리나 배열에 익숙한 상태일 것이다. 루아에서 테이블은 배열과 딕셔너리를 합친 개념이고, 이것이 루아 테이블이 유연하고 강력한 이유이다.


If the Corona SDK is your first foray into the programming world, however, the description above probably means nothing to you. In that case, you can think of a table as a dresser.

만약 당신이 코로나 SDK로 처음 프로그래밍을 하는 것이라면, 설명은 거의 당신에게 도움이 안 될 지도 모른다. 그렇다면, 테이블을 옷장이라고 생각하라.


The drawers of the dresser would be known as “keys”, and the stuff (data) you’d put into the drawers is what’s known as the “value”. Where Lua tables differ from real drawers, however, is that you can place complete dressers (tables) within the individual drawers!

옷장의 서랍들은 "키(key)"라고 불리며, 서랍 안에 들어갈 내용물들을 "값(value)"라고 부른다. 루아 테이블이 실제의 서랍과 다른 점은, 당신은 그 서랍 안에 또 다른 옷장을 넣을 수도 있다는 점이다!


Before we go any further, let’s break down what you’ve learned so far:

좀 더 깊숙이 연구해보기 전에, 일단 배운 것을 한번 점검해 보자.


Tables hold data (aka “stuff”). Data can be of any type, to include functions.

Tables can also hold other tables.

테이블은 데이터(내용물)을 가진다. 데이터는 어떤 타입도 될 수 있고, 함수를 포함하기도 한다. 테이블에는 또 다른 테이블이 들어갈 수도 있다.


A “key” is the location where data is stored (like a drawer).

A “value” is the data that’s stored in a specific key.

"키"는 데이터가 들어가는 곳의 위치이다(서랍처럼).

"값"은 특정 키의 위치에 저장된 데이터이다.


And that’s probably the most basic explanation of Lua tables as you can get. In the following sections, I’ll show you how to define tables, how to store/retrieve the data within tables, and also how to use tables in conjunction with a “for” loop.

그리고 이것이 보통 듣게 되는 루아 테이블의 기본적인 설명이다. 다음에 나올 섹션에서, 어떻게 테이블을 정의하고, 테이블 안에 데이터를 저장하고 참조하며, "for" 루프를 이용해 테이블에 접근하고 응용하는 방법을 배워보도록 하겠다.



Defining Tables

테이블 정의하기


And by defining, of course, I mean creating a table so you can use it whenever you want. For now, I’ll focus on creating a blank table, with no data in it. This is going to be our brand new dresser:

테이블을 정의함으로써, 언제든지 원하는 테이블을 만들고 사용할 수 있다. 지금은 데이터가 들어있지 않은 빈 테이블을 만드는 것에 대해 중점적으로 설명하겠다. 


    local myTable = {}


A table is just another variable in Lua, so it’s defined the same way: just a variable name separated by an equals sign and the data you want to store in the variable.

테이블은 루아에서 단지 좀 다른 형태의 변수에 지나지 않는다. 그러므로 테이블을 만드는 것은 변수를 만드는 것과 같은 방법으로 만들 수 있다. 


The way Lua can tell it’s a table is, you guessed it, because of the brackets. Anywhere you see an opening bracket ( “{” ) in Lua, you know it’s a start of a table. The end of a table is always denoted by a closing bracket ( “}” ). You’ll see these all along, many times as arguments within functions, so it’s important for you to be able to identify them as tables whenever you see them.

루아에서 테이블을 설정하려면 브래킷("{}")을 사용한다. 루아에서는 어디서나 "{" 기호를 볼 수 있는데, 이것을 본다면 테이블이 생성되는구나 라고 생각하면 된다. 테이블의 끝은 닫히는 "}" 브래킷 기호로 끝난다. 함수 등에서도 흔히 볼 수 있으며, 언제든 테이블을 봤을 때 그 내용을 판단하는 데에 매우 중요하다.


Now that you have a blank table (myTable), it’s time to start storing stuff in it! Next I’ll go over the different ways to store data into a table, and also how to retrieve that data.

이제 우리는 빈 테이블(myTable)을 갖게 됐다. 이제 안의 내용물을 정렬할 시간이다. 테이블 안에 데이터를 넣는 다른 방법과, 그 데이터를 검색해 찾는 방법을 설명해 보겠다.



Tables as Arrays

배열로써의 테이블


Below are three different ways you can use a table as a numerical array. Each “method” shown below is completely identical. They are simply three ways to do the same exact thing.

아래에 테이블을 수치값 배열로 사용할 수 있는 3가지 방법이 있다. 아래에 나오는 각각의 "메소드"는 완전히 동일한 효과를 가진다. 이것은 단지 정확히 같은 작업을 수행하는 3가지 다른 방법의 예를 설명한다.


The fourth method is exactly the same as the third, but it shows how line breaks aren’t necessary?you’ll see this one a lot when passing tables as arguments to functions.

네번째의 메소드는 세번째 메소드와 완전히 같지만, 라인 브레이크를 쓰지 않아도 되는 방법이다. 테이블을 함수에 인자로 보낼 때 이런 메소드를 많이 보게 된다.


METHOD 1:

메소드 1:


    local colorTable = {}


    colorTable[1] = "blue"

    colorTable[2] = "red"

    colorTable[3] = "yellow"

    colorTable[4] = "green"

    colorTable[5] = "purple"


    print( colorTable[3] )  -- "yellow"가 출력됨


METHOD 2:

메소드 2:


    local colorTable = {

        [1] = "blue",

        [2] = "red",

        [3] = "yellow",

        [4] = "green",

        [5] = "purple"

    }


    print( colorTable[3] )  -- "yellow"가 출력됨

    

METHOD 3:

메소드 3:


    local colorTable = {

        "blue",

        "red",

        "yellow",

        "green",

        "purple"

    }


    print( colorTable[3] )  -- "yellow"가 출력됨

    

METHOD 4:

메소드 4:


    local colorTable = { "blue", "red", "yellow", "green", "purple" }


    print( colorTable[3] )  -- "yellow"가 출력됨

    

Once again, the examples shown above all produce the same thing. A table with five different keys, all with the same value. As a Corona developer, you’ll see every single one because they all depend on personal preference.

한번 더 이야기하지만, 위의 예제는 전부 같은 결과를 보여준다. 5개의 키를 가진 테이블이 있고, 안에 들어있는 값도 전부 같다. 


When a table is used as a numerical array, the keys are all numerical values that go in order (starting from 1, not 0 as with most other programming languages). The print statement in each example (above) shows you how to access data in a table by placing their index number between square brackets ( “[]” ).

테이블이 수치 배열로 사용될 때, 키들은 전부 숫자값이 되며 순서를 나타내게 된다(1부터 시작한다. 다른 대부분의 프로그램 언어들처럼 0부터 시작하지 않는다). 위의 각각의 예제에 있는 print 명령은, [] 기호 사이에 인덱스 숫자값을 넣음으로써 테이블에 있는 데이터를 바꾸는 방법을 보여준다.


Also remember, whenever you define a table, keys are always separated by commas, with the final key not requiring one.

그리고 기억하자. 언제든 테이블을 정의할 때, 키들은 ","(콤마)로 정렬되고, 가장 마지막 키에는 콤마를 붙이지 않는다.


To get the total count of a table with numerical keys, you can do so by using the ‘#’ sign in front of the table name, like so:

숫자 키를 가진 테이블의 전체 갯수를 얻고 싶을 때에는, 테이블명 앞에 "#" 기호를 붙이면 된다. 다음 예제를 보자.


print( #colorTable )    -- 5가 출력됨



Tables as Dictionaries

딕셔너리로써의 테이블


Lua tables can also behave like dictionaries from other programming languages (aka, “associative arrays”). Below is an example of a table behaving like a dictionary:

루아 테이블은 또한 다른 프로그램 언어의 딕셔너리처럼 사용될 수도 있다(연관 배열이라고도 불린다). 딕셔너리처럼 사용되는 테이블의 예제를 보자.


    local colorTable = {

        sky = "blue",

        grass = "green",

        water = "blue",

        lava = "red"

    }


    colorTable.dirt = "brown"


    -- 데이터 액세스하기


    print( colorTable.grass )   -- green이 출력됨

    print( colorTable["dirt"] )  -- brown이 출력됨

    

In the above example, you can see the keys are NOT defined numerically, and that’s the main difference here. Sometimes, data is easier to identify using this method because of the way you’re able to access the data.

위 예제에서는, 키들이 숫자로 정의되어 있지 않다. 키 값이 문자로 되어 있을 때엔 위와 같은 방식으로 액세스하는 것이 데이터를 다루기 쉽다.


Instead of accessing data using numbers, you can “associate” the keys with words instead. In the example above, you see two different methods of accessing the data:

숫자를 사용해 데이터를 액세스하는 대신, 단어로 된 키값을 연관시키는 것이다. 위 예제에서는 데이터에 액세스하는 두 가지 다른 방법을 볼 수 있다.


    colorTable["sky"]


    -- and...


    colorTable.sky


The two methods shown above are exactly the same?just two different ways to access the same data. And just as with numerical keys, you can add keys later on, as you can see with the dirt key being added after the table was already defined.

위 예제에서 보여지는 두 가지 메소드는 완전히 같다. 단지 같은 데이터에 액세스하는 각각 다른 방법일 뿐이다. 여기에 숫자 키 값을 써서 읽으려고 하면 테이블이 이미 정의된 다음에 들어간 쓰레기 키값만을 볼 수 있다.


And speaking of flexibility, although Lua tables can behave like arrays and dictionaries, they can also behave like both at the same time. If you want, you could mix numerical keys with string-based keys, though this would make for a very confusing table structure. Normally, it’s best to go with either or.

유연성을 위해서, 루아 테이블은 배열이나 딕셔너리처럼 사용될 수 있고, 두 가지 특성을 동시에 나타낼 수도 있다. 원한다면 숫자 키값과 문자열 키값을 동시에 사용할 수도 있는데, 이것이 테이블 문법을 매우 헷갈리게 만든다. 보통은 한가지만 사용하는 게 좋다.



Data Types

데이터형


As mentioned before, tables can hold any kind of data within it’s individual keys. That means you can store additional tables, functions, and function references with the keys of a table, as well as the more common numbers and strings.

전에 설명한 바와 같이, 테이블은 각각의 키에 어떤 형태의 데이터도 저장할 수 있다. 이것은 테이블 안에 단지 숫자나 문자열만이 아니라, 또다른 테이블, 함수, 그리고 또다른 테이블의 키 값을 포함하는 함수 레퍼런스도 데이터로서 저장할 수 있다는 뜻이다. 


Here’s an example of how to store a table within a table (and how to access the data):

다음은 테이블 안에 또다른 테이블을 저장하고 액세스하는 방법을 보여주는 예제이다.


    local people = {

        { name="Bob", age=32, gender="male" },

        { name="Jane", age=29, gender="female" }

    }


    print( people[1].name )     -- Bob이 출력됨


    print( people[2]["gender"] )    -- female이 출력됨

    

There is no limit to how many tables you can store within other tables.

테이블 안에 저장될 수 있는 테이블의 갯수에는 제한이 없다.


Another complex form of data you’ll see stored within the keys of a table are functions and references to other functions. Here’s an example of a reference to a function stored in the key of a table:

테이블의 키에 저장될 수 있는 또 다른 데이터 조합 형태로는 함수, 다른 함수에의 레퍼런스가 있다. 테이블 키에 함수 레퍼런스를 저장하는 예제를 보자.


    local function helloWorld()

        print( "Hello World!" )

    end


    local myTable = {

        name = "Bob",

        func = helloWorld

    }


    myTable.func()  -- Hello World!가 출력됨



    ----------



    local function helloWorld()

        print( "Hello World!" )

    end


    local myTable = { 100, 100, helloWorld, true }


    myTable[3]()    -- Hello World!가 출력됨

    

And here’s how you would store an actual function (not a reference) in a table’s key:

그리고 테이블 키에 실제 함수를 저장시켜 버리는 예제이다.


    local myTable = { 100, 100, function() print( "Hello World!" ); end, true }


    myTable[3]()    -- Hello World!가 출력됨


As you’ve probably already figured out by now, each key within a table is no different than any other variable in Lua. You can store anything you want within it. That’s the best way to look at it.

이미 짐작했겠지만 테이블의 키는 루아의 다른 변수들과 차이가 없다. 키 안에 원하는 어떤 것이라도 넣을 수 있다. 


When tables start getting big and confusing, the best advice I can give is to just look at what’s between the commas separately, as if it is on a line of code by itself. From there, your confusion should start clearing up.

테이블이 커지고 복잡해지기 시작하면, 그 테이블의 구조를 파악하는 가장 좋은 방법은 ","로 나눠진 요소들이 무엇무엇인가를 보는 것이다. 그렇게 하면 구조가 확실하게 파악될 것이다.



Tables and Loops

테이블과 루프


One of the most common purposes of using tables over regular variables is the ability to “iterate” over the keys of a table with a loop.

일반적인 변수가 아니라 테이블을 사용하는 주된 목적 중의 하나는 루프로 테이블의 키와 데이터를 보다 편리하게 액세스하는 것에 있다.


Below is an example of how to iterate through a table with numerical keys:

다음 수치 키값을 가진 테이블을 검색하는 예제를 보자.


    local myTable = { "blue", "red", "yellow", "green", "white", "purple" }


    for i=1,#myTable do

        print( myTable[i] )

    end


    -- 출력:

    blue

    red

    yellow

    green

    white

    purple

    

With everything that I’ve went over so far, the above code should be pretty clear. Iterating over the contents of a table with numerical keys is pretty straight-forward.

지금까지 공부한 내용을 기억한다면 위의 코드는 꽤 알기 쉬울 것이다. 숫자 키를 가진 테이블의 내용은 for 루프에 의해 순차적으로 읽어지고 출력된다.


However, what if your table has key names instead of numbers?

그러나, 만약 여러분의 테이블이 숫자 대신에 문자 키값을 가진다면?


For that, we’ll use the pairs() function (which returns two variables):

그렇다면, pairs() 함수를 사용하자. 이 함수는 2개의 값을 변수를 통해 되돌려준다.


local colorTable = {

    sky = "blue",

    grass = "green",

    water = "blue",

    lava = "red",

    dirt = "brown"

}


for key,value in pairs(colorTable) do

    print( key, value )

end


-- 출력:


sky     blue

grass   green

water   blue

lava    red

dirt    brown


If a table uses names to identify the keys, then you can’t simply get the count and iterate over the keys numerically. Instead, you use the pairs() function with tables that don’t have numerical keys (just as you see in the example above).

테이블이 키값으로 문자열을 가진다면, 이 키들을 수치적으로 카운트하고 정렬하는 것은 간단하지 않다. 위 예제에서 보는 것처럼 pairs() 함수를 사용해야 한다.



Further Reading

더 읽어볼 것들


To get a more complete, well-rounded understanding of tables in Lua, please visit the following two web pages (both of which were extremely useful to me when I was learning):

루아의 테이블에 대해 좀 더 확실하게 이해하고 싶다면 다음 두 개의 웹페이지를 참고하라. 둘 다 필자가 공부할 때 매우 도움이 되었다.


http://www.lua.org/pil/2.5.html

http://lua.gts-stolberg.de/en/Tables.php


The more you see them and use them “out in the wild”, the more clear tables will become. When you finally have a real need for tables is when their power and flexibility will really shine through.

실제로 보고 실습해 보면 테이블이 좀 더 알기 쉽게 다가올 것이다. 테이블의 강력함과 유연성을 알게 되면 정말로 테이블이 필수적인 것이라는 것도 알게 된다.


Feel free to post your questions in the comments section, I’ll try my best to respond to them as they come (be sure to do a quick skim of the comments to make sure your question wasn’t already asked!).

댓글 란에 편하게 질문을 남겨 주시기 바란다. 가능한 한 성심껏 답글을 달도록 하겠다. 다만 이미 있는 질문이 아닌지는 한번 쓱 확인해 주시기 바란다.


Filed Under: Lua, Tutorials.

Create amazing games for iOS and Android with the Corona SDK

45 Responses to “Understanding Lua tables in Corona SDK”



Rob Miracle

Very well done Jonathan!

조나단, 짱임!


June 21st, 2011 Reply


carlos m. icaza

I even learned from reading this. Thanks Jon.

이거 읽고 많이 배웠어. 조나단 고마워.


C.


June 21st, 2011 Reply



Nick W

Nice one, thanks Jon.

멋진 글이네. 고마워 조나단.


Just a quick query does “Joe” turn into “Bob” because of a typo (or have I missed something?)

근데 "Joe"가 "Bob"으로 바뀌지 않았어? 아님 내가 헷갈렸나?


Very clear explanation, I’m not a programmer but could understand it.

아주 알기 쉬운 설명이네. 나는 프로그래머가 아닌데도 이해하기 쉬웠어.


Thanks

고마워.


Nick


local people = {


{ name=”Joe”, age=”32″, gender=”male” },


{ name=”Jane”, age=”29″, gender=”female” }


}


print( people[1].name ) ? output: Bob


print( people[2]["gender"] ) ? output: female


June 21st, 2011 Reply


Jonathan Beebe

@Nick: Nice catch! I’m not sure how or why his name got changed, lol. I updated the article.

좋은 지적이네. 왜 이름이 바뀌었는지 모르겠지만 본문 수정했어.


June 21st, 2011 Reply


Rob

Jon,


These tutorials are great and helping a lot of us get to grips with Lua & Corona. Could I suggest a metatables tutorial and using them for OO in Lua? I use these techniques in my code but I don’t really understand what is really going on ;-)

조나단, 이 튜토리얼 끝내준다. 루아와 코로나 공부에 매우 도움이 됐어. 루아의 객체지향 메타 테이블에 대한 튜토리얼을 부탁해도 될까? 내 코드에 객체지향 메타테이블을 쓰고는 있는데 사실 잘 모르겠어.


Cheers!


Rob


June 21st, 2011 Reply


Altaf

hi Jon,


Thanks for this. MY suggestion is to also to consider a coordinate , scaling tutorial based on best practices for creating apps which can run both on iOS and android.

이 글 고마워. iOS와 안드로이드 양쪽에서 돌아가는 좌표와 스케일링에 대한 튜토리얼도 제안하고 싶은데.


Keep up the good work.

계속 분발해 주시길.


June 21st, 2011 Reply


Mo

WOW! Thank you. Great stuff. Just a quick question about tables. Let say I want to setup a sprites which have position x and y. Could I use something like this:

와, 고마워, 멋진 글이야. 테이블에 대해서 조금 질문하고 싶은데, 위치 x와 y를 가진 스프라이트를 세팅하려고 할 때 이렇게 사용해도 될까?


sprite[1].x = 1000

sprite[1].y = 10

sprite[2].x = 2000

sprite[2].x = 4000

……


Thanks again for wonderful tutorials. I will also suggest one about timers and when they actual get triggered in a lua file(when they are declared or when the lua initialization is finished)

멋진 튜토리얼에 대해 다시 한번 감사를 표하고 싶어. 루아 파일에서 타이머와 타이머가 작동될 때(막 정의됐을때나 루아 초기화가 끝났을 때)에 대한 튜토리얼도 부탁하고 싶네.


Mo


June 21st, 2011 Reply


Jonathan Beebe

@Mo: Yup, you can definitely do that. Just make sure that “sprite” is a table before you start assigning values to its individual keys. Example:

응, 그렇게 정의해도 돼. 다만 "스프라이트"가 값을 넣기 전부터 이미 테이블이 되어야 한다는 것을 알아둬야 해. 예를 들면 다음처럼:


sprite = {}


Also, in your example, sprite[1] and sprite[2] are also tables, because you are assigning values to their individual keys (x & y).

그리고, 당신의 예제에서는 각각의 키(x, y)에 값을 넣었기 때문에 sprite[1]과 sprite[2]도 역시 테이블이 된다는 점을 알아둬.


And thanks for the suggestions everyone.

그리고, 튜토리얼에 대한 제안을 해준 여러분 고마워.


June 21st, 2011 Reply


Piyush

You have removed all the doubts about Tables.

테이블에 대한 모든 의혹을 없애 줬군.


June 21st, 2011 Reply


Mo

Cool. Thanks Jon

짱인데. 고마워 조나단.


Mo


June 21st, 2011 Reply


Chris

Usefull post, Jon!

아주 도움이 되는 글이야 조나단!


Maybe you should mention removing tables aswell (though i guess nil’ing them will work fine ;) )

테이블을 제거하는 방법도 써주는 게 좋을 것 같애. nil을 넣으면 될 거라고 봐.


June 22nd, 2011 Reply


Adrian Eraldo

Thanks Jon!

Loud and clear.

고마워 조나단!


June 22nd, 2011 Reply


paul

Nice ? a clear and succinct definition of tables. Thanks Jonathan!

멋진데. 테이블에 대해 깔끔하고 간결하게 정리돼 있네. 고마워 조나단!


June 22nd, 2011 Reply


Leon

Good one Jon. I have gone back to my game and started using tables now.

이거 멋져 조나단. 난 내가 만들던 게임에 이제 테이블을 적용하고 있어.


June 22nd, 2011 Reply


Dan

Is it possible to remove an item from a table/array like pop it off the list?

테이블이나 배열에서 요소를 제거할 수 있어?


I’m planning on storing a bunch of levels in a table and randomly picking one, then popping it off the table so it can’t be picked again in the same session.

테이블에 많은 스테이지를 저장해 두고 랜덤으로 하나를 가져오게끔 하려고 하는데, 한번 읽어온 건 같은 세션 내에서는 또 가져올 수가 없어.


Thanks.


June 23rd, 2011 Reply


Daniel

@Jonathan Beebe It would awesome if you could write a tutorial about modules and how to use them. I know that I can’t be the only one still lost on them.

모듈과 그 사용법에 대해서도 튜토리얼을 써 주면 고맙겠어. 아마 거기서 막힌 사람이 나 혼자만은 아닐거야.


June 23rd, 2011 Reply


Jonathan Beebe

@Dan: Yes, you can do that. Just use table.remove( table, position ) ? I should’ve went over that in the article!

응 그렇게 해도 돼. 그냥 table.remove( table, position ) 이라고 해주면 될거야.


You can also just set the key to nil, for example:

아니면 그냥 키에 nil 값을 넣어버려도 돼. 예를 들자면:


myTable[3] = nil


또는...


myTable.favoriteColor = nil


@Daniel: Great idea! I’ll definitely add that to the list of upcoming topics. Right now I’m juggling collisions or external modules.

좋은 생각인데! 다음에 쓸 글 리스트에 넣어놓을께. 지금은 충돌에 대해서 쓸지 외장 모듈에 대해서 쓸지 망설이는 중이야.


June 23rd, 2011 Reply


arma9

Why sometimes it used in if block this format, by example:

왜 가끔 블럭이 이런 형식으로 돼 있을 때도 쓰이는 거지? 예를 들어:


local colorTable = {

sky = “blue”,

grass = “green”,

water = “blue”,

lava = “red”,

dirt = “brown”

}


이건 어째서야?


for _,value in pairs(colorTable) do

print( key, value )

end


June 23rd, 2011 Reply


Jonathan Beebe

@arma9: Not exactly sure what you’re asking, but the table you are showing me cannot be indexed numerically, therefore you have to use the pairs() function, which returns two variables: a key, and a value (rather than just an index number, when dealing with numerically indexed tables)

네가 묻는게 정확히 뭔지 모르겠는데, 니가 쓴 테이블은 숫자로는 인덱싱할 수가 없으니까 pairs() 함수를 써야 하고, 그건 키와 데이터 2개의 변수값을 리턴하는거야.


June 23rd, 2011 Reply


Alex

please give a short tutorial on OO best practices

객체지향 개념에 대해서도 짧고 간결한 튜토리얼 좀 써주라.


June 28th, 2011 Reply


Garet

I use tables for pretty much everything! My character = a table, his weapons = a table.

난 거의 대부분의 요소에 테이블을 쓰고 있어. 캐릭터도 테이블, 무기도 테이블.


It’s very useful to layout your weapons and pickups as tables, such as:

무기와 다른 것들을 테이블로 만들면 짱 편해. 예를 들면:


myGun = {}

myGun.sprite = mySprite

myGun.damage = damage


기타등등


Then I can just assign it to my character like:

그러고 나면 캐릭터를 이렇게 정의할 수 있게 되지:


myCharacter.weapon = myGun


Then whenever I want to access something like damage I can simply call:

그럼 난 언제든 대미지나 기타 등등의 것들에 요렇게 아주 간단하게 액세스할 수 있어:


myCharacter.weapon.damage


They make like so much easier :)

쉽잖아?


June 29th, 2011 Reply


Mo

Hello Jon

안녕, 조나단?


One more question if I may: how would you make a table of sprites? For instance 

괜찮다면 뭐 하나 더 물어보고 싶은데, 스프라이트를 위한 테이블은 어떻게 만들어? 예를 들면:

sprites ={}

sprites[1].x = 100, sprites[1].y = 100


but about attaching an image to that table element?

요렇게 쓰는데, 테이블 요소에 이미지를 넣으려면 어떻게 하는거지?


At this I am using sprite1, sprite2 images and their x and y coordinates but I will love to use a table so to make my code more general.

지금은 sprite1, sprite2 이미지랑 x, y좌표를 쓰고 있긴 한데, 코드를 좀 더 제대로 만들고 싶어서 테이블을 써보려고 해.


Thanks a lot for any pointers

어떤 조언이라도 도움이 될거야.


Mo


July 13th, 2011 Reply


Mo

EDIT: Hi Jon. Forget it. I think I figure out ( I should have simply search better this great forum). I will come back here if I have still issues.

수정: 안녕 조나단. 내가 위에 부탁한 건 그냥 무시해줘. 아마 내가 직접 검색해보고 찾아보는 게 좋을 것 같아. 도저히 모르겠으면 다시 올께.


Thanks for a great post again!

좋은 글 써줘서 고마워!


Mo


July 13th, 2011 Reply


Michelle

Jonathan,


Thanks for the post but I do have a question. I am a newby and was still able to catch on to alot of your docment but need some clarity. My gameboard has 16 spaces and I have 16 gamepieces. To complete this game the game pieces will form a specific pattern on the board. This pattern can change but overall it still comes down to the same logic with pieces shifted slightly. I thought about your game array you showed and started doing a ( “1″, “2″, through 16) but then was not sure how to progress from that. How do I know when a piece has landed on a specific spot on the board and once all the pieces are on the board, how do I tell whether the pattern is correct via the logic?

조나단, 좋은 글 써줘서 고마워. 질문이 있는데, 난 아직 초보자고 네 글에서 배울게 많은 사람이지만 좀 더 명확한 게 필요해. 내가 만들고 있는 게임판에는 16개의 칸이 있고 말도 16개 있어. 게임에서 이기려면 말을 게임판에 특정한 패턴으로 늘어놔야해. 이 패턴은 바뀔 수도 있지만 같은 로직으로 만들어지도록 돼 있어. 이것 때문에 1부터 시작해서 16까지 있는 배열을 만들려고 하는데 어떻게 해야할지를 모르겠어. 말이 판의 특정 지점에 놓여졌다는 것, 그리고 모든 말이 다 판에 놓여진 것을 어떻게 알 수 있을까? 그리고 말이 놓여진 패턴이 맞는 패턴인지 체크하려면 어떻게 해야 될까?


July 18th, 2011 Reply



fjal

hi,


how can i get the data which is a table inside a table, i mean like this:

테이블 속의 테이블에 들어있는 데이터를 액세스 하려면 어떻게 해야 되지? 예를 들면:


t = { {a, b, c}, {d, e, f} };


print(t[1]) ??>>> {a, b, c}


how can i print just the letter “a”?

여기서 데이터 "a"를 가져오려면, 어떻게 액세스하지?


TIA


July 24th, 2011 Reply


Jonathan Beebe

To print the letter “a” in your example, you do this:

네 예제에서 데이터 "a"를 액세스하려면, 이렇게 해봐:


print( t[1][1] )


July 25th, 2011 Reply


ZaidiSoft

Hey Jon,

안녕 조나단,


Great tutorial and helped me a lot as newby on Lua.

좋은 튜토리얼 덕분에 나같은 루아 초보자에게 많은 도움이 됐어.


Quck question here. I am trying to make a dictionary app with audio translation included. How will I accomplish that. I think using a table will be a great way to go but how can I associate a word with audio file and access it.

질문 좀 할께. 음성 번역 기능이 있는 사전 앱을 만들려고 하는데, 이걸 어떻게 구현하면 좋을까? 테이블을 쓰면 좋을 것 같은데, 오디오 파일과 단어를 어떻게 연결하고 액세스하면 좋을지를 모르겠어.


August 5th, 2011 Reply


Sean

Jon,


How might I store various image files in a table and call them at random? Any suggestions on how to code this would be greatly appreciated.

여러 개의 이미지 파일을 테이블에 저장하고 랜덤으로 불러오려면 어떻게 하면 될까? 어떤 거라도 코딩하는 방법을 알려주면 매우 고맙겠어.


Thanks,

Sean



August 8th, 2011 Reply


Jonathan Beebe

Hi sean, here’s the most basic way I could think to do that:

안녕 숀, 그걸 하려면 아마 가장 간단한 방법은 이런 걸거야:


local imgTable = {

“image1.png”,

“image2.png”,

“image3.png”

}


local randN = math.random(1,3)

local imageObj = display.newImage( imgTable[randN] )


August 8th, 2011 Reply


Sean

Thanks Jon,


Your suggestion worked like a charm!

고마워 조나단, 알려준 거 완전 잘 된다!


Sean


August 8th, 2011 Reply


luiz

hi,

i want to see a “simple shooter” demonstrating how to crate

a enemies table,a shot tabe and a ship table and how it works all together.

there is a HUGE difference between just read the “syntax” in lua docs and

and have an example demonstrating how tables works in a game.

안녕, 간단한 슈팅 게임 만드는 걸 좀 보고 싶어. 적 테이블, 총알 테이블, 우주선 테이블을 만들고 그게 다 제대로 돌아가는 게임 말야. 루아 문서에 있는 짧은 "문법"을 보는거랑, 실제로 게임에서 돌아가는 예제랑은 완전 다르니까 말야.


August 31st, 2011 Reply


Nicholas Golden

Jon you are a pimp!


I’ve been avoiding tables like the freaking plague! I’ve made a game, i’ve got my structure and then I had to think about saving data like score, level completed etc. Since I never programmed anything before lua/corona, I knew I needed to learn tables.

존 너는 정말 끝내줘! 난 전에 테이블 쓰는걸 완전 꺼렸었어. 전에 게임 만들때 점수나 클리어한 스테이지 수 같은 데이터를 보존해야 됐는데. 루아나 코로나 이전엔 프로그램 한 적이 없어서 테이블을 배워야 한다는걸 알았지.


This really helped me out, I’ve read through this several times and my guess I’ll be reading through this over and over again basically using as my reference doc for tables. It’s really good!

이거 정말 도움이 됐어. 이 글을 몇번 읽어보고 이걸 그냥 내 테이블 참고문서로 하기로 했어. 정말 좋아!


Off to go build a dresser with a dresser containing a dresser. Whoa. lol.

옷장 안의 옷장 안의 옷장이라. 와... ㅋㅋㅋ


-Nick g


September 28th, 2011 Reply


Rodrigo RSCdev

Hello Jonathan,

안녕 조나단,


Just would like to say something…”Thank You Mate!”

그냥 이 한마디만 할께. 정말 고마워 친구!


Help like this article is invaluable.

이 글은 가치를 매길 수 없을 정도로 좋은 글이야.


Regards,

Rodrigo.


October 29th, 2011 Reply


Binod Suman

Hi,


Very thanks for good tutorial and best thing is that you have explained in very basic way. One small question, if I have one table and that is not numerical index based then how to remove item from that table.

좋은 튜토리얼 고마워. 특히 아주 기본적인 방식으로 설명하고 있는게 매우 좋아. 작은 질문이 하나 있는데, 테이블을 하나 만들었고 이게 숫자 인덱스가 아니라면 테이블에서 값을 지울라면 어떻게 해야 되지?


예를 들어서:


local person = {}

person.name=”Jonathan”

person.friend=”Binod”

person.mobile=”9999999999″


Now I have to remove mobile info from person table?

이제 person 테이블에서 mobile 값을 지우려면 어떻게 해야 하지?


Thanks again from sharing very nice tutorial.


Binod Suman

Bangalore, India


December 28th, 2011 Reply


Marco Otte

Hi,

I was wondering if I can dynamically define tables.

So something like this:

안녕, 내가 동적으로 테이블을 생성할 수 있을까? 예를 들면 이렇게:


local theName = {“tableName1″, “tableName2″}

local theName[1] = {}


Then having not only the initial table called ‘theName’ but also a table called ‘tableName1′.

이러면 "theName"이라는 테이블과 "tableName1"이라는 테이블이 생기잖아?


On the Net I found some references to:

내가 검색해서 찾아본 어떤 참고문서에는 이렇게 나와있었어:


local _G['theName[1]‘] = {}


but that doesn’t seem to work with the Corona SDK.

근데 이건 코로나 SDK에서는 잘 작동하지 않는 것 같애.


Thanks!


February 3rd, 2012 Reply


daniel

hi can som one HELPPPPPPPPPP ME i try to spawn 2 monsters and i cant

here is the code i need this because i need to spawn like 30 diferent characters with same properties

누가 나 좀 도와줘. 몬스터 2마리를 불러내려고 하는데 안돼. 아래 코드가 있으니까 좀 도와줘. 30마리의 다른 캐릭터를 같은 속성으로 불러내야 한다구...


local myTable = {“monster1″,”monster2″}

for i=1,#myTable do

local ( myTable[i])= display.newImage”images/mosntruos/monstruo”..i..”.png”)

end


February 8th, 2012 Reply


Jim

Index does not start at zero? Hmmm. That could explain some problems I was having recently. Thanks for taking the time to go over this topic!

인덱스가 0에서 시작하지 않는다구? 흠. 그럼 내가 지금 겪는 문제들의 원인이 뭔지 알겠네. 시간 내서 이런 글 써줘서 고마워!


November 24th, 2012 Reply


vik

I like it very much,very helpful tutorial.

아주 도움되는 튜토리얼이야, 너무 좋아!


December 20th, 2012 Reply


mayank

Nice one dude …..

please give a tutorial on layers..

이거 멋져 친구, 부탁인데 레이어에 대해서도 튜토리얼을 써줘.


January 1st, 2013 Reply


Guillermo

hi guys, how i can get a lenght of table, for example:

안녕 여러분, 테이블의 길이를 얻으려면 어떻게 해야 되지? 예를 들면:


local imgTable = {

“image1.png”,

“image2.png”,

“image3.png”

}


January 4th, 2013 Reply


godslave

Hi guys can i put some variable within lua table like

안녕 여러분, 루아 테이블에 다음과 같이 변수 몇 개를 넣을 수 있을까?


local myTable = {}

myTable.firstVariable

myTable.secondVariable

myTable.thirdVariable


and use these variable letter in my script like

myTable.firstVariable = display.newImageRect( “assets/backgrounds/apple_ash.png”)

그리고 이 변수 이름들을 내 스크립트에 다음처럼 사용할 수 있을까?


March 19th, 2013 Reply


Rob Miracle

Yes, you can, in fact that may be one of my favorite features of Lua. Even if you did:

응 가능해. 사실 그건 루아에서 내가 가장 좋아하는 기능 중의 하나야.


myImage = display.newImageRect(“myimage.png”,width, height)


myImage is a table and you could do:

myImage는 테이블이고 넌 이렇게 하면 돼:


myImage.isActiveImage = true


or whatever creative things you can throw at it.

아니면 그냥 니가 만들고 싶은 걸 넣어버려.


March 19th, 2013 Reply


Philgin

How do you dynamically append to a table without defining a key like:

키를 정의하지 않은 테이블에 동적 참조를 하려면 어떻게 하지?


myTable = {}

myTable[] = “red”

myTable[] = “blue”


Posted by windship
프로그래밍/Corona SDK2013. 8. 27. 18:41

* 테이블이란


 테이블은 루아에서 사용하는 데이터 구조체이다. nil값을 제외하면 숫자뿐 아니라 문자열이나 다른 어떤 값으로도 참조할 수 있는 연관 배열을 구현한다. 타 언어의 배열, 리스트, 셋, 레코드, 그래프 등과 동등하다. 

 루아 테이블은 연관 배열과 닮았다. 연관 배열은 숫자만이 아니라 어떤 자료형도 인덱스로서 사용해 참조할 수 있다. 테이블에 정수 인덱스를 사용하면 배열이 된다. 고정된 크기가 아니므로 필요한만큼 크기가 늘어난다. 테이블을 초기화할 때, 크기는 간접적으로 정해진다.



* 테이블 생성 예제


a = {}     --> "a"라는 이름의 테이블 생성

b = "y"

a[b] = 10    --> 키는 "b", 값은 10인 새로운 요소를 만들어 넣는다

a[20] = "Monday"    --> 키는 "20", 값은 "Monday"인 새로운 요소를 만들어 넣는다

print(a["y"])     --> 10이 출력된다

b = 20

print(a[b])    --> "Monday"가 출력된다

c = "hello"    --> 새로운 변수에 "hello" 값을 넣는다

print(c)        --> "hello"가 출력된다


 5번째 줄을 보면 a["y"]는 3번째 줄에 있는 값을 인덱스로 사용한다는 사실을 알 수 있다. 7번째 줄에서 a[b]는 변수 b의 새로운 값인 20을 인덱스로 사용해 문자열 "Monday"를 값으로 갖는다. 마지막 줄에서 c는 이전 변수들과는 다르게 단지 "hello" 문자열 값만을 가지고 있다.



* 테이블을 배열처럼 사용하기


 테이블 키는 연속적인 정수들을 사용해 만들 수 있는데 1부터 시작하게 된다. 이런 속성을 이용해 배열(또는 리스트)로 사용할 수 있다.


colors = 

{

[1] = "Green",

[2] = "Blue",

[3] = "Yellow",

[4] = "Orange",

[5] = "Red"

}


print(colors[4])           --> "Orange"가 출력된다


 테이블 생성자를 다음처럼 만들면, 일일이 테이블 키를 지정할 필요 없이 좀 더 빠르고 손쉽게 배열을 만들 수 있다.


colors = {"Green", "Blue", "Yellow", "Orange", "Red"}

print(colors[4])          --> 똑같이 "Orange"가 출력된다



* 테이블 내부의 값을 교체하기


 테이블을 사용해 작업 중, 기존 값을 수정, 제거, 또는 새로운 값을 추가할 수도 있다. 할당 연산자를 사용하면 된다. 세 사람과 그들 각자가 좋아하는 음료수를 내용으로 가지는 테이블을 만드는 예를 보자. 어떤 한 사람의 음료수(내용)를 변경할 수도 있고, 테이블에 새로운 사람과 그 사람이 좋아하는 음료수를 세트로 추가할 수도 있으며, 기존에 있던 사람과 음료수를 세트로 제거할 수도 있다.


drinks = {Jim = "orange juice", Matt = "soda", Jackie = "milk"}

drinks.Jackie = "lemonade"    --> 원래 Jackie의 값이었던 "milk"를 "lemonade"로 변경

drinks.Anne = "water"     --> Anne과 "water"를 세트로 추가

drinks.Jim = nil      --> Jim이 테이블에서 제거된다. 

print(drinks.Jackie, drinks.Anne, drinks.Matt, drinks.Jim)    --> 각각의 값을 출력한다


drinks.Jackie의 원래 값인 "milk"는 "lemonade"로 변경된다.

drinks.Anne 키와 그 값인 "water"가 테이블에 새롭게 추가된다. 추가되기 전에 drinks.Anne의 값을 얻으려 하면 nil이 나온다.

drinks.Matt = "soda"는 변경되지 않았으므로 그대로 있다.

drinks.Jim의 원래 값은 "orange juice"이나 값이 nil로 변경된다. 테이블에서 키 Jim이 제거된다.


 주의 : 이 경우 문자열 키 값을 인덱스로 사용해 값을 넣어 배열을 만들었는데, 이 배열은 정수를 사용한 순서와는 관계 없다. 즉 위 예제에서 Jackie의 값을 얻기 위해 print(drinks[3]) 을 실행해도 nil 값만 나온다. 위 예제와 같이 문자열을 인덱스로 사용해 배열을 만들었을 때 그것을 순서대로 참조하기 위해서는 별도로 for문 등을 이용해 순서를 매겨서 판단해야 한다. 



* 테이블의 크기(요소의 갯수) 구하기


 위 항목에서 설명했듯이 루아의 테이블은 동적으로 생성되고 자동으로 크기가 변하므로 그 갯수를 파악하거나 어떤 자료가 몇번째에 들어가있는지 수치적으로 참조하기가 어렵다. 이런 처리를 위해서는 몇 가지 편법을 써야 한다. (참고 : http://icarosss.egloos.com/1274992)


 1. #, getn 사용


 i = #테이블명

 i = table.getn(테이블명)


 위와 같이 하면 테이블의 요소 갯수가 i 값으로 구해진다. 다만 이것은 요소가 연속적인 수치로 되어있을 때에만 유효하다. 예를 들어,


t = {1, 2, 3, a=10}


 위와 같은 테이블이 존재할 경우 t[4]의 값이 nil이므로 3을 돌려준다.

 

 이런 불규칙적인 데이터가 들어있을 경우에라도 모든 요소의 갯수를 전부 구하고 싶을 때에는 pairs() 함수를 이용한다.



 2. pairs() 함수 사용


function getTableSize(t)    --> 테이블 갯수 크기 구하기용 함수 선언

    local size = 0                    --> 테이블 갯수 크기를 알아보기 위한 변수 size 선언

    for index, value in pairs(t) do    --> 루프를 테이블 요소의 갯수만큼 돌린다

        size = size + 1              --> size를 1씩 누적시킨다

    end

    return size                         --> 루프가 끝난 뒤 누적된 size 값을 테이블의 갯수 크기로 반환한다

end


 ipairs() 함수도 있는데, 이것은 정수 요소에만 접근하려고 할때 사용하면 된다.

 


* 테이블에 값 넣기


 빈 테이블에 하나씩 값을 넣어 테이블을 채워 보자. 테이블을 생성하고 초기화하기 위해서 생성자를 사용하는데, 가장 간단한 생성자는 빈 생성자이다.


myNumbers = {}    --> 빈 테이블 생성자


for i = 1, 5 do

myNumbers[i] = i    --> 1에서 5까지 증가하는 루프를 돌리면서, 테이블 myNumbers에 순서대로 값을 집어넣는다.

end


for i = 1, 5 do

print("This is number " .. myNumbers[i])    --> 1에서 5까지 증가하는 루프를 돌려, 테이블 myNumbers에서 순서대로 

  값을 읽어 출력한다.

end


 다음은 터미널에 출력된 결과 값이다.


...

Posted by windship
프로그래밍/Corona SDK2013. 8. 27. 16:28

* 비균일 스프라이트란


 스프라이트는 알다시피 여러 장의 그림이 번갈아가며 보여지면서 움직이는 것인데, 프로그램상에서 각각의 그림의 크기가 전부 다른 경우는 좀 더 처리하기가 어렵다. 이걸 각 그림에 대해서 크기와 위치 정보도 함께 넣어 처리하는 스프라이트가 비균일 스프라이트이다. 



* 비균일 스프라이트 만들기


 먼저 외부 스프라이트 시트 데이터 파일을 준비한다. 내용은 다음과 같이 만들어진다. 


local 변수4 = {}


변수4.sheet = 

{

frames = {

{

- 이름1

x = 출력될 가로위치,

y = 출력될 세로위치,

width = 출력될 가로폭,

height = 출력될 세로폭,

sourceX = 원본에서의 가로위치,

sourceY = 원본에서의 세로위치,

sourceWidth = 원본에서의 가로폭,

sourceHeight = 원본에서의 세로폭

}                                                    --> 사용하는 프레임수만큼 반복된다

}  --> frames = {} 종료


sheetContentWidth = 이미지내 사용영역 가로폭

sheetContentHeight = 이미지내 사용영역 세로폭


}      --> 변수4.sheet = {} 종료


return 변수4    --> 변수4에 들어간 스프라이트의 데이터는 여기서 실행파일로 넘어가면서 변수1에 들어가게 된다.



 다음으로 실행파일에서 다음과 같이 하여 스프라이트 시트 파일의 데이터를 불러와 사용한다.


local 변수1 = 

{

frames = require("스프라이트파일명").frames

--> 이름이 지정된 외부 스프라이트 데이터 파일을 참조해 변수명1로 접근한다. 다만 파일명에 .lua 확장자는 붙이지 않는다.

}


local 변수3 = graphics.newImageSheet( "이미지파일명.png", 변수1)

local 변수2 = { name = "스프라이트파일명", start = 1, count = 8, time = 1000 }

local 객체명 = display.newSprite( 변수3, 변수2 )


객체명 : setSequence("시퀀스데이터명")

   --> 애니메이션 시퀀스가 할당된 스프라이트(객체)를, 다른 애니메이션 시퀀스로 바꾸어 넣는다

         (참고 : http://stackoverflow.com/questions/17887014/changing-animation-object-in-corona)


객체명 : setFrame(math.random(1 객체명.numFrames))

   --> 필요할 경우, 할당된 애니메이션 시퀀스 중 특정 프레임부터 재생을 시작하도록 한다


객체명 : play()

   --> 스프라이트 객체의 재생을 시작한다



 스프라이트 파일의 변수4에 기록된 스프라이트 데이터는 실행파일로 넘어오면서 변수1에 저장된다. 이 변수 1을 다음과 같이 액세스함으로써, 스프라이트 데이터를 읽어 사용하거나 변경할 수 있다.


변수4.sheet = 

{

frames = {

{

- 이름1

x = 출력될 가로위치,

y = 출력될 세로위치,

width = 출력될 가로폭,

height = 출력될 세로폭,



 위의 스프라이트 데이터에서, 변수1 안에 저장된 frames{} 안의 데이터값들은 다음과 같이 읽거나 변경하면 된다.


print(options.frames[1].x)

print(options.frames[1].y)

print(options.frames[1].width)

print(options.frames[1].height)    --> x, y, width, height 값을 각각 읽어 출력한다. 사용할 때에도 이렇게 사용하면 된다.


options.frames[1].x = 999     --> x의 값에 999를 넣는다. 



Posted by windship
프로그래밍/Corona SDK2013. 8. 27. 13:07

* XML 파싱하기

 

 우선은 기본적으로 XML 파싱 스크립트가 만들어져 있는 게 있으므로 그것을 사용하는 것이 편하다. 다음 주소에서 xml.lua 파일을 다운받자. https://github.com/coronalabs/Corona-XML-Module


 대부분의 XML 파일을 다룰 때 가장 어려운 부분은 이 파일 안에 대부분 미리 만들어져 있으므로 문제가 없으나, 각자의 프로젝트에서 사용하기 위해서는 XML 데이터의 형식에 따라 좀 헷갈리는 부분이 있을 수도 있다.


 이 파일을 저장해둔 폴더와 같은 폴더에 main.lua 파일을 만든다.


local xml = require("xml").newParser()


local sprite = xml:loadFile( "xxx.xml" )

 --> sprite 변수는 xxx.xml 파일을 읽어오기 위한 변수이다


local spriteData = {} 


for i=1,#sprite.child do 

  --> sprite 변수를 사용해 읽은 내용을 spriteData에 순차적으로 집어넣는다(이 부분이 없으면 내용이 안들어감)

         spriteData[i] = sprite.child[i]

end


  이것으로 해당 xml 파일의 내용은 spriteData 테이블 안에 저장되었다. 


  다음은 원하는 트리부분을 읽어서 데이터값으로 가져와야 하는데, for문으로 루프를 돌려 가져온다.


<Project>


  <SpriteSheets>

    <SpriteSheet>

      <ID>1</ID>

      <FullPath>../test1.png</FullPath>

    </SpriteSheet>

    <SpriteSheet>

      <ID>2</ID>

      <FullPath>../test2.png</FullPath>

    </SpriteSheet>

  </SpriteSheets>


  <Sprites>

    <Sprite>

      <ConnectID>1</ConnectID>

      <ID>1</ID>

      <CutRectangle Left="11" Top="8" Width="91" Height="91" />

    </Sprite>

    <Sprite>

      <ConnectID>1</ConnectID>

      <ID>2</ID>

      <CutRectangle Left="119" Top="12" Width="76" Height="82" />

    </Sprite>

    <Sprite>

      <ConnectID>1</ConnectID>

      <ID>3</ID>

      <CutRectangle Left="215" Top="12" Width="97" Height="30" />

    </Sprite>

  </Sprites>


</Project>


 위와 같은 XML 데이터가 있을 경우 우선 가장 상위의 <Project>는 무시한다. 그 아래에 있는 <SpriteSheets>가 spriteData 테이블의 1번데이터가 된다. 즉 spriteData[1]이 된다. 


 또한 그 아래에 있는 <SpriteSheet>는 spriteData 테이블의 자식(child)이 된다. 즉 spriteData[1].child[1]이 된다.


 마찬가지로 그 아래에 있는 <ID>와 <FullPath>는 spriteData 테이블의 자식의 자식이 되므로, 각각 spriteData[1].child[1].child[1]spriteData[1].child[1].child[2]가 된다. 


 위 XML 데이터에서 <SpriteSheets>는 리소스 이미지 정보를, <Sprites>는 이미지로부터 잘라온 조각그림을 지정하는 데이터이며, 자식 데이터의 구조도 다르므로, 각각 다르게 읽을 필요가 있다. 


for i=1,#spriteData[1].child do

 for i2=1, #spriteData[1].child[i].child do

  print(spriteData[1].child[i].child[i2].value)

 end

end


 <SpriteSheets>             ---> spriteData[i]

   <SpriteSheet>             ---> spriteData[i].child[i]

     <ID>                            ---> spriteData[i].child[i].child[1].value  

(여기엔 값이 있고, 우리가 이 값을 사용하므로 .value를 붙여 값을 읽어온다)

     <FullPath>                 ---> spriteData[i].child[i].child[2].value


for i=1,#spriteData[2].child do


 print(spriteData[2].child[i].child[1].value)

 print(spriteData[2].child[i].child[2].value)


 local moduleX = (spriteData[2].child[i].child[3].properties["Left"])

 local moduleY = (spriteData[2].child[i].child[3].properties["Top"])

 local moduleX2 = (spriteData[2].child[i].child[3].properties["Width"])

 local moduleY2 = (spriteData[2].child[i].child[3].properties["Height"])

 

 print(moduleX, moduleY, moduleX2, moduleY2)


end


 기본적 구조는 위의 <SpriteSheets>를 읽어올 때와 같지만, <CutRectangle>에는 아래와 같이 값이 여러개 들어있다. 


<CutRectangle Left="11" Top="8" Width="91" Height="91" />


 요것은 .value 대신 .properties를 사용해 값을 읽어오게 된다. 어떤 값을 읽어올 것이냐에 따라 .properties["이름"]과 같이 사용한다.


Posted by windship
프로그래밍/Corona SDK2013. 8. 27. 12:32

* 정지된 한 장짜리 이미지를 띄우기

 

  local 변수명 = display.newImage( "표시할이미지파일명" )


  으로 이미지를 표시한다. 

  (블렌딩에 관해서는 다음 참조 : http://www.coronalabs.com/blog/2011/04/28/compositing-fun-with-additive-blends/)

  

  변수명.x = X위치값

  변수명.y = Y위치값


으로 이미지의 표시좌표를 지정할 수 있다.



* 균일 스프라이트


 스프라이트의 가장 간단한 형태로, 스프라이트를 이루는 각각의 그림의 크기가 전부 똑같은 크기로 되어 있는 형태이다(여기서 말하는 그림의 크기는 실제의 그림 내용의 부분이 아니라, 여백을 포함한 그림파일 전체의 물리적 크기를 말한다). 이 방식은 스프라이트 중에 가장 간단한 방식으로, 모든 그림의 크기가 같으므로 일일이 크기나 위치 정보를 저장할 필요가 없고 쉽게 구현할 수 있지만, 작은 그림이 들어가도 전부 같은 크기의 여백이 필요하므로 용량의 낭비가 심하며, 살짝 움직이는 등의 작은 동작도 전부 그림이 바뀌어야 하므로 더욱 용량이 낭비된다. 


1. 스프라이트 시트를 사용하기 위해 먼저 다음과 같은 선언을 한다.

 

 local sprite = require "sprite"    --> 스프라이트 라이브러리의 import

  local options =

  {

    frames = require("스프라이트시트 파일명").frames, --> 스프라이트 파일(*.lua)에 정의된 데이터를 가져와 각 프레임에 할당한다

  }



2. 다음으로 스프라이트 시트를 불러온다. 


local 스프라이트시트변수명 = graphics.newImageSheet( "이미지리소스파일명", options ) 

   --> 가장 중심이 되는 선언부. 어떤 이미지 파일을 사용하는지 정의한다.

local spriteOptions = { name="스프라이트시트 파일명", start=1, count=4, time=400 } 

   --> 각 프레임을 어떻게 넣는가에 대한 것. 

         hero1.lua 파일을 사용하며, 1프레임부터 시작하고, 총 4장의 프레임으로 구성되며, 딜레이는 400ms.

local spriteInstance = display.newSprite( 스프라이트시트변수명, spriteOptions ) 

   --> 첫번째줄의 스프라이트시트 변수명과 같은것을 사용



3.  스프라이트를 실제로 화면에 띄운다.


spriteInstance:setReferencePoint(display.BottomRightReferencePoint)

spriteInstance.x = 300  --> X좌표

spriteInstance.y = 300  --> Y좌표



4.  스프라이트를 재생한다.


spriteInstance:play()



5. 다른 재생관련 제어 기능은 다음과 같다.


  spriteInstance:prepare([sequence])

  현재 플레이 되고 있는 애니메이션 시퀀스를 정지한다. 현재 시퀀스를 바꿀수도 있고 첫번째 시퀀스의 프레임으로 갈 수도 있다.


  spriteInstance:play()

  애니메이션 시퀀스를 플레이한다. 현재의 프레임에서 시작한다.

 

  spriteInstance:pause()

  애니메이션을 정지시킨다. 맨 마지막에 보여졌던 프레임이 남아 있게 된다.

 

  spriteInstance:addEventListener("sprite", listener)

  스프라이트 인스턴스 애니메이션이 이벤트를 일으켰을 때 리스너에 통보한다.


  이벤트는 리스너에게 다음과 같은 필드들을 전달한다.


  event.sprite

  이벤트를 발생한 스프라이트. 

  event.sprite.sequence 와 같은 식으로 현재 스프라이트의 프로퍼티들에 접근하는 것도 가능


  event.phase

  phase는 다음과 같은 요소들이 있다.


  "end" - 플레이를 멈춘다.

  "loop" - 순차적으로 아니면 거꾸로 스프라이트를 루핑.

  "next" - 스프라이트의 다음 프레임이 플레이된다.


Posted by windship
프로그래밍/Corona SDK2013. 8. 27. 12:26

* 주 실행파일은 main.lua 파일


기본적으로는 main.lua 파일 하나에서 대부분의 작업이 이루어진다. 별도 파일을 쓸 경우는 같은 폴더에 추가해 넣으면 된다.



* 화면의 뷰포트 렌더 해상도 지정


 config.lua 파일에 지정한다. main.lua 파일과 같은 폴더에 넣는다.

뷰포트 해상도 외에도, 실제 물리 해상도와 렌더 해상도 사이의 확대 방법에 대해서도 지정할 수 있다.


-- config.lua

application =

{

    content =

    {

        width = 640,    --> 뷰포트 가로

        height = 960,    --> 뷰포트 세로

        scale = "letterbox"  --> 확대하여 화면을 채운다. zoom to fill screen, possibly cropping edges

    },

}



* 아이폰 위쪽 상태바 없애기


  display.setStatusBar (display.HiddenStatusBar) 

  를 main.lua 파일에 넣는다.



* 화면 가로/세로 모드 지정


build.settings 파일에 설정한다(역시 main.lua 파일과 같은 폴더에 넣을 것).


  settings = {

orientation = {

default = "landscapeRight",

}

   } 


  를 build.settingss 파일에 넣는다. 이것을 지정하지 않을 경우, 아이폰은 자동으로 세로 모드가 되니 주의할 것.



Posted by windship