Помощь - Поиск - Пользователи - Календарь
Полная версия: Простенький PONG
Форум «Всё о Паскале» > Pascal, Object Pascal > Написание игр
ShpateL
Сабж... Сейчас пишу эту игру и столкнулся с такой проблемой: когда один игрок зажал клавишу, то другой не может переместить свою доску: комп на нажатие клавиши просто не реагирует. Одним словом, доски не могут двигаться одновременно. Как можно исправить эту ошибку? А, кстати, пишу я на одной сишной библиотеке, но ИМХО это дела не меняет. Вот фрагмент проги:

//W, S - клавиши первого игрока
//UP, DOWN - клавиши второго игрока
//y1, y2 - координаты первой и второй доски
//20, 480 - координаты границ


if (SgIsKeyDown('W')){
			y1-=3;
			if (y1<=20)
				y1=20;
		} else if (SgIsKeyDown('S')){
			y1+=3;
			if (y1>=480)
				y1=480;
		} else if (SgIsKeyDown(VK_UP)){
			y2-=3;
			if (y2<=20)
				y2=20;
		} else if (SgIsKeyDown(VK_DOWN)){
			y2+=3;
			if (y2>=480)
				y2=480;
		}

mamont001
Тебе прийдётся подключать дополнительные модули по клавиатуре,так-что поиск по форуму тебе в руки...
с помощью одногоцрт не обойтись sad.gif
Archon
else убери отовсюду.
Алена
Скан-коды в помощь...
Archon
Цитата
Тебе прийдётся подключать дополнительные модули по клавиатуре,так-что поиск по форуму тебе в руки...
с помощью одногоцрт не обойтись sad.gif
Да ну?

...
if keypressed then c := readkey;
if c = ... then ...
if c = ... then ...
...
c := #0;
...
Алена
Archon, правда?

uses crt;
var c: char;
begin
  repeat
    if keypressed then c := readkey;
    if c = 'a' then writeln('a');
    if c = 's' then writeln('s');

    if c = #27 then break;

    c := #0;
  until false;
end.
Запускаешь, жмешь A потом S (не отпуская A), а потом отпускаешь S ... Результат? Этого надо автору?
Archon
Блин, точно sad.gif. Значит модуль юзать...
ShpateL
Блин, все гениальное просто!!! Спасибо, просто убрал else! Долго с ебя ржал)))
Archon
Не ругайся smile.gif
TarasBer
Я в сях не силён, поэтому дам паскальный ответ, суть не меняется, я думаю.
В ситуациях, когда нажимается сразу много клавиш, я уже отказываюсь от чтения из клавиатурного буфера (редкей).
Я бы повесил на прерывание $09 процедуру с таким кодом:

procedure New09; interrupt;
var
  Key: byte;
begin
  Key := Port[$60];
  asm
    pushf
  end
  Old09;
  if Key = $E0 then
    WasK := WasK or 1
  else if (Key = $2A) and Odd(WasK) then
    WasK := 2
  else begin
    if Key < $80 then begin
      if Odd(WasK) then
        KeyState[Key shr 3 + 16] :=
          KeyState[Key shr 3 + 16] or (1 shl (Key and 7))
      else
        KeyState[Key shr 3] := KeyState[Key shr 3] or (1 shl (Key and 7));
    end else begin
      if Odd(WasK) then
        KeyState[Key shr 3] :=
          KeyState[Key shr 3] and not (1 shl (Key and 7))
      else
        KeyState[Key shr 3 - 16] :=
          KeyState[Key shr 3 - 16] and not (1 shl (Key and 7));
    end;
    WasK := 0;
  end;
end;


Пояснение:
Old09 - вызов стандартного обработчика прерывания.
WasK: byte;
KeyState: array [0 .. 31] of byte;
То есть это переменная из 128 битов. Каждой клавиши соответствует свой бит.
Система такая примерно - клавиши клавиатуры, начаиная с ескейпа, нумеруются слева направо сверху вниз. Нумерация с единицы. В общем, сами посмотрите, какой клавише какая цифра соответствует.
Вот из этого массива KeyState и надо вычленить бит с соответствующим номером:

function Pressed(Key: byte): boolean;
begin
  Pressed := Odd(KeyState[Key shr 3] shr (Key and 7));
end;


Изначально массиы KeyState следует заполнить нулями.

НО: у меня не вышло зафиксировать одновременное нажатие 3х буквенных клавиш (A, B и C). Подозреваю, что тут уже проблема физическая - клавиатура так спаяна.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.