Решил написать приложение по изучению ПДД - Правил Дорожного Движения. Посмотрел различные сайты, изучил вопрос. Есть около десятка сайтов с возможностью изучения ПДД и сдачи экзаменов.
Вот первые по поиску:
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 строчек. Есть вопросы с двумя ответами, есть вопросы с пятью ответами.
Задачка на пару месяцев, не меньше. Плюс картинки и вопросы надо откуда-то импортировать/сканировать. Половину функций уже отладил, можно уже кое-что выложить.
Файл 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"
