Главная \
Уроки \
Урок -
4
\

Урок
по Blitz
3D . Ввод текста с клавиатуры в графическом режиме.
Этот урок научит работать со строками и кодами клавиш в
среде Blitz.
На сколько я знаю, в Blitz 3D нет функции ввода текста с
клавиатуры. Конечно, есть команда Input, но она некрасивая и
очень тугая. Я предлагаю сделать свою функцию ввода с
клавиатуры: красивую и с рамочкой. :)
Поставим задачу:
* В точке, где кликнули мышью, появляется окошечко для ввода
текста. После ввода текст отображается на экране.
Вот такая простая задача! Начнем с простого – с мыши и
окошка:
Назовем функцию ввода : My_Input()
; Устанавливаем
графический режим
Graphics3D 800,600,0,2
SetBuffer BackBuffer()
;
Устанавливаем шрифт, ибо красиво должно быть.
font=LoadFont("Times New Roman",20,0,1)
SetFont font
;Создаем
текстовую переменную, которую будем отображать на
экране
; Значок доллара указывает на то, что переменная
текстовая
Label$="Hello
World"
; Как
обычно <Пока не нажата клавиша Esc выполнять все до
оператора Wend>
While Not KeyHit(1)
; Очистка
экрана
Cls
;
Выставляем цвет текста
Color
255,255,255
; Выводим
на экран значение нашей переменной и просьбу нажать
на кнопку мыши
Text
20,20,"Click The Mouse Button On A Screen..."
Text 20,60,"Label = "+Label
; Если
нажата левая кнопка мыши, тогда…
If
MouseHit(1) Then
; Нашей
переменной Label присваиваем значение функции
my_input()
Label=my_input(Label$,MouseX(),MouseY(),150,40)
EndIf
; Обновить
содержимое экрана
Flip
Wend
End
Function my_input$(s$,x#,y#,dx#,dy#)
End Function
|
Можно запустить и увидеть на экране две
строчки текста. В первой написано «Жми мышью на экран»
(вольный перевод), а во второй «Hello World» - это значение
переменной Label.

При клике мышью пропадает значение
переменной (становится равной 0). Это потому, что функция
My_Input() пуста, а ее значение, соответственно, равно нулю.
Исправим это:
Как Вы уже заметили, у функции есть 5 входных параметров:
x#, y# - координаты верхнего левого угла
окошка;
dx#, dy# - ширина и высота окошка;
s$ - это значение по умолчанию, т.е. какой
текст уже будет введен при создании окошка.
Чтобы присвоить функции какое-либо значение, используется
команда Return. Впишем в тело функции
строку:
Function my_input$(s$,x#,y#,dx#,dy#)
Return s$
End Function
|
Теперь при клике на экран, значение
переменной не обнуляется.
Пора рисовать само окошко. Для этого впишем в тело функции
после строки Function my_input$(s$,x#,y#,dx#,dy#)
следующее:
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
view_text= s
Text x+dx/2,y+dy/2,view_text,1,1
Flip
Wend
|
Запускаем и кликаем в любое место экрана.
Там где мы был произведен клик, появляется окошко с текстом,
равным значению переменной Label. Окно не
исчезает до тех пор, пока не будет нажата клавиша
Enter (код 28).

Окошко работает нормально. Переходим к этапу
ввода текста с клавиатуры.
Для того, чтобы узнать какая клавиша была нажата, в Blitz
используются несколько функций. Нам подойдет функция
WaitKey(). Эта функция останавливает работу
программы до тех пор, пока не будет нажата клавиша, и
возвращает код этой клавиши.
ВНИМАНИЕ !!! Существует стандартная таблица
символов, в которой перечислены все символы и клавиши и их
коды (называется ASCII). В Blitz есть своя
такая таблица, но с другими кодами (Scancodes).
Важно не перепутать к какой таблице обращается функция.
Например: В таблице Blitz клавиша Esc имеет
код 1, а в стандартной таблице (ASCII)
клавиша Esc под кодом 27.
Обе таблицы можно найти нажав на иконку «Домик»
на панели управления среды Blitz. Затем нажимаем на ссылку «Command
Reference». Слева в списке категорий найдете
таблицs ASCII и Scancodes.
Функция WaitKey работает с таблицей
ASCII.
В нашу функцию после строки Flip добавляем
код:
Теперь программа будет останавливаться на
этой строке и ждать нажатия на клавишу. Код нажатой клавиши
сохранится в переменной k.
Чтобы добавить нажатую клавишу к выводимой строке, допишем:
Текст функции на данный момент:
Function
my_input$(s$,x#,y#,dx#,dy#)
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
view_text$=s
Text x+dx/2,y+dy/2,view_text,1,1
Flip
k=WaitKey()
s$=s$+Chr(k)
Wend
Return s$
End Function
|
Запускаем и проверяем. Любая нажатая клавиша
добавляется к нашей строке. Сразу заметьте, что при нажатии
на клавиши, не содержащие букв или цифр, к строке
добавляется какой-то квадратик. Дело в том, что, если к коду
не прикреплен символ, то программа рисует квадратик. Это
надо исправлять:
Посмотрев внимательно в таблицу кодов ASCII,
заметим, что коды букв, цифр и спецзнаков лежат в диапазоне
от 32 до 126.
Воспользуемся этим и поставим условие на добавление символа
к строке: Если код нажатой клавиши в диапазоне от 32
до 126, то …
Наша функция примет вид:
Function
my_input$(s$,x#,y#,dx#,dy#)
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
view_text$=s
Text x+dx/2,y+dy/2,view_text,1,1
Flip
k=WaitKey()
If (k>31)And(k<127) Then
s$=s$+Chr(k)
EndIf
Wend
Return s$
End Function
|
Вот теперь лишних квадратиков не появляется.
Теперь добавим возможность удалять символы из строки.
Используем тот же способ проверки кода клавиши. Клавиша
BackSpace имеет код 8. Для
работы над строками нам понадобятся три функции Left(),
Right(), Mid().
Left() – Возвращает указанное количество
символов, начиная с начала строки.
Right() – Возвращает указанное количество
символов, начиная с конца строки.
Mid() - Возвращает указанное количество
символов, начиная с указанного символа.
Примеры по использованию этих функций смотри в справке
Blitz.
Перед строкой Wend добавляем код:
If k=8 Then
s= Left(s,Len(s)-1)
EndIf
|
Запускаем, проверяем. При нажатии на клавишу
BackSpace, символы стираются с конца
строки. Нам не хватает курсора!!! Сейчас будет. Только
функция немного изменится. В качестве курсора будем
использовать знак « | ». Чтобы курсор не
становился частью строки, а только выводился на экран, я
заранее ввел переменную View_Text$.
Еще нам понадобится переменная Cur_Pos –
значение этой переменной будет содержать позицию курсора в
строке. Управление курсором осуществляется клавишами влево и
вправо, коды 31 и 30
соответственно.
СОВЕТ: Чтобы не искать код той или иной клавиши в таблице
ASCII, создайте новый лист и наберите
маленькую программку:
While Not KeyHit(1)
k=WaitKey()
Print k
Wend
|
Эта программа выводит на экран код нажатой
клавиши.
После доработки наша функция выглядит так:
Function my_input$(s$,x#,y#,dx#,dy#)
cur_pos%=Len(s)
view_text$=""
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
view_text=Left(s,cur_pos)
view_text=view_text+"|"
view_text=view_text+Right(s,Len(s)-cur_pos)
Text x+dx/2,y+dy/2,view_text,1,1
Flip
k=WaitKey()
If (k>31)And(k<127) Then
temp$=s
s$=Left(temp$,cur_pos)+Chr(k)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos+1
EndIf
If k=8 Then
If cur_pos<>0 Then
temp$=s$
s= Left(temp$,cur_pos-1)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos-1
EndIf
EndIf
If k=4 Then
If cur_pos<>Len(s) Then
temp$=s
s= Left(temp$,cur_pos)+Right(temp$,Len(temp$)-cur_pos-1)
EndIf
EndIf
If k=31 Then
cur_pos=cur_pos-1
If cur_pos<0 Then cur_pos=0
EndIf
If k=30 Then
cur_pos=cur_pos+1
If cur_pos>Len(s) Then cur_pos=Len(s)
EndIf
Wend
Return s$
End Function
|
Теперь Мы можем перемещать курсор по строке
и удалять символы перед и после курсора, как во всех
редакторах.
Перед дальнейшим улучшением нашей функции, оптимизируем уже
имеющийся код.
Заменим наши условия оператором Case:
Function my_input$(s$,x#,y#,dx#,dy#)
cur_pos%=Len(s)
view_text$=""
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
view_text=Left(s,cur_pos)
view_text=view_text+"|"
view_text=view_text+Right(s,Len(s)-cur_pos)
Text x+dx/2,y+dy/2,view_text,1,1
Flip
k=WaitKey()
Select True
Case (k>31)And(k<127)
temp$=s
s$=Left(temp$,cur_pos)+Chr(k)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos+1
Case k=8
If cur_pos<>0 Then
temp$=s$
s= Left(temp$,cur_pos-1)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos-1
EndIf
Case k=4
If cur_pos<>Len(s) Then
temp$=s
s= Left(temp$,cur_pos)+Right(temp$,Len(temp$)-cur_pos-1)
EndIf
Case k=31
cur_pos=cur_pos-1
If cur_pos<0 Then cur_pos=0
Case k=30
cur_pos=cur_pos+1
If cur_pos>Len(s) Then cur_pos=Len(s)
End Select
Wend
Return s$
End Function
|
Так намного красивее, а главное - быстрее. В
нашей программе разницу в скорости Вы не заметите, а в
огромных проектах или играх разница существенна.
Для удобства добавим обработку клавиш Home
и End, в начало или конец строки:
Case k=1
cur_pos=0
Case k=2
cur_pos=Len(s)
|
Надеюсь, что понятно, куда дописать эти
строки.
Остался только один Bug. И этот недостаток заключается в
том, что Строка в окошке может выходить за его пределы – это
не хорошо, но исправимо.
Воспользуемся командой ViewPort(), которая
ограничивает зону вывода на экран.
Добавив ограничение вывода на экран, получим окончательный
вариант функции.
Вот текст всей программы вместе с последними добавлениями:
Graphics3D 800,600,0,2
SetBuffer BackBuffer()
font=LoadFont("Times New Roman",20,0,1)
SetFont font
Label$="Hello World"
While Not KeyHit(1)
Cls
Color 255,255,255
Text 20,20,"Click The Mouse Button On A Screen..."
Text 20,60,"Label = "+Label
If MouseHit(1) Then Label=my_input(Label$,MouseX(),MouseY(),150,40)
Flip
Wend
End
Function my_input$(s$,x#,y#,dx#,dy#)
cur_pos%=Len(s)
view_text$=""
While Not KeyHit(28)
Cls
Color 200,200,200
Rect x,y,dx,dy,1
Color 0,0,0
Rect x+2,y+2,dx-4,dy-4,0
Viewport x+2,y+2,dx-4,dy-4
view_text=Left(s,cur_pos)
view_text=view_text+"|"
view_text=view_text+Right(s,Len(s)-cur_pos)
Text x+dx/2,y+dy/2,view_text,1,1
Flip
k=WaitKey()
Select True
Case (k>31)And(k<127)
temp$=s
s$=Left(temp$,cur_pos)+Chr(k)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos+1
Case k=8
If cur_pos<>0 Then
temp$=s$
s= Left(temp$,cur_pos-1)+Right(temp$,Len(temp$)-cur_pos)
cur_pos=cur_pos-1
EndIf
Case k=4
If cur_pos<>Len(s) Then
temp$=s
s= Left(temp$,cur_pos)+Right(temp$,Len(temp$)-cur_pos-1)
EndIf
Case k=31
cur_pos=cur_pos-1
If cur_pos<0 Then cur_pos=0
Case k=30
cur_pos=cur_pos+1
If cur_pos>Len(s) Then cur_pos=Len(s)
Case k=1
cur_pos=0
Case k=2
cur_pos=Len(s)
End Select
Wend
Viewport 0,0,GraphicsWidth(),GraphicsHeight()
Return s$
End Function
|
Полученную функцию можно подогнать под Вашу программу и
использовать. Основной принцип я объяснил.
Удачного кодинга!
<К оглавлению>
|