nakor 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/lib/nakor/generators/corona-game-template/README +32 -0
  2. data/lib/nakor/generators/corona-game-template/about.lua +34 -0
  3. data/lib/nakor/generators/corona-game-template/bk_default.png +0 -0
  4. data/lib/nakor/generators/corona-game-template/btn_about.png +0 -0
  5. data/lib/nakor/generators/corona-game-template/btn_about_over.png +0 -0
  6. data/lib/nakor/generators/corona-game-template/btn_help.png +0 -0
  7. data/lib/nakor/generators/corona-game-template/btn_help_over.png +0 -0
  8. data/lib/nakor/generators/corona-game-template/btn_play.png +0 -0
  9. data/lib/nakor/generators/corona-game-template/btn_play_over.png +0 -0
  10. data/lib/nakor/generators/corona-game-template/btn_settings.png +0 -0
  11. data/lib/nakor/generators/corona-game-template/btn_settings_over.png +0 -0
  12. data/lib/nakor/generators/corona-game-template/build.settings +15 -0
  13. data/lib/nakor/generators/corona-game-template/config.lua +13 -0
  14. data/lib/nakor/generators/corona-game-template/director.lua +2226 -0
  15. data/lib/nakor/generators/corona-game-template/help.lua +34 -0
  16. data/lib/nakor/generators/corona-game-template/init_buttons.lua +55 -0
  17. data/lib/nakor/generators/corona-game-template/loadmenu.lua +33 -0
  18. data/lib/nakor/generators/corona-game-template/main.lua +12 -0
  19. data/lib/nakor/generators/corona-game-template/menu.lua +93 -0
  20. data/lib/nakor/generators/corona-game-template/newgame.rb +56 -0
  21. data/lib/nakor/generators/corona-game-template/play.lua +34 -0
  22. data/lib/nakor/generators/corona-game-template/radlib.lua +73 -0
  23. data/lib/nakor/generators/corona-game-template/settings.lua +34 -0
  24. data/lib/nakor/generators/corona-game-template/splash_screen.png +0 -0
  25. data/lib/nakor/generators/corona-game-template/ui.lua +318 -0
  26. data/lib/nakor/version.rb +1 -1
  27. metadata +28 -4
  28. data/.gitmodules +0 -3
@@ -0,0 +1,34 @@
1
+ module(..., package.seeall)
2
+
3
+ -- Main function - MUST return a display.newGroup()
4
+ function new()
5
+ local localGroup = display.newGroup()
6
+
7
+ -- Background
8
+ local background = display.newImageRect("bk_default.png", 480, 320)
9
+ background.x = display.contentCenterX
10
+ background.y = display.contentCenterY
11
+ localGroup:insert(background)
12
+
13
+ -- Title
14
+ local title = display.newText("Touch to go back", 0, 0, native.systemFontBold, 16)
15
+ title:setTextColor( 255,255,255)
16
+ title.x = display.contentCenterX
17
+ title.y = display.contentCenterY
18
+ title.name = "title"
19
+ localGroup:insert(title)
20
+
21
+ -- Touch to go back
22
+ local function touched ( event )
23
+ if ("ended" == event.phase) then
24
+ director:changeScene("menu","fade")
25
+ end
26
+ end
27
+ background:addEventListener("touch",touched)
28
+
29
+ unloadMe = function()
30
+ end
31
+
32
+ -- MUST return a display.newGroup()
33
+ return localGroup
34
+ end
@@ -0,0 +1,55 @@
1
+ _G.buttons = {
2
+ about = {
3
+ defaultSrc = "btn_about.png",
4
+ defaultX = 160,
5
+ defaultY = 32,
6
+ overSrc = "btn_about_over.png",
7
+ overX = 160,
8
+ overY = 32,
9
+ id = "btnAbout",
10
+ text = "",
11
+ font = "Helvetica",
12
+ textColor = { 255, 255, 255, 255 },
13
+ emboss = false
14
+ },
15
+ help = {
16
+ defaultSrc = "btn_help.png",
17
+ defaultX = 160,
18
+ defaultY = 32,
19
+ overSrc = "btn_help_over.png",
20
+ overX = 160,
21
+ overY = 32,
22
+ id = "btnHelp",
23
+ text = "",
24
+ font = "Helvetica",
25
+ textColor = { 255, 255, 255, 255 },
26
+ emboss = false
27
+ },
28
+ play = {
29
+ defaultSrc = "btn_play.png",
30
+ defaultX = 160,
31
+ defaultY = 32,
32
+ overSrc = "btn_play_over.png",
33
+ overX = 160,
34
+ overY = 32,
35
+ id = "btnPlay",
36
+ text = "",
37
+ font = "Helvetica",
38
+ textColor = { 255, 255, 255, 255 },
39
+ emboss = false
40
+ },
41
+ settings = {
42
+ defaultSrc = "btn_settings.png",
43
+ defaultX = 160,
44
+ defaultY = 32,
45
+ overSrc = "btn_settings_over.png",
46
+ overX = 160,
47
+ overY = 32,
48
+ id = "btnSettings",
49
+ text = "",
50
+ font = "Helvetica",
51
+ textColor = { 255, 255, 255, 255 },
52
+ emboss = false
53
+ }
54
+ }
55
+
@@ -0,0 +1,33 @@
1
+ module(..., package.seeall)
2
+
3
+ require "init_buttons"
4
+
5
+ -- Main function - MUST return a display.newGroup()
6
+ function new()
7
+ local localGroup = display.newGroup()
8
+
9
+ local theTimer
10
+ local loadingImage
11
+
12
+ local showLoadingScreen = function()
13
+ loadingImage = display.newImageRect( "splash_screen.png", 480, 320 )
14
+ loadingImage.x = display.contentWidth
15
+ loadingImage.y = display.contentHeight
16
+ localGroup:insert(loadingImage)
17
+
18
+ local goToLevel = function()
19
+ director:changeScene( "menu" )
20
+ end
21
+
22
+ math.randomseed( os.time() )
23
+ theTimer = timer.performWithDelay( 1000, goToLevel, 1 )
24
+ end
25
+
26
+ showLoadingScreen()
27
+
28
+ unloadMe = function()
29
+ end
30
+
31
+ -- MUST return a display.newGroup()
32
+ return localGroup
33
+ end
@@ -0,0 +1,12 @@
1
+ display.setStatusBar( display.HiddenStatusBar )
2
+
3
+ local director = require("director")
4
+ local mainGroup = display.newGroup()
5
+
6
+ local function main()
7
+ mainGroup:insert(director.directorView)
8
+ director:changeScene("loadmenu")
9
+ return true
10
+ end
11
+
12
+ main()
@@ -0,0 +1,93 @@
1
+ module(..., package.seeall)
2
+
3
+ local radlib = require "radlib"
4
+
5
+ -- Main function - MUST return a display.newGroup()
6
+ function new()
7
+ local ui = require("ui")
8
+
9
+ local localGroup = display.newGroup()
10
+
11
+ -- Background
12
+ local background = display.newImageRect("bk_default.png", 480, 320)
13
+ background.x = display.contentCenterX
14
+ background.y = display.contentCenterY
15
+ localGroup:insert(background)
16
+
17
+ -- Menu Buttons - Start
18
+
19
+ local playButton = nil
20
+ local function onPlayPressed ( event )
21
+ if event.phase == "ended" and playButton.isActive then
22
+ director:changeScene("play", "fade", 30.0,60.0,90.0)
23
+ end
24
+ end
25
+ playButton = ui.newButton(
26
+ radlib.table.merge(
27
+ _G.buttons['play'],
28
+ { onRelease = onPlayPressed }
29
+ )
30
+ )
31
+ playButton.x = 160
32
+ playButton.y = 80
33
+ playButton.isActive = true
34
+ localGroup:insert(playButton)
35
+
36
+ local settingsButton = nil
37
+ local function onSettingsPressed ( event )
38
+ if event.phase == "ended" and settingsButton.isActive then
39
+ director:changeScene("settings", "fade", "green")
40
+ end
41
+ end
42
+ settingsButton = ui.newButton(
43
+ radlib.table.merge(
44
+ _G.buttons['settings'],
45
+ { onRelease = onSettingsPressed }
46
+ )
47
+ )
48
+ settingsButton.x = 160
49
+ settingsButton.y = 130
50
+ settingsButton.isActive = true
51
+ localGroup:insert(settingsButton)
52
+
53
+ local helpButton = nil
54
+ local function onHelpPressed ( event )
55
+ if event.phase == "ended" and helpButton.isActive then
56
+ director:changeScene("help", "overFromTop")
57
+ end
58
+ end
59
+ helpButton = ui.newButton(
60
+ radlib.table.merge(
61
+ _G.buttons['help'],
62
+ { onRelease = onHelpPressed }
63
+ )
64
+ )
65
+ helpButton.x = 160
66
+ helpButton.y = 180
67
+ helpButton.isActive = true
68
+ localGroup:insert(helpButton)
69
+
70
+ local aboutButton = nil
71
+ local function onAboutPressed ( event )
72
+ if event.phase == "ended" and aboutButton.isActive then
73
+ director:changeScene("about", "moveFromLeft")
74
+ end
75
+ end
76
+ aboutButton = ui.newButton(
77
+ radlib.table.merge(
78
+ _G.buttons['about'],
79
+ { onRelease = onAboutPressed }
80
+ )
81
+ )
82
+ aboutButton.x = 160
83
+ aboutButton.y = 230
84
+ aboutButton.isActive = true
85
+ localGroup:insert(aboutButton)
86
+ -- Menu Buttons - End
87
+
88
+ unloadMe = function()
89
+ end
90
+
91
+ -- MUST return a display.newGroup()
92
+ return localGroup
93
+ end
@@ -0,0 +1,56 @@
1
+ require 'fileutils'
2
+
3
+ # Creates a new game at the parent directory.
4
+ # Usage:
5
+ # macruby newgame <appname>
6
+ # For example, if this template is on /Users/rad/Documents/games/corona-game-template,
7
+ # running "macruby newgame mygame"
8
+ # will create the directory /Users/rad/Documents/games/mygame
9
+ # and copy all files from the template to that directory
10
+
11
+ def generate_new_app(appname)
12
+ app_dir = "../#{appname}"
13
+ code_dir = "#{app_dir}/#{appname}"
14
+ assets_dir = "#{app_dir}/assets"
15
+ doc_dir = "#{app_dir}/doc"
16
+
17
+ # create the app directories
18
+ FileUtils.mkdir_p app_dir
19
+ FileUtils.mkdir_p code_dir
20
+ FileUtils.mkdir_p assets_dir
21
+ FileUtils.mkdir_p doc_dir
22
+
23
+ # copy the files to the app code directory
24
+ FileUtils.cp_r './.', code_dir
25
+
26
+ # copy README
27
+ FileUtils.cp_r 'README', app_dir
28
+
29
+ # Remove support files used only for corona-game-template development
30
+ FileUtils.rm_r "#{code_dir}/.git"
31
+ FileUtils.rm_r "#{code_dir}/README"
32
+ FileUtils.rm "#{code_dir}/newgame.rb"
33
+ end
34
+
35
+ def show_help
36
+ print %{
37
+ Creates a new game at the parent directory.
38
+ Usage:
39
+ macruby newgame.rb <appname>
40
+ For example, if this template is on /Users/rad/Documents/games/corona-game-template,
41
+ running "macruby newgame mygame"
42
+ will create the directory /Users/rad/Documents/games/mygame
43
+ and copy all files from the template to that directory
44
+ }
45
+ end
46
+
47
+ def main
48
+ appname = ARGV[0]
49
+ if appname && appname.strip != ''
50
+ generate_new_app(appname)
51
+ else
52
+ show_help
53
+ end
54
+ end
55
+
56
+ main()
@@ -0,0 +1,34 @@
1
+ module(..., package.seeall)
2
+
3
+ -- Main function - MUST return a display.newGroup()
4
+ function new()
5
+ local localGroup = display.newGroup()
6
+
7
+ -- Background
8
+ local background = display.newImageRect("bk_default.png", 480, 320)
9
+ background.x = display.contentCenterX
10
+ background.y = display.contentCenterY
11
+ localGroup:insert(background)
12
+
13
+ -- Title
14
+ local title = display.newText("Touch to go back", 0, 0, native.systemFontBold, 16)
15
+ title:setTextColor( 255,255,255)
16
+ title.x = display.contentCenterX
17
+ title.y = display.contentCenterY
18
+ title.name = "title"
19
+ localGroup:insert(title)
20
+
21
+ -- Touch to go back
22
+ local function touched ( event )
23
+ if ("ended" == event.phase) then
24
+ director:changeScene("menu","fade")
25
+ end
26
+ end
27
+ background:addEventListener("touch",touched)
28
+
29
+ unloadMe = function()
30
+ end
31
+
32
+ -- MUST return a display.newGroup()
33
+ return localGroup
34
+ end
@@ -0,0 +1,73 @@
1
+ -- Rad's Library of awesome Lua functions to complement the awesome Corona SDK
2
+
3
+ local M = {}
4
+ M.io = {}
5
+ M.table = {}
6
+
7
+ require "json"
8
+
9
+ local parseJson = function( filename )
10
+ local file = io.open( filename, "r" )
11
+ if file then
12
+ local contents = file:read( "*a" )
13
+ result = json.decode( contents )
14
+ io.close( file )
15
+ return result
16
+ else
17
+ return {}
18
+ end
19
+ end
20
+ M.io.parseJson = parseJson
21
+
22
+ -- From: http://stackoverflow.com/questions/1283388/lua-merge-tables
23
+ local tableMerge = function(t1, t2)
24
+ for k,v in pairs(t2) do
25
+ if type(v) == "table" then
26
+ if type(t1[k] or false) == "table" then
27
+ table.merge(t1[k] or {}, t2[k] or {})
28
+ else
29
+ t1[k] = v
30
+ end
31
+ else
32
+ t1[k] = v
33
+ end
34
+ end
35
+ return t1
36
+ end
37
+ M.table.merge = tableMerge
38
+
39
+ -- Similar to Ruby's Enumerable#select
40
+ -- Given an input table and a function, return only those rows where fx(row) returns true
41
+ local tableFindAll = function( t, fx )
42
+ local result = {}
43
+ for i,v in ipairs(t) do
44
+ if fx(v) then
45
+ result[#result + 1] = v
46
+ end
47
+ end
48
+ return result
49
+ end
50
+ M.table.findAll = tableFindAll
51
+
52
+ local tablePrint = function( t )
53
+ for i,v in pairs(t) do
54
+ if "table" == type(v) then
55
+ print(i .. " = [table]: ")
56
+ print("---")
57
+ table.print(v)
58
+ print("---")
59
+ else
60
+ print(i .. " = " .. v)
61
+ end
62
+ end
63
+ end
64
+ M.table.print = tablePrint
65
+
66
+ local debug = function( msg )
67
+ native.showAlert("DEBUG", msg, {"OK"})
68
+ end
69
+ M.debug = debug
70
+
71
+ return M
72
+
73
+
@@ -0,0 +1,34 @@
1
+ module(..., package.seeall)
2
+
3
+ -- Main function - MUST return a display.newGroup()
4
+ function new()
5
+ local localGroup = display.newGroup()
6
+
7
+ -- Background
8
+ local background = display.newImageRect("bk_default.png", 480, 320)
9
+ background.x = display.contentCenterX
10
+ background.y = display.contentCenterY
11
+ localGroup:insert(background)
12
+
13
+ -- Title
14
+ local title = display.newText("Touch to go back", 0, 0, native.systemFontBold, 16)
15
+ title:setTextColor( 255,255,255)
16
+ title.x = display.contentCenterX
17
+ title.y = display.contentCenterY
18
+ title.name = "title"
19
+ localGroup:insert(title)
20
+
21
+ -- Touch to go back
22
+ local function touched ( event )
23
+ if ("ended" == event.phase) then
24
+ director:changeScene("menu","fade")
25
+ end
26
+ end
27
+ background:addEventListener("touch",touched)
28
+
29
+ unloadMe = function()
30
+ end
31
+
32
+ -- MUST return a display.newGroup()
33
+ return localGroup
34
+ end
@@ -0,0 +1,318 @@
1
+ -- ui.lua (currently includes Button class with labels, font selection and optional event model)
2
+
3
+ -- Version 1.5 (works with multitouch, adds setText() method to buttons)
4
+ --
5
+ -- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
6
+ --
7
+ -- Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ -- this software and associated documentation files (the "Software"), to deal in the
9
+ -- Software without restriction, including without limitation the rights to use, copy,
10
+ -- modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11
+ -- and to permit persons to whom the Software is furnished to do so, subject to the
12
+ -- following conditions:
13
+ --
14
+ -- The above copyright notice and this permission notice shall be included in all copies
15
+ -- or substantial portions of the Software.
16
+ --
17
+ -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18
+ -- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19
+ -- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
20
+ -- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
+ -- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ -- DEALINGS IN THE SOFTWARE.
23
+
24
+ ----------------------------------------------------
25
+ -- Edited by William Flagello, williamflagello.com
26
+ ----------------------------------------------------
27
+ -- Works with Dynamic Scaling.
28
+ ----------------------------------------------------
29
+
30
+ --
31
+ -- Abstract: Goshts Vs Monsters sample project
32
+ -- Designed and created by Jonathan and Biffy Beebe of Beebe Games exclusively for Ansca, Inc.
33
+ -- http://beebegamesonline.appspot.com/
34
+
35
+ -- (This is easiest to play on iPad or other large devices, but should work on all iOS and Android devices)
36
+ --
37
+ -- Version: 1.0
38
+ --
39
+ -- Sample code is MIT licensed, see http://developer.anscamobile.com/code/license
40
+ -- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
41
+
42
+
43
+ module(..., package.seeall)
44
+
45
+ -----------------
46
+ -- Helper function for newButton utility function below
47
+ local function newButtonHandler( self, event )
48
+
49
+ local result = true
50
+
51
+ local default = self[1]
52
+ local over = self[2]
53
+
54
+ -- General "onEvent" function overrides onPress and onRelease, if present
55
+ local onEvent = self._onEvent
56
+
57
+ local onPress = self._onPress
58
+ local onRelease = self._onRelease
59
+
60
+ local buttonEvent = {}
61
+ if (self._id) then
62
+ buttonEvent.id = self._id
63
+ end
64
+
65
+ local phase = event.phase
66
+ if "began" == phase then
67
+ if over then
68
+ default.isVisible = false
69
+ over.isVisible = true
70
+ end
71
+
72
+ if onEvent then
73
+ buttonEvent.phase = "press"
74
+ result = onEvent( buttonEvent )
75
+ elseif onPress then
76
+ result = onPress( event )
77
+ end
78
+
79
+ -- Subsequent touch events will target button even if they are outside the stageBounds of button
80
+ display.getCurrentStage():setFocus( self, event.id )
81
+ self.isFocus = true
82
+
83
+ elseif self.isFocus then
84
+ local bounds = self.stageBounds
85
+ local x,y = event.x,event.y
86
+ local isWithinBounds =
87
+ bounds.xMin <= x and bounds.xMax >= x and bounds.yMin <= y and bounds.yMax >= y
88
+
89
+ if "moved" == phase then
90
+ if over then
91
+ -- The rollover image should only be visible while the finger is within button's stageBounds
92
+ default.isVisible = not isWithinBounds
93
+ over.isVisible = isWithinBounds
94
+ end
95
+
96
+ elseif "ended" == phase or "cancelled" == phase then
97
+ if over then
98
+ default.isVisible = true
99
+ over.isVisible = false
100
+ end
101
+
102
+ if "ended" == phase then
103
+ -- Only consider this a "click" if the user lifts their finger inside button's stageBounds
104
+ if isWithinBounds then
105
+ if onEvent then
106
+ buttonEvent.phase = "release"
107
+ result = onEvent( buttonEvent )
108
+ elseif onRelease then
109
+ result = onRelease( event )
110
+ end
111
+ end
112
+ end
113
+
114
+ -- Allow touch events to be sent normally to the objects they "hit"
115
+ display.getCurrentStage():setFocus( self, nil )
116
+ self.isFocus = false
117
+ end
118
+ end
119
+
120
+ return result
121
+ end
122
+
123
+
124
+ ---------------
125
+ -- Button class
126
+
127
+ function newButton( params )
128
+ local button, defaultSrc , defaultX , defaultY , overSrc , overX , overY , size, font, textColor, offset
129
+
130
+ if params.defaultSrc then
131
+ button = display.newGroup()
132
+ default = display.newImageRect ( params.defaultSrc , params.defaultX , params.defaultY )
133
+ button:insert( default, true )
134
+ end
135
+
136
+ if params.overSrc then
137
+ over = display.newImageRect ( params.overSrc , params.overX , params.overY )
138
+ over.isVisible = false
139
+ button:insert( over, true )
140
+ end
141
+
142
+ -- Public methods
143
+ function button:setText( newText )
144
+
145
+ local labelText = self.text
146
+ if ( labelText ) then
147
+ labelText:removeSelf()
148
+ self.text = nil
149
+ end
150
+
151
+ local labelShadow = self.shadow
152
+ if ( labelShadow ) then
153
+ labelShadow:removeSelf()
154
+ self.shadow = nil
155
+ end
156
+
157
+ local labelHighlight = self.highlight
158
+ if ( labelHighlight ) then
159
+ labelHighlight:removeSelf()
160
+ self.highlight = nil
161
+ end
162
+
163
+ if ( params.size and type(params.size) == "number" ) then size=params.size else size=20 end
164
+ if ( params.font ) then font=params.font else font=native.systemFontBold end
165
+ if ( params.textColor ) then textColor=params.textColor else textColor={ 255, 255, 255, 255 } end
166
+
167
+ size = size * 2
168
+
169
+ -- Optional vertical correction for fonts with unusual baselines (I'm looking at you, Zapfino)
170
+ if ( params.offset and type(params.offset) == "number" ) then offset=params.offset else offset = 0 end
171
+
172
+ if ( params.emboss ) then
173
+ -- Make the label text look "embossed" (also adjusts effect for textColor brightness)
174
+ local textBrightness = ( textColor[1] + textColor[2] + textColor[3] ) / 3
175
+
176
+ labelHighlight = display.newText( newText, 0, 0, font, size )
177
+ if ( textBrightness > 127) then
178
+ labelHighlight:setTextColor( 255, 255, 255, 20 )
179
+ else
180
+ labelHighlight:setTextColor( 255, 255, 255, 140 )
181
+ end
182
+ button:insert( labelHighlight, true )
183
+ labelHighlight.x = labelHighlight.x + 1.5; labelHighlight.y = labelHighlight.y + 1.5 + offset
184
+ self.highlight = labelHighlight
185
+
186
+ labelShadow = display.newText( newText, 0, 0, font, size )
187
+ if ( textBrightness > 127) then
188
+ labelShadow:setTextColor( 0, 0, 0, 128 )
189
+ else
190
+ labelShadow:setTextColor( 0, 0, 0, 20 )
191
+ end
192
+ button:insert( labelShadow, true )
193
+ labelShadow.x = labelShadow.x - 1; labelShadow.y = labelShadow.y - 1 + offset
194
+ self.shadow = labelShadow
195
+
196
+ labelHighlight.xScale = .5; labelHighlight.yScale = .5
197
+ labelShadow.xScale = .5; labelShadow.yScale = .5
198
+ end
199
+
200
+ labelText = display.newText( newText, 0, 0, font, size )
201
+ labelText:setTextColor( textColor[1], textColor[2], textColor[3], textColor[4] )
202
+ button:insert( labelText, true )
203
+ labelText.y = labelText.y + offset
204
+ self.text = labelText
205
+
206
+ labelText.xScale = .5; labelText.yScale = .5
207
+ end
208
+
209
+ if params.text then
210
+ button:setText( params.text )
211
+ end
212
+
213
+ if ( params.onPress and ( type(params.onPress) == "function" ) ) then
214
+ button._onPress = params.onPress
215
+ end
216
+ if ( params.onRelease and ( type(params.onRelease) == "function" ) ) then
217
+ button._onRelease = params.onRelease
218
+ end
219
+
220
+ if (params.onEvent and ( type(params.onEvent) == "function" ) ) then
221
+ button._onEvent = params.onEvent
222
+ end
223
+
224
+ -- set button to active (meaning, can be pushed)
225
+ button.isActive = true
226
+
227
+ -- Set button as a table listener by setting a table method and adding the button as its own table listener for "touch" events
228
+ button.touch = newButtonHandler
229
+ button:addEventListener( "touch", button )
230
+
231
+ if params.x then
232
+ button.x = params.x
233
+ end
234
+
235
+ if params.y then
236
+ button.y = params.y
237
+ end
238
+
239
+ if params.id then
240
+ button._id = params.id
241
+ end
242
+
243
+ return button
244
+ end
245
+
246
+
247
+ --------------
248
+ -- Label class
249
+
250
+ function newLabel( params )
251
+ local labelText
252
+ local size, font, textColor, align
253
+ local t = display.newGroup()
254
+
255
+ if ( params.bounds ) then
256
+ local bounds = params.bounds
257
+ local left = bounds[1]
258
+ local top = bounds[2]
259
+ local width = bounds[3]
260
+ local height = bounds[4]
261
+
262
+ if ( params.size and type(params.size) == "number" ) then size=params.size else size=20 end
263
+ if ( params.font ) then font=params.font else font=native.systemFontBold end
264
+ if ( params.textColor ) then textColor=params.textColor else textColor={ 255, 255, 255, 255 } end
265
+ if ( params.offset and type(params.offset) == "number" ) then offset=params.offset else offset = 0 end
266
+ if ( params.align ) then align = params.align else align = "center" end
267
+
268
+ if ( params.text ) then
269
+ labelText = display.newText( params.text, 0, 0, font, size )
270
+ labelText:setTextColor( textColor[1], textColor[2], textColor[3], textColor[4] )
271
+ t:insert( labelText )
272
+ -- TODO: handle no-initial-text case by creating a field with an empty string?
273
+
274
+ if ( align == "left" ) then
275
+ labelText.x = left + labelText.stageWidth * 0.5
276
+ elseif ( align == "right" ) then
277
+ labelText.x = (left + width) - labelText.stageWidth * 0.5
278
+ else
279
+ labelText.x = ((2 * left) + width) * 0.5
280
+ end
281
+ end
282
+
283
+ labelText.y = top + labelText.stageHeight * 0.5
284
+
285
+ -- Public methods
286
+ function t:setText( newText )
287
+ if ( newText ) then
288
+ labelText.text = newText
289
+
290
+ if ( "left" == align ) then
291
+ labelText.x = left + labelText.stageWidth / 2
292
+ elseif ( "right" == align ) then
293
+ labelText.x = (left + width) - labelText.stageWidth / 2
294
+ else
295
+ labelText.x = ((2 * left) + width) / 2
296
+ end
297
+ end
298
+ end
299
+
300
+ function t:setTextColor( r, g, b, a )
301
+ local newR = 255
302
+ local newG = 255
303
+ local newB = 255
304
+ local newA = 255
305
+
306
+ if ( r and type(r) == "number" ) then newR = r end
307
+ if ( g and type(g) == "number" ) then newG = g end
308
+ if ( b and type(b) == "number" ) then newB = b end
309
+ if ( a and type(a) == "number" ) then newA = a end
310
+
311
+ labelText:setTextColor( r, g, b, a )
312
+ end
313
+ end
314
+
315
+ -- Return instance (as display group)
316
+ return t
317
+
318
+ end