Этот урок научит работать со строками и кодами клавиш в среде Blitz. На сколько я знаю, в Blitz3D нет функции ввода текста с клавиатуры. Конечно, есть команда 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». Слева в списке категорий найдете таблицы ASCII и Scancodes. Функция WaitKey работает с таблицей ASCII.В нашу функцию после строки Flip добавляем код: k=WaitKey() Теперь программа будет останавливаться на этой строке и ждать нажатия на клавишу. Код нажатой клавиши сохранится в переменной k. Чтобы добавить нажатую клавишу к выводимой строке, допишем: s$= s$+Chr(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, создайте новый лист и наберите маленькую программку: 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 |
Эта программа выводит на экран код нажатой клавиши. После доработки наша функция выглядит так: 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 Полученную функцию можно подогнать под Вашу программу и использовать. Основной принцип я объяснил.
Источник: http://blitzetc.blitzmax.ru/index.php/ |