WorldSim3D Community

WorldSim3D русскоязычный => Примеры и видеоуроки => Topic started by: Alec - WS3D Developer on October 21, 2017, 05:05:22 PM

Title: Группа кнопок (GUI) на примере викторины
Post by: Alec - WS3D Developer on October 21, 2017, 05:05:22 PM
Группа кнопок (GUI) на примере викторины

Привет всем!  :)

Я тут решил потестировать новые возможности WS3D 1.03 St. и для этого состряпал примерчик.
В нём показано, как пользоваться группами кнопок, хотя это уже показано в примере, входящем в дистрибутив WS3D 1.03 St./Ext.

Вообще-то, просмотрев код, вы заметите, что это не просто примерчик но по-сути основа для создания викторин/тестов и т.п.
Я взял 10 групп слов (по 4 в группе). Слова довольно примитивны, всё быстро угадывается. Рассчитано на интеллект младшего школьника. В задании викторины нужно отмечать лишнее слово, которое по смыслу не вписывается в группу других трёх. Цель примера - не сама викторина, а функциональность, поэтому я и поместил пример сюда, а не в категорию "Проекты". Комментарии довольно подробные, но если что непонятно, спрашивайте отвечу. Приложил в архив исходники, включая с кодировкой UTF-8 (для линуксоидов). В архиве также исполняемый файл. Поэтому если вы новичёк, то просто разархивируйте  и запустите на исполнение. Убавьте немного громкость вашего устройства, фоновая музыка - бодренькая. Не обращайте внимание на дизайн, это просто пример. Если кто-нибудь сделает что-то своё на основе этого примера, будет очень интересно посомтреть!

Буду благодарен за любые отзывы!

Скачать (https://yadi.sk/d/67wZeIoc3Nx8zK) (11,6 мб zip)

Code: [Select]
'' ----------------------------------------------------------------------------
'' Название проекта (игры): Викторина "Отметь лишнее слово"
'' Автор(ы) проекта: Alex Artifex
'' Дата начала создания проекта: 16.10.2017
'' Дата окончания проекта: 21.10.2017
'' ----------------------------------------------------------------------------
'' Краткое описание.
'' Викторина, первоначальной целью которой являлось тестирование новых возможностей
'' WorldSim3D v1.03 (St). Тестировалась возможность создания и работы с группой кнопок
'' и другими аспектами GUI. Этот проект является хорошей основой для создания полноценного
'' учебного приложения, в т.ч. игры.
'' ----------------------------------------------------------------------------
'' Для удобства уберём подключение заголовков, а также разные пользовательские
'' (т.е. созданные вами) функции в отдельный модуль, который мы подключаем здесь,
'' в самом начале проекта.
#include "MyFunctions.bi"
'' Для удобства и порядка в коде можно убрать переменные, первоначальные настройки
'' и меню в отдельные модули и затем здесь подключить их.
'' ------------------------------------------------------------------------------
' Объявим пользовательскую функцию для добавления кнопок в группу кнопок
Declare sub AddRadioButtonToGroup(ByVal group As wGUIObject,ByVal posX As Int32, ByVal posY As Int32,Byref tex0 As wTexture,ByRef tex1 As wTexture,ByVal text As WString Ptr=0,ByVal ID As Int32=0,ByVal mode As Int32=0)

'' ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
'' Для порядка в коде лучше разделить объявление переменных по типам, тогда сразу
'' будет видно, где какая переменная.

Dim GUIEvent as wGUI_EVENT Ptr
Dim CheckBox_1 As wGUIobject  ' чекбокс для подсказки: группа слов, в которую не вписывается одно слово
Dim CheckBox_2 As wGUIobject  ' чекбокс для подсказки: верно или неверно

'' [1.] Для работы со звуками
Dim As wNode sound_backgr ' фоновая музыка

'' [2.] Объекты WorldSim3D (Меши, Ноды, Текстуры, Камеры, Селекторы и т.д.)
Dim backgr as wTexture ' спрайт фона посередине для вывода сообщений и самой викторины
Dim mouse_pointer as wTexture ' переменная для спрайта своего (графич.) указателя мыши вместо обычного

'DIM KeyEvent as wKEY_EVENT PTR
'DIM MouseEvent as wMOUSE_EVENT Ptr

'Dim Camera as wCamera
'DIM CameraNode as wNode
DIM BF as wFont ' шрифт
DIM BF_2 as wFont ' шрифт

'' [3.] Другие переменные, не связанные напрямую с объектами и звуком. Это могут быть
'' разные флаги, счётчики, математика, а также для отладочных целей.

Dim page As Int32 = 0 ' пременная для "страниц". Переходя от одной группы слов к другой, пользователь как бы
' "листает страницы". Такой подход мне удобен для перехода от одной группы вопросов к другой. Я это сделал через
' Select Case ... End Select, где каждый case это "страница", отображающая одну группу слов. Я использовал 12 таких
' страниц: 1 - 10 для самих групп слов; 0-ая страница для описания (можно использовать для меню или настроек игры);
' 11-я страница для подготовки к выводу результата викторины, когда скрывается кнопка "дальше" (справа) и показывается
' кноака "Результат".

'' [4.] Для работы с текстом, если в проекте много разных сообщений, выводимых на экран, например,
'' тексты для меню, диалогов между персонажами, GUI и т.д.
Dim correct_mes As String ' сообщение правильный или нет ответ (верно/неверно)
'Dim gameover_mes As String

'' [5.] Для сохранения состояния игры, первоначальных настроек игры, таблицы результатов (рекордов)
'' и т.д.
Dim flag_settings As Boolean = TRUE ' флаг для показа/скрытия первоначального описания, меню, настроек и т.д.

'' [6.] Другие переменные, не вошедшие в предыдущие разделы.

'' Естественно, в зависимосчти от типа вашего проекта, какие-то разделы переменных вам не понадобятся,
'' а какие-то, наоборот, вы захотите добавить.

' Макросы для того, чтобы видеть какой ID относится к какому элементу GUI.
'#Define MY_GUI_BUTTON_QUIT     201
#Define MY_GUI_CHECKBOX         202
#Define MY_GUI_CHECKBOX_2     203

'' =============================================================================================
'' Запускаем интерфейс WorldSim3D
wStart (wDT_OPENGL, 800, 600, 32, FALSE, TRUE, TRUE, TRUE)

wLogoWS3D (TRUE)

'' ++++++++++++++++++  ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ ПРОЕКТА  ++++++++++++++++++++++++++++++++++
'' Сюда включается всё, что должно быть выполнено только один раз или инициализировано для
'' последующей работы только один раз. Эта часть кода расположена до главного цикла,
'' который начинается с While wRunning. Также здесь расположены функции, инициализирующие
'' работу объектов WorldSim3D, которые будут продолжать работать и в главном цикле:
'' камеры, аниматоры и другие.
'' Также в этом разделе можно сделать работу меню, ведь обычно послезапуска игры сначала
'' появляется меню, из которого можно уже начать игру.

'' ------------------  ИНИЦИАЛИЗАЦИЯ РАБОТЫ ЗВУКОВ  ---------------------------------------
' загружаем фоновую музыку
sound_backgr = wLoadSound ("Assets/sounds/Qusic_Dragonfly.ogg")
'' ---------------------------------------------------------------------------------------
' Устанавливаем текст заголовка окна приложения
wSetWindowCaption ( "A WS3D project. Quiz: Which word is odd? " )

' загружаем нужный шрифт из папки ресурсов через функцию wGetFont
BF = wGetFont ( "Assets/fonts/Cyr.xml" )
BF_2 = wGetFont ( "Assets/fonts/Stylo_bold_18.xml" )
wGUISetFont (BF) ' устанавливаем шрифт для GUI по умолчанию
wGUISetColor ( wGUI_CE_BUTTON_TEXT, 55, 200, 100, 255 ) ' устанавливаем цвет шрифта для кнопок GUI по умолчанию

'' ------- ЗАГРУЗКА ИГРОВЫХ ОБЪЕКТОВ НА СЦЕНУ ---------------------------------------------
'' Загрузку игровых объектов (3D моделей, частиц, скайбоксов и др.) на сцену.
'' [1.] Ноды для 3D моделей
backgr = wGetTexture ( "Assets/textures/simple_rounded_40.png" )
mouse_pointer = wGetTexture( "Assets/textures/pointer.png" ) ' загружаем спрайт для нового указаетля мыши
Dim desc As wTexture = wGetTexture ( "Assets/textures/desc.png" ) ' загружаем спрайт описания вначале
'' [2.] Аниматоры Нодов, например, wAddFlyCircleAnimator, wAddRotationAnimator и др.

'' [3.] Камеры, Ноды для них и первоначальные настройки камер

'' [4.] Частицы (огонь, взрыв, снег и т.д. )

'' ------------------ УСТАНОВКА ФИЗИКИ: ПРОВЕРКИ СТОЛКНОВЕНИЙ И ДР. -------------------
'' Это может быть как базовая физика, встроенная в WorldSim3D так и Newton и других.

'' ------------------------------------------------------------------------------------
'' ------------------ ОСВЕЩЕНИЕ -------------------------------------------------------
' добавим в проект яркий свет, освещающий всё вокруг
''wSetAmbientLight ( 1, 1, 1 )

'' ------------------ ДРУГИЕ НАСТРОЙКИ или КОД ------------------------------------------------
'
'' [5.] GUI ---------------------------------------------------------------------------------------------------------
' SETTINGS -----------------------------------------------------------------------------------------------------
' загрузим и установим группу кнопок для викторины
Dim As wGUIObject group1 = wAddButtonGroup (100, 80, 700, 550, 0)
'wButtonGroupSetBackgroundColor (group1, 255, 210, 190, 190)
wButtonGroupDrawBackground (group1, FALSE) ' небудем отрисовывать фон группы кнопок, т.к. загрузили отдельно
' другой, более красивый

' загружаем 2 текстуры для кнопок
Dim As wTexture tex2=wGetTexture("Assets/textures/yes_64.png")
Dim As wTexture tex3=wGetTexture("Assets/textures/no_64.png")

' пользовательская функция (смотрите внизу кода) для добавления кнопки к группе
AddRadioButtonToGroup (group1, 400, 80, tex2, tex3, "", 100, 1)
AddRadioButtonToGroup (group1, 400, 150, tex2, tex3, "", 101, 1)
AddRadioButtonToGroup (group1, 400, 220, tex2, tex3, "", 102, 1)
AddRadioButtonToGroup (group1, 400, 290, tex2, tex3, "", 103, 1)

wButtonGroupSetSelectedIndex (group1, 0) ' установим индекс кнопки на 1-й странице (это не обязательно),
' просто если хотите, чтобы кнопка "крестик" была на определённом слове первоначально

' Кнопка "Дальше" (Next button)
Dim As wTexture tex4 = wGetTexture ("Assets/textures/Next-Button_64.png") 'текстура для кнопки
Dim As wGUIobject button_next = wAddButton ( 690, 240, 754, 304, 201, "", 0, 0) 'добавляем кнопку на сцену
' Чтобы кнопка выглядела красиво, нужно сделать ей "графический" вид, а не как у системных приложений
wButtonSetDrawBorder (button_next, 0) ' скрываем лицо кнопки (hide the face of the button)
wButtonSetUseAlpha (button_next, 1) ' используем альфа-канал для фона кнопки (use alpha for drawing background image)
wButtonSetImage (button_next, tex4) ' устанавливаем текстуру на кнопку (set image for the button)

' То же самое для кнопки "Результат"
' Result button
Dim As wTexture tex5 = wGetTexture ("Assets/textures/result.png")
Dim As wGUIobject button_result = wAddButton ( 630, 515, 764, 573, 201, "", 0, 0) 'the button is 134x48 (размер кнопки)
wButtonSetDrawBorder (button_result, 0) ' hide the face of the button
wButtonSetUseAlpha (button_result, 1) ' use alpha for drawing background image
wButtonSetImage (button_result, tex5) ' set image for the button
wGUISetVisible (button_result, FALSE)

' То же самое для кнопки "Выход"
' Exit button
Dim As wTexture tex6 = wGetTexture ("Assets/textures/exit.png")
Dim As wGUIobject button_exit = wAddButton ( 650, 515, 746, 576, 201, "", 0, 0) 'the button is 96x51 (размер кнопки)
wButtonSetDrawBorder (button_exit, 0) ' hide the face of the button
wButtonSetUseAlpha (button_exit, 1) ' use alpha for drawing background image
wButtonSetImage (button_exit, tex6) ' set image for the button
wGUISetVisible (button_exit, FALSE)

' CheckBoxes
' Первоначально установлены на то, чтобы не выводить подсказки (в конце значение FALSE)
CheckBox_1 = wAddCheckBox  ( " Показывать подсказку:", 20, 520, 310, 540, MY_GUI_CHECKBOX, FALSE )
CheckBox_2 = wAddCheckBox  ( " Показывать, верно или неверно:", 20, 550, 320, 570, MY_GUI_CHECKBOX_2, FALSE )
         
' Важный момент. Чтобы кнопка "Дальше" не срабатывала 60 раз в секунду, т.е. чтобы группы слов (страницы) у нас не
' перелистывались одним кликом по много штук, необходимо сделать так, чтобы когда пользователь кликает по кнопке,
' она срабатывала 1 раз за секунду или 10-ю часть секунды, но не сотую часть секунды. Для этого я сделал свой простенький
' таймер, который не даёт кнопке срабатывать каждую 1/60 долю секунды.
' Объявим переменные для этого таймера
Dim timer_press_but As int32 = 0 ' время таймера
Dim timer_start As Boolean = 0 'флаг для запуска таймера, сначала на нуле (не запущен)

' массив переменных для слов викторины
Dim words (1 To 4) As String
' массив переменных для полсказок викторины
Dim prompt (0 To 10) As String

' MENU / Settings
Dim As wTexture menu = wGetTexture ("Assets/textures/menu_2.png")
Dim menu_title As String = "Викторина"

Dim correct_answer As uint32 = 0 ' количество верных ответов

Dim answer As String ' при выводе результата: текст ответа с правильным окончанием: "ответ", "ответов" или "ответа"
Dim prompt_show As Boolean = FALSE ' показывать ли подсказку (для группы слов)
Dim answer_show As Boolean = FALSE ' показывать ли подсказку: верно или неверно
Dim result As Boolean = FALSE ' вывод результата, сначала флаг установлен на "скрывать"
'Dim menu_desc As String = "Перед вами викторина, в которой вам нужно отмечать из 4-х слов 1 слово, которое по смыслу не вписывается в 3 остальных. Всего 10 вопросов."
'Dim menu_level_title As String = "Выберите уровень:"
'Dim menu_level_easy As String = "Лёгкий, с подсказкой, время на ответ 10 секунд"
'Dim menu_level_average As String = "Средний, без подсказки, время на ответ 10 секунд"
'Dim menu_level_hard As String = "Трудный, без подсказки, время на ответ 3 секунды"
wHideMouse ' скроем системный указатель мыши, т.к. будет свой
' -----------------------------------------------------------------------------
'******************************************************************************
'----------------------- ГЛАВНЫЙ ЦИКЛ ВАШЕГО ПРОЕКТА --------------------------
' здесь главный цикл приложения, поэтому
' мы устанавливаем цикл с условием: пока движок работает (функция wRunning)
' внутри цикла постоянно выполняются определённые команды, в основном для отображения сцены
While wRunning
        ' начинаем отрисовку сцены с цветом фона, например зелёный (который устанавливаем числами 0,55,0)
        wBeginScene ( 0, 30, 50 )
       
        ' если таймер для кнопки (смотри объяснение выше) включен, то он начал отсчитывать время
        ' это время ровно FPS (фреймрейту). Если FPS = 60, то таймер отсчитывает время по 1/60 секунды.
        ' Если у вас не установлена функция wSetFPSLimit(60) (в этом коде она есть, в конце), то FPS может быть
        ' намного больше и таймер может работать некорректно.
        If timer_start = TRUE Then timer_press_but = timer_press_but + 1
        ' если нажата кнопка "дальше", то таймер включается
        If wButtonIsPressed (button_next) = TRUE Then
        timer_start = TRUE
        EndIf
       
         ' если нажата кнопка "результат", то таймер включается
        If wButtonIsPressed (button_result) = TRUE Then
        timer_start = TRUE
        EndIf
       ' если этот таймер досчитал до 5 (при FPS 60, это будет: 60/5, т.е. 1/12 секунды), то
        If timer_press_but = 5 Then
        page = page + 1 ' меняем страницу (переход к след. группе слов)
        timer_start = FALSE ' останавливаем таймер
        timer_press_but = 0 ' обнуляем таймер для дальнейшего использования
        If page > 11 Then ' не даём страницам выйти за предел отведённый для количества страниц
        page = 11
        EndIf
        EndIf
 
  ' Change questions
  ' Меняем страницы, т.е. группы слов
        Select Case page
        Case 0 ' нулевая страница для вывода описания, меню или настроек
        flag_settings = TRUE
        wGUISetVisible (group1, FALSE) ' пока скрываем кнопки для ответов
        Case 1
        flag_settings = FALSE ' настройки/описание скрываем
        prompt (1) = "Домашние животные" ' подсказка
        words(1) = "Корова": words(2) = "Лошадь": words(3) = "Овца": words(4) = "Лиса"
        ' Если номер кнопки (ID) соответствует правильному (в данном случае 3), то ответ верный
        ' помните, что ID начинается с 0, значит если ID = 3, то это 4-я кнопка
        If wButtonGroupGetSelectedIndex (group1) = 3 Then
        correct_mes = "Верно"
        ' если ответ верный, то прибаляем к числу верных ответов
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно" ' если пользователь выбрал неправильный ответ, то если чекбокс для
        ' подсказки включен, то выодится соответствующее сообщение
        EndIf
        Case 2
        prompt (2) = "Устройство с операционной системой"
        words(1) = "Ноутбук": words(2) = "Молоток": words(3) = "Планшет": words(4) = "Роутер"
        If wButtonGroupGetSelectedIndex (group1) = 1 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 3
        prompt (3) = "Общественный вид транспорта"
        words(1) = "Автобус": words(2) = "Троллейбус": words(3) = "Трамвай": words(4) = "Мотоцикл"
        If wButtonGroupGetSelectedIndex (group1) = 3 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 4
        prompt (4) = "Части тела"
        words(1) = "Рука": words(2) = "Нога": words(3) = "Голова": words(4) = "Родинка"
        If wButtonGroupGetSelectedIndex (group1) = 3 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 5
        prompt (5) = "Цвета"
        words(1) = "Белый": words(2) = "Соленый": words(3) = "Красный": words(4) = "Черный"
        If wButtonGroupGetSelectedIndex (group1) = 1 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 6
        prompt (6) = "Посуда"
        words(1) = "Стакан": words(2) = "Принтер": words(3) = "Ложка": words(4) = "Тарелка"
        If wButtonGroupGetSelectedIndex (group1) = 1 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 7
        prompt (7) = "Командные виды спорта"
        words(1) = "Футбол": words(2) = "Хоккей": words(3) = "Шахматы": words(4) = "Волейбол"
        If wButtonGroupGetSelectedIndex (group1) = 2 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 8
        prompt (8) = "Языки программирования"
        words(1) = "BASIC": words(2) = "Java": words(3) = "Assembler": words(4) = "Windows"
        If wButtonGroupGetSelectedIndex (group1) = 3 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 9
        prompt (9) = "Органы"
        words(1) = "Почка": words(2) = "Пятка": words(3) = "Сердце": words(4) = "Печень"
        If wButtonGroupGetSelectedIndex (group1) = 1 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
        EndIf
        Case 10
        prompt (10) = "Водоёмы"
        words(1) = "Пруд": words(2) = "Озеро": words(3) = "Вулкан": words(4) = "Море"
        If wButtonGroupGetSelectedIndex (group1) = 2 Then
        correct_mes = "Верно"
        If timer_press_but = 1 Then correct_answer = correct_answer  + 1
        Else correct_mes = "Неверно"
       
        EndIf
        Case 11
        'после всех ответов  скрываем кнопку "дальше" и показываем кнопку "результат"
        wGUISetVisible (button_next, FALSE)
        wGUISetVisible (button_result, TRUE)
        End Select
       
        wDrawGUI
'Фоновый звук играет все время
  If wIsSoundPlaying (sound_backgr) = FALSE  Then
wPlaySound (sound_backgr)
  EndIf
     
      '' ------------------------ СОБЫТИЯ КЛАВИАТУРЫ ----------------------------
        ' если события клавиатуры могут быть обработаны, то:
        /'
        while wKeyEventAvailable
            ' читаем события клавиатуры.
            KeyEvent = wReadKeyEvent
   
            ' если нажата какая-либо клавиша, связываем с ней событие, оторое мы хотим
            ' чтобы оно произошло. Это может быть что угодно:
            select case as const KeyEvent->key
            case KEY_KEY_D     ' клавиша D
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
   
            case KEY_KEY_W     ' клавиша W
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
            case KEY_KEY_A     ' клавиша A
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
                   
            case KEY_KEY_S     ' клавиша S
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                End If
            ' Добавим функцию для закрытия окна через клавишу ESCAPE.
    ' Если клавиатура не исчпользуется, то для этой цели нужно использовать
    ' другую функцию - wCloseESC(), которую можно поместить в конце главного цикла.
            end Select
        Wend
       
    '' --------------------------- СОБЫТИЯ МЫШИ -----------------------------------------
        '
        While wMouseEventAvailable
            MouseEvent = wReadMouseEvent
   
            if MouseEvent->action = wME_MOUSE_MOVED then
   
            End If
   
        Wend
      '' ----------------------------------------------------------------------------------   
      '/
     
      '' Завершение отрисовки 3D сцены
        wDrawScene
  '' ------------------------- ОТОБРАЖЕНИЕ ТЕКСТА НА ЭКРАНЕ ---------------------------------
  '' отображаем на экране загруженный ранее шрифт. Это нужно сделать после функции wDrawScene,
  '' т.е. после отрисовки 3D сцены, чтобы выводимый на экран текст отображался поверх объектов
  '' сцены, иначе объекты сцены будут закрывать текст.
  ''
' выводим в конце выражение "правильный ответ" с правильным окночанием в зависимости от количества
' правильных ответов. Скобка в конце - для процентов   
If correct_answer = 1 Then
answer = " правильный ответ ("
ElseIf correct_answer > 1 And correct_answer < 5 Then
answer = " правильных ответа ("
ElseIf correct_answer > 4 Or correct_answer = 0 Then
answer = " правильных ответов ("
EndIf

' пока не показан результат, т.е. викторина в процессе, выводим следующие тексты   
If result = FALSE Then
    If flag_settings = FALSE Then
    If page < 11 Then w2DFontDraw (BF, "Слово №:  " + Str(page) + "  из 10", 320, 30, 400, 45, 255, 90, 100, 200 )
    w2DFontDraw (BF, "Отметьте лишнее слово:  ", 280, 120, 575, 140, 255, 190, 100, 200 )
    w2DFontDraw (BF_2, "Правильных ответов:  " + Str(correct_answer), 260, 480, 450, 490, 255,  90, 100, 200)
    If prompt_show = TRUE Then w2DFontDraw (BF, prompt (page), 260, 520, 600, 540,   255, 30, 100, 190 )
    If answer_show = TRUE Then w2DFontDraw (BF, correct_mes, 330, 550, 520, 570,   255, 30, 100, 190 )
    EndIf
    ' Слова викторины
    w2DFontDraw (BF_2, words(1), 230, 180, 300, 200,  255, 90, 240, 200 )
    w2DFontDraw (BF_2, words(2), 230, 250, 300, 270,  255, 90, 240, 200 )
    w2DFontDraw (BF_2, words(3), 230, 320, 300, 340,  255, 90, 240, 200 )
    w2DFontDraw (BF_2, words(4), 230, 390, 300, 410,  255, 90, 240, 200 )
Else ' если викторина закончилась скрываем её элементы и выводим результат
wGUISetVisible (group1, FALSE)
'If wButtonIsPressed (button_result) = TRUE Then result
w2DFontDraw (BF_2, "      Ваш результат:  " + Chr(13) + Chr(13) + Str(correct_answer) + answer  + Str(correct_answer*10) + " %)", 230, 180, 450, 450, 255,  190, 100, 200)
page = 12' меняем странице ещё раз, чтобы скрыть кнопку "результат", которая находится на 11-й странице
End If
' если нажата кнопка "результат" и флаг результата был до этого выключен, то:
If wButtonIsPressed (button_result) = TRUE And result = FALSE Then
result = TRUE ' включаем флаг результата
wGUISetVisible (button_exit, TRUE) ' показываем кнопку "Выход"
EndIf
' если таймер для кнопок на 0 и результат включен, то:
If timer_press_but > 0 And result = TRUE Then
wGUISetVisible (button_result, FALSE) ' скрываем кнопку "результат"
timer_start = FALSE ' останавливаем таймер
timer_press_but = 0 ' обнуляем таймер
EndIf

' Показываем первоначальный текст: описание, настройки и т.п.       
       If flag_settings = TRUE Then
        wDraw2DImageWithRotation (menu, 305, 20, 0,0,0, 0.6, 0.5, TRUE, 100, 20, 200, 200)
        wGUISetVisible (group1, TRUE)
        w2DFontDraw (BF, menu_title, 345, 35, 400, 160, 255, 90, 255, 155 )
        wDraw2DImageWithRotation (desc, 200, 120, 0,0,0, 1.0, 1.0, TRUE, 255, 20, 200, 200)
       EndIf
       ' показываем постоянно спрайт фона
       wDrawSpriteAdvanced ( backgr, 140, 80, 1.5, 2.0, TRUE, 1)

' Работа с чекбоксами
    If wGUIEventAvailable then
        ' read the GUI event out
        GUIEvent = wReadGUIEvent

        ' process the particular control
        select case GUIEvent->id

        case MY_GUI_CHECKBOX
            ' if the checkbox state has changed
            If GUIEvent->event = wGUI_ET_CHECKBOX_CHANGED then
                '
                if GUIEvent->x = 1 Then
                    prompt_show = TRUE ' показываем подсказку для группы слов
                Else
                    prompt_show = FALSE ' скрываем подсказку для группы слов
                End if
            End If
           
        Case MY_GUI_CHECKBOX_2
            ' if the checkbox state has changed
            If GUIEvent->event = wGUI_ET_CHECKBOX_CHANGED then
                '
                if GUIEvent->x = 1 Then
                    answer_show = TRUE ' показываем подсказку: верно/неверно
                Else
                    answer_show = FALSE ' скрываем подсказку: верно/неверно
                End if
            End If

        End Select
    End If
    wMousePointerSprite (mouse_pointer) ' прикрепляем к системному (который мы скрыли) указателю мыши свой спрайт-указатель
     ' заканчиваем отрисовку всего, что на экране и отображаем это
      wEndScene
       
      wCloseEsc()
      wSetFPSLimit(60)   'устанавливаем фреймрейт по умолчанию 60 кадров в секунду
      If wButtonIsPressed (button_exit) = TRUE Then Exit While ' если пользователь кликнул на кнопку "Выход"? заканчиваем
      'работу приложения
Wend
' -----------------------КОНЕЦ ГЛАВНОГО ЦИКЛА ВАШЕГО ПРОЕКТА ----------------------------------
'**********************************************************************************************

' ---------------------------------------------------------------------------------------------
' Останавливаем работу движка и высвобождаем ресурсы памяти
wStop

' Пользовательская функция для графической части кнопок, входящих в группу
Sub AddRadioButtonToGroup(ByVal group As wGUIObject, ByVal posX As Int32, ByVal posY As Int32, ByRef tex0 As wTexture, ByRef tex1 As wTexture,_
ByVal text As WString Ptr=0, ByVal ID As Int32=0, ByVal mode As Int32=0)
Dim As UInt32 tWidth,tHeight,tPitch
Dim tFormat as wCOLOR_FORMAT
wGetTextureInformation(tex0,tWidth,tHeight,tPitch,tFormat)
Dim As wGUIObject btn=wAddButton(posX,posY,posX+tWidth,posY+tHeight,ID,"")
wButtonSetUseAlpha(btn,TRUE)
wButtonSetDrawBorder(btn,FALSE)
wButtonSetImage(btn,tex0)
wButtonSetPressedImage(btn,tex1)
wButtonGroupAdd(group,btn)
Dim As UInt32 posX2,posY2,Width2,Height2
If mode=0 Then
wGUIGetAbsolutePosition(group,@posX2,@posY2,@Width2,@Height2)
If posX2+posX+tWidth+100< posX2+Width2 Then
Dim As wGUIObject label=wAddLabel(text,posX2+posX+tWidth+5,posY2+posY+tHeight/3,posX2+posX+tWidth+100,posY2+posY+tHeight,FALSE,FALSE,0)
EndIf
EndIf
End Sub
Title: Re: Группа кнопок (GUI) на примере викторины
Post by: Nikolas - WS3D Developer on October 21, 2017, 06:29:24 PM
Привет, Alec.
Прошел викторину. Даже ошибся  :(
Замечательный пример того, как на простых вещах можно делать интересные сюжеты.
Все стильно, оформлено со вкусом. Мне понравилась игруха.
Думаю, можно включить ее в шаблоны для будущих проектов.
Продолжение будет?


PS. Невольно вспомнилось время, когда на VB6 делал игру "Пятнашки", используя форму, кнопки, TextBox-ы и текстовые метки.

PSS. Я тут как-то добавил функцию
Code: [Select]
wGUIObjectIsMouseOver, которая возвращает тру при наведении мышью на любой GUI-объект.
Потом понял, что это лишнее, так как у нас в enum-е событий гуя есть wGUI_ET_ELEMENT_HOVERED- как раз для этого. Наверное, надо функцию надо будет убрать.
Title: Re: Группа кнопок (GUI) на примере викторины
Post by: Alec - WS3D Developer on October 21, 2017, 06:34:02 PM
Привет. Спасибо.  :)

Продолжение - да, хочу сделать что-нибудь посерьёзнее. Может быть даже с выбором тем/категорий.
В шаблоны - да, может быть основой для проектов, особенно образовательных, да и просто развлечься.

На VB6 тоже кое-что делал, интересные времена были.  :)
Title: Re: Группа кнопок (GUI) на примере викторины
Post by: Marsha on November 14, 2017, 08:52:04 PM
Всем привет. Мне понравилось. Тоже один раз ошиблась при первом прохождении  :-\
С таким примером интересно поиграть. А что, если сделать фон GUI полупрозрачным, а на заднем фоне 3D-мир, где периодически что-то происходит. Проползает черепаха, идёт дождь. Ну и где-то на поляне фонарь, который загорается разным цветом после правильных и неправильных ответов.
Title: Re: Группа кнопок (GUI) на примере викторины
Post by: Alec - WS3D Developer on November 15, 2017, 06:19:59 PM
Quote
А что, если сделать фон GUI полупрозрачным, а на заднем фоне 3D-мир, где периодически что-то происходит. Проползает черепаха, идёт дождь. Ну и где-то на поляне фонарь, который загорается разным цветом после правильных и неправильных ответов.
Хорошие идеи. Думаю, будет лучше смотреться.