Понедельник, 25 Ноября 2024, 20:08

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
PascalABC Вопрос (события клавиш)
WhoAmIДата: Среда, 02 Января 2013, 14:51 | Сообщение # 1
Сумасшедший программист
Сейчас нет на сайте
Здравствуйте. Я на днях решил начать делать игры на паскале. Выучил язык, но тут я столкнулся с проблемой: как сделать событие нажатой клавиши?
Например если нажата клавиша 'w', то move:=move+32(это-то я понял biggrin ).
Модуль нужен какой, или что?(извиняюсь за глупые вопросы smile ).


Struggle #Gamiron12
DestroyДата: Среда, 02 Января 2013, 15:02 | Сообщение # 2
постоянный участник
Сейчас нет на сайте
попробуй что то типо того
Код

case chr(ord(Key)) of
   'W': move:=move+32;
   'S': ...
   'D': ...
   'A': ...

однако здесь большую роль играет шрифт, и раскладка клавиатуры, сам этот код в pascalABC не проверял, выполнил его в дельфи
ммм.. pascalABC не самый лучший выбор для написания игр, установи delphi.
karuyДата: Среда, 02 Января 2013, 15:07 | Сообщение # 3
заслуженный участник
Сейчас нет на сайте
Цитата (Destroy)
pascalABC не самый лучший выбор для написания игр, установи delphi.

Делфи тоже не самый лучшый))
WhoAmIДата: Среда, 02 Января 2013, 15:15 | Сообщение # 4
Сумасшедший программист
Сейчас нет на сайте
Destroy, я пишу простенькую игру - арканойд. И-то потом переведу на Free Pascal. Спасибо грамадное - работает.

Добавлено (02.01.2013, 15:09)
---------------------------------------------
Destroy, ещё - в паскале и делфи одинаковые языки(object pascal)

Добавлено (02.01.2013, 15:15)
---------------------------------------------
Destroy, эммм.. ord() есть только в паскале(помоему) поэтому жду ещё помощи. Но всё равно спасибо - вы меня на идею подтолкнули.


Struggle #Gamiron12
TimKruzДата: Среда, 02 Января 2013, 20:09 | Сообщение # 5
старожил
Сейчас нет на сайте
Цитата (WhoAmI)
ord() есть только в паскале

Ord есть в любом диалекте Паскаля. Возвращает код символа.
Цитата (Destroy)
попробуй что то типо того
Код
case chr(ord(Key)) of
       'W': move:=move+32;
       'S': ...
       'D': ...
       'A': ...

Во-первых, это бред, потому что chr(ord(key))=key, т.к. ord возвращает код символа, а chr возвращает символ по коду.
Во-вторых, ты в этом коде предлагаешь обработку уже имеющегося значения переменной key, но WhoAmI не знает, как его получить можно.
Цитата (Destroy)
сам этот код в pascalABC не проверял, выполнил его в дельфи

Ага, теперь понятно. Ты его вписал в обработчик события OnKeyPress формы, вот он и заработал. В PascalABC формы есть, но работа с ними другая.
Цитата (Destroy)
pascalABC не самый лучший выбор для написания игр, установи delphi.

Какая разница, если человек хочет именно на PascalABC игру писать. На нём тоже игры делать можно.
Цитата (karuy)
Делфи тоже не самый лучшый))

Эй, эй, чтобы определять, что что-то лучше чего-то, нужно определиться, по какому критерию мы их сравниваем. Критериев огромная куча, и сравнивать сразу по всем бессмысленно и бесполезно. Поэтому как Delphi, так и какой-либо диалект Паскаля может быть самым лучшим выбором для написания игр с какой-то определённой точки зрения. А если смотреть совсем со стороны и в общем смысле - то самого лучшего инструмента для разработки игр нет и никогда не будет.
Цитата (WhoAmI)
Destroy, ещё - в паскале и делфи одинаковые языки(object pascal)

Паскаль - это либо изначальный язык Pascal, либо обобщённое название всех диалектов. Object Pascal - вполне конкретный диалект Паскаля. Delphi - вообще отдельный язык программирования. Так что никакие это не одинаковые языки, хотя похожие места в них безусловно есть.
Цитата (WhoAmI)
как сделать событие нажатой клавиши?

Всё зависит от того, как ты делаешь игру. Есть несколько способов, например, через готовые классы окон. Сейчас установлю себе PascalABC, гляну и напишу здесь...

А вообще, посмотри проекты из папки "C:\PABCWork.NET\Samples\Games", если устанавливал PascalABC вместе с примерами. Там несколько игр, посмотришь, как они устроены, некоторые алгоритмы интересные есть...




Ага, вот, нашёл. Посмотри исходник KillThem.pas (если у тебя нет его - вот он), там как раз кнопочное управление устроено. Если в двух словах, то создаётся окно, событиям окна присваиваются пользовательские процедуры-обработчики (OnKeyDown := KeyDown; OnKeyPress := KeyPress; OnKeyUp := KeyUp; в основном коде программы), в самом конце запускается таймер для анимации. Например, вот обработчики событий клавиш из этого исходника:
Код
/// Обработчик нажатия клавиши
procedure KeyDown(Key: integer);
begin
    case Key of
vk_Left:  kLeftKey := True;
vk_Right: kRightKey := True;
vk_Space: if kSpaceKey=2 then kSpaceKey := 1;
    end;
end;

/// Обработчик отжатия клавиши
procedure KeyUp(Key: integer);
begin
    case Key of
vk_Left:  kLeftKey := False;
vk_Right: kRightKey := False;
vk_Space: kSpaceKey := 2;
    end;
end;

/// Обработчик нажатия символьной клавиши
procedure KeyPress(Key: char);
begin
    if (Key in ['G','П','g','п']) and EndOfGame then
    begin
      NewGame.Visible := False;
      EndOfGame := False;
      t.Start;
      CreateObjects;
      kSpaceKey := 2;
      kLeftKey := False;
      kRightKey := False;
    end;
end;

В первых двух процедурах аргумент Key - это число, соответствующее виртуальному коду клавиши (константа vk_key, где vk - virtual key, а key - собственно название клавиши), в третьем Key - символ. Ну и обрабатываются они кейсами и ифами, тут всё просто.

Если быть более точным, то обработчики нажатий/отжатий клавиш в играх обычно не напрямую обрабатывают их, а лишь устанавливают/сбрасывают соответствующие клавишам флаги (булевы переменные) или устанавливают число в переменной-переключателе (или счётчике). А вот эффект от этих действий проявляется в обработчике события таймера, чтобы синхронизировать все действия со временем. Т.е., например, флаг kLeftKey устанавливается сразу после нажатия клавиши "курсор влево", затем его проверяет специальная конструкция в процедуре таймера (здесь - TimerProc), потом пользователь отпускает эту кнопку и соответствующая процедура сбрасывает флаг kLeftKey, из-за чего производимые действия в процедуре таймера меняются должным образом. Точно так же - для каждой другой кнопки.

P.S. Не знаю, зачем они выделили отдельную процедуру для символьных клавиш, потому что у каждой символьной клавиши есть свой виртуальный код, независящий от раскладки клавиатуры и состояния спец-клавиш типа шифта...




Сообщение отредактировал TimKruz - Среда, 02 Января 2013, 21:03
DestroyДата: Среда, 02 Января 2013, 23:51 | Сообщение # 6
постоянный участник
Сейчас нет на сайте
Цитата (TimKruz)
это бред, потому что chr(ord(key))=key,

да не бред, просили же для клавиши 'W', а не стрелочек smile
WhoAmI,
пожалуйста)
TimKruzДата: Четверг, 03 Января 2013, 01:01 | Сообщение # 7
старожил
Сейчас нет на сайте
Цитата (Destroy)
да не бред, просили же для клавиши 'W', а не стрелочек

Код
case chr(ord(Key)) of

Ещё раз. Key - это символ char. Так? Так. Ord(c:char):byte в данном случае возвращает код символа. Так? Так. Chr(x:byte):char возвращает символ по коду символа. Так? Так. Значит, chr(ord(key)) возвращает key. Следовательно, нужно было писать case key of, а не делать какую-то многоуровневую конструкцию непонятно зачем.


DestroyДата: Четверг, 03 Января 2013, 01:36 | Сообщение # 8
постоянный участник
Сейчас нет на сайте
это понятно, однако вводится не стрелка же, а символ, проверь сам свой и мой вариант
где 1.
Код
case chr(ord(Key)) of

2.
Код
case Key of

будет несовместимость типов


Сообщение отредактировал Destroy - Четверг, 03 Января 2013, 01:38
TimKruzДата: Четверг, 03 Января 2013, 12:59 | Сообщение # 9
старожил
Сейчас нет на сайте
Цитата (Destroy)
будет несовместимость типов

Что ты глупости какие-то говоришь (или никак понять не могу, что ты хочешь сказать). Ты ведь используешь этот код так:
Код
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
   case Key of
   'w': showmessage('w');
   's': showmessage('s');
   end;
end;

А OnKeyPress реагирует на символьные клавиши.
Но для игр следует использовать OnKeyDown и OnKeyUp, которые в переменной Key дают виртуальный код клавиши, поэтому код нужно переписать так:
Код
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
   case Key of
   ord('W'): showmessage('кнопка [w]'); //именно ord('W'), а не ord('w')
   vk_right: showmessage('стрелка вправо');
   //vk_right стандартная константа, соответствующая виртуальному коду клавиши "курсор вправо"
   $41: showmessage('кнопка [a]');
   //$41 это то, что возвращает ord('A'), т.е. соответствует виртуальному коду кнопки [a/ф]
   end;
end;

При этом этот код не зависит от состояний клавиш Shift, Alt и Ctrl (состояния этих клавиш регистрируются в множестве Shift) и раскладки клавиатуры.
Лично я для удобства описал в отдельном модуле константы от VK_A до VK_Z (которых нет в стандартных модулях).




Сообщение отредактировал TimKruz - Четверг, 03 Января 2013, 13:00
DestroyДата: Четверг, 03 Января 2013, 13:44 | Сообщение # 10
постоянный участник
Сейчас нет на сайте
Цитата (TimKruz)
Что ты глупости какие-то говоришь

ладно мы тут походу не поняли друг друга, остановимся каждый на своем мнении и удобстве своего кода
WhoAmIДата: Понедельник, 07 Января 2013, 14:45 | Сообщение # 11
Сумасшедший программист
Сейчас нет на сайте
TimKruz, + - спс большое.

Добавлено (07.01.2013, 14:45)
---------------------------------------------
А вызвать OnKeyPress:=KeyUp и.т.д?


Struggle #Gamiron12
TimKruzДата: Понедельник, 07 Января 2013, 15:42 | Сообщение # 12
старожил
Сейчас нет на сайте
Цитата (WhoAmI)
А вызвать OnKeyPress:=KeyUp и.т.д?

Что-то я не понял, что ты хочешь спросить. wacko
Эта строчка (OnKeyPress:=KeyUp) присваивает процедурной переменной OnKeyPress идентификатор пользовательской процедуры KeyUp, после чего класс окна сможет корректно вызывать пользовательскую процедуру для обработки определённого события (нажатия клавиши).


WhoAmIДата: Вторник, 08 Января 2013, 12:33 | Сообщение # 13
Сумасшедший программист
Сейчас нет на сайте
Я об этрм :-) . Тему можно закрывать.

Struggle #Gamiron12
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг