fix: another PNG CRC error
[poca-love.git] / rainbowring.lua
blob8a67cfbd77a9b7e61cbc25377f541eb0f480a1e3
1 --[[
2 Rainbow Ring - a minigame is a part of POCA - a puzzle game
4 POCA is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This software is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
19 require('special')
21 rr = {
23 hijacked_love_functions = {
24 'draw', 'resize',
25 'mousepressed', 'mousemoved', 'mousereleased',
26 'keypressed'
30 hijacked_globals = {'menus'},
33 init = function(self, length)
34 self.ending = false
35 self.game_mode = false
36 self.length = self.length or 7
37 self.next_coin = false
38 self.ring = {}
39 self.menu_button = {}
40 self.random = {}
41 self:reset_coins()
42 self.resize()
43 self.last_score = nil
44 self.time_started = nil
45 end,
48 ring_insert = function(self, pos, p)
49 if self.ring[pos] then return false end
50 local newring = {}
51 for a = 1, self.length do
52 local newpos = (2 * a - pos - 1) % self.length + 1
53 newring[newpos] = self.ring[a]
54 end
55 newring[pos] = p
56 self.ring = newring
57 return true
58 end,
61 save_scores = function()
62 local ok, err = love.filesystem.write('rr_scores', 'rr.scores = ' .. serialize(rr.scores))
63 if not ok then error(err) end
64 end,
67 load_scores = function()
68 rr.scores = {}
69 local rr_scores, err = love.filesystem.load('rr_scores')
70 if not err then rr_scores() end
71 end,
74 main = function(self)
75 hijack(self)
76 self:populate_menus()
77 self:init()
78 self:load_scores()
79 self.show_menu = true
80 menus.main.onload()
81 end,
84 draw_coin = function(self, x, y, color, value, selected)
85 --rr.rainbow(love.timer.getTime() * 10 % 100 / 100), 1
86 color = color or {1, 1, 1}
87 love.graphics.setColor(color[1] * 1.3, color[2] * 1.3, color[3] * 1.3, 1)
88 love.graphics.circle('fill', x - rr.smallr * .02, y - rr.smallr * .02, rr.smallr)
89 love.graphics.setColor(color[1] * .7, color[2] * .7, color[3] * .7, 1)
90 love.graphics.circle('fill', x + rr.smallr * .02, y + rr.smallr * .02, rr.smallr)
91 if selected then
92 love.graphics.setColor(color[1] * .7, color[2] * .7, color[3] * .7, 1)
93 else
94 love.graphics.setColor(color)
95 end
96 love.graphics.circle('fill', x, y, rr.smallr * .96)
97 love.graphics.setColor(color[1] * 1.3, color[2] * 1.3, color[3] * 1.3, 1)
98 love.graphics.circle('fill', x + rr.smallr * .02, y + rr.smallr * .02, rr.smallr * .7)
99 love.graphics.setColor(color[1] * .7, color[2] * .7, color[3] * .7, 1)
100 love.graphics.circle('fill', x - rr.smallr * .02, y - rr.smallr * .02, rr.smallr * .7)
101 love.graphics.setColor(color)
102 love.graphics.circle('fill', x, y, rr.smallr * .66)
103 if value then
104 love.graphics.setColor(1,1,1, .9)
105 local offsety = screen.fontheight / 2
106 love.graphics.printf(value, x - rr.smallr / 2, y - offsety, rr.smallr ,'center')
108 love.graphics.setColor(1,1,1, 1)
109 end,
112 draw_playfield = function(self)
113 local r = screen.playfieldsize / 2
114 local centerx = screen.playfieldx + r
115 local centery = screen.playfieldy + r
116 love.graphics.setColor(1,1,1, 1)
117 love.graphics.rectangle('fill', self.playfieldx, self.playfieldy,
118 self.playfieldsize, self.playfieldsize, self.smallr / 2
120 love.graphics.setColor(0,0,0, 1)
121 love.graphics.setLineWidth(self.smallr / 4)
122 love.graphics.circle('line', self.bigx, self.bigy, self.bigr)
123 for a = 1, self.length do
124 love.graphics.setColor(0,0,0, 1)
125 love.graphics.circle('fill', self.coins[a].x, self.coins[a].y, self.smallr * 1.25)
126 if self.ring[a] then
127 self:draw_coin(self.coins[a].x, self.coins[a].y, self.elements[self.ring[a]].color, self.elements[self.ring[a]].value)
128 else
129 if self.selected and (self.selected.y == 1) and (self.selected.x + 1 == a) then
130 love.graphics.setColor(1,1,1, .5)
131 else
132 love.graphics.setColor(1,1,1, 1)
134 love.graphics.circle('fill', self.coins[a].x, self.coins[a].y, self.smallr)
137 love.graphics.setLineWidth(1)
138 love.graphics.setColor(1,1,1, 1)
139 for a = 1, #self.elements do
140 if not self.elements[a].hidden or
141 (a == #self.elements and self.selected and not self.ending) -- keep next_coin in keyboard selection
142 then
143 self:draw_coin(
144 self.elements[a].x, self.elements[a].y,
145 self.elements[a].color or
146 (self.next_coin and self.elements[self.next_coin].color) or
147 {.5, .5, .5},
148 self.elements[a].value or self.next_coin or '?',
149 self.elements[a].selected or
150 self.selected and (
151 ((self.selected.y == 0) and (self.selected.x + 1 == a)) or
152 ((self.selected.y == 2) and (a == self.length + 1))
157 -- ending text
158 if self.ending then
159 love.graphics.setColor(0, 0, 0)
160 local offsety = screen.fontheight / 2
161 love.graphics.printf(self.ending, self.bigx - self.bigr / 2, self.bigy - offsety, self.bigr ,'center')
163 -- menu button
164 local w = self.smallr * 2 / 3
165 local x1 = self.menu_button.x + w * .25
166 local y1 = self.menu_button.y + w * .25
167 local x2 = self.menu_button.x + w * 1.75
168 local y2 = self.menu_button.y + w * 1.75
169 if self.menu_button.selected then
170 love.graphics.setColor(1,1,1, .5)
171 love.graphics.rectangle('fill', self.menu_button.x, self.menu_button.y, w * 2, w * 2, w / 4)
172 love.graphics.setColor(.2,.6,.8, 1)
173 else
174 love.graphics.setColor(.1,.3,.4, 1)
175 love.graphics.rectangle('line', self.menu_button.x, self.menu_button.y, w * 2, w * 2, w / 4)
177 love.graphics.setLineWidth(w * .1)
178 if self.game_mode and not self.ending then
179 love.graphics.line(x1, y1, x2, y2)
180 love.graphics.line(x1, y2, x2, y1)
181 else
182 love.graphics.line(x1, (4 * y1 + y2) / 5, x2, (4 * y1 + y2) / 5)
183 love.graphics.line(x1, (y1 + y2) / 2, x2, (y1 + y2) / 2)
184 love.graphics.line(x1, (y1 + 4 * y2) / 5, x2, (y1 + 4 * y2) / 5)
186 love.graphics.setLineWidth(1)
187 love.graphics.setColor(1, 1, 1)
188 end,
191 draw = function() -- hijacked function
192 love.graphics.clear(.2, .6, .8)
193 if rr.show_menu then
194 draw_menu()
195 return
197 rr:draw_playfield()
198 end,
201 rainbow = function(h, a)
202 local r, g, b
203 if h < 1/3 then
204 r = math.cos(3 * math.pi * h / 2)
205 g = math.sin(3 * math.pi * h / 2)
206 b = -1
207 elseif h < 2/3 then
208 h = h - 1/3
209 r = -1
210 g = math.cos(3 * math.pi * h / 2)
211 b = math.sin(3 * math.pi * h / 2)
212 else
213 h = h - 2/3
214 r = math.sin(3 * math.pi * h / 2)
215 g = -1
216 b = math.cos(3 * math.pi * h / 2)
218 return {r, g, b, a or 1}
219 end,
222 reset_coins = function(self)
223 self.coins = {}
224 self.elements = {}
225 for a = 1, self.length do self.coins[a] = {} end
226 for a = 1, self.length do
227 self.elements[a] = {
228 color = rr.rainbow((a - 1) / self.length),
229 value = a
232 self.elements[self.length + 1] = {}
233 end,
236 resize = function() -- hijacked function
237 resize_common()
238 -- rainbow ring-specific variables
239 rr.bigx = screen.w / 2
240 rr.bigy = screen.h / 2
241 local bigr_w = screen.w / (2 + 6 / rr.length)
242 local bigr_h = screen.h / (2 + 15 / rr.length)
243 rr.bigr = math.min(bigr_w, bigr_h)
244 rr.smallr = 2 * rr.bigr / rr.length
245 rr.playfieldx = rr.bigx - rr.bigr - rr.smallr * 1.25
246 rr.playfieldy = rr.bigy - rr.bigr - rr.smallr * 1.25
247 rr.playfieldsize = 2 * (rr.bigr + rr.smallr * 1.25)
248 -- coins on ring
249 for a = 1, rr.length do
250 local pos = (a - 1) * 2 * math.pi / rr.length
251 rr.coins[a].x = rr.bigx + math.sin(pos) * rr.bigr
252 rr.coins[a].y = rr.bigy + math.cos(pos) * rr.bigr
254 -- palette
255 local offsetx = (screen.w - 2 * rr.smallr) / (rr.length - 1)
256 local offsety = rr.playfieldy - rr.smallr * 1.25
257 for a = 1, rr.length do
258 rr.elements[a].x = (a - 1) * offsetx + rr.smallr
259 rr.elements[a].y = offsety
261 -- central button
262 rr.elements[rr.length + 1].x = rr.bigx
263 rr.elements[rr.length + 1].y = rr.bigy
264 -- menu button
265 rr.menu_button.x = rr.smallr * .25
266 rr.menu_button.y = rr.playfieldy + rr.playfieldsize + rr.smallr * (3.5 / 6 )
267 -- menu background
268 screen.pfcanvas:renderTo(rr.menubg)
269 end,
272 -- determines if the clicked point is within radius
273 isin = function(mx, my, x, y, r)
274 return math.abs(mx - x) ^ 2 + math.abs(my - y) ^ 2 <= r ^ 2
275 end,
278 check_score = function(self)
279 self.last_score = love.timer.getTime() - self.time_started
280 local today = os.time()
281 local ending
282 if self.ending == 'Impressive!' then
283 ending = 'ccw'
284 else
285 ending = 'cw'
287 self.scores[self.length] = self.scores[self.length] or {}
288 local a = 0
289 repeat
290 a = a + 1
291 until
292 not self.scores[self.length][a] or
293 not self.scores[self.length][a][2] or
294 self.last_score < self.scores[self.length][a][2]
295 table.insert(self.scores[self.length], a, {today, self.last_score, ending})
296 table.remove(self.scores[self.length], 6) -- shave table to 5
297 if a <= 5 then -- show high score
298 self:save_scores()
299 self.show_menu = true
300 menus.main.onload()
302 end,
305 -- checks for victory condition
306 -- exits if ring not entirely full
307 ring_check = function(self)
308 local function wrap(a) return (a - 1) % self.length + 1 end
309 local forwards, backwards = true, true
310 for a = 2, self.length do
311 if not (self.ring[a - 1] and self.ring[a]) then return end
312 forwards = forwards and (wrap(self.ring[a - 1] + 1) == self.ring[a])
313 backwards = backwards and (wrap(self.ring[a - 1] - 1) == self.ring[a])
315 if forwards then
316 if self.game_mode == 1 then
317 self.ending = 'Bravo!'
318 elseif self.game_mode == 2 then
319 self.ending = 'Wow!'
320 elseif self.game_mode == 3 then
321 self.ending = 'Impressive!'
322 self:check_score()
324 elseif backwards then
325 if self.game_mode == 1 then
326 self.ending = 'Ovarb!'
327 elseif self.game_mode == 2 then
328 self.ending = 'Antiwow!'
329 elseif self.game_mode == 3 then
330 self.ending = 'Expressive!'
331 self:check_score()
333 else
334 self.ending = '' -- mark ring as full but no victory
336 -- hide last element
337 self.elements[self.length + 1].hidden = true
338 end,
341 click1 = function(self, a)
342 if not (self.next_coin and (not self.game_mode or self.game_mode == 1)) then return end
343 local ne = self.elements[self.next_coin]
344 self.game_mode = 1
345 self.elements[self.length + 1].hidden = true
346 self:ring_insert(a, self.next_coin)
347 self:ring_check()
348 ne.hidden = true
349 rr.next_coin = false
350 end,
353 click2 = function(self, a)
354 if not self.game_mode or self.game_mode == 2 or self.game_mode == 3 then
355 if not self.game_mode then
356 self.game_mode = 2
357 for b = 1, self.length do
358 self.elements[b].hidden = true
361 if self.game_mode == 2 then
362 self.next_coin = (self.next_coin or 1)
364 if self:ring_insert(a, self.next_coin) then
365 if self.game_mode == 2 then
366 if self.next_coin < self.length then
367 self.next_coin = self.next_coin + 1
369 elseif self.game_mode == 3 then
370 self.next_coin = self.random[#self.random]
371 self.random[#self.random] = nil
373 self:ring_check()
376 end,
379 -- activates random mode
380 click3 = function(self, a)
381 for b = 1, self.length do
382 self.elements[b].hidden = true
384 self.game_mode = 3
385 self.random = random_list(self.length)
386 self.next_coin = self.random[#self.random]
387 self.random[#self.random] = nil
388 self.time_started = love.timer.getTime()
389 end,
392 click_menu_button = function(self)
393 self.menu_button.selected = false
394 if self.game_mode and not self.ending then
395 self:init()
396 else
397 self.show_menu = true
398 menus.main.onload()
400 end,
403 mousepressed = function(mx, my, button) -- hijacked function
404 -- menu button click
405 if isin(mx, my, rr.menu_button.x, rr.menu_button.y, rr.smallr * 2, rr.smallr * 2) then
406 rr:click_menu_button()
407 return
409 if rr.selected then
410 rr.selected = false
411 if not rr.game_mode or rr.game_mode == 1 then rr.next_coin = false end
413 if rr.show_menu then
414 menu_click(mx, my)
415 return
417 if rr.ending then
418 rr:init()
419 return
421 for a = 1, rr.length do
422 if rr.isin(mx, my, rr.coins[a].x, rr.coins[a].y, rr.smallr) then
423 rr:click2(a)
426 -- drag - game mode 1
427 for a = 1, rr.length do
428 if rr.isin(mx, my, rr.elements[a].x, rr.elements[a].y, rr.smallr) and not rr.elements[a].hidden
429 then
430 rr.next_coin = a
431 love.mouse.setGrabbed(true)
434 -- click to '?' - game mode 3
435 if rr.isin(mx, my,
436 rr.elements[rr.length + 1].x, rr.elements[rr.length + 1].y, rr.smallr)
437 and (not rr.game_mode)
438 then
439 rr:click3()
441 end,
444 mousemoved = function(x, y, dx, dy) -- hijacked function
445 if rr.show_menu then return end
446 if isin(x, y, rr.menu_button.x, rr.menu_button.y, rr.smallr * 2, rr.smallr * 2) then
447 rr.menu_button.selected = true
448 else
449 rr.menu_button.selected = false
451 if rr.selected then return end
452 if not rr.next_coin or rr.game_mode == 3 then return end
453 rr.elements[rr.next_coin].x = rr.elements[rr.next_coin].x + dx
454 rr.elements[rr.next_coin].y = rr.elements[rr.next_coin].y + dy
455 end,
458 mousereleased = function(mx, my, button) -- hijacked function
459 if rr.show_menu then return end
460 love.mouse.setGrabbed(false)
461 if rr.selected then
462 rr.selected = false
463 return
465 if not (rr.next_coin and (not rr.game_mode or rr.game_mode == 1)) then return end
466 local ne = rr.elements[rr.next_coin]
467 for a = 1, rr.length do
468 if ne and not rr.ring[a] and rr.isin(ne.x, ne.y, rr.coins[a].x, rr.coins[a].y, rr.smallr)
469 then
470 rr:click1(a)
471 ne.hidden = true
474 rr.next_coin = false
475 rr.resize()
476 end,
479 -- keyboard selection
480 mark = function(self, x)
481 rr.menu_button.selected = false
482 if self.selected.y == 0 then -- pallette
483 if x == 0 and self.elements[self.selected.x + 1].hidden then x = 1 end
484 if self.ending or not self.game_mode == 1 then return end -- skip if no palette
485 local n = 0
486 repeat
487 self.selected.x = (self.selected.x + x) % self.length
488 n = n + 1
489 until not self.elements[self.selected.x + 1].hidden or (n > self.length)
490 elseif self.selected.y == 1 then -- ring
491 if x == 0 and self.ring[self.selected.x + 1] then x = 1 end
492 if self.ending then return end -- skip if all full
493 local n = 0
494 repeat
495 n = n + 1
496 self.selected.x = (self.selected.x - x) % self.length
497 until not self.ring[self.selected.x + 1] or (n > self.length)
498 elseif self.selected.y == 3 then -- menu button
499 rr.menu_button.selected = true
501 end,
504 keypressed = function(k)
505 if rr.show_menu then
506 if k == 'left' then
507 menu_select(-1, 0)
508 elseif k == 'right' then
509 menu_select(1, 0)
510 elseif k == 'up' then
511 menu_select(0, -1)
512 elseif k == 'down' then
513 menu_select(0, 1)
514 elseif k == 'return' then
515 menu_press()
517 else -- not menu
518 if not rr.selected then rr.selected = {x = math.floor(rr.length / 2), y = 0} end
519 if k == 'up' then
520 if rr.game_mode then
521 rr.menu_button.selected = not rr.menu_button.selected
522 return
524 rr.next_coin = false
525 rr.selected.y = (rr.selected.y - 1) % 4
526 rr:mark(0)
527 elseif k == 'down' then
528 if rr.game_mode then
529 rr.menu_button.selected = not rr.menu_button.selected
530 return
532 rr.next_coin = false
533 rr.selected.y = (rr.selected.y + 1) % 4
534 rr:mark(0)
535 elseif k == 'left' then
536 if rr.selected.y == 3 then rr.selected.y = 1 end -- menu button was sel
537 if rr.game_mode == 2 or rr_game_mode == 3 then rr.selected.y = 1 end
538 rr:mark(-1)
539 elseif k == 'right' then
540 if rr.selected.y == 3 then rr.selected.y = 1 end -- menu button was sel
541 if rr.game_mode == 2 or rr_game_mode == 3 then rr.selected.y = 1 end
542 rr:mark(1)
543 elseif k == 'return' then
544 if rr.menu_button.selected then
545 rr:click_menu_button()
546 return
548 if rr.ending then
549 rr:init()
550 return
551 elseif rr.selected.y == 0 then -- pallette
552 rr.next_coin = rr.selected.x + 1
553 rr.selected.y = 1
554 rr:mark(0)
555 elseif rr.selected.y == 1 then -- ring
556 rr:click1(rr.selected.x + 1)
557 rr:click2(rr.selected.x + 1)
558 if rr.game_mode == 1 then rr.selected.y = 0 end
559 rr:mark(0)
560 elseif rr.selected.y == 2 then
561 rr.selected.y = 1
562 rr:click3()
563 rr:mark(0)
567 -- global keys
568 if k == 'q' then
569 love.event.push('quit')
571 if k == 'escape' or k == 'm' then
572 rr.show_menu = not rr.show_menu
573 if rr.show_menu then menus.main.onload() end
575 end,
578 -- background in menu
579 menubg = function()
580 local ts = screen.tilesize
581 -- show coins
582 love.graphics.clear(.2, .6, .8)
583 love.graphics.setColor(1, 1, 1)
584 love.graphics.rectangle(
585 'fill',
586 0, ts * 0.5,
587 screen.playfieldsize, ts * 3,5
589 local offsetx = rr.smallr + .8 * ts
590 for a = 1, rr.length do
591 rr:draw_coin(
592 offsetx + (a - 1) * (2.3 * ts - rr.smallr) / rr.length,
593 ts * 0.5, rr.elements[a].color
596 -- darken central square for text display
597 love.graphics.setColor(0,0,0, .25)
598 love.graphics.rectangle('fill',
599 ts * .8, ts * .2,
600 ts * 2.4, ts * .6
602 love.graphics.setColor(1, 1, 1)
603 -- prepare to print scores
604 local scores = rr.get_scores(rr.length) or {}
605 local max_date_width, max_time_width = 0, 0
606 for a = 1, #scores do -- get max width of fuzzy date
607 max_date_width = math.max(
608 screen.defaultfont:getWidth(scores[a].date), max_date_width
610 max_time_width = math.max(
611 screen.defaultfont:getWidth(scores[a].time), max_time_width
614 local max_width = ts * .6 + max_date_width + max_time_width
615 offsetx = math.floor((screen.playfieldsize - max_width) / 2)
616 local offsety = 1.5 * ts
617 -- actually print scores
618 love.graphics.setColor(0, 0, 0)
619 if #scores > 0 then love.graphics.print('High scores', offsetx, ts) end
620 for a = 1, #scores do
621 -- draw rectangle behind fresh scores
622 love.graphics.setColor(rr.rainbow((a - 1) / 5, .5))
623 local highlight_length = ts * .25
624 if scores[a].date == 'just now' then highlight_length = ts * .1 + max_width end
625 love.graphics.rectangle(
626 'fill',
627 offsetx - ts * .05, offsety + (a - 1) * ts / 3,
628 highlight_length, screen.fontheight, ts * .1
630 love.graphics.setColor(0, 0, 0)
631 -- print score position and date
632 love.graphics.print(a .. '. ',
633 offsetx, offsety + (a - 1) * ts / 3
635 love.graphics.print(scores[a].date,
636 offsetx + ts * .3, offsety + (a - 1) * ts / 3
638 -- draw direction
639 love.graphics.setColor(0, 0, 0)
640 if scores[a].direction == 'ccw' then
641 draw_image({name = 'cw'},
642 (ts * .1 + offsetx + ts * .4 + max_date_width) / ts,
643 (ts * .11 + offsety + (a - 1) * ts / 3) / ts,
644 0, -.18
646 elseif scores[a].direction == 'cw' then
647 draw_image({name = 'cw'},
648 (ts * .1 + offsetx + ts * .4 + max_date_width) / ts,
649 (ts * .11 + offsety + (a - 1) * ts / 3) / ts,
650 0, .18
653 -- draw score time
654 love.graphics.setColor(0, 0, 0)
655 love.graphics.print(scores[a].time,
656 offsetx + max_width - screen.defaultfont:getWidth(scores[a].time), offsety + (a - 1) * ts / 3
659 love.graphics.setColor(1, 1, 1)
660 end,
663 menus = {},
666 get_scores = function(length)
667 if not (rr.scores and rr.scores[length]) then return end
668 local function fuzzy_ago(s)
669 if s < 60 then return 'last minute' end
670 local m = math.floor(s / 60)
671 local h = math.floor(m / 60)
672 local d = math.floor(h / 24)
673 local y = d / 365
674 if y >= 1 then return string.format('%.1f', y) .. ' years ago' end
675 m = m % 60
676 h = h % 24
677 d = d % 365
678 local o
679 if d >= 1 then
680 o = d .. ' day'
681 if d > 1 then o = o .. 's' end
682 o = o .. ', '
683 if h > 0 then o = o .. h .. 'h, ' end
684 else
685 o = ''
686 if h > 0 then o = o .. h .. 'h, ' end
687 if m > 0 then o = o .. m .. '\', ' end
689 o = string.sub(o, 1, -3) .. ' ago'
690 return o
692 local rrsl = rr.scores[length]
693 local scores = {}
694 for a = 1, 5 do
695 if rrsl[a] and rrsl[a][1] then
696 scores[a] = {
697 date = fuzzy_ago(os.time() - rrsl[a][1]),
698 time = string.format('%.2fs', rrsl[a][2]),
699 direction = rrsl[a][3]
701 if (rr.last_score == rrsl[a][2]) then
702 scores[a].date = 'just now'
706 return scores
707 end,
710 populate_menus = function(self)
711 rr.menu_elements = {
712 coin_minus = {
713 x = .05, y = .05, w = .15, h = .15,
714 content = '-',
715 onclick = function ()
716 rr.menu_elements.confirm_reset.hidden = true
717 rr.menu_elements.reset_scores.hidden = false
718 rr.length = math.max(5, rr.length - 2)
719 rr:init()
720 end,
722 coin_count = {
723 x = .25, y = 0, w = .5, h = .25,
724 content = function()
725 return rr.length .. ' Coins'
726 end,
728 coin_plus = {
729 x = .8, y = .05, w = .15, h = .15,
730 content = '+',
731 onclick = function ()
732 rr.menu_elements.confirm_reset.hidden = true
733 rr.menu_elements.reset_scores.hidden = false
734 rr.length = math.min(11, rr.length + 2)
735 rr:init()
736 end,
738 confirm_reset = {
739 x = .5, y = .85, w = .25, h = .15,
740 content = 'Are you sure?',
741 onclick = function ()
742 rr.scores[rr.length] = {}
743 rr.menu_elements.confirm_reset.hidden = true
744 rr.menu_elements.reset_scores.hidden = false
745 screen.pfcanvas:renderTo(rr.menubg)
746 end,
748 reset_scores = {
749 x = .25, y = .85, w = .25, h = .15,
750 content = 'Reset',
751 onclick = function ()
752 rr.menu_elements.confirm_reset.hidden = false
753 rr.menu_elements.reset_scores.hidden = true
754 end,
758 menus = {
759 main = {
760 onload = function()
761 rr.menu_elements.confirm_reset.hidden = true
762 rr.menu_elements.reset_scores.hidden = false
763 screen.pfcanvas:renderTo(rr.menubg)
764 end,
766 x = 0, y = - .25, w = .5, h = .25,
767 content = 'Play\nRainbow Ring',
768 onclick = function () rr.show_menu = false end,
771 x = .5, y = -.25, w = .5, h = .25,
772 content = 'Return to POCA',
773 onclick = function ()
774 release(rr)
775 -- becomes relevant after changing screens
776 change_screen('menu_objects')
777 love.resize()
778 end,
781 x = 0, y = 0, w = 1, h = 1,
782 content = function() return {
783 bmp = screen.pfcanvas,
784 offsetx = 0, offsety = 0,
785 scale = screen.playfieldsize
786 } end,
788 rr.menu_elements.coin_minus,
789 rr.menu_elements.coin_count,
790 rr.menu_elements.coin_plus,
791 rr.menu_elements.reset_scores,
792 rr.menu_elements.confirm_reset,
795 -- default menu
796 menus.current = menus.main
797 end,
800 } -- end of rr