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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Posted on

. Written by



오늘 Electronic Arts (EA)사가 Word Smack game을 새로 개발해서 출시했다는 소식을 기쁘게 알려드립니다. 바로 모두가 좋아하는 cross-platform development platform으로 개발을 한 게임입니다. 예 맞습니다. 세계에서 가장 큰 게임 개발사 중의 하나인 EA 사가 코로나로 게임을 개발해서 출시했습니다.




Corona team 은 good guessing game 을 사랑합니다. EA의 Word Smack 는 정말 짱이구요. 두개의 유명한 보드 게임을 합쳐놓은 것 같아요. Mastermind 하고 Scrabble 요. Word Smack 는 2인용 게임이구요. 3라운드에 5 글자의 단어를 맞추는 거예요. 처음 게임을 시작하면 보드에 글자가 보일 겁니다. 그러면 나머지 칸을 여러분이 다른 글자로 채워 넣는 거예요.



너무 쉽게 생각하지 마세요. 만만치 않아요. 고맙게도 Word Smack 은 오른쪽에 살짝 힌트를 제공해 줘요. 만약에 맞는 글자(알파벳)인데 칸을 다른 곳에 넣었다면 이것을 알 수 있게 해주죠. Facebook integration은 친구들끼리 시합을 할 수도 있게 해 줍니다. 그리고 random 하게 상대방을 골라서 게임을 할 수도 있구요. 상대편 보다 단어를 더 빨리 맞추면 되는 겁니다.





word game 을 좋아하는 분들을 위해 power up 기능을 구입할 수도 있습니다. power up 은 word synonym들을 제공합니다. Word Smack 은 바로 오늘 출시 됐습니다. 

App Store에서 지금 당장 free 버전을 다운 받아 보세요.



반응형

새 위젯 사용하기 Part 1

2012. 11. 8. 21:44 | Posted by 솔웅


반응형

Posted on . Written by


만약 여러분이 Corona Indie 나 Pro 의 등록자라면 daily builds 를 다운 받아서 사용하실 수 있으실 겁니다. 그리고 Build 947 에 new widgets 들이 포함된 내용도 전달 받으셨을 겁니다. 이 포함된 widget들은 아래 사항들을 포함하고 있습니다.


  • switch — in the form of a radio button, checkbox, or “on/off” slider.
  • segmented control — a “segmented button” in which each segment responds individually.


이 새 위젯들은 일반적인 특성을 따르고 있습니다. 각 위젯들은 새로운 widget library foundation 을 바탕으로 추가 돼 좀 더 flexible 하고 essentially 합니다.


Patience Please!



이 새 위젯들은 widget library 의 개선해 나가는 것들 중의 일부입니다. 더 많은 widget들이 다음주에 더 새로운 모습으로 소개 될 겁니다. 그 각각에 대해 cover 할 수 있도록 tutorial 을 작성해 드릴겁니다. 지난 widget들과 비교하면 거의 새로운 기반하에서 새롭게 작성되어야 할 정도로 많은 변화가 있었습니다. 여러분들은 아직까지 이전 위젯들을 사용하고 계실 건데요. 이전 위젯들에 대해서는 중요한 버그들에 대한 수정만 해 나갈 것이고 그 기능에 대한 개선이나 변경은 없을 겁니다. 이번주 다음주에 발표할 새로운 위젯들이 기존의 위젯들을 대신해 나가도록 진행할 계획입니다.


이 글은 native iOS visual theme 에 대해 설명드립니다. Android theme 은 다음번 daily build 에서 추가될 겁니다. 물론 굳이 이 주어진 visual theme만 사용할 수 있는 건 아닙니다. 여러분들 나람대로 스타일링해서 위젯들을 customizing 해서 사용하실 수 있습니다.



Getting Started…


새 위젯들을 경험하기 위해 우선 새로운 project 부터 만듭니다.



1. “require” the widget library


Just like with many Corona libraries, you’ll need to “require” the widget library to use widgets:

다른 많은 Corona library들과 같이 widget을 사용하기 위해서는 widget library 를 require 합니다.


local widget = require( "widget" )

2. Copy theme file and assets



모든 widget들은 디폴트로 Lua file 이름에서 theme 정보를 가져옵니다. theme_ios.lua or (coming soon) theme_android.lua 가 그 파일 이름입니다. 이미지 파일들은 이 파일에서 정한 폴더에서 가져오게 됩니다. 위젯들은 custom theme file 을 세팅함으로서 스타일링할 수 있고 이미지 세트들도 생성할 수 있습니다. 이런 부분들은 약간 고급 기술 부분인데요. 나중에 이런 고급 기술 부분에 대해서 따로 다루도록 하겠습니다.


일단 default theme file과 asset folder를 여러분의 main project 디렉토리에 카피해 넣으세요. 이름은 theme_ios.lua and widget_ios가 될 겁니다.  이 파일들은 아래 경로로 가면 찾을 수 있습니다. 또는 이곳에서 다운로드 받으실 수도 있습니다.



CoronaSDK > SampleCode > Interface > WidgetDemo




3. Declare the theme using “setTheme()”


widget library 를 require 한 후 그 다음줄에 theme 을 정의해야 합니다.

아래 예제를 참조하세요. 처음부터 새로 만드실 필요는 없고 샘플로 드린 파일을

수정하셔서 사용하시면 편리하실 겁니다.


widget.setTheme( "theme_ios" )

NOTE:  Do not  append .lua to the reference passed to widget.setTheme().



Widget #1: Switch


첫번쨰로 선보일 새로운 widget 은 switch widget 입니다. 이 위젯은 세가지 종류가 있습니다.
checkbox, radio button, or on/off slider




Event Listener



이 위젯에 유저가 어떤 행위를 했을 때 이를 감지할 basic listener function를 생성하셔야 합니다. 이 섹션에서 사용할 샘플 리스너를 한들어 보죠.

아래 예제를 여러분 파일에 복사해 넣으세요.


local function onSwitchPress( event )
   local switch = event.target --event.target references the switch object
   local response = switch.id.." is on: "..tostring( switch.isOn )
   print( response )
   switch.text:setText( tostring( switch.isOn ) )
end


switch의 현 상태는 .isOn parameter에 의해 참조됩니다. 여러분은 이 프로퍼티를 사용해서 현재의 switch 상태를 파악할 수 있습니다. true 이면 selected 나 on 인 상태이구요. false 이면 off 나 deselected 상태입니다.



Checkbox



checkbox switch widget을 생성하려면 아래와 같이 하세요.


local checkbox = widget.newSwitch
{
   left = 60,
   top = 230,
   style = "checkbox",
   id = "My checkbox widget",
   initialSwitchState = false,
   onPress = onSwitchPress
}

-- Text to show the on/off switch state
checkbox.text = display.newEmbossedText( tostring( checkbox.isOn ), 0, 0, native.systemFontBold, 18 )
checkbox.text.x = checkbox.x
checkbox.text.y = checkbox.y - checkbox.text.contentHeight



보시다시피 실제 widget은 widget.newSwitch command를 사용해서 생성합니다. 그리고 디테일한 내용은 “options” table에 있습니다. 이 예제에서는 아래 프로퍼티들이 콤마로 구분돼 있습니다.


  • left and top (optional) — the left and top position of the switch. You can also position the switch normally by setting its x and y position afterward.
  • style — for this example, set it to checkbox.
  • id (optional) — this property allows you to set a named reference for the widget. This is useful if you want to use the same event listener function for several switches and identify a specific one by its .id property within the listener function.
  • initialSwitchState (optional) — true = on/selected; false = off/deselected.  Default is false.
  • onPress (optional) — listener function called when the switch is touched.



Radio Button


radio button
switch는 checkbox widget 이랑 거의 같은 방식으로 생성합니다. 다른 부분은 style parameter를 radio로 세팅하는 부분입니다. 위에 on-off 를 테스트하기 위해 만들었던 리스너 함수를 복사해서 여기서 사용하시면 됩니다.


local radioButton = widget.newSwitch
{
   left = 150,
   top = 230,
   style = "radio",
   id = "My radio button widget",
   initialSwitchState = false,
   onPress = onSwitchPress
}

-- Text to show the on/off switch state
radioButton.text = display.newEmbossedText( tostring( radioButton.isOn ), 0, 0, native.systemFontBold, 18 )
radioButton.text.x = radioButton.x
radioButton.text.y = radioButton.y - radioButton.text.contentHeight


 


On/Off Switch


on/off switch는 작은 “flick” switch 입니다. 일반 전등 스위치같은 역할을 하죠. 디폴트 switch widget 입니다. 셋업하는 부분은 switch widget 과 비슷한데요. 몇가지 key 가 다르죠. 기본 구조는 아래와 같습니다.


local onOffSwitch = widget.newSwitch
{
   left = 250,
   top = 230,
   id = "My on/off switch widget",
   initialSwitchState = true,
   onRelease = onSwitchPress
}


가장 많이 다른 부분은 event listener function 인데요. onPress parameter가 아닌 onRelease parameter 로 분류 됩니다.  이 경우 touch 가 released 되면 “release” event가 발생합니다.


Widget #2: Segmented Control


segmented control 은  multi-segment 버튼을 쉽게 만들 수 있도록 도와줍니다. 각 segment 별로 on/off 상태가 될 수 있고 그에 따라 관련된 값이 return 됩니다.



Event Listener


switch widget 처럼 segment control 에 대ㅐ 유저의 action 을 report 하기 위해 basic listener function을 생성해야 됩니다.


local function onControlPress( event )
   local target = event.target
   print( "Segment Label is:", target.segmentLabel )
   print( "Segment Number is:", target.segmentNumber )
end

 

이 segmented control 은 리스너에게 두가지 essential 값을 전달합니다. 유저가 touch 한 segment 의  segment labelsegment number 가 그 값들입니다.


Basic Segmented Control


segmented control 은 아주 간단합니다. 아래 예제를 보세요


local segmentedControl = widget.newSegmentedControl
{
   left = 65,
   top = 110,
   segments = { "s1", "s2", "s3", "s4" },
   segmentWidth = 50,
   defaultSegment = 4,
   onPress = onControlPress
}

  
  • left and top (optional) — the left and top position of the control. You can also position the control normally by setting its x and y position afterward.
  • segments — sub-table in which you define the segments; it determines the total count and the label that appears on each. Simply define them as comma-separated strings.
  • segmentWidth (optional) — the pixel width of each segment. Default is 50 pixels.
  • defaultSegment (optional) — this property allows you to set the segment that is “on” when the control is rendered. Specify a number between 1 and the total number of segments. If you don’t specify this property, it defaults to the first segment.
  • onPress (optional) — listener function called when the control is touched.


More to Come!


다른 훌륭한 widgets들이 이어서 선보입니다. 다음주 daily builds 가 릴리즈 될 때 선보일 예정인데요. 다음주 화요일의 Tutorial 을 통해서 그 위젯들에 대한 설명을 드리겠습니다. 그 동안 최신 daily build를 다운 받으시고 위 3개 widget들에 대해 익혀 두세요. daily builds 는 유료 등록하신 분들만 다운받으실 수 있습니다. 코로나의 최신 기술을 그 때 그 때 사용하고 싶으신 분은 지금 유료등록을 해 주세요.










반응형


반응형

오늘은 CoronaLabs 에서 facebook을 통해 알려준 Lua Performance 관련 한 정보를 정리하겠습니다.


있는 곳은 http://trac.caspring.org/wiki/LuaPerformance 입니다.


여기에 정리해 두고 나중에 Corona SDK project 진행할 때 미리 한번 훑어 보고 해야겠네요.



Things you should know about Lua's performance


This wiki is a result of some lua performance tests (the widget is included with ca sandbox).


TEST 1: localize

Code:

local min = math.min

Results:

normal way: 0.719 (158%)
localized: 0.453 (100%)

Conclusion:

  -> Yeah, we should localize all used funtions.


TEST 2: localized class-methods (with only 3 accesses!)

Code1:

  for i=1,1000000 do
    local x = class.test()
    local y = class.test()
    local z = class.test()
  end

Code2:

  for i=1,1000000 do
    local test = class.test
    local x = test()
    local y = test()
    local z = test()
  end

Results:

normal way: 1.203 (102%)
localized: 1.172 (100%)

Conclusion:

  -> No, it isn't faster to localize a class method IN the function call.


TEST 3: unpack a table

Code1:

  for i=1,1000000 do
    local x = min( a[1],a[2],a[3],a[4] )
  end

Code2:

  local unpack = unpack
  for i=1,1000000 do
    local x = min( unpack(a) )
  end

Code3:

  local function unpack4(a)
    return a[1],a[2],a[3],a[4]
  end
  for i=1,1000000 do
    local x = min( unpack4(a) )
  end

Results:

with [ ]: 0.485 (100%)
unpack(): 1.093 (225%)
custom unpack4: 0.641 (131%)

Conclusion:

  -> Don't use unpack() in time critical code!


TEST 4: determine maximum and set it ('>' vs. max)

Code1:

  local max = math.max
  for i=1,1000000 do
     x = max(random(cnt),x)
  end

Code2:

  for i=1,1000000 do
    local r = random(cnt)
    if (r>x) then x = r end
  end

Results:

math.max: 0.437 (156%)
'if > then': 0.282 (100%)

Conclusion:

  -> Don't use math.[max|min]() in time critical code!


TEST 5: nil checks ('if' vs. 'or')

Code1:

  for i=1,1000000 do
    local y,x
    if (random()>0.5) then y=1 end 
    if (y==nil) then x=1 else x=y end
  end

Code2:

  for i=1,1000000 do
    local y
    if (random()>0.5) then y=1 end 
    local x=y or 1
  end

Results:

nil-check: 0.297 (106%)
a=x or y: 0.281 (100%)

Conclusion:

  -> WOW! the or-operator is faster than a nil-check. Use it! :D


TEST 6: 'x2' vs. 'x*x'

Code1:

  for i=1,1000000 do
     local y = x^2
  end

Code2:

  for i=1,1000000 do
     local y = x*x
  end

Results:

x^2: 1.422 (110%)
x*x: 1.297 (100%)


TEST 7: modulus operators (math.mod vs. %)

Code1:

  local fmod = math.fmod
  for i=1,1000000 do
    if (fmod(i,30)<1) then
      local x = 1
    end
  end

Code2:

  for i=1,1000000 do
    if ((i%30)<1) then
      local x = 1
    end
  end

Results:

math.mod: 0.281 (355%)
%: 0.079 (100%)

Conclusion:

  -> Don't use math.fmod() for positive numbers (for negative ones % and fmod() have different results!)!


TEST 8: functions as param for other functions

Code1:

  local func1 = function(a,b,func) 
    return func(a+b) 
  end

  for i=1,1000000 do
    local x = func1(1,2,function(a) return a*2 end)
  end

Code2:

  local func1 = function(a,b,func) 
    return func(a+b) 
  end
  local func2 = function(a) 
    return a*2 
  end

  for i=1,1000000 do
    local x = func1(1,2,func2)
  end

Results:

defined in function param: 3.890 (1144%)
defined as local: 0.344 (100%)

Conclusion:

  -> REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!!
     i.e if you use gl.BeginEnd(), gl.CreateList(), ...!!!


TEST 9: for-loops

Code1:

  for i=1,1000000 do
    for j,v in pairs(a) do
      x=v
    end
  end

Code2:

  for i=1,1000000 do
    for j,v in ipairs(a) do
      x=v
    end
  end

Code3:

  for i=1,1000000 do
    for i=1,100 do
      x=a[i]
    end
  end

Code4:

  for i=1,1000000 do
    for i=1,#a do
      x=a[i]
    end
  end

Code5:

  for i=1,1000000 do
    local length = #a
    for i=1,length do
      x=a[i]
    end
  end

Results:

pairs: 3.078 (217%)
ipairs: 3.344 (236%)
for i=1,x do: 1.422 (100%)
for i=1,#atable do 1.422 (100%)
for i=1,atable_length do: 1.562 (110%)

Conclusion:

  -> Don't use pairs() or ipairs()!
     Try to save the table-size somewhere and use "for i=1,x do"!


TEST 10: array access (with [ ]) vs. object access (with .method)

Code1:

  for i=1,1000000 do
    x = a["foo"]
  end

Code2:

  for i=1,1000000 do
    x = a.foo
  end

Results:

atable["foo"]: 1.125 (100%)
atable.foo: 1.141 (101%)


TEST 11: buffered table item access

Code1:

  for i=1,1000000 do
    for n=1,100 do
      a[n].x=a[n].x+1
    end
  end

Code2:

  for i=1,1000000 do
    for n=1,100 do
      local y = a[n]
      y.x=y.x+1
    end
  end

Results:

'a[n].x=a[n].x+1': 1.453 (127%)
'local y=a[n]; y.x=y.x+1': 1.140 (100%)


TEST 12: adding table items (table.insert vs. [ ])

Code1:

  local tinsert = table.insert
  for i=1,1000000 do
    tinsert(a,i)
  end

Code2:

  for i=1,1000000 do
    a[i]=i
  end

Code3:

  for i=1,1000000 do
    a[#a+1]=i
  end

Code4:

  local count = 1
  for i=1,1000000 do
    d[count]=i
    count=count+1
  end

Results:

table.insert: 1.250 (727%)
a[i]: 0.172 (100%)
a[#a+1]=x: 0.453 (263%)
a[count++]=x: 0.203 (118%)

Conclusion:

  -> Don't use table.insert!!!
     Try to save the table-size somewhere and use "a[count+1]=x"!



반응형