Вступление
В завершении этого выпуска хотелось бы показать комплексный пример управления интерфейсом и внутренним состоянием данных с помощью QlikView. Для такой демонстрации возможностей я выбрал всем известную простую игру на запоминание. Цель игры по очереди, открывая карточки на игровом поле, найти парные картинки. Если картинка открыта не парная, то ход переходит сопернику. Побеждает тот, кто больше пар картинок открыл.
НА ЗАМЕТКУ! Попробуйте сыграть и обыграть Qlik! Замечу, что Qlik играет честно, т.е. не подсматривает какие картинки на карточках, которые ещё не переворачивали, а лишь запоминает те, которые были открыты во время игры.
Также в моём примере, перед нажатием на «Новая игра», можно выбрать одну из нескольких загруженных тем. Ну, а теперь перейдем к тонкостям реализации такой игры…
НА ЗАМЕТКУ! Для реализации данного примера нам потребуется возможность QlikView
динамически изменять данные во внутренних таблицах макета. Для включения данной
возможности нужно в меню «Settings\Document Properties» на вкладке «Server»
включить галочку «Enable Dynamic Data Update».
Исходные данные
Для начала нам необходимо в скрипте создать игровое поле:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[GAME FIELD 4x4]: LOAD 10*(MOD(RowNo()-1,4)+1) + Ceil(RowNo()/4) as GFIELD_4x4, 0 as GFIELD_4x4_STATE, null() as GFIELD_4x4_IMG, 0 as GFIELD_4x4_SEEN AUTOGENERATE 16; |
В этой таблице мы присвоили каждой ячейке уникальное значение:
- 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
;
Загружаем картинку для «рубашки»:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
_FON: LOAD RowNo() as _Fon AUTOGENERATE 1; LET vFileImg = `$(vPathImg)\рубашка_01.gif`; [_bundle fon]: BUNDLE INFO LOAD 1 as _Fon, `$(vFileImg)` as _FileImg AUTOGENERATE 1; |
Теперь загружаем сами картинки (при чем самих картинок может быть и больше, чем 8 необходимых).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
LET vMaxCountImg = 10; _ANI: LOAD RowNo() as _Ani AUTOGENERATE $(vMaxCountImg); FOR n=1 TO $(vMaxCountImg) LET vFileImg = `$(vPathImg)\ani_`&Num($(n),`00`)&`.jpg`; IF not IsNull(QvdCreateTime(vFileImg)) THEN _bundle: BUNDLE INFO LOAD $(n) as _Ani, $(vFileImg) as _FileImg AUTOGENERATE 1; END IF; NEXT n; |
Проверяем, что у нас все картинки загрузились. Для этого создадим первый элемент поля обычный «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.
Пример (А)
Теперь напишем в скрипте код, который сгенерирует случайные расположения картинок на игровом поле и таких случайных распределений сделаем побольше,
например, сгенерируем 41 вариант расположения пар картинок:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
FOR n=1 TO 41 //отбираем только восемь случайных пар картинок LET vRandomImg = Round(($(vMaxCountImg)-1)*RAND(),1)+1; [RND]: LOAD 1 as ID, $(vRandomImg) as R_IMG AUTOGENERATE 1; DO WHILE NoOfRows(`RND`)<8 LET vRandomImg = Round(($(vMaxCountImg)-1)*RAND(),1)+1; [RND]: LOAD NoOfRows(`RND`)+1 as ID, $(vRandomImg) as R_IMG AUTOGENERATE 1 WHERE not EXISTS(R_IMG, $(vRandomImg)); LOOP; //добавляем к отобранным - вторые пары [RND]: Concatenate LOAD ID+8 as ID, R_IMG RESIDENT [RND]; //определяем случайное место картинки на поле 4x4 LET vRandomID = Round(15*RAND(),1)+1; //1..16 [RND_ID]: LOAD 1 as ID, $(vRandomID) as R_ID AUTOGENERATE 1; DO WHILE NoOfRows(`RND_ID`)<16 LET vRandomID = Round(15*RAND(),1)+1; //1..16 [RND_ID]: LOAD NoOfRows(`RND_ID`)+1 as ID, $(vRandomID) as R_ID AUTOGENERATE 1 WHERE not EXISTS(R_ID, $(vRandomID)); LOOP; //преобразуем полученный случайный номер в X,Y поля LEFT JOIN ([RND]) LOAD ID, 10*(MOD(R_ID-1,4)+1) + Ceil(R_ID/4) as R_XY RESIDENT [RND_ID]; DROP TABLE [RND_ID]; //переносим результат в общую таблицу вариантов [RANDOM VARIANTS]: LOAD Ani as RANDOM_TYPE, $(n) as RANDOM_VARIANT, R_IMG as RANDOM_IMG, R_XY as RANDOM_XY RESIDENT [RND]; DROP TABLE [RND]; NEXT n; |
Ну, и конечно, нам понадобятся переменные. Только в нашем случае мы будем использовать не чисто переменные клика а «псевдо-переменные» реализованные как поля специальной таблицы. Сделано это для того, чтобы не «сбить» игру при нажатии на команды «Back» или «Forward».
Итак, допишем скрипт, создадим таблицу, в которую поместим все необходимые переменные:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Variables: LOAD * INLINE [ Line,Theme,Win,ScorePlayer,ScoreQlik,StepPlayer,StepQlik, PicPlayer1,PicPlayer2,PicPlayer3,PicPlayer4,PicPlayer5,PicPlayer6,PicPlayer7,PicPlayer8, PicQlik1,PicQlik2,PicQlik3,PicQlik4,PicQlik5,PicQlik6,PicQlik7,PicQlik8 1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1 2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 ]; |
Все названия переменных, конечно же, пишем в одной первой строке).
Поясним их назначения:
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:
1 2 3 4 5 |
=MOD( Round((Count({1}distinct RANDOM_VARIANT)-1)*RAND(),1)+Second(Now()), Count({1}distinct RANDOM_VARIANT)) +1 (добавка +Second(Now()) необходима, чтобы функция RAND() не «зацикливалась» на одни и те же цепочки значений) |
Второй командой очищаем игровое поле и переносим выбранное расположение, которое только что определили полем RANDOM_VARIANT. Добавляем вторую команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 0 WHERE GFIELD_4x4_STATE=1; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 0 WHERE GFIELD_4x4_STATE=-1; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_SEEN = 0 WHERE GFIELD_4x4_SEEN=1; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={11}>} RANDOM_IMG)) WHERE GFIELD_4x4=11; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={21}>} RANDOM_IMG)) WHERE GFIELD_4x4=21; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={31}>} RANDOM_IMG)) WHERE GFIELD_4x4=31; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={41}>} RANDOM_IMG)) WHERE GFIELD_4x4=41; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={12}>} RANDOM_IMG)) WHERE GFIELD_4x4=12; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={22}>} RANDOM_IMG)) WHERE GFIELD_4x4=22; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={32}>} RANDOM_IMG)) WHERE GFIELD_4x4=32; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={42}>} RANDOM_IMG)) WHERE GFIELD_4x4=42; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={13}>} RANDOM_IMG)) WHERE GFIELD_4x4=13; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={23}>} RANDOM_IMG)) WHERE GFIELD_4x4=23; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={33}>} RANDOM_IMG)) WHERE GFIELD_4x4=33; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={43}>} RANDOM_IMG)) WHERE GFIELD_4x4=43; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={14}>} RANDOM_IMG)) WHERE GFIELD_4x4=14; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={24}>} RANDOM_IMG)) WHERE GFIELD_4x4=24; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={34}>} RANDOM_IMG)) WHERE GFIELD_4x4=34; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_IMG = $(=MAX({<RANDOM_XY={44}>} RANDOM_IMG)) WHERE GFIELD_4x4=44; |
И третьей командой прописываем начальные значения для всех наших игровых переменных. Добавляем третью команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
UPDATE [Variables] SET PicPlayer1 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer2 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer3 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer4 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer5 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer6 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer7 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer8 = 0 WHERE Line=1; UPDATE [Variables] SET PicPlayer1 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer2 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer3 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer4 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer5 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer6 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer7 = 0 WHERE Line=2; UPDATE [Variables] SET PicPlayer8 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik1 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik2 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik3 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik4 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik5 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik6 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik7 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik8 = 0 WHERE Line=1; UPDATE [Variables] SET PicQlik1 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik2 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik3 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik4 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik5 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik6 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik7 = 0 WHERE Line=2; UPDATE [Variables] SET PicQlik8 = 0 WHERE Line=2; UPDATE [Variables] SET Win = 0 WHERE Line=1; UPDATE [Variables] SET Win = 0 WHERE Line=2; UPDATE [Variables] SET ScoreQlik = 0 WHERE Line=1; UPDATE [Variables] SET ScoreQlik = 0 WHERE Line=2; UPDATE [Variables] SET ScorePlayer = 0 WHERE Line=1; UPDATE [Variables] SET ScorePlayer = 0 WHERE Line=2; UPDATE [Variables] SET StepQlik = 0 WHERE Line=1; UPDATE [Variables] SET StepQlik = 0 WHERE Line=2; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=1; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=2; UPDATE [Variables] SET Theme = `Ani` WHERE Line=1; UPDATE [Variables] SET Theme = `Ani` WHERE Line=2; |
Как видим, чтобы проапдейтить одну переменную, нам приходится это делать двумя командами. Отдельно для первой строки и отдельно для второй. А чтобы гарантировать, что никак нельзя выбрать в поле (RANDOM_VARIANT) несколько значений сразу введем специальное ограничение на единственный выбор, путем создания в клике специального ListBox.
На вкладке General выберем для Field поле RANDOM_VARIANT
После чего, нажмем закончить кнопкой «OK» и в получившемся списке выберем всего один из вариантов!
Теперь, снова вернёмся в свойства этого списка на вкладку «General» и поставим наше ограничение: ставим галочку напротив свойства Always One Selected Value (для самой игры данный ListBox не нужен, поэтому его можно просто навсегда скрыть. На вкладке «Layout» поставьте позже «Conditional» =0).
Пример (Б)
Вернёмся к построению визуализации игрового поля. Первую ячейку нашего будущего поля мы уже с вами сделали (это объекты «FON11» и «IMG11»). Доработаем их. Пропишем команды для объекта «FON11», чтобы можно стало на него нажимать.
На вкладке Actions пропишем список из трёх команд. Первой командой выясним, открыли ли мы вторую одинаковую картинку? Добавляем первую команду External\Set Variable, указываем Variable: vWin, а в Value вписываем формулу:
1 2 3 4 5 6 7 |
=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1, IF( Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={11}>} GFIELD_4x4_IMG), 1,-1) ,0) |
Второй командой вычислим новые значения для переменных. Добавляем вторую команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 8 9 10 11 |
UPDATE [Variables] SET Win = $(vWin) WHERE Line=1; UPDATE [Variables] SET Win = $(vWin) WHERE Line=2; UPDATE [Variables] SET ScorePlayer = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1 AND Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={11}>} GFIELD_4x4_IMG), RangeSum(Only(ScorePlayer),1), RangeSum(Only(ScorePlayer)) )) WHERE Line=1; UPDATE [Variables] SET ScorePlayer = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1 AND Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={11}>} GFIELD_4x4_IMG), RangeSum(Only(ScorePlayer),1), RangeSum(Only(ScorePlayer)) )) WHERE Line=2; UPDATE [Variables] SET StepPlayer = $(=ALT(Only(StepPlayer),1)-1) WHERE Line=1; UPDATE [Variables] SET StepPlayer = $(=ALT(Only(StepPlayer),1)-1) WHERE Line=2; |
И третьей командой открываем клетку игрового поля. Добавляем третью команду External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 1 WHERE GFIELD_4x4=11; UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_SEEN = 1 WHERE GFIELD_4x4=11; |
(Замечу, что во второй и третьей команде, мы в апдейтах прописываем координаты именно этой ячейки, т.е. 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 на новый код, где вы расположили копию объекта).
Смотри схему расположения на примере (В).
Элементы управления
Ну, а сейчас, нам осталось сделать самое главное — элементы управления игрой. Так как данную игру можно отнести к игре «состояний» (по принципу конечного автомата), определим для себя все такие состояния:
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 вписываем формулу:
1 |
=Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) |
Вторая команда:
1 |
External\Dynamic Update |
и в поле ввода «Statement» пропишем всего одну команду:
1 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = -1 WHERE GFIELD_4x4_STATE=1 |
Третья команда:
1 2 3 4 5 6 7 8 9 10 11 |
External\Dynamic Update и в поле ввода "Statement" пропишем следующий список команд: UPDATE [Variables] SET PicPlayer$(=Only(ScorePlayer)) = $(vImg) WHERE Line=1; UPDATE [Variables] SET PicPlayer$(=Only(ScorePlayer)) = $(vImg) WHERE Line=2; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=1; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=2; |
Для кнопки «◄ передать ход Qlik»:
Первая команда:
1 |
External\Dynamic Update |
и в поле ввода «Statement» пропишем всего одну команду:
1 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 0 WHERE GFIELD_4x4_STATE=1 |
Вторая команда:
1 |
External\Dynamic Update |
и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 |
UPDATE [Variables] SET Win = 0 WHERE Line=1; UPDATE [Variables] SET Win = 0 WHERE Line=0; UPDATE [Variables] SET StepQlik = 2 WHERE Line=1; UPDATE [Variables] SET StepQlik = 2 WHERE Line=2; |
Для кнопки «◄ забрать»:
Первая команда:
External\Set Variable
указываем Variable: vImg, а в Value вписываем формулу:
=Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG)
Вторая команда:
1 |
External\Dynamic Update |
и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 |
UPDATE [Variables] SET PicQlik$(=Only(ScoreQlik)) = $(vImg) WHERE Line=1; UPDATE [Variables] SET PicQlik$(=Only(ScoreQlik)) = $(vImg) WHERE Line=2; UPDATE [Variables] SET StepQlik = $(=IF( COUNT({1<GFIELD_4x4_STATE={0}>} GFIELD_4x4)>0 ,2,-1)) WHERE Line=1; UPDATE [Variables] SET StepQlik = $(=IF( COUNT({1<GFIELD_4x4_STATE={0}>} GFIELD_4x4)>0 ,2,-1)) WHERE Line=2; |
Третья команда:
External\Dynamic Update
и в поле ввода «Statement» пропишем всего одну команду:
1 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = -1 WHERE GFIELD_4x4_STATE=1 |
Для кнопки «переход хода к игроку ►»:
Первая команда:
1 |
External\Dynamic Update |
и в поле ввода «Statement» пропишем всего одну команду:
1 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 0 WHERE GFIELD_4x4_STATE=1 |
Вторая команда:
External\Dynamic Update
и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 |
UPDATE [Variables] SET Win = 0 WHERE Line=1; UPDATE [Variables] SET Win = 0 WHERE Line=2; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=1; UPDATE [Variables] SET StepPlayer = 2 WHERE Line=2; |
Для кнопки «1 попытка Qlik»:
Первая команда:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
External\Set Variable указываем Variable: vField, а в Value вписываем формулу: =IF( LEN(MinString( AGGR( IF(Index(CONCAT({1<GFIELD_4x4_STATE={0,1},GFIELD_4x4_SEEN={1}>} GFIELD_4x4,`|`),`|`), CONCAT({1<GFIELD_4x4_STATE={0,1},GFIELD_4x4_SEEN={1}>} GFIELD_4x4,`|`,GFIELD_4x4_STATE) ), GFIELD_4x4_IMG)) )>1, LEFT(MinString( AGGR( IF(Index(CONCAT({1<GFIELD_4x4_STATE={0,1},GFIELD_4x4_SEEN={1}>} GFIELD_4x4,`|`),`|`), CONCAT({1<GFIELD_4x4_STATE={0,1},GFIELD_4x4_SEEN={1}>} GFIELD_4x4,`|`,GFIELD_4x4_STATE) ), GFIELD_4x4_IMG)),2), MID(CONCAT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} `|`&GFIELD_4x4), MOD(Round(COUNT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} GFIELD_4x4)*RAND())+Second(Now()), COUNT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} GFIELD_4x4))*3+2,2) ) |
Вторая команда External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 1 WHERE GFIELD_4x4=$(vField); UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_SEEN = 1 WHERE GFIELD_4x4=$(vField); |
Третья команда External\Dynamic Update и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 |
UPDATE [Variables] SET Win = 0 WHERE Line=1; UPDATE [Variables] SET Win = 0 WHERE Line=2; UPDATE [Variables] SET StepQlik = 1 WHERE Line=1; UPDATE [Variables] SET StepQlik = 1 WHERE Line=2; |
Для кнопки «2 попытка Qlik»:
Первая команда:
External\Set Variable указываем Variable: vField2, а в Value вписываем формулу:
1 2 3 4 5 6 7 8 9 10 11 |
=IF( Only({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={1},GFIELD_4x4_IMG=P({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG)>} GFIELD_4x4)>0, Only({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={1},GFIELD_4x4_IMG=P({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG)>} GFIELD_4x4), MID(CONCAT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} `|`&GFIELD_4x4), MOD(Round(COUNT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} GFIELD_4x4)*RAND())+Second(Now()), COUNT({1<GFIELD_4x4_STATE={0},GFIELD_4x4_SEEN={0}>} GFIELD_4x4))*3+2,2) ) |
Вторая команда:
1 2 3 4 5 6 7 8 9 10 |
External\Set Variable указываем Variable: vWin, а в Value вписываем формулу: =IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1, IF( Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={$(vField2)}>} GFIELD_4x4_IMG), 2,-2) ,0) |
Третья команда:
External\Dynamic Update
и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 4 5 6 7 8 9 10 11 |
UPDATE [Variables] SET Win = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1, IF( Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={$(vField2)}>} GFIELD_4x4_IMG), 2,-2),0)) WHERE Line=1; UPDATE [Variables] SET Win = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1, IF( Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={$(vField2)}>} GFIELD_4x4_IMG), 2,-2),0)) WHERE Line=2; UPDATE [Variables] SET ScoreQlik = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1 AND Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={$(vField2)}>} GFIELD_4x4_IMG), RangeSum(Only(ScoreQlik),1), RangeSum(Only(ScoreQlik)) )) WHERE Line=1; UPDATE [Variables] SET ScoreQlik = $(=IF( COUNT({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4)=1 AND Only({1<GFIELD_4x4_STATE={1}>} GFIELD_4x4_IMG) = Only({1<GFIELD_4x4={$(vField2)}>} GFIELD_4x4_IMG), RangeSum(Only(ScoreQlik),1), RangeSum(Only(ScoreQlik)) )) WHERE Line=2; UPDATE [Variables] SET StepQlik = 0 WHERE Line=1; UPDATE [Variables] SET StepQlik = 0 WHERE Line=2; |
Третья команда:
External\Dynamic Update
и в поле ввода «Statement» пропишем следующий список команд:
1 2 3 |
UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_STATE = 1 WHERE GFIELD_4x4=$(vField2); UPDATE [GAME FIELD 4x4] SET GFIELD_4x4_SEEN = 1 WHERE GFIELD_4x4=$(vField2); |
Далее расставляем кнопки на свои места.
Пример (Г)
Осталось прописать ещё условия показа для кнопок (все условия прописываются на вкладке «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» пропишем такую формулу:
1 2 3 4 5 |
Only(StepPlayer)<=0 OR COUNT({1<GFIELD_4x4_IMG={>0}>} GFIELD_4x4)=0 OR COUNT({1<GFIELD_4x4_STATE={-1}>} GFIELD_4x4)=16 |
Ну, и, конечно, выведем информацию о текущем счете. Очки клика — это формула:
1 2 3 4 5 |
=Only(ScoreQlik) Очки игрока, это формула: =Only(ScorePlayer) |
Пример (Д)
Вот и готова наша игра.
Удачной тренировки ума!
Свежие комментарии