Вступление

В завершении этого выпуска хотелось бы показать комплексный пример управления интерфейсом и внутренним состоянием данных с помощью QlikView. Для такой демонстрации возможностей я выбрал всем известную простую игру на запоминание. Цель игры по очереди, открывая карточки на игровом поле, найти парные картинки. Если картинка открыта не парная, то ход переходит сопернику. Побеждает тот, кто больше пар картинок открыл.

НА ЗАМЕТКУ! Попробуйте сыграть и обыграть Qlik! Замечу, что Qlik играет честно, т.е. не подсматривает какие картинки на карточках, которые ещё не переворачивали, а лишь запоминает те, которые были открыты во время игры.

Также в моём примере, перед нажатием на «Новая игра», можно выбрать одну из нескольких загруженных тем. Ну, а теперь перейдем к тонкостям реализации такой игры…

НА ЗАМЕТКУ! Для реализации данного примера нам потребуется возможность QlikView

динамически изменять данные во внутренних таблицах макета. Для включения данной

возможности нужно в меню «Settings\Document Properties» на вкладке «Server»

включить галочку «Enable Dynamic Data Update».

Исходные данные

Для начала нам необходимо в скрипте создать игровое поле:

В этой таблице мы присвоили каждой ячейке уникальное значение:

  • GFIELD_4x4 — по принципу нумерации X и Y расположения в матрице,
  • поля GFIELD_4x4_IMG — номер картинки;
  • GFIELD_4x4_SEEN — открывали ли уже карточку во время игры (1=открывали) и GFIELD_4x4_STATE — поле для хранения состояния карточки (0=закрыта; 1=открыта; -1=убрана с поля).

Далее нам потребуется картинка «рубашки» и хотя бы 8 разных картинок для угадывания пар. Подготовьте их и положите в один каталог.

После в скрипте продолжаем писать:

LET vPathImg = C:\QlikView\Documents\Games\Memory\Pictures\Small;

Загружаем картинку для «рубашки»:

Теперь загружаем сами картинки (при чем самих картинок может быть и больше, чем 8 необходимых).

Проверяем, что у нас все картинки загрузились. Для этого создадим первый элемент поля обычный «Text Object».

На вкладке General в свойстве «Text» пропишем:

=qmem://_Fon/1

и переключим режим отображения «Representation» на Image, а способ отображения картинки «Image Stretch» переключим на Fill with Aspect.

Этот элемент поля будет у нас находиться в верхнем левом углу поля, поэтому данному объекту присвоим код «11» и, чтобы далее было легче ориентироваться на этой же вкладке «General» пропишем его «ObjectID» как FON11.

Создадим второй «Text Object» на этот раз для показа картинки. На вкладке General в свойстве «Text» пропишем (пока временно только для проверки, что картинки у нас прогрузились):

=qmem://_Ani/1

Режим отображения «Representation» также переключим на «Image» и способ отображения картинки «Image Stretch» на «Fill with Aspect». Этот элемент поля будет у нас находиться там же в верхнем левом углу поля, в точности под объектом «рубашки». И его «ObjectID» пропишем как IMG11.

QlikView Data Visualization

Пример (А)

Теперь напишем в скрипте код, который сгенерирует случайные расположения картинок на игровом поле и таких случайных распределений сделаем побольше,

например, сгенерируем 41 вариант расположения пар картинок:

Ну, и конечно, нам понадобятся переменные. Только в нашем случае мы будем использовать не чисто переменные клика а «псевдо-переменные» реализованные как поля специальной таблицы. Сделано это для того, чтобы не «сбить» игру при нажатии на команды «Back» или «Forward».

Итак, допишем скрипт, создадим таблицу, в которую поместим все необходимые переменные:

Все названия переменных, конечно же, пишем в одной первой строке).

Поясним их назначения:

Theme — хранит название выбранной темы когда нажали «Начало игры».

Win — состояние (угадал/не угадал) когда открывается вторая картинка.

ScorePlayer — текущие очки игрока (количество открытых одинаковых пар).

ScoreQlik — текущие очки клика.

StepPlayer — количество оставшихся действий игрока.

StepQlik — количество оставшихся действий клика.

Переменные с PicPlayer1 по PicPlayer8 хранят номера картинок, пары которых открывал игрок и забирал себе.

Переменные с PicQlik1 по PicQlik8 хранят номера картинок, пары которых открывал клик и забирал себе.

Ну, и самое первое поле: Line — своего рода заглушка (поле которое с одной стороны не должно меняться и второе используется для ссылки на первую и вторую строчку таблицы).

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

//временные и вспомогательные переменные

LET vImg = 0;

LET vWin = 0;

LET vField = 0;

LET vField2 = 0;

Приведение к начальному состоянию. Важно, в самом начале, после загрузки скрипта, привести игру к начальному состоянию, т.е. сбросить все переменные и заполнить игровое поле выбранным вариантом расположения карточек.

Для этого создадим кнопку «Новая игра». Это обычный объект клика «Button», в поле «Text» напишем «Новая игра».

На вкладке Actions пропишем список из трёх команд. Первая команда вычисляет новое случайное расположение карточек. Добавляем первую команду:

Selection\Select in Field

и вписываем в ячейку Field: RANDOM_VARIANT, и в формулу Search String:

Второй командой очищаем игровое поле и переносим выбранное расположение, которое только что определили полем RANDOM_VARIANT. Добавляем вторую команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

И третьей командой прописываем начальные значения для всех наших игровых переменных. Добавляем третью команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

Как видим, чтобы проапдейтить одну переменную, нам приходится это делать двумя командами. Отдельно для первой строки и отдельно для второй. А чтобы гарантировать, что никак нельзя выбрать в поле (RANDOM_VARIANT) несколько значений сразу введем специальное ограничение на единственный выбор, путем создания в клике специального ListBox.

На вкладке General выберем для Field поле RANDOM_VARIANT

После чего, нажмем закончить кнопкой «OK» и в получившемся списке выберем всего один из вариантов!

Теперь, снова вернёмся в свойства этого списка на вкладку «General» и поставим наше ограничение: ставим галочку напротив свойства Always One Selected Value (для самой игры данный ListBox не нужен, поэтому его можно просто навсегда скрыть. На вкладке «Layout» поставьте позже «Conditional» =0).

QlikView Data Visualization

Пример (Б)

Вернёмся к построению визуализации игрового поля. Первую ячейку нашего будущего поля мы уже с вами сделали (это объекты «FON11» и «IMG11»). Доработаем их. Пропишем команды для объекта «FON11», чтобы можно стало на него нажимать.

На вкладке Actions пропишем список из трёх команд. Первой командой выясним, открыли ли мы вторую одинаковую картинку? Добавляем первую команду External\Set Variable, указываем Variable: vWin, а в Value вписываем формулу:

Второй командой вычислим новые значения для переменных. Добавляем вторую команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

И третьей командой открываем клетку игрового поля. Добавляем третью команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

(Замечу, что во второй и третьей команде, мы в апдейтах прописываем координаты именно этой ячейки, т.е. 11).

Теперь для этого же объекта «FON11» пропишем условие показа. На вкладке Layout выберем «Conditional» и пропишем для него формулу:

Only({1<GFIELD_4x4={11}>} GFIELD_4x4_STATE)=0

(т.е. рубашка показывается если статус данной ячейки равен 0)

Доработаем и объект «IMG11». Для него так же пропишем условие показа на вкладке Layout выберем «Conditional» и пропишем для него формулу:

Only({1<GFIELD_4x4={11}>} GFIELD_4x4_STATE)>0

И на вкладке General для «Text» теперь пропишем уже вот такую формулу:

=qmem://_&Theme&/&Only({1<GFIELD_4x4={11}>} GFIELD_4x4_IMG)

(т.е. показываем именно ту картинку, которая прописана для данной ячейки на игровом поле)

Теперь надо просто накопировать объекты «FON11» и «IMG11» и расставить их по своим местам, сформировав игровое поле (только в каждом новом объекте не забудьте сделать замену 11 на новый код, где вы расположили копию объекта).

Смотри схему расположения на примере (В).

QlikView Data Visualization


Элементы управления

Ну, а сейчас, нам осталось сделать самое главное — элементы управления игрой. Так как данную игру можно отнести к игре «состояний» (по принципу конечного автомата), определим для себя все такие состояния:

1.Начальное состояние (картинки ещё не назначены).

2.Перед первой попыткой игрока.

3.Перед второй попыткой игрока.

4.Игрок открыл парную картинку.

5.Игрок вторым ходом не открыл парную картинку.

6.Перед первой попытка клика.

7.Перед второй попытка клика.

8.Клик открыл парную картинку.

9.Клик вторым ходом не открыл парную картинку.

10.Все картинки с поля убраны (конец игре).

Таким образом, на каждый переход между состояниями нужна своя кнопка. Заметим, что для перехода от 1—>2 и для перехода от 10—>2 у нас уже есть кнопка «Новая игра», а для переходов от 2—>3, 3—>4 и 3—>5 используются клетки самого поля («FON11» … «FON44»).

Итак, после состояния 3, мы можем оказаться либо в состоянии 4 или 5. Из состояния 4 возможен только переход снова на 2. Сделаем для этого кнопку «забрать ►».

А из состояния 5 возможен переход на состояние 6. Для этого сделаем кнопку «◄ передать ход Qlik». Со стороны клика возникает аналогичная ситуация. Из состояния 8 возможен только переход снова на 6. Сделаем для этого кнопку «◄ забрать». А из состояния 9 возможен переход на состояние 2. Для этого сделаем кнопку «переход хода к игроку ►». Ну, и чтобы было видно, как клик открывает поочередно карточки,

сделаем для перехода 6—>7 кнопку «1 попытка Qlik» и для перехода 7—>8 кнопку «2 попытка Qlik». Пропишем для каждой кнопки свой набор команд на вкладке «Actions».

Для кнопки «забрать ►»:

Первая команда:

External\Set Variable

указываем Variable: vImg, а в Value вписываем формулу:

Вторая команда:

и в поле ввода «Statement» пропишем всего одну команду:

Третья команда:

Для кнопки «◄ передать ход Qlik»:

Первая команда:

и в поле ввода «Statement» пропишем всего одну команду:

Вторая команда:

и в поле ввода «Statement» пропишем следующий список команд:

Для кнопки «◄ забрать»:

Первая команда:

External\Set Variable

указываем Variable: vImg, а в Value вписываем формулу:

=Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG)

Вторая команда:

и в поле ввода «Statement» пропишем следующий список команд:

Третья команда:

External\Dynamic Update

и в поле ввода «Statement» пропишем всего одну команду:

Для кнопки «переход хода к игроку ►»:

Первая команда:

и в поле ввода «Statement» пропишем всего одну команду:

Вторая команда:

External\Dynamic Update

и в поле ввода «Statement» пропишем следующий список команд:

Для кнопки «1 попытка Qlik»:

Первая команда:

Вторая команда External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

Третья команда External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:

Для кнопки «2 попытка Qlik»:

Первая команда:

External\Set Variable указываем Variable: vField2, а в Value вписываем формулу:

Вторая команда:

Третья команда:

External\Dynamic Update

и в поле ввода «Statement» пропишем следующий список команд:

Третья команда:

External\Dynamic Update

и в поле ввода «Statement» пропишем следующий список команд:

Далее расставляем кнопки на свои места.

QlikView Data Visualization

Пример (Г)

Осталось прописать ещё условия показа для кнопок (все условия прописываются на вкладке «Layout» в поле «Conditional»).

Для кнопки «забрать ►»:

Only(Win)=1 AND Only(StepPlayer)=0

Для кнопки «◄ передать ход Qlik»:

Only(Win)=-1 AND Only(StepPlayer)=0

Для кнопки «◄ забрать»:

Only(Win)=2 AND Only(StepQlik)=0

Для кнопки «переход хода к игроку ►»:

Only(Win)=-2 AND Only(StepQlik)=0 AND Only(StepPlayer)=0

Для кнопки «1 попытка Qlik»:

Only(StepQlik)=2

Для кнопки «2 попытка Qlik»:

Only(StepQlik)=1

И для всех кнопок поставим уровень «Layer» (на вкладке «Layout») Custom = 20

Осталось сделать ещё «защитный экран» на тот момент, чтобы когда шел ход клика, игрок не мог нажимать на клетки поля.

Для этих целей подойдет обычный «Text Object». Создадим такой объект и сразу на вкладке «General» сделаем ему цвет фона прозрачным (передвинем ползунок «Transparency» в крайне правое положение)

На вкладке «Layout» надо указать такой уровень, чтобы этот экран был выше объектов «FON» и «IMG», но ниже уровня кнопок. Для нашего случая поставим ему значение «Layer» = Top.

А появляться этот «экран» должен в трёх случаях. В поле «Conditional» пропишем такую формулу:

Ну, и, конечно, выведем информацию о текущем счете. Очки клика — это формула:

QlikView Data Visualization

Пример (Д)

Вот и готова наша игра.

Удачной тренировки ума!