@@ -6,23 +6,36 @@ class("Stats").extends(BaseScene)
66
77local items
88local grid
9-
9+ local modal
1010local locked_image = gfx .image .new (" /assets/images/locked" )
1111local heart_image = gfx .image .new (" /assets/images/heart" )
1212local icons_it = gfx .imagetable .new (" /assets/images/kenney-icons" )
1313local columns , rows = icons_it :getSize ()
14- local modal , modal_animator
14+ local modal_animator = gfx .animator .new (
15+ 500 ,
16+ Geometry .lineSegment .new (
17+ 200 , 275 ,
18+ 200 , 120
19+ ),
20+ Ease .outBack
21+ )
1522local keyTimer
1623Stats .inputHandler = {
24+ BButtonHeld = function ()
25+ Noble .transition (Title )
26+ end ,
1727 upButtonDown = function ()
28+ -- If there's already a timer, ignore
1829 if keyTimer ~= nil then
1930 return
2031 end
32+ -- Add repeat timers so users can hold the direction
2133 local function timerCallback ()
2234 grid :selectPreviousRow (true )
2335 end
2436 keyTimer = playdate .timer .keyRepeatTimer (timerCallback )
2537 end ,
38+ -- Remove the listener on button up
2639 upButtonUp = function ()
2740 if keyTimer == nil then
2841 return
@@ -80,31 +93,27 @@ Stats.inputHandler = {
8093 end ,
8194 AButtonDown = function ()
8295 local _ , row , column = grid :getSelection ()
83- local index = math.floor (columns * (row - 1 ) + column )
84- if index == 1 then
96+ local index = math.floor (columns * (row - 1 ) + column ) -- Convert row/column to index
97+ if index == 1 then -- Index 1 is blank, use a placeholder
8598 modal = notify (" *HELLO :)\n Thanks for checking out the example project!*" , function ()
8699 Noble .currentScene ():removeSprite (modal )
87100 modal = nil
88101 end )
89102 else
103+ -- If the item is locked, skip
90104 if items [tostring (index )] == nil then
91105 return
92106 end
107+ -- Else show the status
93108 local count = items [tostring (index )]
94109 modal = notify (" *#" .. index .. " *: Collected " .. count .. " time" .. (count > 1 and " s" or " " ), function ()
95110 Noble .currentScene ():removeSprite (modal )
96111 modal = nil
97112 end )
98113 end
99- modal_animator = gfx .animator .new (
100- 500 ,
101- Geometry .lineSegment .new (
102- 200 , 275 ,
103- 200 , 120
104- ),
105- Ease .outBack
106- )
107- Noble .currentScene ():addSprite (modal )
114+ modal :moveTo (200 , 275 ) -- Move the modal to the bottom of the screen
115+ modal_animator :reset ()
116+ Noble .currentScene ():addSprite (modal ) -- Add to the current scene
108117 end
109118}
110119
@@ -116,11 +125,12 @@ function Stats:init()
116125 grid :setNumberOfRows (rows )
117126 grid :setSelection (1 , 1 , 1 )
118127 grid .changeRowOnColumnWrap = false
119- function grid :drawCell (_ , row , column , selected , x , y , _ , _ )
128+ function grid :drawCell (_ , row , column , selected , x , y , _ , _ ) -- Override the drawCell function
129+ -- Get either the locked image or the unlocked tile image
120130 local index = math.floor (columns * (row - 1 ) + column )
121131 local image = items [tostring (index )] == nil and locked_image or icons_it :getImage (index )
122132
123- if index == 1 then
133+ if index == 1 then -- Index 1 is blank, use a heart when selected
124134 if selected then
125135 image = heart_image
126136 else
@@ -129,95 +139,44 @@ function Stats:init()
129139 end
130140
131141 if selected then
132- image :drawScaled (x , y , 2 )
142+ image :drawScaled (x , y , 2 ) -- Draw the sprite larger if selected
133143 else
134144 image :draw (x + 8 , y + 8 )
135145 end
136146 end
137147 self .menu :addMenuItem (" menu" , function () Noble .transition (Title ) end )
138148end
139149
150+ -- This will be drawn behind all sprites (the ui popup is a sprite)
140151function Stats :drawBackground ()
141152 grid :drawInRect (0 , 0 , 400 , 240 )
142153end
143154
144155function Stats :update ()
145- if grid .needsDisplay then
156+ if grid .needsDisplay then -- If the grid changed, redraw background
146157 gfx .sprite .redrawBackground ()
147158 end
148- if modal ~= nil then
159+ if modal ~= nil and not modal_animator : ended () then -- Animate the modal
149160 modal :moveTo (modal_animator :currentValue ())
150161 end
151162end
152163
153- -- TODO Show number of items collected total %
154-
155- -- function Title:pause()
156- -- Title.super.pause(self)
157- -- -- Your code here
158- -- end
159- -- function Title:resume()
160- -- Title.super.resume(self)
161- -- -- Your code here
162- -- end
163-
164- --
165- -- -- This runs when your scene's object is created, which is the
166- -- -- first thing that happens when transitioning away from another scene.
167- -- function Title:init()
168- -- Title.super.init(self)
169-
170- -- -- gfx.setFontFamily(Noble.Text.FONT_NEWSLEAK_FAMILY)
171- -- Noble.Text.setFont(Noble.Text.FONT_NEWSLEAK)
172- -- menu = Noble.Menu.new(
173- -- true, -- Activate
174- -- Noble.Text.ALIGN_CENTER,
175- -- false, -- No localization
176- -- nil, -- Use default color
177- -- 4, 6 -- Adjust padding
178- -- )
179- -- menu:addItem("Play", function() Noble.transition(Play, 1, Noble.TransitionType.DIP_WIDGET_SATCHEL) end)
180- -- menu:addItem("Stats", function() Noble.transition(Stats, 1, Noble.TransitionType.DIP_WIDGET_SATCHEL) end)
181- -- end
182-
183- -- -- When transitioning from another scene, this runs as soon as this
184- -- -- scene needs to be visible (this moment depends on which transition type is used).
185- -- function Title:enter()
186- -- Title.super.enter(self)
187-
188- -- self:addSprite(logo)
189- -- end
190-
191- -- -- This runs once a transition from another scene is complete.
192- -- function Title:start()
193- -- Title.super.start(self)
194- -- -- Your code here
195- -- end
196-
197- -- -- This runs once per frame.
198- -- function Title:update()
199- -- Title.super.update(self)
200- -- -- Your code here
201- -- menu:draw(200, 160)
202- -- end
203-
204- -- -- This runs as as soon as a transition to another scene begins.
205- -- function Title:exit()
206- -- Title.super.exit(self)
207- -- -- Your code here
208- -- end
209-
210- -- -- This runs once a transition to another scene completes.
211- -- function Title:finish()
212- -- Title.super.finish(self)
213- -- -- Your code here
214- -- end
164+ function Stats :pause ()
165+ Play .super .pause (self )
166+ local icon_count = (# icons_it - 1 ) -- ID 1 is blank
167+ local item_count = 0
168+ local collected_count = 0
169+ for _ , count in pairs (items ) do
170+ item_count += 1
171+ collected_count += count
172+ end
215173
216- -- function Title:pause()
217- -- Title.super.pause(self)
218- -- -- Your code here
219- -- end
220- -- function Title:resume()
221- -- Title.super.resume(self)
222- -- -- Your code here
223- -- end
174+ local _img = gfx .image .new (400 , 240 , gfx .kColorWhite )
175+ gfx .pushContext (_img )
176+ gfx .drawTextAligned (" *Collected*" , 100 , 90 , kTextAlignment .center )
177+ gfx .drawTextAligned (item_count .. " /" .. icon_count , 100 , 110 , kTextAlignment .center )
178+ gfx .drawTextAligned (string.format (" %.2f %%" , item_count / icon_count * 100 ), 100 , 130 , kTextAlignment .center )
179+ gfx .drawTextAligned (collected_count .. " Collected total" , 100 , 150 , kTextAlignment .center )
180+ gfx .popContext ()
181+ pd .setMenuImage (_img )
182+ end
0 commit comments