Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > FAQ

FAQ Туториалы и часто задаваемые вопросы

Ответ
 
Опции темы
Старый 09.12.2007, 17:21   #1
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Сообщение Примеры элементов GUI

Решил поделиться своим меню. Материал написан скорее для новичков, тем более, что в свое время я искал такой материал с примерами, но не нашел.
http://www.boolean.name/archive/gadgets/gadjets.htm
Старался описать функции по максимуму, если есть вопросы - пишите.
В конце статьи есть пример для нетерпеливых. Он рассчитан на копипаст, потому без комментов.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Nex (10.04.2009)
Старый 11.01.2008, 22:27   #2
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Сорри, после переезда немогу отредактировать пост, добавляю аттач с уроком:
Вложения
Тип файла: zip gadgets.zip (31.1 Кб, 783 просмотров)
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Nex (10.04.2009)
Старый 11.01.2008, 22:35   #3
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

А для тех кому удобнее смотреть прямо в постах, скопирую сюда:
Интерактивные элементы интерфейса в примерах.

Этот материал не претендует на оригинальность и не гарантирует ознакомление с эталонами алгоритмов построения меню, а также правильного написания функций интерактивных элементов интерфейса. Все ниже написанное взято из моих исходников и было написано без использования специальной литературы.
Целью статьи является упрощение жизни начинающих блитцеров, ознакомление с готовыми функциями и как это работает . Ничто не мешает улучшить имеющиеся примеры и оптимизировать под свои потребности.
Итак, самый первый интерактивный элемент в приложениях - это кнопка (по крайней мере, у меня было так . Так же это самый простой элемент, возвращающий бинарное значение и использующийся в большинстве своем для моментальных действий, таких как перемещение по меню или применение параметров. Кнопка может быть как текстовой надписью, так и картинкой. Второе предпочтительнее, так как может иметь свой дизайн и требует меньше ресурсов. Однако для каждой кнопки в таком случае необходимо заготавливать свою картинку с названием. Оптимальным было бы генерировать картинки при загрузке меню, рендеря надписи на фоне картинки, но это по желанию. В моем случае такая подготовка не делалась, и на экран выводилась картинка кнопки, а поверх ее название.
Для начала нам понадобятся некоторые картинки:
Изображения
     
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Nex (10.04.2009)
Старый 11.01.2008, 22:37   #4
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

а так же глобальные переменные для меню:
Global opt_apply=0 ;эта группа переменных - ключи возвращающие состояние кнопок
Global save=0 ;«сохранить», «загрузить», «применить» для последующего перехода
Global load=0 ;к этим функциям.
Global exploration$=0 ;переменная для хранения текущей подсказки
Global help_delay=0 ;счетчик задержки перед появлением подсказки
Global maxhelp_delay=100 ;величина задержки
Const RIC1=220,GIC1=180,BIC1=120 ;color1 цветовая палитра интерфейса
Const RIC2=100,GIC2=100,BIC2=10 ;color2 в данном случае три оттенка:
Const RIC3=45,GIC3=35,BIC3=25 ;color3 текст, рамка,фон
Global TrackerImxSize=128 ;ширина выпадающего списка (нужно при использовании картинки)
Global TrackerImySize=32 ;высота списка
Global ButtonImxSize=128 ;ширина кнопки(в соответствии с шириной картинки)
Global ButtonImySize=32 ;высота кнопки(тое в соответствии)
Global CheckImSize=32 ;сторона чекбокса, используется квадратное изображение
;заранее считаем половины всех размеров
Global TrackerImxHalfSize=TrackerImxSize*.5
Global ButtonImxHalfSize=ButtonImxSize*.5
Global TrackerImyHalfSize=TrackerImySize*.5
Global ButtonImyHalfSize=ButtonImySize*.5
Global CheckImHalfSize=CheckImSize*.5
;кэш мыши, необходим для избавления от глюков и тормозов
Global Mouse_HitX=0 ;координаты последнего клика мыши
Global Mouse_HitY=0
Global Mouse_HitZ=0 ;то же для колесика
Global Mouse_HitZold=0
Global Mouse_Hit=0 ;была ли нажата ЛКМ (левая кнопка мыши)
Global Mouse_Hit2=0

;грузим шрифты
Global fnt1=LoadFont("Arial",18,True,True,False)
Global fnt2=LoadFont("Arial Black",18,0,0,False)
Global fnt3=LoadFont("Arial",32,True,0,False)

;картинки и путь к ним, изменить под ваши файлы
Global GLBUIpath$="..\ui\"
Global MenuButtonMPASS=LoadImage(GLBUIpath$+"buttpass.png ")
Global MenuButtonMON=LoadImage(GLBUIpath$+"button.png")
Global MenuButtonMPRESS=LoadImage(GLBUIpath$+"buttpress.p ng")
Global MenuCheckOFF=LoadImage(GLBUIpath$+"CheckOFF.png")
Global MenuCheckON=LoadImage(GLBUIpath$+"CheckON.png")

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

Последний раз редактировалось FrankH, 11.01.2008 в 22:46.
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:44   #5
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Кнопка
Сама функция:
; atx – положение центра элемента на экране (в окне, если хотите) по горизонтали
; аty – то же по вертикали
; name$ - имя элемента
; expl$ - содержимое всплывающей подсказки
; clr – флаг активности кнопка (активна/отключена)
; state – здесь для специальных кнопок, вызывающих подфункцию ("сохранить", "старт")

Function CrtMenuButton(atx,aty,name$,expl$,clr,state) ;button
tx=atx-ButtonImxHalfSize ;координаты габаритов элемента,
ty=aty-ButtonImyHalfSize ;левый верхний угол
i=0 ;состояние кнопки: нажата/отпущена
;если мышь наведена на кнопку и кнопка активна, тогда
If (Mouse_HitX>tx) And (Mouse_HitX<tx+ButtonImxSize) And (Mouse_HitY>ty) And (Mouse_HitY<ty+ButtonImySize) And clr Then
;если был ЛКМ, тогда показываем нажатую кнопку и применяем статус
If Mouse_Hit Then
DrawImage MenuButtonMPRESS, tx,ty,ty
i=1
If state=1 opt_apply=1 ;apply Options
If state=2 save =1 ;saving
If state=3 load=1 ;loading
Mouse_Hit=0
;
иначе показываем подсвеченную кнопку и запускаем счетчик задержки
;
если мышь не сдвинется, по окончании счета появится подсказка
Else
DrawImage MenuButtonMON, tx,ty
;если счетчик достиг предела, копируем подсказку в
;обрабатываемую переменную
If expl$<>0 And help_delay=maxhelp_delay Then exploration$=expl$
EndIf
;если мышь не наведена, рисуем простую, не подсвеченную кнопку
Else DrawImage MenuButtonMPASS, tx,ty
EndIf
SetFont fnt2
Color 100-100*clr,100-100*clr,100-100*clr
Text atx,aty,name$,1,1 ;подписываем кнопку

Return I ;результат возвращаемый функцией - нажата кнопка или нет
End Function

Этот элемент возвращает бинарный результат. Однако существуют кнопки ("сохранить", "применить"..), для которых необходимо сразу же вызывать определенную функцию, не относящуюся к построению меню. Для этого, при создании кнопки, мы укажем ее тип, и в случае нажатия будет установлен один из ключей (save, load, opt_apply).
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:48   #6
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Чекбокс
Теперь давайте вспомним еще один графический элемент интерфейса, возвращающий бинарное значение, - чекбокс (CheckBoxGadget в визуале). По сути чекбокс - это ни что иное как кнопка с фиксатором положений (какие можно встретить на ЭЛТ мониторах и телевизорах). Можно было бы использовать картинку кнопки для этого элемента, но дабы разнообразить интерфейс, я рендернул в максе лампочку, как на приборной панели:
Function CrtMenuCheck(atx,aty,name$,expl$,clr,state) ;check
tx=atx-CheckImHalfSize
ty=aty-CheckImHalfSize
;попадает ли курсор на чекбокс
If (Mouse_HitX>tx) And (Mouse_HitX<tx+CheckImSize) And (Mouse_HitY>ty) And (Mouse_HitY<ty+CheckImSize) And clr Then

;если ЛКМ то инвертируем состояние (state здесь используется как состояние вкл/выкл)и рисуем соотв. картинку
If state=0 Then DrawImage MenuCheckOFF,tx,ty Else If Mouse_Hit Then DrawImage MenuCheckOFF,tx,ty state=0 Mouse_Hit=0
If state=1 Then DrawImage MenuCheckON,tx,ty Else If Mouse_Hit Then DrawImage MenuCheckON,tx,ty state=1 Mouse_Hit=0

;если счетчик достиг предела - назначаем подсказку
If expl$<>0 And help_delay=maxhelp_delay Then exploration$=expl$
Else

;если не ЛКМ рисуем текущее состояние
If state=0 Then DrawImage MenuCheckOFF,tx,ty
If state=1 Then DrawImage MenuCheckON,tx,ty
EndIf

;имя чекбокса справа от него
SetFont fnt2
Color 100+150*clr,100+150*clr,100+150*clr
Text atx+CheckImHalfSize,aty,name$,0,1

;возвращаем состояние
Return state
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:50   #7
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Система кнопок
Чекбокс удобно использовать в опциях с двумя вариантами, например, для включения антиалайзинга, звука, спецэффектов или теней. Если же необходимо выбрать разрешение экрана, уровень деталей, сложность, мод или что-либо, имеющее более двух вариантов ответа, необходимо пользоваться другим методом. Первый из них основан на уже описанных выше элементах, и является системой кнопок, объединенных таким образом, что при нажатии на одну из них - она фиксируется во включенном положении, в то время как остальные - отключаются (RadioButtonGadget).
Сам код:

;этот радиобаттн всего на три кнопки, если хотите сделать больше, ;необходимо добавить соответствующих элементов и параметров
Function CrtMenuTracker(atx1,aty1,atx2,aty2,atx3,aty3,name1 $,name2$,name3$,typ,clr,state)
tx1=atx1-TrackerImxHalfSize ;вычисляем положение для каждой картинки отдельно
ty1=aty1-TrackerImyHalfSize ;предполагая что они могут быть разными по размеру
tx2=atx2-TrackerImxHalfSize ;в нашем случае картинка одна
ty2=aty2-TrackerImyHalfSize
tx3=atx3-TrackerImxHalfSize
ty3=aty3-TrackerImyHalfSize

;наведена ли мыщь и имеет ли место ЛКМ, соответственно рисуем картинку и меняем статус
If ((Mouse_HitX>tx1) And (Mouse_HitX<tx1+TrackerImxSize) And (Mouse_HitY>ty1) And (Mouse_HitY<ty1+TrackerImySize) And clr) Then
If Mouse_Hit Then DrawImage MenuButtonMPRESS, tx1,ty1 state=1 Mouse_Hit=0 Else DrawImage MenuButtonMON, tx1,ty1
Else DrawImage MenuButtonMPASS, tx1,ty1
EndIf
;то же для двух других кнопок
If ((Mouse_HitX>tx2) And (Mouse_HitX<tx2+TrackerImxSize) And (Mouse_HitY>ty2) And (Mouse_HitY<ty2+TrackerImySize) And clr) Then
If Mouse_Hit Then DrawImage MenuButtonMPRESS, tx2,ty2 state=2 Mouse_Hit=0 Else DrawImage MenuButtonMON, tx2,ty2
Else DrawImage MenuButtonMPASS, tx2,ty2
EndIf

If ((Mouse_HitX>tx3) And (Mouse_HitX<tx3+TrackerImxSize) And (Mouse_HitY>ty3) And (Mouse_HitY<ty3+TrackerImySize) And clr) Then
If Mouse_Hit Then DrawImage MenuButtonMPRESS, tx3,ty3 state=3 Mouse_Hit=0 Else DrawImage MenuButtonMON, tx3,ty3
Else DrawImage MenuButtonMPASS, tx3,ty3
EndIf

;если мышь вне кнопок, в зависимости от текущего состояния рисуем картинку активной кнопки
If (state=1) Then DrawImage MenuButtonMPRESS, tx1,ty1
If (state=2) Then DrawImage MenuButtonMPRESS, tx2,ty2
If (state=3) Then DrawImage MenuButtonMPRESS, tx3,ty3

;подписываем
SetFont fnt2
Color 100-100*clr,100-100*clr,100-100*clr
Text atx1,aty1,name1$,1,1
Color 100-100*clr,100-100*clr,100-100*clr
Text atx2,aty2,name2$,1,1
Color 100-100*clr,100-100*clr,100-100*clr
Text atx3,aty3,name3$,1,1

;возвращаем текущее состояние
Return state
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:55   #8
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Выпадающий свиток
Визуально такой элемент является удобным и информативным, однако есть ситуации, где необходимо сделать выбор из десятка и более предложений. Вы, наверное, представили себе заполненный кнопками экран... Конечно, такой метод не годится для большого списка вариантов ответов. Для этих целей было бы неплохо создать динамический элемент, показывающий весь список ответов только при необходимости. Напишем свиток, а для него введем еще переменную:
Global svit1=0 Она будет отвечать за состояние этого (и только) свитка. Если у вас два свитка в меню, добавьте еще одну переменную. Приступим к созданию выпадающего свитка:
Function TrackerShort5_1(atx,aty,sizx,sizy,name1$,name2$,na me3$,name4$,name5$,expl$,typ,clr,state) ;switcher x5
If state=1 name$=name1$ ;этот выпадающий список рассчитан на максимум пять вариантов
If state=2 name$=name2$ ;в случае, если вам необходимо больше, добавьте переменных
If state=3 name$=name3$ ;name6$, name7$ и т.д. везде, где присутствуют name1$ - name5$.
If state=4 name$=name4$ ;если же вы будете использовать меньше максимума - 4, просто при вызове
If state=5 name$=name5$ ;функции вместо названия для name5$ укажите ноль
;если typ=1 то рисуем кнопку, она будет рамкой для списка
If typ DrawImage MenuButtonMPASS, atx-5,aty-5

;проверяем переменные начиная с конца, если находим ноль - уменьшаем список
If name5$ Then d=5 Else If name4$ Then d=4 Else If name3$ Then d=3 Else If name2$ Then d=2 Else If name1$ Then d=1 Else d=0

;проверяем наведена ли мышь на основное поле свитка
If ((Mouse_HitX>atx) And (Mouse_HitX<atx+sizx) And (Mouse_HitY>aty) And (Mouse_HitY<aty+sizy) And clr) Then
If Mouse_Hit Then ;если да и ЛКМ - ставим ключ что свиток развернут
svit1=1
Mouse_Hit=0
Else ;если да но нет ЛКМ, рисуем нажатую кнопку и проверяем счетчик подсказки
If typ DrawImage MenuButtonMON, atx-5,aty-5
If expl$<>0 And help_delay=maxhelp_delay Then exploration$=expl$
EndIf
Else ;иначе если клик вне списка - сворачиваем его
If Mouse_Hit And ((Mouse_HitX<atx) Or (Mouse_HitX>atx+sizx) Or (Mouse_HitY<aty) Or (Mouse_HitY>aty+sizy*(d+1))) Then svit1=0
EndIf
Color 100-100*clr,100-100*clr,100-100*clr ;пишем в основном поле имя активного элемента списка
Text atx+sizx*.5,aty+sizy*.5,name$,1,1
If svit1 ;если свиток развернут, рисуем фон для списка
Color 0,0,0
Rect atx,aty+sizy,sizx,sizy*d,1
Color RIC1,GIC1,BIC1
Rect atx,aty,sizx,sizy*(d+1),0
;подсвечиваем элемент списка что сейчас под курсором мышки
For i=1 To d
If (Mouse_HitX>atx) And (Mouse_HitX<atx+sizx) And (Mouse_HitY>aty+sizy*i) And (Mouse_HitY<aty+sizy*(i+1)) Then
Color RIC3,GIC3,BIC3
Rect atx+1,aty+1+sizy*i,sizx-2,sizy-2,1
If Mouse_Hit Then state=(Mouse_HitY-aty)/sizy svit1=0 ;если ЛКМ, получаем номер выбранного элемента
EndIf
Next

;теперь выводим имена элементов в списке
Color RIC1,GIC1,BIC1
t=atx+sizx*.5
If d>0 Text t,aty+sizy*1+sizy*.5,name1$,1,1
If d>1 Text t,aty+sizy*2+sizy*.5,name2$,1,1
If d>2 Text t,aty+sizy*3+sizy*.5,name3$,1,1
If d>3 Text t,aty+sizy*4+sizy*.5,name4$,1,1
If d>4 Text t,aty+sizy*5+sizy*.5,name5$,1,1

EndIf
Return state
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:57   #9
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Цифры
Все ранее описанное является большей частью основы графического интерфейса. Эти элементы используются практически во всех играх и приложениях, и прекрасно ведут себя с небольшим количеством (от одного до десятков), как правило, заранее определенных значений. Однако этого не достаточно, когда необходимо изменить уровень чего-то (звук, гамма, цвет чего-либо..) или выбрать какое-либо числовое значение в гораздо больших пределах (количество очков, время за раунд, число респаунов или патронов). Для этого я написал простейший числовой счетчик с индикацией. Он не предоставляет возможности вводить свое значение, но зажав на нем ЛКМ, вы можете прокручивать значение. Так же такой счетчик не сложно изменить под графическое отображение "конька". Для следующих примеров я использовал еще две переменные:
Global GWeit=800
Global GHeit=600

В моем случае они хранили разрешение экрана и использовались для определения положения графических элементов, и возвращения размера вьюпорта во весь экран:
;param - текущее значение в счетчике
;value - максимальное значение счетчика, счет идет с нуля
Function CrtMenuRott(atx,aty,name$,expl$,typ,clr,param,valu e) ;rott slider 0~value
tx=atx-CheckImHalfSize ;определение координат рабочей области, картинка не используется
ty=aty-CheckImHalfSize
newparam=param
Color RIC3,GIC3,BIC3
ClsColor RIC3,GIC3,BIC3
Rect atx-20,aty-10,40,20,1 ;рисуем прямоугольник рабочей области
Color RIC1,GIC1,BIC1
;проверка наведен ли курсор
If ((Mouse_HitX>tx) And (Mouse_HitX<tx+CheckImSize) And (Mouse_HitY>ty) And (Mouse_HitY<ty+CheckImSize) And clr) Then
tempx=MouseX() ;создаем временный кеш2 для мыши
tempy=MouseY()
Viewport atx-20, aty-10, 40, 20 ;переключаемся на отображение только рабочей области
While (MouseDown(1)) ;пока нажата мышь, меняем значение счетчика на дельту кеш-кеш2
Cls
If (param>=0 And param<=value) Then
newparam=param+(MouseX()-tempx)-(MouseY()-tempy)
If newparam>value newparam=value
If newparam<0 newparam=0
EndIf
Text atx,aty,newparam,1,1

Flip
Wend
Mouse_Hit=0 ;обнуляем переменные, возвращаем вьюпорт на место, проверяем счетчик подсказки
Viewport 0, 0, GWeit, GHeit
If expl$<>0 And help_delay=maxhelp_delay Then exploration$=expl$
EndIf

SetFont fnt2 ;прописываем параметр и его имя сверху, возвращаем результат
Text atx,aty,newparam,1,1
Color 100+150*clr,100+150*clr,100+150*clr
Text atx,aty-16,name$,1,1
Return newparam
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 22:59   #10
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Ввод
Итак, у нас есть основные элементы выбора готовых значений и цифр, однако нам еще кое-чего не хватает. Если вы вдруг захотите, чтобы игрок мог ввести свое имя перед игрой, указать IP адрес сервера или же назвать файл своего сохранения, вам понадобится функция, обеспечивающая ввод символов прямо с клавиатуры. Ниже приведен пример простенького, но все же рабочего элемента с полем ввода символов:
;функция ввода до max символов с начальным значением word$ Function CrtMenuInput$(atx,aty,name$,expl$,typ,clr,word$,ma x) ;Input Len=20
SetFont fnt2 ;устанавливаем шрифт

half_letter=5 ;реальная ширина одной буквы используемого шрифта в пикселях,
Input_size=max*half_letter ;для расчета ширины поля
newword$=word$
num=Len(word$)+1 ;узнаем количество символов в текущем слове (числовом значении)
savename=CreateBank(max+5) ;создаем банк памяти для динамической работы с
newsymbol=32 ;определенным количеством значений и временный символ
Color RIC3,GIC3,BIC3
ClsColor RIC3,GIC3,BIC3
Rect atx-Input_size,aty-10,Input_size*2,20,1 ;определяем область ввода и рисуем фон для текста
Color RIC1,GIC1,BIC1
TC=0 ;переменная для смена цвета текста во время ввода
For i=1 To num ;заносим текущее слово в банк для работы с ним
k$=Mid$(newword$,i,1)
PokeByte savename,i, Asc(k$)
Next
For i=num To max ;заполняем оставшуюся длину пробелами
PokeByte savename,i, 32
Next
Text atx,aty,newword$,1,1 ;вывод текущего слова на экран


If ((Mouse_HitX>atx-Input_size) And (Mouse_HitX<atx+Input_size) And (Mouse_HitY>aty-10) And (Mouse_HitY<aty+10) And clr) Then ;проверяем наведен ли курсор на рабочую область

TC=70 ;если да, изменяем цвет текста


If (Mouse_Hit) ;если ЛКМ, обнуляем буффер клавы и мыши,
Mouse_Hit=0 ;переводим вьюпорт на рабочую область
Flip 0
FlushKeys()
Viewport atx-Input_size, aty-10, Input_size*2, 20
While Not KeyHit(2 ;пока не нажали ввод
Cls

newsymbol=WaitKey() ;ждем ввода символа и
If (newsymbol= Then ;если нажат BACKSPACE то
If num>1 Then ;если символы еще есть
num=num-1 ;уменьшаем их количество
PokeByte savename,num,32 ;меняем символ в конце слова на пробел
EndIf
Else
If (newsymbol=27) Then ;если нажат ESCAPE то выходим из функции возвращая
newword$=word$ ;первоначальное слово
Text atx,aty,newword$,1,1
Viewport 0, 0, GWeit, GHeit ;возвращаем вьюпорт на весь экран
FreeBank savename
Return word$
EndIf
If (newsymbol>31) And (newsymbol<127) And (num<max+1) Then ;если нажат допустимый
PokeByte savename,num,newsymbol ;символ и есть куда писать, добавляем его к слову
num=num+1
EndIf
EndIf
newword$ = "" ;обнуляем временное слово
For j=1 To max ;и заполняем символами из банка интерпретируя коды
newword$ = newword$+Chr(PeekByte (savename,j))
Next

Text atx,aty,newword$,1,1 ;выводим результат

Flip 0

Wend
Viewport 0, 0, GWeit, GHeit ;возвращаем вьюпорт на весь экран
EndIf
If expl$<>0 And help_delay=maxhelp_delay Then exploration$=expl$ ;проверяем счетчик подсказки
EndIf

Color RIC1+TC,GIC1+TC,BIC1+TC*.5
Text atx,aty,newword$,1,1 ;выводим в рабочую область слово

newword$=Trim$(newword$) ;обрезаем пробелы в конце слова
FreeBank savename ;освобождаем банк
Return newword$ ;возвращаем результат
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 23:01   #11
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

На этом пожалуй все, хотя нет, я упоминаю в каждом куске кода о подсказке при наведении мыши на элемент. Для его работы необходимо в функцию меню (там где используете графические элементы) добавить следующие строчки (в начало):
If MouseHit(1) Mouse_Hit=1
OMouse_HitX=Mouse_HitX
OMouse_HitY=Mouse_HitY
Mouse_HitX=MouseX()
Mouse_HitY=MouseY()
If (OMouse_HitX=Mouse_HitX And OMouse_HitY=Mouse_HitY) Then
If help_delay<maxhelp_delay Then
help_delay=help_delay+1
EndIf
Else
help_delay=0
exploration$=0
EndIf


А после вызова всех элементов:
If exploration$<>0 ShowHelp(Mouse_HitX,Mouse_HitY,exploration$)
И сама функция с расчетом положения относительно краев экрана:
Function ShowHelp(x,y,txt$)
lt=ch_size*Len(txt$)/2
;просчитываем, какую область покажет подсказка
ltt=lt*.5
Color RIC3,GIC3,BIC3
If x>GWeit-ltt Then xt=x-lt Else If x<ltt Then xt=x Else xt=x-ltt ;если выходит за экран,
If y<ch_size Then yt=y+ch_size+24 Else yt=y ;переносим в другое место
Rect xt,yt-ch_size,lt,ch_size,1
Color RIC2,GIC2,BIC2
Rect xt,yt-ch_size,lt,ch_size,0
Color RIC1,GIC1,BIC1
Text xt+ltt,yt-ch_size,txt$,1,0
End Function
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 23:03   #12
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Дополнения от АВТОМАТа:
1) Дам несколько комментариев к статье, которые помогут, на мой взгляд, упростить код:
If state=1 opt_apply=1 ;apply Options
If state=2 save =1 ;saving
If state=3 load=1 ;loading
Здесь, по моему мнению, использование Ифов (If … End If) можно заменить на более простой Select … Case:
Select state ; выбираем переменную state
Case 1 opt_apply=1 ; Если она равна 1, то ставим opt_apply = 1
Case 2 save =1 ; В случае, если она равна двум, то save = 1
Case 3 load=1 ; Если же 3, то load = 1
End select
2) Насчет координат элементов:
ИМХО, удобнее и привычнее было бы указывать кнопкам не координаты их середин, а координаты их левого верхнего угла: так делают во многих визуальных редакторах интерфейса (в Delphi, например) - это поможет нам избавиться от переменных:
Global TrackerImxHalfSize=TrackerImxSize*.5
Global ButtonImxHalfSize=ButtonImxSize*.5
Global TrackerImyHalfSize=TrackerImySize*.5
Global ButtonImyHalfSize=ButtonImySize*.5
Global CheckImHalfSize=CheckImSize*.5

Не нужно будет вычислять левый край элемента (он у нас будет непосредственно передаваться в функцию), на примере кнопки:
tx=atx-ButtonImxHalfSize ;координаты габаритов элемента,
ty=aty-ButtonImyHalfSize ;левый верхний угол

и при проверке - наведен ли курсор на кнопку - вместо tx подставляем atx :
If (Mouse_HitX>atx) And (Mouse_HitX<atx+ButtonImxSize) And (Mouse_HitY>aty) And (Mouse_HitY<aty+ButtonImySize) And clr Then
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 23:05   #13
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

От автора:
Привожу эти комментарии как пример того, что вы можете писать и оформлять функции элементов, как вам будет удобно. Внесу однако некоторые пояснения насчет второго пункта. Экономия количества переменных и просчетов окупится только в случае, если элементы графического интерфейса привязаны, например, к окнам или панелям, не меняющимся в размере и не зависящим от разрешения экрана. В моем же случае я поступал именно так, пока не "полезли косяки" при смене разрешений. Для того, чтобы элементы не выходили за экран и не оставляли пустых мест при смене разрешения, пришлось разбить экран на виртуальную сетку координат и позиционировать все меню по ней, располагая центры элементов по пересечениям сетки. Так, например, ряд кнопок при смене разрешения будет равномерно сжиматься или вытягиваться, а так же можно легко установить элемент по центру экрана или любой панели, нарисованной по той же сетке.
И в конце приведу вам исходник (не рабочую версию игры, а часть ее интерфейса), как пример использования элементов без картинок. Просто скопируйте код в Блитц и запускайте:
Global GWeit=200
Global GHeit=200
Global life,have_pitomec,want_noeat,want_sleep,want_play
Global Mouse_HitX=0
Global Mouse_HitY=0
Global Mouse_Hit=0
Global G_Menu=0
Global G_Exit=0
Global xq=GWeit/20
Global yq=GHeit/20
Global ch_size1=11
Global ch_size2=16
Global ch_size3=20
Global ch_size=ch_size1
Global RIC=160:Global GIC=170:Global BIC=255
Global RIC1=45:Global GIC1=45:Global BIC1=85
life=100:have_pitomec=0:want_noeat=10:want_sleep=5 0:want_play=20

Global opt_apply=1
;apply Options
Global opt_reset=1 ;reset changes in options

Global Winstate=1
Global help_delay=0
Global maxhelp_delay=60
Global exploration$=0

Global svit1=0:Global svit2=0:Global svit3=0:Global svit4=0:Global svit5=0:Global svit6=0:Global svit7=0:

Global guizone=0

Graphics3D GWeit,GHeit,32,2
Global fnt=LoadFont("Arial",ch_size,1,0,0)
SetFont fnt
While (Not (G_Exit))
Cls

UpdateWorld

RenderWorld
If Not(have_pitomec) Then mainmenu()

Color RIC,GIC,BIC
Text 6,45,"TRIS: "+TrisRendered()+have_pitomec
Rect 3,38,GWeit-6,GHeit-yq*2-38,0
gui()

Flip 0
Wend

End

Function gui()

Color RIC,GIC,BIC
Text GWeit*.5,GHeit-yq*3,"FREEMEN studio ©",1,1
If MouseHit(1) Mouse_Hit=1
OMouse_HitX=Mouse_HitX
OMouse_HitY=Mouse_HitY
Mouse_HitX=MouseX()
Mouse_HitY=MouseY()
If (OMouse_HitX=Mouse_HitX And OMouse_HitY=Mouse_HitY) Then
If help_delay<maxhelp_delay Then
help_delay=help_delay+1
EndIf
Else
help_delay=0
exploration$=0
EndIf

If guizone = 0 Then
guizone=guizone+button(xq*1,yq*18.5,xq*3,yq,"еда", 0,1,0,"накормите питомца")*1+button(xq*5,yq*18.5,xq*3,yq,"игра",0,0 ,0,0)*2+button(xq*9,yq*18.5,xq*3,yq,"аптека",0,0,0 ,0)*3
If button(xq*16,yq*18.5,xq*3,yq,"меню",0,1,0,"выйти в главное меню") mainmenu()
EndIf

If guizone = 1 Then
If button(xq*1,yq*18.5,xq*3,yq,"молоко",0,1,0,"придае т сил и уверенности") And (want_sleep<90) Then want_noeat=want_noeat+7 want_sleep=want_sleep+3 want_play=want_play+15 life=life+10
If button(xq*5,yq*18.5,xq*3,yq,"мясо",0,1,0,"самая сытная еда") And (want_sleep<70) Then want_noeat=want_noeat+20 want_sleep=want_sleep+28 want_play=want_play-8 life=life+4
If button(xq*9,yq*18.5,xq*3,yq,"рыба",0,1,0,"любимое всеми кошками") And (want_sleep<90) Then want_noeat=want_noeat+15 want_sleep=want_sleep+18 want_play=want_play+4 life=life+1
If button(xq*16,yq*18.5,xq*3,yq,"назад",0,1,0,"вернут ься") guizone=0
If want_noeat>100 want_sleep=want_sleep+18 want_play=want_play-2*(want_noeat-100) life=life-(want_noeat-100) want_noeat=100
If want_sleep>100 want_play=0 want_sleep=100
If want_play>100 want_play=100
If life>100 want_play=want_play+life-100 life=100
EndIf

ShowLine()
If exploration$<>0 ShowHelp(Mouse_HitX,Mouse_HitY,exploration$)
Flip

If (Mouse_HitX<>MouseX() Or Mouse_HitY<>MouseY()) Then Mouse_Hit=0 FlushMouse
End Function
Function ShowHelp(x,y,txt$)
lt=ch_size*Len(txt$)/2
ltt=lt*.5
Color RIC1,GIC1,BIC1
If x>GWeit-ltt Then xt=x-lt Else If x<ltt Then xt=x Else xt=x-ltt
If y<ch_size Then yt=y+ch_size+24 Else yt=y
Rect xt,yt-ch_size,lt,ch_size,1
Color 230,200,100
Text xt+ltt,yt-ch_size,txt$,1,0
End Function
Function ShowLine()
Color 220,10,10
Rect 20,4,(GWeit-26)*.01*life,6
Color 220,120,10
Rect 20,12,(GWeit-26)*.01*want_noeat,6
Color 10,160,10
Rect 20,20,(GWeit-26)*.01*want_play,6
Color 30,30,250
Rect 20,28,(GWeit-26)*.01*want_sleep,6
If Mouse_HitY<11 And help_delay=maxhelp_delay Then
exploration$="pet's life"
Else
If Mouse_HitY<20 And help_delay=maxhelp_delay Then
exploration$="pet's satiety"
Else
If Mouse_HitY<29 And help_delay=maxhelp_delay Then
exploration$="pet's joy"
Else
If Mouse_HitY<36 And help_delay=maxhelp_delay Then
exploration$="pet's desire to sleep"
EndIf
EndIf
EndIf
EndIf


End Function
Function mainmenu()
G_Menu=1
FlushMouse
Mouse_Hit=0
menuzone = 2


While (G_Menu)
RenderWorld
Color RIC,GIC,BIC
Rect 3,3,GWeit-6,GHeit-yq*2-3,0
Text GWeit*.5,GHeit-yq*3,"FREEMEN studio ©",1,1
If MouseHit(1) Mouse_Hit=1
OMouse_HitX=Mouse_HitX
OMouse_HitY=Mouse_HitY
Mouse_HitX=MouseX()
Mouse_HitY=MouseY()
If (OMouse_HitX=Mouse_HitX And OMouse_HitY=Mouse_HitY) Then
If help_delay<maxhelp_delay Then
help_delay=help_delay+1
EndIf
Else
help_delay=0
exploration$=0
EndIf

If menuzone = 2 Then
menuzone=menuzone+button(xq*5,yq*18.5,xq*3,yq,"opt ion",0,1,0,"опции")*1+button(xq*9,yq*18.5,xq*3,yq, "back",0,have_pitomec,0,"назад")*-1+button(xq*16,yq*18.5,xq*3,yq,"quit",0,1,0,"выход ")*-2
If button(xq*1,yq*18.5,xq*3,yq,"start",0,1,0,"начать игру") Then have_pitomec=1 G_Menu=0
EndIf
;options
If menuzone = 3 Then
menuzone=menuzone+button(xq*1,yq*18.5,xq*3,yq,"res et",0,0,2,0)*0+button(xq*5,yq*18.5,xq*3,yq,"accept ",0,1,1,"применить")*-1+button(xq*16,yq*18.5,xq*3,yq,"discard",0,1,0,"от мена")*-1
Winstate=TrackerShort5_1(xq,yq,xq*4,yq*2,"200x200" ,"300x300","400x400",0,0,0,1,Winstate)
EndIf

If menuzone = 4 Then
menuzone=menuzone+button(xq*1,yq*18.5,xq*3,yq,"sta rt",0,1,0,"начать игру")*0+button(xq*5,yq*18.5,xq*3,yq,"option",0,1, 0,"опции")*0
EndIf

If menuzone = 1 Then G_Menu=0
If menuzone = 0 Then G_Menu=0 G_Exit=1

If opt_apply
If Winstate=1 GWeit=200 GHeit=200
If Winstate=2 GWeit=300 GHeit=300
If Winstate=3 GWeit=400 GHeit=400
FreeFont fnt
xq=GWeit/20:yq=GHeit/20
Graphics3D GWeit,GHeit,32,2
If Winstate=1 ch_size=ch_size1
If Winstate=2 ch_size=ch_size2
If Winstate=3 ch_size=ch_size3
fnt=LoadFont("Arial",ch_size,1,0,0)
SetFont fnt
opt_apply=0
EndIf
If opt_reset
opt_reset=0
EndIf

If exploration$<>0 ShowHelp(Mouse_HitX,Mouse_HitY,exploration$)
Flip
ClsColor 0,0,0
Cls
If (Mouse_HitX<>MouseX() Or Mouse_HitY<>MouseY()) Then Mouse_Hit=0 FlushMouse
Wend
End Function
Function button(atx,aty,sizx,sizy,name$,typ,clr,state,expl$ )

i=0
Color 200,200,200
Rect atx-3,aty-3,sizx+6,sizy+6,0

If (Mouse_HitX>atx) And (Mouse_HitX<atx+sizx) And (Mouse_HitY>aty) And (Mouse_HitY<aty+sizy) And clr Then
If Mouse_Hit Then
Color RIC,GIC,BIC
Rect atx,aty,sizx,sizy,1
i=1
If state=1 opt_apply=1 ;apply Options
If state=2 opt_reset=1 ;apply changes in Edit
Mouse_Hit=0
Else
If expl$<>0 And help_delay=maxhelp_delay Then
exploration$=expl$
EndIf
Color 255,255,255
Rect atx,aty,sizx,sizy,1
EndIf
Else
Color RIC,GIC,BIC
Rect atx,aty,sizx,sizy,1
EndIf
Color 100-100*clr,100-100*clr,100+100*clr
Text atx+sizx*.5,aty+sizy*.5,name$,1,1
Return i

End Function

Function TrackerShort5_1(atx,aty,sizx,sizy,name1$,name2$,na me3$,name4$,name5$,typ,clr,state) ;switcher1 x5

If state=1 name$=name1$
If state=2 name$=name2$
If state=3 name$=name3$
If state=4 name$=name4$
If state=5 name$=name5$
If name5$ Then d=5 Else If name4$ Then d=4 Else If name3$ Then d=3 Else If name2$ Then d=2 Else If name1$ Then d=1 Else d=0
If ((Mouse_HitX>atx) And (Mouse_HitX<atx+sizx) And (Mouse_HitY>aty) And (Mouse_HitY<aty+sizy) And clr) Then
If Mouse_Hit Then
svit1=1
Else
Color RIC1,GIC1,BIC1
Rect atx+1,aty+1,sizx-2,sizy-2,1
EndIf
Else
If Mouse_Hit And ((Mouse_HitX<atx) Or (Mouse_HitX>atx+sizx) Or (Mouse_HitY<aty+sizy) Or (Mouse_HitY>aty+sizy*(d+1))) Then svit1=0 ;Color 0,0,0 Rect atx,aty,sizx,sizy,1
EndIf
Color RIC,GIC,BIC
Rect atx,aty,sizx,sizy,0
Text atx+sizx*.5,aty+sizy*.5,name$,1,1
;
If svit1
Color 0,0,0
Rect atx,aty+sizy,sizx,sizy*d,1
Color RIC,GIC,BIC
Rect atx,aty,sizx,sizy*(d+1),0

For i=1 To d
If (Mouse_HitX>atx) And (Mouse_HitX<atx+sizx) And (Mouse_HitY>aty+sizy*i) And (Mouse_HitY<aty+sizy*(i+1)) Then
Color RIC1,GIC1,BIC1
Rect atx+1,aty+1+sizy*i,sizx-2,sizy-2,1
If Mouse_Hit Then state=(Mouse_HitY-aty)/sizy svit1=0
EndIf
Next
Color RIC,GIC,BIC
t=atx+sizx*.5
If d>0 Text t,aty+sizy*1+sizy*.5,name1$,1,1
If d>1 Text t,aty+sizy*2+sizy*.5,name2$,1,1
If d>2 Text t,aty+sizy*3+sizy*.5,name3$,1,1
If d>3 Text t,aty+sizy*4+sizy*.5,name4$,1,1
If d>4 Text t,aty+sizy*5+sizy*.5,name5$,1,1

EndIf
Text 100,10,state+" "+(Mouse_HitY-aty)/sizy,1,1
Return state
End Function
В исходнике нет комментов, но построен он на тех же функциях, что описаны выше. Удачи!
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо FrankH за это полезное сообщение:
dimanche13 (11.01.2008), tormoz (11.01.2008)
Старый 11.01.2008, 23:07   #14
FrankH
Разработчик
 
Регистрация: 09.12.2007
Сообщений: 376
Написано 83 полезных сообщений
(для 122 пользователей)
Re: Примеры элементов GUI

Можете оставлять комменты и варианты оптимизации, вобщем все что поможет пользователю. Критику кривости кода можете написать в личку, а сюда по делу.

И напомню что во втором посте есть этот урок аттачем, в более наглядной форме.
(Offline)
 
Ответить с цитированием
Старый 11.01.2008, 23:11   #15
dimanche13
Мастер
 
Регистрация: 19.03.2007
Сообщений: 1,039
Написано 153 полезных сообщений
(для 252 пользователей)
Ответ: Примеры элементов GUI

Все не осилил, но определенно "в мемориз". То есть в журнал к Матвею.
__________________
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
примеры ии Sand Основной форум 11 20.12.2009 14:13
Перебор элементов типа в обратном порядке ELIAS Blitz3D 4 08.12.2009 22:31
Lib_line32 - Горизонтальная полоска элементов odd Библиотеки 7 29.09.2009 21:59
Не работают примеры !!! DRAG C++ 5 11.03.2007 00:51
Вывод названий элементов загруженной модели Chuma 3D-программирование 25 08.01.2007 03:56


Часовой пояс GMT +4, время: 08:51.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com