Advertisement
Pirnogion

[OC]fast

Mar 13th, 2016
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 25.09 KB | None | 0 0
  1. local button = require "button"
  2. local rect = require "rectangle"
  3.  
  4. local component = require "component"
  5. local event = require "event"
  6. local ser = require "serialization"
  7. local unicode = require "unicode"
  8.  
  9. local gpu = component.gpu
  10. local gameTimer = nil
  11.  
  12. -- КОСТЫЛИ, НЕ ТРОГАТЬ --
  13. local update = nil
  14. local selectCategories = nil
  15. local drawStatistics = nil
  16. local drawTop = nil
  17. local xui = nil
  18. local xui2 = nil
  19.  
  20. -- Автоматический сброс цветов при завершении программы --
  21. local exitListener = {}
  22. setmetatable(exitListener, {__gc = function()
  23.     gpu.setBackground( 0x000000 )
  24.     gpu.setForeground( 0xffffff )
  25.  
  26.     if (gameTimer) then event.cancel(gameTimer) end
  27.     event.ignore("touch", xui)
  28.     event.ignore("scroll", xui2)
  29.     button.stop()
  30.  
  31.     package.loaded["button"] = nil
  32.     package.loaded["rectangle"] = nil
  33. end})
  34.  
  35. -- КОНСТАНТЫ --
  36. local bgColor = 0xffffff
  37. local fgColor = 0x000000
  38.  
  39. local questionsFilepath = "questions.txt"
  40.  
  41. local screenWidth, screenHeight = gpu.getResolution()
  42. local centerScreenX, centerScreenY = math.floor(screenWidth/2), math.floor(screenHeight/2)
  43.  
  44. -- Информация о кнопках --
  45. local buttonMinWidth, buttonHeight = 10, 3
  46. local buttonMarginX, buttonMarginY = 1, 1
  47. local buttonsPosX, buttonsPosY = 0, 0
  48. local summaryButtonsWidth = 0
  49.  
  50. local statistics, questions, buttons = nil
  51. local currentPlayer = nil
  52. local currentCategory = "Мемология"
  53. local currentQuestionId = 1
  54.  
  55. local firstRun = true
  56.  
  57. -- РАЗНОЕ --
  58. local function swap(array, index1, index2)
  59.   array[index1], array[index2] = array[index2], array[index1]
  60. end
  61.  
  62. local function shake(array)
  63.   local counter = #array
  64.  
  65.   while counter > 1 do
  66.     local index = math.random(counter)
  67.  
  68.     swap(array, index, counter)    
  69.     counter = counter - 1
  70.   end
  71. end
  72.  
  73. local function tableLen( array )
  74.     local length = 0
  75.  
  76.     for _, _ in pairs(array) do
  77.         length = length + 1
  78.     end
  79.  
  80.     return length
  81. end
  82.  
  83. local function shakeCategories(questions)
  84.     for _, category in ipairs(questions) do
  85.         shake(category)
  86.     end
  87. end
  88.  
  89. local function addMetaToCategoriesAndShake(questions)
  90.     for name, category in pairs(questions) do
  91.         -- Перемешать массив с вопросами--
  92.         shake(category)
  93.  
  94.         -- Мета-информация --
  95.         category.countQuestions = #category
  96.         category.name = name
  97.     end
  98. end
  99.  
  100. -- КНОПКИ --
  101.  
  102. --Данные о внешнем виде кнопок
  103. local buttonDesign_categories = {
  104.     blink_time = 0.2,
  105.  
  106.     -- Вид кнопки в обычном состоянии --
  107.     [0] = {
  108.         bg = 0xBF2008,
  109.         fg = 0xffffff,
  110.         char = ' '
  111.     },
  112.  
  113.     -- Вид кнопки в состоянии "недоступна" --
  114.     [5] = {
  115.         bg = 0xFF9696,
  116.         fg = 0xffffff,
  117.         char = ' '
  118.     },
  119.  
  120.     -- Подсветка кнопки --
  121.     [10] = {
  122.         bg = 0xff0000,
  123.         fg = 0xffffff,
  124.         char = ' '
  125.     }
  126. }
  127.  
  128. local buttonDesign_incorrect = {
  129.     blink_time = 0.2,
  130.  
  131.     -- Вид кнопки в обычном состоянии --
  132.     [0] = {
  133.         bg = 0xCCCCCC,
  134.         fg = 0xffffff,
  135.         char = ' '
  136.     },
  137.  
  138.     -- Вид кнопки в состоянии "недоступна" --
  139.     [5] = {
  140.         bg = 0xffffff,
  141.         fg = 0x000000,
  142.         char = ' '
  143.     },
  144.  
  145.     -- Подсветка кнопки --
  146.     [10] = {
  147.         bg = 0xBF2008,
  148.         fg = 0xffffff,
  149.         char = ' '
  150.     }
  151. }
  152.  
  153. local buttonDesign_incorrect = {
  154.     blink_time = 0.2,
  155.  
  156.     -- Вид кнопки в обычном состоянии --
  157.     [0] = {
  158.         bg = 0xCCCCCC,
  159.         fg = 0xffffff,
  160.         char = ' '
  161.     },
  162.  
  163.     -- Вид кнопки в состоянии "недоступна" --
  164.     [5] = {
  165.         bg = 0xffffff,
  166.         fg = 0x000000,
  167.         char = ' '
  168.     },
  169.  
  170.     -- Подсветка кнопки --
  171.     [10] = {
  172.         bg = 0xBF2008,
  173.         fg = 0xffffff,
  174.         char = ' '
  175.     }
  176. }
  177.  
  178. local buttonDesign_correct = {
  179.     blink_time = 0.2,
  180.  
  181.     -- Вид кнопки в обычном состоянии --
  182.     [0] = {
  183.         bg = 0xCCCCCC,
  184.         fg = 0xffffff,
  185.         char = ' '
  186.     },
  187.  
  188.     -- Вид кнопки в состоянии "недоступна" --
  189.     [5] = {
  190.         bg = 0xffffff,
  191.         fg = 0x000000,
  192.         char = ' '
  193.     },
  194.  
  195.     -- Подсветка кнопки --
  196.     [10] = {
  197.         bg = 0x00911B,
  198.         fg = 0xffffff,
  199.         char = ' '
  200.     }
  201. }
  202.  
  203. -- xxx --
  204.  
  205. local function saveStatistics( statistics, statisticsFilepath )
  206.     local file = assert( io.open(statisticsFilepath, "w"), "Can't open/create the file!" )
  207.     file:write( ser.serialize( statistics ) )
  208.     file:close()
  209. end
  210.  
  211. local function loadStatistics( statisticsFilepath )
  212.     local statistics = nil
  213.  
  214.     local file = assert( io.open(statisticsFilepath, "r"), "File not found!" )
  215.     statistics = assert( ser.unserialize( file:read("*a") ), "Parse statistics file failed!" )
  216.     file:close()
  217.  
  218.     return statistics
  219. end
  220.  
  221. local function findPlayerStatistic( playerName )
  222.     for i = 1, #statistics, 1 do
  223.         if (statistics[i].player == playerName) then
  224.             return statistics[i], i
  225.         end
  226.     end
  227. end
  228.  
  229. local function addPlayerToStatistics( playerName )
  230.     if ( not findPlayerStatistic(playerName) ) then
  231.         table.insert(statistics,
  232.         {
  233.             player = playerName,
  234.             totalPlayTime = 0,
  235.             totalCorrectAnswers = 0,
  236.             totalIncorrectAnswers = 0,
  237.             totalAverageResponseTime = 0,
  238.             totalLeave = 0,
  239.         })
  240.     end
  241. end
  242.  
  243. local function editPlayerStatistic( playerName, key, value, opertion )
  244.     for i = 1, #statistics, 1 do
  245.         if (statistics[i].player == playerName) then
  246.             if ( opertion == "add" or not opertion ) then
  247.                 statistics[i][key] = statistics[i][key] + value
  248.             elseif ( opertion == "sub" ) then
  249.                 statistics[i][key] = statistics[i][key] - value
  250.             end
  251.  
  252.             break
  253.         end
  254.     end
  255. end
  256.  
  257. local function timer_gameTime()
  258.     editPlayerStatistic(currentPlayer, "totalPlayTime", 1, "add")
  259. end
  260.  
  261. local function hideAnimation()
  262.     for i=0, screenWidth-1, 1 do
  263.         gpu.copy(1-i, buttonsPosY, screenWidth+1, buttonHeight, -1, 0)
  264.         coroutine.yield();
  265.     end
  266. end
  267.  
  268. local function showAnimation()
  269.     local countAnswers = #questions[currentCategory][currentQuestionId].answers
  270.    
  271.     for j=screenWidth, buttonsPosX, -1 do
  272.         gpu.setBackground(0xffffff)
  273.         gpu.fill(j, buttonsPosY, summaryButtonsWidth+1, buttonHeight, ' ')
  274.  
  275.         for i = 1, #buttons, 1 do
  276.             rect.MoveNXY( buttons[i].rectangle, buttons[i].rectangle.sx-1, buttonsPosY )
  277.  
  278.             buttons[i]:redraw()
  279.         end
  280.        
  281.         coroutine.yield();
  282.     end
  283. end
  284.  
  285. -- Реакция на ответ --
  286. local function callback_returnToMenu()
  287.     event.ignore( "touch", xui )
  288.     event.ignore("scroll", xui2)
  289.     button.destroyAllButtons()
  290.     if (gameTimer) then event.cancel(gameTimer) end
  291.  
  292.     saveStatistics(statistics, "statistics.txt")
  293.  
  294.     -- Очистка экрана для следующего вывода --
  295.     gpu.setBackground(bgColor)
  296.     gpu.setForeground(fgColor)
  297.     gpu.fill(1, 1, screenWidth, screenHeight, ' ')
  298.  
  299.     selectCategories(questions)
  300.  
  301.     firstRun = true
  302. end
  303.  
  304. local function callback_runShoolTest(btn, catname)
  305.     currentPlayer = btn.pressedPlayer
  306.  
  307.     addPlayerToStatistics(currentPlayer)
  308.  
  309.     gameTimer = event.timer(1, timer_gameTime, math.huge)
  310.  
  311.     currentCategory = catname
  312.     currentQuestionId = 1
  313.  
  314.     button.destroyAllButtons()
  315.    
  316.     update( questions )
  317.  
  318.     firstRun = false
  319. end
  320.  
  321.  
  322. local function incorrectAnswer()
  323.     editPlayerStatistic(currentPlayer, "totalIncorrectAnswers", 1, "add")
  324. end
  325.  
  326. local function correctAnswer()
  327.     editPlayerStatistic(currentPlayer, "totalCorrectAnswers", 1, "add")
  328.  
  329.     if ( currentQuestionId < questions[currentCategory].countQuestions) then
  330.         currentQuestionId = currentQuestionId + 1
  331.     else
  332.         shakeCategories(questions)
  333.         callback_returnToMenu()
  334.  
  335.         return nil
  336.     end
  337.  
  338.     update(questions)
  339. end
  340.  
  341. -- РАБОТА С МАССИВОМ ВОПРОСОВ --
  342.  
  343. -- Получение массива вопросов из файла --
  344. local function readQuestions( filename )
  345.     local questions = nil
  346.  
  347.     local file = assert( io.open(filename, "r"), "File not found!" )
  348.     questions = assert( ser.unserialize( file:read("*a") ), "Parse questions file failed!" )
  349.     file:close()
  350.  
  351.     -- Перемешать вопросы и добавить мета-информацию --
  352.     addMetaToCategoriesAndShake(questions)
  353.  
  354.     return questions
  355. end
  356.  
  357. local function repositionButtons( buttons )
  358.     summaryButtonsWidth = 0
  359.  
  360.     -- Инициализировать кнопки --
  361.     for i = 1, #buttons, 1 do
  362.         buttons[i]:recalculateWidth( buttonMinWidth )
  363.         summaryButtonsWidth = summaryButtonsWidth + buttons[i].rectangle.width + buttonMarginX
  364.     end
  365.  
  366.     -- Рассчитать позиции кнопок --
  367.     buttonsPosX = centerScreenX - math.floor(summaryButtonsWidth/2)
  368.     buttonsPosY = centerScreenY - math.floor(buttonHeight/2) + buttonHeight - 2
  369.    
  370.     local currentButtonPosX = ( not firstRun ) and screenWidth or buttonsPosX
  371.     for i = 1, #buttons, 1 do
  372.         rect.MoveNXY( buttons[i].rectangle, currentButtonPosX, buttonsPosY )
  373.  
  374.         currentButtonPosX = currentButtonPosX + buttons[i].rectangle.width + buttonMarginX
  375.     end
  376. end
  377.  
  378. local function initButtons( questions )
  379.     local buttons = {}
  380.  
  381.     local countAnswers = #questions[currentCategory][currentQuestionId].answers
  382.     local currentQuestion = questions[currentCategory][currentQuestionId]
  383.  
  384.     -- Инициализировать кнопки --
  385.     button.destroyAllButtons()
  386.     for i = 1, countAnswers, 1 do
  387.         local currentAction = (currentQuestion.correctAnswer == i) and correctAnswer or incorrectAnswer
  388.         local currentDesign = (currentQuestion.correctAnswer == i) and buttonDesign_correct or buttonDesign_incorrect
  389.  
  390.         buttons[i] = button.createRubber( 1, 1, buttonMinWidth, buttonHeight, {currentQuestion.answers[i]}, currentAction, currentDesign )
  391.     end
  392.  
  393.     repositionButtons( buttons )
  394.  
  395.     return buttons
  396. end
  397.  
  398. -- XXX --
  399. local function drawProgressBar(currentValue, totalValue, xPos, yPos, width, progressColor, backgroundColor, char, notcenter)
  400.     -- Отлов исключительных ситуаций --
  401.     currentValue = (currentValue > totalValue) and totalValue or currentValue
  402.  
  403.     -- Вычисление текущего прогресса --
  404.     local progress = ( width * (currentValue-1) ) / totalValue
  405.  
  406.     -- Смена точки привязки от начала к центру прогресс-бара --
  407.     local centerPosX = xPos - math.floor(width/2)
  408.  
  409.     -- Отрисовка подложки --
  410.     gpu.setForeground(backgroundColor)
  411.     gpu.fill( notcenter and xPos or centerPosX, yPos, width, 1, char )
  412.  
  413.     -- Отрисовка прогресса --
  414.     gpu.setForeground(progressColor)
  415.     gpu.fill( notcenter and xPos or centerPosX, yPos, progress, 1, char )
  416. end
  417.  
  418. local function drawDownVerticalProgressBar(currentValue, totalValue, xPos, yPos, height, progressColor, backgroundColor, char, notcenter)
  419.     -- Отлов исключительных ситуаций --
  420.     currentValue = (currentValue > totalValue) and totalValue or currentValue
  421.  
  422.     -- Вычисление текущего прогресса --
  423.     local progress = ( height * (currentValue-1) ) / totalValue
  424.  
  425.     -- Смена точки привязки от начала к центру прогресс-бара --
  426.     local centerPosY = yPos - math.floor(height/2)
  427.  
  428.     -- Отрисовка подложки --
  429.     gpu.setForeground(backgroundColor)
  430.     gpu.fill( xPos, notcenter and yPos or centerPosY, 1, height, char )
  431.  
  432.     -- Отрисовка прогресса --
  433.     gpu.setForeground(progressColor)
  434.     gpu.fill( xPos, notcenter and yPos or centerPosY, 1, progress, char )
  435. end
  436.  
  437. local function drawUpVerticalProgressBar(currentValue, totalValue, xPos, yPos, height, progressColor, backgroundColor, char, notcenter)
  438.     -- Отлов исключительных ситуаций --
  439.     currentValue = (currentValue > totalValue) and totalValue or currentValue
  440.  
  441.     -- Вычисление текущего прогресса --
  442.     local progress = ( height * (currentValue-1) ) / totalValue
  443.  
  444.     -- Смена точки привязки от начала к центру прогресс-бара --
  445.     local centerPosY = yPos - math.floor(height/2)
  446.  
  447.     -- Отрисовка подложки --
  448.     gpu.setForeground(backgroundColor)
  449.     gpu.fill( xPos, (notcenter and yPos or centerPosY)-height, 1, height, char )
  450.  
  451.     -- Отрисовка прогресса --
  452.     gpu.setForeground(progressColor)
  453.     gpu.fill( xPos, (notcenter and yPos or centerPosY)-progress, 1, progress, char )
  454. end
  455.  
  456. update = function(questions)
  457.     local currentQuestion = questions[currentCategory][currentQuestionId]
  458.     buttons = initButtons( questions )
  459.  
  460.     -- Анимации --
  461.     local h = coroutine.create(hideAnimation)
  462.     local s = coroutine.create(showAnimation)
  463.  
  464.     if ( not firstRun ) then
  465.         while ( coroutine.status(h) ~= "dead" and coroutine.status(s) ~= "dead" ) do
  466.             coroutine.resume(h)
  467.             coroutine.resume(s)
  468.             os.sleep(0)
  469.         end
  470.     end
  471.  
  472.     -- Очистка экрана для следующего вывода --
  473.     gpu.setBackground(bgColor)
  474.     gpu.setForeground(fgColor)
  475.     gpu.fill(1, 1, screenWidth, screenHeight, ' ')
  476.  
  477.     -- Отрисовка всего --
  478.     for i, btn in ipairs(buttons) do
  479.         btn:redraw()
  480.     end
  481.  
  482.     button.createXYWH(screenWidth-15-2, screenHeight-4-1, 15, 4, {"↩ Вернуться", "к категориям"}, callback_returnToMenu, buttonDesign_categories):redraw()
  483.  
  484.     -- Восстановление цветов после отрисовки предыдущих элементов --
  485.     gpu.setBackground(bgColor)
  486.     gpu.setForeground(fgColor)
  487.  
  488.     gpu.set( centerScreenX - math.floor(unicode.len(currentQuestion.question)/2), centerScreenY-2, currentQuestion.question )
  489.     drawProgressBar(currentQuestionId, questions[currentCategory].countQuestions, centerScreenX, centerScreenY+8, screenWidth/1.2, 0xBF2008, 0xCCCCCC, '▂')
  490. end
  491.  
  492. local function callback_drawStat(btn)
  493.     currentPlayer = btn.pressedPlayer
  494.  
  495.     addPlayerToStatistics(currentPlayer)
  496.  
  497.     drawStatistics(statistics)
  498. end
  499.  
  500. selectCategories = function(questions)
  501.     local countOfCategories = tableLen(questions)
  502.  
  503.     local startDrawButtonsX = 8
  504.     local startDrawButtonsY = 4
  505.  
  506.     local buttonMarginX = 2
  507.     local buttonMarginY = 1
  508.  
  509.     local buttonWidth = 20
  510.     local buttonHeight = 3
  511.  
  512.     local maxButtonsInRow = math.ceil( (screenWidth - startDrawButtonsX*2) / (buttonWidth + buttonMarginX) )
  513.     local maxButtonsInColumn = math.ceil( (screenHeight - startDrawButtonsY*2) / (buttonHeight + buttonMarginY) )
  514.  
  515.     local statButton = button.createXYWH( screenWidth-centerScreenX+9, screenHeight-3, centerScreenX-10, 3, {"Общая статистика"}, callback_drawStat, buttonDesign_categories )
  516.     local topButton = button.createXYWH( 3, screenHeight-3, centerScreenX-10, 3, {"Топ игроков"}, drawTop, buttonDesign_categories )
  517.  
  518.     local pages = math.ceil( countOfCategories/(maxButtonsInRow*maxButtonsInColumn) )
  519.     --local buttonsInEndRow = countOfCategories % maxButtonsInRow
  520.     --local rowCount = (buttonsInEndRow > 0) and math.floor(countOfCategories/2)+1 or math.floor(countOfCategories/2)
  521.  
  522.     local summaryButtonsWidth = (buttonWidth+buttonMarginX) * maxButtonsInRow
  523.     local summaryButtonsHeight = (buttonWidth+buttonMarginX) * maxButtonsInColumn
  524.  
  525.     local text1 = "Пожайлуста, выберите одну любую категорию вопросов из предложенных ниже."
  526.     gpu.set( centerScreenX - math.floor(unicode.len(text1)/2), 2, text1 )
  527.  
  528.     local buttons = {}
  529.  
  530.     local i, j = 1, 1
  531.     for _, category in pairs(questions) do
  532.         buttons[i] = button.createXYWH( startDrawButtonsX+(buttonWidth+1)*(i-1), startDrawButtonsY+(buttonHeight+1)*(j-1), buttonWidth, buttonHeight, {category.name}, callback_runShoolTest, buttonDesign_categories )
  533.         buttons[i].args = category.name
  534.         buttons[i]:redraw()
  535.        
  536.         i = (i % maxButtonsInRow) + 1
  537.         j = (i == 1) and j+1 or j
  538.     end
  539.  
  540.     statButton:redraw()
  541.     topButton:redraw()
  542. end
  543.  
  544. local playersInOnePage = 4
  545. local currentPage = 1
  546.  
  547. local function callback_nextStatisticsPage()
  548.     currentPage = currentPage + playersInOnePage
  549.  
  550.     drawStatistics(statistics)
  551. end
  552.  
  553. local function callback_prevStatisticsPage()
  554.     currentPage = currentPage - playersInOnePage
  555.  
  556.     drawStatistics(statistics)
  557. end
  558.  
  559. drawStatistics = function(statistics)
  560.     button.destroyAllButtons()
  561.  
  562.     gpu.setForeground(0)
  563.     gpu.setBackground(0xFFFFFF)
  564.     gpu.fill(1, 1, screenWidth, screenHeight, ' ')
  565.  
  566.     local nextListButton = button.createXYWH( screenWidth-centerScreenX+9, screenHeight-3, centerScreenX-10, 3, {"Следующий лист ►"}, callback_nextStatisticsPage, buttonDesign_categories, (currentPage >= #statistics-playersInOnePage+1) and 5 or 0 )
  567.     local prevListButton = button.createXYWH( 3, screenHeight-3, centerScreenX-10, 3, {"◄ Предыдущий лист"}, callback_prevStatisticsPage, buttonDesign_categories, (currentPage <= 1) and 5 or 0 )
  568.     local returnToMenu = button.createXYWH( centerScreenX-5, screenHeight-3, 12, 3, {"↩"}, callback_returnToMenu, buttonDesign_categories )
  569.  
  570.     gpu.setForeground(0)
  571.     gpu.setBackground(0xffffff)
  572.  
  573.     local plr, iplr = findPlayerStatistic(currentPlayer)
  574.  
  575.     if ( plr and plr ~= statistics[1] ) then
  576.         swap(statistics, 1, iplr)
  577.     end
  578.  
  579.     local players = #statistics
  580.  
  581.     local columnMargin = 1
  582.     local columnWidth = math.floor(screenWidth/playersInOnePage)
  583.  
  584.     local centerColumn = math.floor(columnWidth/2)
  585.  
  586.     for i = currentPage, currentPage+playersInOnePage, 1 do
  587.         local bgcolor = (i%2 == 0) and 0xEEEEEE or 0xFFFFFF
  588.         local centerText = math.floor(unicode.len(statistics[i].player)/2)
  589.  
  590.         gpu.setBackground(bgcolor)
  591.  
  592.         if ( i%2 == 0 ) then
  593.             gpu.fill(1 + columnWidth * (i-currentPage), 1, columnWidth, screenHeight, ' ')
  594.         end
  595.  
  596.         -- Отрисовать имя игрока
  597.         gpu.set(1 + (centerColumn - centerText) + columnWidth * (i-currentPage), 2, statistics[i].player)
  598.  
  599.         centerText = math.floor(unicode.len("Отношение верных ответов к неверным:")/2)
  600.         gpu.set(1 + (centerColumn - centerText) + columnWidth * (i-currentPage), 4,"Отношение верных ответов к неверным:")
  601.         drawProgressBar(statistics[i].totalCorrectAnswers, statistics[i].totalIncorrectAnswers, centerColumn + columnWidth * (i-currentPage), 5, columnWidth-10, 0x7AFF93, 0xFF9696, '▄')
  602.         gpu.setForeground(0)
  603.  
  604.         centerText = math.floor(unicode.len("Суммарное время прохождения:")/2)
  605.         gpu.set(1 + (centerColumn - centerText) + columnWidth * (i-currentPage), 9, "Суммарное время прохождения:")
  606.         drawProgressBar(statistics[i].totalPlayTime, columnWidth-10, centerColumn + columnWidth * (i-currentPage), 10, columnWidth-10, 0xFF9696, 0xCCCCCC, '▄')
  607.         gpu.setForeground(0)
  608.  
  609.         centerText = math.floor(unicode.len("Количество прерываний теста:")/2)
  610.         gpu.set(1 + (centerColumn - centerText) + columnWidth * (i-currentPage), 12, "Количество прерываний теста:")
  611.         drawProgressBar(statistics[i].totalLeave, columnWidth-10, centerColumn + columnWidth * (i-currentPage), 13, columnWidth-10, 0xFF9696, 0xCCCCCC, '▄')
  612.         gpu.setForeground(0)
  613.  
  614.         nextListButton:redraw()
  615.         prevListButton:redraw()
  616.         returnToMenu:redraw()
  617.         gpu.setForeground(0)
  618.     end
  619. end
  620.  
  621. local function fixedString(str, len, char)
  622.     if (#str < len) then
  623.         return string.rep(char, len-#str) .. str
  624.     end
  625.  
  626.     return str
  627. end
  628.  
  629. local curpage = 1
  630. local prevSelected = nil
  631. local selected = 1
  632.  
  633. local function callback_nextTopPage()
  634.     local maxPlayerInOnePage = math.floor( (screenHeight-7)/3 )
  635.     curpage = curpage + maxPlayerInOnePage
  636.     selected = curpage
  637.     prevSelected = curpage
  638.  
  639.     drawTop(true)
  640. end
  641.  
  642. local function callback_prevTopPage()
  643.     local maxPlayerInOnePage = math.floor( (screenHeight-7)/3 )
  644.     curpage = curpage - maxPlayerInOnePage
  645.  
  646.     selected = curpage+maxPlayerInOnePage-1
  647.     prevSelected = curpage+maxPlayerInOnePage-1
  648.  
  649.     drawTop(true)
  650. end
  651.  
  652. xui = function( ... )
  653.     local e = {...}
  654.  
  655.     if e[1] ~= "touch" then return end
  656.  
  657.     local playersInOnePage = 16
  658.     local players = #statistics
  659.  
  660.     local maxPlayerInOnePage = math.floor( (screenHeight-7)/3 )
  661.  
  662.     for i = curpage, math.min(curpage+maxPlayerInOnePage-1, #statistics), 1 do
  663.         if (rect.PointInRectFree(e[3], e[4], 1, 1+3+3*(i-curpage), screenWidth, 3+3+3*(i-curpage))) then
  664.             if ( selected == i ) then
  665.                 event.ignore( "touch", xui )
  666.                 event.ignore("scroll", xui2)
  667.                 drawStatistics(statistics)
  668.                 break
  669.             end
  670.  
  671.             prevSelected = selected
  672.             selected = i
  673.             drawTop()
  674.             break
  675.         end
  676.     end
  677. end
  678.  
  679. xui2 = function( ... )
  680.     local e = {...}
  681.  
  682.     if e[1] ~= "scroll" then return end
  683.  
  684.     local playersInOnePage = 16
  685.     local players = #statistics
  686.  
  687.     local maxPlayerInOnePage = math.floor( (screenHeight-7)/3 )
  688.  
  689.     if ( selected - e[5] > math.min(curpage+maxPlayerInOnePage-1, #statistics) ) then
  690.         if ( math.min(curpage+maxPlayerInOnePage-1, #statistics) < #statistics ) then
  691.             callback_nextTopPage()
  692.         else
  693.             selected = math.min(curpage+maxPlayerInOnePage-1, #statistics)
  694.         end
  695.     elseif ( selected - e[5] < curpage ) then
  696.         if ( curpage > 1 ) then
  697.             callback_prevTopPage()
  698.         else
  699.             selected = curpage
  700.         end
  701.     else
  702.         prevSelected = selected
  703.         selected = selected - e[5]
  704.     end
  705.    
  706.     drawTop()
  707. end
  708.  
  709. drawTop = function( redraw )
  710.     if ( prevSelected and not redraw) then
  711.         local i = prevSelected
  712.  
  713.         local bgcolor = (i%2 == 0) and 0xEEEEEE or 0xFFFFFF
  714.         local bgcolorn = (i%2 == 0) and 0x5E5E5E or 0x424242
  715.  
  716.         gpu.setForeground(0xffffff)
  717.         gpu.setBackground(bgcolor)
  718.         gpu.fill(1, 1+3+3*(i-curpage), screenWidth, 3, ' ')
  719.        
  720.         gpu.setBackground(bgcolorn)
  721.         gpu.fill(1, 1+3+3*(i-curpage), 6, 3, ' ')
  722.         gpu.set(3, 2+3+3*(i-curpage), fixedString(tostring(i), 2, '0'))
  723.         gpu.setBackground(bgcolor)
  724.  
  725.         gpu.setForeground(0)
  726.         gpu.set(9, 2+3+3*(i-curpage), statistics[i].player)
  727.         gpu.set(39, 2+3+3*(i-curpage), tostring(statistics[i].totalPlayTime))
  728.         gpu.set(59, 2+3+3*(i-curpage), tostring(statistics[i].totalCorrectAnswers))
  729.         gpu.set(79, 2+3+3*(i-curpage), tostring(statistics[i].totalIncorrectAnswers))
  730.  
  731.         i = selected
  732.  
  733.         bgcolor = 0xFF9696
  734.         bgcolorn = 0xBF2008
  735.  
  736.         gpu.setForeground(0xffffff)
  737.         gpu.setBackground(bgcolor)
  738.         gpu.fill(1, 1+3+3*(i-curpage), screenWidth, 3, ' ')
  739.        
  740.         gpu.setBackground(bgcolorn)
  741.         gpu.fill(1, 1+3+3*(i-curpage), 6, 3, ' ')
  742.         gpu.set(3, 2+3+3*(i-curpage), fixedString(tostring(i), 2, '0'))
  743.         gpu.setBackground(bgcolor)
  744.  
  745.         gpu.setForeground(0x424242)
  746.         gpu.set(9, 2+3+3*(i-curpage), statistics[i].player)
  747.         gpu.set(39, 2+3+3*(i-curpage), tostring(statistics[i].totalPlayTime))
  748.         gpu.set(59, 2+3+3*(i-curpage), tostring(statistics[i].totalCorrectAnswers))
  749.         gpu.set(79, 2+3+3*(i-curpage), tostring(statistics[i].totalIncorrectAnswers))
  750.  
  751.         return nil
  752.     end
  753.  
  754.     button.destroyAllButtons()
  755.  
  756.     event.ignore( "touch", xui )
  757.     event.ignore( "scroll", xui2 )
  758.  
  759.     event.listen( "touch", xui )
  760.     event.listen( "scroll", xui2 )
  761.  
  762.     local playersInOnePage = 16
  763.     local players = #statistics
  764.  
  765.     local maxPlayerInOnePage = math.floor( (screenHeight-7)/3 )
  766.  
  767.     local nextListButton = button.createXYWH( screenWidth-centerScreenX+9, screenHeight-3, centerScreenX-10, 3, {"Вниз ▼"}, callback_nextTopPage, buttonDesign_categories, (curpage >= #statistics-maxPlayerInOnePage+1) and 5 or 0 )
  768.     local prevListButton = button.createXYWH( 3, screenHeight-3, centerScreenX-10, 3, {"▲ вверх"}, callback_prevTopPage, buttonDesign_categories, (curpage <= 1) and 5 or 0 )
  769.     local returnToMenu = button.createXYWH( centerScreenX-5, screenHeight-3, 12, 3, {"↩"}, callback_returnToMenu, buttonDesign_categories )
  770.  
  771.     gpu.setBackground(0xFFFFFF)
  772.     gpu.setForeground(0x000000)
  773.     gpu.fill(1, 1, screenWidth, screenHeight, ' ')
  774.  
  775.     nextListButton:redraw()
  776.     prevListButton:redraw()
  777.     returnToMenu:redraw()
  778.  
  779.     -- Отрисовать заголовок --
  780.     gpu.setForeground(0xFFFFFF)
  781.     gpu.setBackground(0x5E5E5E)
  782.     gpu.fill(1, 1, 6, 3, ' ')
  783.     gpu.set(3, 2, '№')
  784.  
  785.     gpu.setBackground(0x424242)
  786.     gpu.fill(7, 1, screenWidth, 3, ' ')
  787.  
  788.     gpu.set(9, 2, 'Никнейм')
  789.     gpu.set(39, 2, 'Время игры')
  790.     gpu.set(59, 2, 'Верных ответов')
  791.     gpu.set(79, 2, 'Неверных ответов')
  792.  
  793.     for i = curpage, math.min(curpage+maxPlayerInOnePage-1, #statistics), 1 do
  794.         local bgcolor = (i%2 == 0) and 0xEEEEEE or 0xFFFFFF
  795.         local bgcolorn = (i%2 == 0) and 0x5E5E5E or 0x424242
  796.  
  797.         --button.create( 1, 1+3+3*(i-1), screenWidth, 3, {"000"}, a, buttonDesign_incorrect, 0, 5 ):redraw()
  798.  
  799.         if (i == selected) then
  800.             bgcolor = 0xFF9696
  801.             bgcolorn = 0xBF2008
  802.         end
  803.  
  804.         gpu.setForeground(0xffffff)
  805.         gpu.setBackground(bgcolor)
  806.         gpu.fill(1, 1+3+3*(i-curpage), screenWidth, 3, ' ')
  807.        
  808.         gpu.setBackground(bgcolorn)
  809.         gpu.fill(1, 1+3+3*(i-curpage), 6, 3, ' ')
  810.         gpu.set(3, 2+3+3*(i-curpage), fixedString(tostring(i), 2, '0'))
  811.         gpu.setBackground(bgcolor)
  812.  
  813.         gpu.setForeground(0x424242)
  814.         gpu.set(9, 2+3+3*(i-curpage), statistics[i].player)
  815.         gpu.set(39, 2+3+3*(i-curpage), tostring(statistics[i].totalPlayTime))
  816.         gpu.set(59, 2+3+3*(i-curpage), tostring(statistics[i].totalCorrectAnswers))
  817.         gpu.set(79, 2+3+3*(i-curpage), tostring(statistics[i].totalIncorrectAnswers))
  818.     end
  819. end
  820.  
  821. -- ИНИЦИАЛИЗАЦИЯ --
  822. gpu.setBackground(bgColor)
  823. gpu.setForeground(fgColor)
  824. gpu.fill(1, 1, screenWidth, screenHeight, ' ')
  825.  
  826. questions = readQuestions( questionsFilepath )
  827. statistics = loadStatistics( "statistics.txt" )
  828. drawTop()
  829. --drawStatistics( statistics )
  830.  
  831. --selectCategories(questions)
  832. --update(questions)
  833.  
  834. button.start()
  835.  
  836. -- Цикл-заглушка, чтобы прога сразу не завершалась --
  837. while (true) do
  838.     os.sleep(100)
  839. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement