Занятие № 6. Средства хранения структурированных данных в мобильном приложении
Задачи
- Изучить особенности использования списков и словарей в App Inventor.
Перед началом работы, скачайте по ссылке архив с шаблонами проектов. На этом занятии вы начинаете выполнение каждого задания с шаблона проекта. Он включает в себя уже настроенные элементы интерфейста и, в некоторых случаях, готовые скрипты.
Задание № 1. Квиз
Создадим приложение с викториной. Ответ на каждый вопрос нужно вводить самостоятельно. Правильный ответ сопроводим звуком.
Вопросы и ответы сохраним в двух списках. Как только пользователь ответит на последний вопрос, начнём викторину заново.
Содержимое шаблона
В медиабиблиотеке проекта находятся два звука: da.wav и net.wav. Они будут проигрываться когда игрок дал правильный или неправильный ответ:
Интерфейс экрана Screen1 содержит следующие компоненты:
Свойства компонентов настроены согласно следующей таблице:
Компонент | Свойства |
---|---|
Screen1 | ВыровнятьПоВертикали=Центр TitleVisible=нет галочки |
НадписьНомерВопроса | ЖирныйШрифт=есть галочка РазмерШрифта=18 Текст=0 |
НадписьВопрос | РазмерШрифта=25 Высота=150 pixels Текст=Вопрос |
ГоризонтальноеРасположение | Ширина=Наполнить родительский |
ТекстОтвет | Ширина=Наполнить родительский Подсказка=Введите ответ |
КнопкаОтвет | Текст=Ответ |
ЗвукДа | Источник=da.wav |
ЗвукНет | Источник=net.wav |
В этом шаблоне нет заранее созданных скриптов.
Программирование компонентов
Элементами списка будут три строки с вопросами:
- В каком году выпущен первый персональный компьютер IBM PC?
- Минимальная единица измерения количества информации.
- В каком году был изобретён транзистор?
- Очищаем текстовое поле для ввода ответа.
- Берём из списка вопросов элемент с индексом номер_вопроса и выводим текст в компоненте НадписьВопрос.
- Выводим на экран строку вида Вопрос 1, Вопрос 2 и так далее.
После нажатия на кнопку КнопкаОтвет должен появиться текст следующего вопроса. Когда мы находимся на последнем вопросе, кнопка должна перебросить нас к первому вопросу. Для этого следующее значение переменной номер_вопроса будем рассчитывать по формуле:
номер_вопроса = (номер_вопроса mod размер списка_вопросов) + 1.
В App Inventor выражение составьте в следующем порядке:
Запустите приложение. Вы должны увидеть текст первого вопроса и надпись Вопрос 1. Нажимайте на кнопку Ответ. Должен появиться следующий вопрос. После третьего вопроса должен снова появиться первый.
Запустите приложение. Впишите ответ на первый вопрос и нажмите кнопку Ответ. В зависимости от правильности ответа, прозвучит определённый звук.
Дополнительное задание
Замените существующие вопросы и ответы на ваши на выбранную вами тему. Предложите соседу ответить на вопросы вашей викторины.
Задание № 2. Общий холст
Разработайте приложение для совместного рисования на общем холсте. Нажатие по экрану добавит круг. Цвет заливки выбирается случайно после каждого запуска приложения.
Информация о точках хранится на сервере. Отправка новой точки и получение списка существующих точек организуем с помощью веб-API. На сервер будем отправлять координаты точки и её цвет:
От сервера каждые 2 секунды будем получать массив точек, в том числе нарисованных другими пользователями:
Откройте шаблон проекта под именем canvas_start.aia.
Содержимое шаблона
Интерфейс экрана Screen1 содержит следующие компоненты:
Свойства компонентов настроены согласно следующей таблице:
Компонент | Свойства |
---|---|
Screen1 | ВыровнятьПоГоризонтали=Центр TitleVisible=нет галочки |
Холст1 | Высота=300 pixels Ширина=300 pixels |
ИнтернетСохранить | Timeout=50000 Адрес URL= https://simple-api-3rug.onrender.com/api/canvas |
ИнтернетПолучить | Timeout=50000 Адрес URL= https://simple-api-3rug.onrender.com/api/canvas |
ЧасыЗапрос | ТаймерВсегдаЗапущен=нет галочки ТаймерВключен=есть галочка Интервал=2000 |
Несмотря на то, что отправка и получение информации на сервер происходит по одному и тому же адресу, сервер отличает назначение запроса благодаря методу запроса.
HTTP-протокол определяет ряд методов по которым сервер понимает, какое действие нужно совершить. Чтобы получить информацию используется метод GET, а для отправки применяется метод POST. Существуют и другие методы, которые не используются в этом проекте. Подробности можно узнать по этой ссылке
Какие методы и другие подробности использования веб-АPI Холст можно узнать из документации к веб-API.
Программирование компонентов
У блока make a dictionary (создать словарь) необходимо оставить только одну пару ключ-значение. Для этого нажмите на и удалите второй блок:
Ключ - Content-Type
, значение - application/json
.
- Меняем цвет заливки круга на значение переменной цвет.
- Рисуем на холсте круг с центром в точке касания.
- Отправляем информацию о точке с помощью веб-API.
- Отправляем данные в виде словаря с тремя парами ключ-значение: координаты и цвет точки.
Запустите приложения. Нажмите несколько раз на холст. В месте касания холста должны появиться точки. Ниже находится холст на котором можно увидеть информацию, хранящуюся на сервере. Нажмите кнопку Обновить, чтобы проверить, сохранилась ли информация об оставленных вами точках. На холсте также отображаются точки оставленные другими пользователями.
Преобразуем содержаниеОтвета в словарь.
Получаем из словаря массив, который хранится в словаре по ключу canvas. Если такого ключа не окажется в словаре, вернём пустой список.
С помощью цикла для каждого () в списке перебираем список точек. На каждом шаге цикла очередной элемент списка сохраняется в переменной точка. Каждая точка - это словарь со следующими парами ключ-значение:
Получаем из словаря точка значение по ключу color. Это будет цвет заливки круга.
Берём из словаря точка координату x.
Берём из словаря точка координату y. Рисуем круг с центром в точке с координатами (x, y).
Запустите приложение. Теперь точки нарисованные другими пользователями будут показываться на холсте в приложении.
Дополнительное задание
Добавьте возможность поделиться изображением на холсте. Как реализовать эту функции можете посмотреть в одном из заданий Занятия № 3.
Задание № 3. Робо-ферма
Разработаем приложение для управления передвижением дрона-фермера. Перед запуском курс прокладывается с помощью кнопок с четырьмя направлениями. Нажатие каждой кнопки добавляет новый курс в очередь команд. После запуска дрон будет следовать по заданному курсу:
Цель - проложить такой курс, который приведёт дрон к урожаю. Курс прокладывается с помощью кнопок со стрелками. Например для следующего поля
Одна из возможных последовательностей движения к урожую может быть такой: вправо, вправо, вправо, вниз, вниз
.
Откройте шаблон проекта под именем fermer_start.aia.
Содержимое шаблона
В медиабиблиотеке проекта находятся все необходимые изображения и звук, проигрываемый в случае успешного завершения мисии:
Интерфейс экрана Screen1 содержит следующие компоненты:
Свойства компонентов настроены согласно следующей таблице:
Компонент | Свойства |
---|---|
Screen1 | ВыровнятьПоГоризонтали=Центр ВыровнятьПоВертикали=Вверх TitleVisible=нет галочки |
КнопкаВверх | Изображение=up.png Текст=пустая строка |
КнопкаВниз | Изображение=down.png Текст=пустая строка |
КнопкаВлево | Изображение=left.png Текст=пустая строка |
КнопкаВправо | Изображение=right.png Текст=пустая строка |
КнопкаПуск | Текст=Пуск |
КнопкаНовоеПоле | Текст=Новое поле |
Холст1 | ЦветФона=Бесцветный ФоновыйРисунок=pole.png Высота=300 pixels Ширина=300 pixels |
СпрайтФермер | Изображение=dron.png X=3 Y=3 |
СпрайтУрожай | Изображение=m.png |
Часы1 | ТаймерВсегдаЗапущен=нет галочки ТаймерВключен=нет галочки ИнтервалТаймера=960 |
ЗвукУспех | Источник=da.wav |
В шаблоне определён один собственный блок-процедура переместить_урожай
. Вызов этого блока перемещает спрайт СпрайтУрожай на случайную клетку поля:
- Случайным образом выбираем номер строки и столбца в котором разместим спрайт. При этом помним, что игровое поле имеет размер 5x5 клеток.
- Перемещаем спрайт в координаты, вычеленные по формуле.
- Число 60 в формулах - ширина одной клетки поля в пикселях.
Программирование компонентов
В этой переменной сохраним последовательность команд для дрона.
Например, если в списке окажутся значения [90, 180, 180, 270]
,то после выполнения блока join items using separator (объединить элементы списка используя разделитель), получим строку 90>180>180>270
.
- Очищаем текущую очередь команд.
- Останавливаем СпрайтФермер, указав скорость его передвижения равной 0.
- Остановим таймер, который следит за выполнением очереди команд.
- Включаем доступ к кнопке КнопкаПуск. На время выполнения очереди команд эту кнопку мы будем отключать.
- Переместим СпрайтУрожай на новую случайную клетку.
Запустите приложение. Проведите следующие тесты:
- Нажмите несколько раз кнопку Новое поле. После каждого нажатия спрайт с урожаем должен переместиться в новую случайную клетку.
- С помощью кнопок со стрелками заполните очередь команд а затем нажмите кнопку Новое поле. Очередь должна очиститься.
Осталось добавить скрипт, который будет выполнять команды, добавленные пользователем в очередь. Добавьте обработчик нажатия кнопки КнопкаПуск.
- Проверяем, пуста ли очередь команд.
- Если команд больше нет, останавливаем таймер и спрайт с дроном.
- Иначе получаем новый курс для дрона из первого элемента со списком команд.
- После этого удаляем первую команду из списка.
- Показываем на экране телефона текущий список команд.
Очередь команд неспроста получила такое название. Любая очередь работает по принципу “первый пришёл - первый вышел”. Первая добавленная команда и будет выполняться первой. Когда мы нажимаем на кнопки со стрелками, очередь заполняется. На первое место попадает команда добавленная первой и так далее:
После запуска таймера, для выполнения из списка всегда берётся команда под индексом 1. После выполнения, эта команда удаляется из списка, как бы сдвигая все остальные команды:
Иначе очередь можно представить в виде воображаемой трубы в один конец которой входят элементы, а из другого - выходят:
В программировании структура данных Очередь встречается довольно часто, например для хранения очереди печати или очереди обработки событий.
Запустите приложение. С помощью кнопок со стрелочками составьте маршрут движения дрона и нажмите кнопку Пуск. Дрон должен последовательно выполнить все команды в очереди.
Победный звук воспроизведётся, если СпрайтФермер пересекается с СпрайтУрожай.
Запустите приложение. Составьте маршрут, который приведёт дрон к клетке с урожаем. Должен проиграться звук. Начните новую игру и составьте неправильный маршрут. Когда все команды выполняться и дрон не окажется в клетке с урожаем, звук не должен воспроизветись.
Проект готов.
Задание № 4. Крок
Крок (бел.) - шаг.
Разработаем приложение для ведения дневника прогулок - скольшо шагов пройдено за день и сколько всего метров пройдено за все дни прогулок. Для того, чтобы долгосрочно хранить количество шаго даже после того, как приложение закрыт, используем компонент TinyDB из категории Хранилище. Компонент сохраняет данные в словаре по заданному ключу. Этот словарь храниться в постоянной памяти телефона и доступен приложению после его повторного запуска.
Откройте шаблон проекта под именем krok_start.aia.
Содержимое шаблона
Интерфейс экрана Screen1 содержит следующие компоненты:
Свойства компонентов настроены согласно следующей таблице:
Компонент | Свойства |
---|---|
Screen1 | TitleVisible=нет галочки |
НадписьЗаголовок | ЖирныйШрифт=есть галочка |
СписокЗначений | ЦветФона=Безцветны ЦветТекста=Тёмно-серый |
Надпись4 | Текст=Всего пройдено метров: |
НадписьПройденоВсего | Текст=0 |
ТекстЗначение | Подсказка=Шагов пройдено сегодня ТолькоЦифры=есть галочка |
КнопкаДобавитьЗначение | Текст=Добавить |
КнопкаСбросить Значение | Ширина=Наполнить родительский Текст=Сбросить |
Программирование компонентов
- Вызываем процедуру
добавить_значение
. В качестве аргумента передаем текстовое значение из компонента ТекстЗначение. В собственном блоке это значение преобразуется в число и добавится к списку наблюдения. - Уберём сохранённое значение из текстового поля, подготовив его для ввода следующего числа.
- Обновим содержимое списка на экране.
Запустите приложение. Введите значение в текстовое поле и нажмите кнопку Добавить. Это значение должно появиться в списке на экране телефона. Введите ещё несколько значений. Нажмите кнопку Сбросить. Список на экране будет пуст. Заново добавьте несколько значений.
Полностью закройте прилоложение и откройте заново. Все значения, добавленные ранее, стёрлись и список на экране будет пуст.
Используем компонент TinyDB чтобы сохранить и загружать список наблюдений даже после перезапуска приложения.
Вызывать этот блок нужно каждый раз, как список наблюдения изменился - после добавления новое значения или очистки.
Теперь список наблюдения сохраняется в базе данных. Но после повторного запуска приложения содержимое списка не загружается заново. Исправим это, добавив обработчик события Инициализировать для экрана. После запуска приложения мы попробуем загрузить значение из базы данных по ключу данные. Если это первый запуск приложения и такого ключа в базе данных ещё нет, то вернём пустой список.
Запустите приложение. Введите значение в текстовое поле и нажмите кнопку Добавить. Введите несколько значений. Нажмите кнопку Сбросить. Полностью закройте прилоложение и откройте заново. Все добавленные ранее значения должны снова появиться на экране.
Нажмите нопку Сбросить и перезапустите приложения. После перезапуска список должен быть пуст.
Посчитаем, сколько метров мы прошли. Для этого нужно:
- Создать новый список на основе списка наблюдения. Каждый элемент нового списка равен соответсвующему элементу исходного списка, умноженному на длину одного шага.
- Сложим все элементы нового списка, чтобы получить ответ.
Для решения задачи используем два новых блока: make new list from (создать новый список на основе) и reduce list (свернуть список).
- Объявляем локальные переменные для хранения нового списка и результата расчётов.
- Получаем новый список, преобразовав количество шагов в расстояние в метры.
- Умножаем на 0.7 - устреднённую длинну одного шага в метрах.
- Свертываем список к одному значению - сумме всех пройденных расстояний.
- Выводим результат в надпись.
Коэффициент в блоке make new list from - количество метров в одном шаге. Расчитать это значения для своего роста можете по следующей формуле: \[ длина\ шага=\frac{рост}{4}+0.37 \] Рост указывается в метрах.
Запустите приложение. Нажмите кнопку Сбросить. Введите следующие значения: 345, 1345, 5436. Суммарное расстояние в метрах должно быть равно 4988.2.
Проект готов.