Тест: Правила Дорожного Движения

Здесь выкладываются готовые статьи и рабочие исходники, решения каких-либо задач или советы

Тест: Правила Дорожного Движения

Сообщение soft42 » 23 мар 2026, 16:29

Добрый день.
Решил написать приложение по изучению ПДД - Правил Дорожного Движения. Посмотрел различные сайты, изучил вопрос. Есть около десятка сайтов с возможностью изучения ПДД и сдачи экзаменов.
Вот первые по поиску:

https://www.drom.ru/pdd/
https://avto-russia.ru/pdd_abma1b1/?part=them
https://pdd-exam.ru/bilet/
https://www.autonews.ru/bilety-pdd
https://koltsovoauto.ru/pdd/gibdd-ab/exam
https://pddmaster.ru/ekzamen-pdd

Каждый сайт имеет свои преимущества и недостатки. Общий недостаток - нужен компьютер, на телефоне все очень мелко. Одни сайты показывают ответы на билет в строгом исходном порядке, другие могут перемешивать ответы. Одни позволяют отвечать на вопросы в произвольном порядке, другие - только строго с 1 по 20. У одних огромные четкие картинки к вопросам, другие - с маленькими блеклыми картинками. Почти все - надо скролировать, прокручивать вниз, так как не все помещается на экран. Это самая большая проблема при написании приложения для ТВ. Есть вопросы от 2-3 слов, и ответы типа "Можно" или "Нельзя". А есть вопросы на 5 строчек и ответы каждый на такие-же 5 строчек. Есть вопросы с двумя ответами, есть вопросы с пятью ответами.
Задачка на пару месяцев, не меньше. Плюс картинки и вопросы надо откуда-то импортировать/сканировать. Половину функций уже отладил, можно уже кое-что выложить.
icon80.png
Иконка к приложению
icon80.png (2.27 КБ) Просмотров: 941


Файл appinfo.json:
Код: Выделить всё
{ "id": "zimfer.app.pdd",
 "version": "1.0.0",
 "vendor": "Zimfer Alex",
 "type": "web",
 "main": "index.html",
 "title": "Test PDD",
 "icon": "icon80.png",
 "largeIcon": "icon130.png",
 "disableBackHistoryAPI": true,
 "bgColor": "black",
 "iconColor": "black",
 "splashColor": "black",
 "splashBackground": "img/fon.png",
 "appDescription": "Traffic Laws.Russia 2026. "
}


В качестве заставки будет использоваться вот такая картинка:
Заставка к приложению

Программа будет иметь 2 режима: Обучение и Экзамен. В режиме Обучение можно ошибаться, смотреть подсказку (пока не реализовано), время не ограничено. В режиме Экзамен будет тикать таймер, время ограничено 20 минут. Хотелось бы еще озвучить вопросы, но надо сначала оценить объем информации. Всего 40 билетов, каждый билет по 20 вопросов. В каждом билете примерно 15 вопросов с картинками. Итого 800 вопросов, около 600 картинок.
Если каждая картинка будет весить 100 kB (надо сканировать в формате webp), то получится приложение весом 60 Мб. Ну это нормально. Например игра Find the Difference (Найди отличия) для LG TV имеет размер 107 Мб.

Вот такой индексный файл:
Код: Выделить всё
<! DOCTYPE html>
<html>

<head>
 <title>Test PDD</title>
 <link rel="stylesheet" href="styles.css"> <! -- подключаем свой CSS-файл -->
</head>

<script src="webOSTVjs-1.2.4/webOSTV.js" charset="utf-8"></script>
<script src="webOSTVjs-1.2.4/webOSTV-dev.js" charset="utf-8"></script>
<script src="js/spatial_navigation.js" type="text/javascript" charset="utf-8"></script>
<script src="js/navigation.js" type="text/javascript" charset="utf-8"></script>
<script src="js/tickets.js" type="text/javascript" charset="utf-8"></script>
<script src="script.js" type="text/javascript" charset="utf-8"></script>

<body>

<div id="container" >
   <div id="header1">
      <div id="timer"></div>
    <div id="text1" class="text-left">Правила дорожного движения (категории А, В, М) </div>
   </div>

   <div id="header2">
   </div>

   <div id="content1">
      <div id="text2" class="text-left2">Вопрос:</div>
      <img id="imgTicket" alt="Dinamic Image">
      <button id="but1" class="item" onclick="Answer (tickets[step][3], tickets[step][5],1) ">Ответ1</button>
      <button id="but2" class="item" onclick="Answer (tickets[step][3], tickets[step][6],2) ">Ответ2</button>
      <button id="but3" class="item" onclick="Answer (tickets[step][3], tickets[step][7],3) ">Ответ3</button>
      <button id="but4" class="item" onclick="Answer (tickets[step][3], tickets[step][8],4) ">Ответ4</button>
      <button id="but5" class="item" onclick="Answer (tickets[step][3], tickets[step][9],5) ">Ответ5</button>
      <! --<div id="texthelp" class="text-left2">Подсказка:</div> -->
   </div>

   <div id="content2">
      <div id="cont21" class="cont5">
         <button id="but01" class="item" onclick="Ticket (1,  1) ">Билет № 01</button>
         <button id="but02" class="item" onclick="Ticket (2, 21) ">Билет № 02</button>
         <button id="but03" class="item" onclick="Ticket (3, 41) ">Билет № 03</button>
         <button id="but04" class="item" onclick="Ticket (4, 61) ">Билет № 04</button>
         <button id="but05" class="item" onclick="Ticket (5, 81) ">Билет № 05</button>
      </div>
      <div id="cont22" class="cont5">
         <button id="but06" class="item" onclick="Ticket (6,101) ">Билет № 06</button>
         <button id="but07" class="item" onclick="Ticket (7,121) ">Билет № 07</button>
         <button id="but08" class="item" onclick="Ticket (8,141) ">Билет № 08</button>
         <button id="but09" class="item" onclick="Ticket (9,161) ">Билет № 09</button>
         <button id="but10" class="item" onclick="Ticket (10,181) ">Билет № 10</button>
      </div>
      <div id="cont23" class="cont5">
         <button id="but11" class="item" onclick="Ticket (11,201) ">Билет № 11</button>
         <button id="but12" class="item" onclick="Ticket (12,221) ">Билет № 12</button>
         <button id="but13" class="item" onclick="Ticket (13,241) ">Билет № 13</button>
         <button id="but14" class="item" onclick="Ticket (14,261) ">Билет № 14</button>
         <button id="but15" class="item" onclick="Ticket (15,281) ">Билет № 15</button>
      </div>
      <div id="cont24" class="cont5">
         <button id="but16" class="item" onclick="Ticket (16,301) ">Билет № 16</button>
         <button id="but17" class="item" onclick="Ticket (17,321) ">Билет № 17</button>
         <button id="but18" class="item" onclick="Ticket (18,341) ">Билет № 18</button>
         <button id="but19" class="item" onclick="Ticket (19,361) ">Билет № 19</button>
         <button id="but20" class="item" onclick="Ticket (20,381) ">Билет № 20</button>
      </div>
      <div id="cont25" class="cont5">
         <button id="but21" class="item" onclick="Ticket (21,401) ">Билет № 21</button>
         <button id="but22" class="item" onclick="Ticket (22,421) ">Билет № 22</button>
         <button id="but23" class="item" onclick="Ticket (23,441) ">Билет № 23</button>
         <button id="but24" class="item" onclick="Ticket (24,461) ">Билет № 24</button>
         <button id="but25" class="item" onclick="Ticket (25,481) ">Билет № 25</button>
      </div>
      <div id="cont26" class="cont5">
         <button id="but26" class="item" onclick="Ticket (26,501) ">Билет № 26</button>
         <button id="but27" class="item" onclick="Ticket (27,521) ">Билет № 27</button>
         <button id="but28" class="item" onclick="Ticket (28,541) ">Билет № 28</button>
         <button id="but29" class="item" onclick="Ticket (29,561) ">Билет № 29</button>
         <button id="but30" class="item" onclick="Ticket (30,581) ">Билет № 30</button>
      </div>
      <div id="cont27" class="cont5">
         <button id="but31" class="item" onclick="Ticket (31,601) ">Билет № 31</button>
         <button id="but32" class="item" onclick="Ticket (32,621) ">Билет № 32</button>
         <button id="but33" class="item" onclick="Ticket (33,641) ">Билет № 33</button>
         <button id="but34" class="item" onclick="Ticket (34,661) ">Билет № 34</button>
         <button id="but35" class="item" onclick="Ticket (35,681) ">Билет № 35</button>
      </div>
      <div id="cont28" class="cont5">
         <button id="but36" class="item" onclick="Ticket (36,701) ">Билет № 36</button>
         <button id="but37" class="item" onclick="Ticket (37,721) ">Билет № 37</button>
         <button id="but38" class="item" onclick="Ticket (38,741) ">Билет № 38</button>
         <button id="but39" class="item" onclick="Ticket (39,761) ">Билет № 39</button>
         <button id="but40" class="item" onclick="Ticket (40,781) ">Билет № 40</button>
      </div>

   </div>

   <div id="content3">
      <button id="test1" class="item" onclick="Trening () ">Тренировка</button>
      <button id="test2" class="item" onclick="Test () ">Экзамен</button>
   </div>

   <div id="clear"></div>
      
   <div id="footer1" class="image-text-container">
   </div>
   <div id="footer2">
      <div id="b00" class="ball"></div>
      <div id="b01" class="ball"></div>
      <div id="b02" class="ball"></div>
      <div id="b03" class="ball"></div>
      <div id="b04" class="ball"></div>
      <div id="b05" class="ball"></div>
      <div id="b06" class="ball"></div>
      <div id="b07" class="ball"></div>
      <div id="b08" class="ball"></div>
      <div id="b09" class="ball"></div>
      <div id="b10" class="ball"></div>
      <div id="b11" class="ball"></div>
      <div id="b12" class="ball"></div>
      <div id="b13" class="ball"></div>
      <div id="b14" class="ball"></div>
      <div id="b15" class="ball"></div>
      <div id="b16" class="ball"></div>
      <div id="b17" class="ball"></div>
      <div id="b18" class="ball"></div>
      <div id="b19" class="ball"></div>
      <div id="b20" class="ball"></div>
   </div>

</div>

</body>

</html>


Билеты (вопросы, ответы, имена файлов/картинки) в отдельном файле:
Код: Выделить всё
var tickets = [
 ["Num", "Img", "Snd", "Otv", "Vopr", "Otv1", "Otv2", "Otv3", "Otv4", "Otv5", "Error", "MyOtv"],
 [ 1, "img/t00.png", "snd/w01-01", "Остановившись на проезжей части из-за технической неисправности транспортного средства", "В каком случае водитель совершит вынужденную остановку? ", "Остановившись непосредственно перед пешеходным переходом, чтобы уступить дорогу пешеходу", "Остановившись на проезжей части из-за технической неисправности транспортного средства", "В обоих перечисленных случаях", "", "", "", "222"],
 [ 2, "img/t01-02.webp", "snd/w01-02", "Разрешен", "Разрешен ли Вам поворот на дорогу с грунтовым покрытием? ", "Разрешен", "Разрешен только при технической неисправности транспортного средства", "Запрещен", "", "", "", ""],
 [ 3, "img/t01-03.webp", "snd/w01-03", "Можно", "Можно ли Вам остановиться в указанном месте для посадки пассажира? ", "Можно", "Можно, если Вы управляете такси", "Нельзя", "", "", "", ""],
 [ 4, "img/t01-04.webp", "snd/w01-04", "Все", "Какие из указанных знаков запрещают движение водителям мопедов? ", "Только А", "Только Б", "В и Г", "Все", "", "", ""],
 [ 5, "img/t01-05.webp", "snd/w01-05", "Перед перекрестком у линии разметки", "Вы намерены повернуть налево. Где следует остановиться, чтобы уступить дорогу легковому автомобилю? ", "Перед знаком", "Перед перекрестком у линии разметки", "На перекрестке перед прерывистой линией разметки", "В любом месте по усмотрению водителя", "", "", ""],
 [ 6, "img/t00.png", "snd/w01-06", "Разрешает движение и информирует о том, что вскоре будет включен запрещающий сигнал", "Что означает мигание зелёного сигнала светофора? ", "Предупреждает о неисправности светофора", "Разрешает движение и информирует о том, что вскоре будет включен запрещающий сигнал", "Запрещает дальнейшее движение", "", "", "", ""],
 [ 7, "img/t00.png", "snd/w01-07", "Во всех перечисленных случаях", "Водитель обязан подавать сигналы световыми указателями поворота (рукой):", "Перед началом движения или перестроением", "Перед поворотом или разворотом", "Перед остановкой", "Во всех перечисленных случаях", "", "", ""],
 [ 8, "img/t01-08.webp", "snd/w01-08", "Возможны оба варианта действий", "Как Вам следует поступить при повороте направо? ", "Перестроиться на правую полосу, затем осуществить поворот", "Продолжить движение по второй полосе до перекрёстка, затем повернуть", "Возможны оба варианта действий", "", "", "", ""],
 [ 9, "img/t01-09.webp", "snd/w01-09", "Только по А", "По какой траектории Вам разрешено выполнить разворот? ", "Только по А", "Только по Б", "По любой из указанных", "", "", "", ""],
 [ 10, "img/t01-10.webp", "snd/w01-10", "Не менее 50 км/ч и не более 90 км/ч", "С какой скоростью Вы можете продолжить движение вне населённого пункта по левой полосе на легковом автомобиле? ", "Не более 50 км/ч", "Не менее 50 км/ч и не более 70 км/ч", "Не менее 50 км/ч и не более 90 км/ч", "", "", "", ""],
 [ 11, "img/t01-11.webp", "snd/w01-11", "Можно", "Можно ли водителю легкового автомобиля выполнить опережение грузовых автомобилей вне населенного пункта по такой траектории? ", "Можно", "Можно, если скорость грузовых автомобилей менее 30 км/ч", "Нельзя", "", "", "", ""],
 [ 12, "img/t01-12.webp", "snd/w01-12", "При соблюдении обоих перечисленных условий", "В каком случае водителю разрешается поставить автомобиль на стоянку в указанном месте? ", "Только если расстояние до сплошной линии разметки не менее 3 м", "Только если расстояние до края пересекаемой проезжей части не менее 5 м", "При соблюдении обоих перечисленных условий", "", "", "", ""],
 [ 13, "img/t01-13.webp", "snd/w01-13", "Пешеходам и велосипедисту", "При повороте направо Вы должны уступить дорогу:", "Только велосипедисту", "Только пешеходам", "Пешеходам и велосипедисту", "Никому", "", "", ""],
 [ 14, "img/t01-14.webp", "snd/w01-14", "Обоим трамваям", "Вы намерены проехать перекресток в прямом направлении. Кому Вы должны уступить дорогу? ", "Обоим трамваям", "Только трамваю А", "Только трамваю Б", "Никому", "", "", ""],
 [ 15, "img/t01-15.webp", "snd/w01-15", "Никому", "Кому Вы обязаны уступить дорогу при повороте налево? ", "Только автобусу", "Только легковому автомобилю", "Никому", "", "", "", ""],
 [ 16, "img/t01-16.webp", "snd/w01-16", "20 км/ч", "С какой максимальной скоростью можно продолжить движение за знаком? ", "60 км/ч", "50 км/ч", "30 км/ч", "20 км/ч", "", "", ""],
 [ 17, "img/t00.png", "snd/w01-17", "Только категории «A» или подкатегории «A1» в течение 2 и более лет", "Для перевозки людей на мотоцикле водитель должен иметь водительское удостоверение на право управления транспортными средствами:", "Категории «A» или подкатегории «A1»", "Любой категории или подкатегории в течение 2 и более лет", "Только категории «A» или подкатегории «A1» в течение 2 и более лет", "", "", "", ""],
 [ 18, "img/t00.png", "snd/w01-18", "Не работает стеклоподъемник", "При какой неисправности разрешается эксплуатация транспортного средства? ", "Не работают запорные устройства топливных баков", "Не работают механизм регулировки и фиксирующее устройство сиденья водителя", "Не работает устройство обдува ветрового стекла", "Не работает стеклоподъемник", "", "", ""],
 [ 19, "img/t00.png", "snd/w01-19", "Не прибегая к торможению, плавно направить автомобиль на проезжую часть", "В случае, когда правые колёса автомобиля наезжают на неукреплённую влажную обочину, рекомендуется:", "Затормозить и полностью остановиться", "Затормозить и плавно направить автомобиль на проезжую часть", "Не прибегая к торможению, плавно направить автомобиль на проезжую часть", "", "", "", ""],
 [ 20, "img/t00.png", "snd/w01-20", "Время с момента обнаружения водителем опасности до начала принятия мер по её избежанию", "Что понимается под временем реакции водителя? ", "Время с момента обнаружения водителем опасности до полной остановки транспортного средства", "Время с момента обнаружения водителем опасности до начала принятия мер по её избежанию", "Время, необходимое для переноса ноги с педали управления подачи топлива на педаль тормоза", "", "", "", ""],

];


Тут требуется пояснение. Сначала идет номер вопроса (глобальная нумерация с 1 по 800), потом имя файла/картинки к вопросу, имя звукового файла, Правильный ответ, Вопрос, варианты ответов (до 5 вариантов) и еще 2 пустые позиции.
["Num", "Img", "Snd", "Otv", "Vopr", "Otv1", "Otv2", "Otv3", "Otv4", "Otv5", "Error", "MyOtv"

За это сообщение автора soft42 поблагодарил:
JackSparrow (23 мар 2026, 21:32)
soft42

 
Сообщения: 34
Зарегистрирован: 11 фев 2023, 23:07
Город: Зеленоград
Благодарил (а): 4 раз.
Поблагодарили: 20 раз.
Телевизор: LG65QNED916pa

Тест: Правила Дорожного Движения

Спонсор » 23 мар 2026, 16:29

Реклама показывается только незарегистрированным пользователям. Войти или Зарегистрироваться
Спонсор

 
Сообщения: 100
Зарегистрирован: 15 июл 2014, 18:43
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Тест: Правила Дорожного Движения

Сообщение JackSparrow » 23 мар 2026, 16:48

Вещь полезная, с интересом буду наблюдать за прогрессом.

За это сообщение автора JackSparrow поблагодарил:
soft42 (23 мар 2026, 21:05)
JackSparrow

 
Сообщения: 12044
Зарегистрирован: 10 июн 2018, 17:48
Благодарил (а): 2089 раз.
Поблагодарили: 2161 раз.
Телевизор: LG OLED 55C9

Re: Тест: Правила Дорожного Движения

Сообщение soft42 » 23 мар 2026, 21:29

Забросил промежуточный вариант TestPDD.rar на яндекс-диск https://disk.yandex.ru/d/LnXYnlpmPJn9hg
Там есть собранный готовый zimfer.app.pdd_1.0.0_all.ipk, можно его установить на LG ТВ в режиме разработчика.

Скриншот, режим обучения:
ПДД, обучение


Скриншот, режим экзамена:
ПДД, экзамен

Думаю, по скриншотам все ясно. Вначале внизу все 20 шариков желтые. Ответили правильно, шарик стал зеленым. Ошибка - шарик стал красным.
В режиме экзамена отображается таймер (минуты: секунды), сколько времени осталось. Подсказки/объяснения пока нет, нет места уже, куда ее выводить.
Может скрывать картинку? Тогда вопрос без картинки будет не ясен. Есть над чем подумать.

За это сообщение автора soft42 поблагодарил:
JackSparrow (23 мар 2026, 21:32)
soft42

 
Сообщения: 34
Зарегистрирован: 11 фев 2023, 23:07
Город: Зеленоград
Благодарил (а): 4 раз.
Поблагодарили: 20 раз.
Телевизор: LG65QNED916pa

Re: Тест: Правила Дорожного Движения

Сообщение soft42 » 25 мар 2026, 22:25

Добрый день.
Сегодня добавил информацию по последнему 40-вому билету. В итоге получились следующие объемы: приложение занимает 52 Мб, из них на картинки к билетам 44 Мб (550 файлов) + 8 Мб на фоновые заставки.
При запуске появляется такой экран:
Скриншот 1

Доступны две кнопки - "Обучение" и "Экзамен". В последующем можно добавить кнопку "Инфо" и "Выход". Если нажать "Обучение", то появляются 40 кнопок-билетов.
Предлагается выбрать билет.
Скриншот 2

Напомню, в каждом билете по 20 вопросов. Большая часть вопросов с картинками. В режиме обучения время не ограничено. Можно хоть весь день сидеть в одном билете. Выбираем 5 билет.
Открывается билет. Вопросы идут по порядку, с 1 по 20. У каждого вопроса от 2 до 5 ответов. Если ответов 5, то они размещаются внизу до красной линии. Свободного места нет!
Можно выбирать ответы курсором/указкой (если у вас есть такой пульт), а можно кнопками "Вверх", "Вниз" и "Ок". При правильном ответе шарик внизу становится зеленым, при неправильном - красный.
При правильном ответе автоматически переходим на следующий вопрос. Если ответ неправильный, то он "краснеет", переход на следующий вопрос не происходит. Надо ответить правильно.
Скриншот 3

Если вопрос без картинки, то он отображается следующим образом:
Скриншот 4: вопрос без картинки

Что тут можно сделать? Можно перемешивать ответы. Сейчас ответы располагаются статично, в исходном порядке. Мешалку реализовать несложно. Можно перемешать сами вопросы в билете, а надо ли это?
На некоторых сайтах видел выбор вопроса, то-есть можно отвечать на вопросы в произвольном порядке. Это труднее реализовать. А еще можно сделать подсказку: при неправильном ответе появляется подсказка.
Но пока не могу понять, где ее располагать. Можно озвучить вопросы. По моим прикидкам, это + 30 Мб (800 вопросов).
По окончании, когда все вопросы пройдены, выводится итог:
Скриншот 5: итог обучения

Забросил TestPDD-ipk.zip на яндекс-диск https://disk.yandex.ru/d/LnXYnlpmPJn9hg, в нем готовое ipk-приложение, которое можно установить на LG-телевизор. В нем все 40 билетов.
Проверяйте свои знания ПДД :lol:
soft42

 
Сообщения: 34
Зарегистрирован: 11 фев 2023, 23:07
Город: Зеленоград
Благодарил (а): 4 раз.
Поблагодарили: 20 раз.
Телевизор: LG65QNED916pa

Re: Тест: Правила Дорожного Движения

Сообщение soft42 » 29 мар 2026, 10:05

Обнаружил ошибку в приложении, исправил. Забросил новый исправленный TestPDD-ipk.rar на яндекс-диск https://disk.yandex.ru/d/LnXYnlpmPJn9hg

За это сообщение автора soft42 поблагодарил:
JackSparrow (29 мар 2026, 22:04)
soft42

 
Сообщения: 34
Зарегистрирован: 11 фев 2023, 23:07
Город: Зеленоград
Благодарил (а): 4 раз.
Поблагодарили: 20 раз.
Телевизор: LG65QNED916pa


Вернуться в Статьи, исходники и примеры



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

Реклама показывается только незарегистрированным пользователям. Вход или Регистрация