Skip to content

Commit 87f9a0a

Browse files
committed
fixes and documentation
1 parent bdd2ade commit 87f9a0a

File tree

4 files changed

+104
-201
lines changed

4 files changed

+104
-201
lines changed

source/scenes/Play.lua

Lines changed: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,30 @@ local playerSlot
1111
local ground = gfx.image.new("/assets/images/ground")
1212
local tree = gfx.image.new("/assets/images/tree")
1313
local grass = gfx.image.new("/assets/images/grass")
14+
local collected = 0
1415

16+
-- Input is mostly handled by the player
1517
Play.inputHandler = {
16-
leftButtonDown = function()
17-
player:setState("left")
18-
end,
19-
leftButtonUp = function()
20-
player:setState("idle")
21-
end,
22-
rightButtonDown = function()
23-
player:setState("right")
24-
end,
25-
rightButtonUp = function()
26-
player:setState("idle")
27-
end,
18+
BButtonHeld = function()
19+
Noble.GameData.set("items", items, playerSlot) -- Save the player's collected items
20+
Noble.transition(Title)
21+
end
2822
}
2923

30-
-- This runs when your scene's object is created, which is the
31-
-- first thing that happens when transitioning away from another scene.
3224
function Play:init()
3325
Play.super.init(self)
3426

27+
collected = 0
3528
playerSlot = tonumber(Noble.Settings.get("playerSlot"))
3629
items = Noble.GameData.get("items", playerSlot)
3730
player = Player(100, 96, playerSlot)
3831
self.menu:addMenuItem("menu", function() Noble.transition(Title) end)
3932
end
4033

41-
-- When transitioning from another scene, this runs as soon as this
42-
-- scene needs to be visible (this moment depends on which transition type is used).
4334
function Play:enter()
4435
Play.super.enter(self)
4536

37+
-- Using regular sprites because of convenience
4638
local tree_sprite = gfx.sprite.new(tree)
4739
tree_sprite:setCenter(0.5, 1) -- This sets the anchor to the bottom center
4840
tree_sprite:moveTo(144, 104)
@@ -65,69 +57,59 @@ function Play:enter()
6557
ground_sprite:setCenter(0.5, 0) -- This sets the anchor to the top center
6658
ground_sprite:moveTo(100, 104)
6759
self:addSprite(ground_sprite)
60+
6861
self:addSprite(player)
69-
player:setState("idle")
70-
playdate.display.setScale(2)
62+
player.active = true -- Setting active sets the state, so we don't set it until the scene enters
63+
playdate.display.setScale(2) -- Set the screen scale so the 16x16 pixels are bigger
64+
end
65+
66+
-- Helper function to collect items, used for adding and removing callbacks to Signal
67+
local function collectItem(_, _, value)
68+
collected += 1
69+
local key = tostring(value) -- Convert to string so the items work like a dictionary and not an array
70+
if items[key] == nil then
71+
items[key] = 0
72+
end
73+
items[key] += 1
7174
end
7275

7376
-- This runs once a transition from another scene is complete.
7477
function Play:start()
7578
Play.super.start(self)
7679

7780
Noble.showFPS = true
78-
Signal:add("collected", self, function(_, _, value)
79-
local key = tostring(value)
80-
if items[key] == nil then
81-
items[key] = 0
82-
end
83-
items[key] += 1
84-
end)
85-
itemTimer = Timer.new(1000, function()
81+
Signal:add("collected", self, collectItem) -- Add our callback when an item is collected
82+
itemTimer = Timer.new(1000, function() -- Once a second, spawn an item at a random position
8683
Item(math.random(10, 190), -10)
8784
end)
8885
itemTimer.repeats = true
8986
end
9087

91-
-- This runs once per frame.
92-
-- function Play:update()
93-
-- Play.super.update(self)
94-
-- -- Your code here
95-
-- end
96-
97-
-- function Play:drawBackground()
98-
-- Play.super.drawBackground(self)
99-
-- -- Your code here
100-
-- tree:draw(24, 80)
101-
-- tree:draw(146, 74)
102-
-- grass:draw(56, 89, gfx.kImageFlippedX)
103-
-- grass:draw(156, 89)
104-
-- ground:draw(4, 104)
105-
-- end
106-
10788
-- This runs as as soon as a transition to another scene begins.
10889
function Play:exit()
10990
Play.super.exit(self)
11091

11192
Noble.showFPS = false
11293
itemTimer:remove()
113-
Signal:remove("collected")
114-
Noble.GameData.set("items", items, playerSlot)
94+
Signal:remove("collected", collectItem)
95+
Noble.GameData.set("items", items, playerSlot) -- Save the player's collected items
11596
end
11697

11798
-- This runs once a transition to another scene completes.
11899
function Play:finish()
119100
Play.super.finish(self)
120-
-- Your code here
121-
playdate.display.setScale(1)
101+
playdate.display.setScale(1) -- Reset the scale when exiting
122102
end
123103

124-
-- TODO Show number of items collected
104+
-- This is called before the system pauses the game
125105
function Play:pause()
126106
Play.super.pause(self)
127-
-- Your code here
128-
end
129107

130-
function Play:resume()
131-
Play.super.resume(self)
132-
-- Your code here
108+
-- Draw the number of collected items to the menu image
109+
local _img = gfx.image.new(400, 240, gfx.kColorWhite)
110+
gfx.pushContext(_img)
111+
gfx.drawTextAligned("*Collected*", 100, 110, kTextAlignment.center)
112+
gfx.drawTextAligned(collected, 100, 130, kTextAlignment.center)
113+
gfx.popContext()
114+
pd.setMenuImage(_img)
133115
end

source/scenes/Stats.lua

Lines changed: 47 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,36 @@ class("Stats").extends(BaseScene)
66

77
local items
88
local grid
9-
9+
local modal
1010
local locked_image = gfx.image.new("/assets/images/locked")
1111
local heart_image = gfx.image.new("/assets/images/heart")
1212
local icons_it = gfx.imagetable.new("/assets/images/kenney-icons")
1313
local 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+
)
1522
local keyTimer
1623
Stats.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 :)\nThanks 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)
138148
end
139149

150+
-- This will be drawn behind all sprites (the ui popup is a sprite)
140151
function Stats:drawBackground()
141152
grid:drawInRect(0, 0, 400, 240)
142153
end
143154

144155
function 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
151162
end
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

Comments
 (0)