IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

2 страниц V  1 2 >  
Closed Topic Открыть новую тему 
> нажатие кнопок..., считывание нажатия в цикле без его ост.
сообщение
Сообщение #1


Гость






я хотел бы знать как в цикле фиксировать нажатие кнопки не останавливая при этом цикл ...
т.е. например в теле цикла х имзеняется по форуле x:=x+1; ... нажал что нада
а цикл всё идёт и ёдет ... но уже x:=x+2; ... вот так вот ...


за ответы заранее благодарен !
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Для какого компилятора? Если ТР (не под Windows) - то написанием своего обработчика прерывания 09Н
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






<< то написанием своего обработчика прерывания 09Н >>

а можно об этом поподробней ?...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Вот каркас (так как написание процедур обработки прерываний - достаточно опасная вещь, я не буду писать ничего кроме "каркаса" программы с коментариями ):
uses Dos, Crt;
var
 Int09Save : Pointer;
{$F+}
procedure KbdHandler; interrupt;
 begin
{Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу
и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается
"настоящее" прерывание 9Н}
 end;
{$F-}
begin
 GetIntVec($09,Int09Save); { Запоминание настоящего вектора прерывания }
 SetIntVec($09,Addr(KbdHandler)); { и подмена его своей процедурой обработки}

 {здесь расположен тот цикл, в течении которого нужно отслеживать нажатия на клавиши}

 SetIntVec($09,Int09Save); { Возврат настоящего вектора прерывания }
end.
P.S. А для чего это нужно, более конкретно можно описать? Возможно есть другой, более безопасный способ...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Цитата

procedure KbdHandler; interrupt;
begin
{Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу
и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается
"настоящее" прерывание 9Н}
end;


Дополню:
1) скэн-код и флаг нажатия-отпускания можно получить из порта $60 (как значение элемента псевдомассива Port, e. g. x := Port[$60]). Младшие 7 бит полученного значения будут разны скэн-коду, а старший 7-й бит равен 0, если клавиша нажата и 1 - если отпущена;
2) вызывать "настоящий" обработчик Int 9 не всегда имеет смысл - например, в том случае, когда мы сами хотим организовать буферизацию событий клавиатуры (в этом случае необходимо перед выходом из обработчика сбрасывать контроллер прерываний: Port[$20] := $20).

Цитата
P.S. А для чего это нужно, более конкретно можно описать? Возможно есть другой, более безопасный способ...

Да, это важно. Во многих случаях можно обойтись без подобных "махинаций" c IRQ1, используя, например, службы BIOS.


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


а зачем такие трудности? Может быть тело цикла выполняется за довольно малое время, и достаточно обойтись
If Keypressed then begin c:=ord(readkey); {выполняем что нужно} end;

смысл думаю ясен...
И цикл не останавливается и никаких TSR и никаких обработчиков.
Но это при условии, что тело цикла выполняется достаточно быстро... (то есть если он выполняется за час, то это не приемлимо smile.gif )


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 206
Пол: Мужской

Репутация: -  3  +


Зачастую этот вопрос возникает, когда важно знать не то, нажималась ли какая-то клавиша перед выполнением очередной итерации цикла, а то, нажата ли она именно сейчас, или нет. Например, это важно в играх. Кроме того, через Keypressed нельзя отследить Ctrl, Shift, Alt etc. Я раньше все хотел написать какую-нить игрушку на ТР, и всякий раз упирался в клавиатуру. В конце концов я таки написал свой корявый обработчик Int09... после чего уперся в другие проблемы. <_< ...и они меня обломали.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


Отсюда вывод: работать с прерываниями в паскале - фигня, юзайте асм, проблем будет меньше.


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Глупость. все разговоры о том, что в Паскале что-то хуже делать чем где-то еще упираются в неправилое проектирование программы.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


... или недостаточный уровень умений программинга на данном языке.


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






huh.gif

народ я то хотел змейку намутить ...
типа не прерывая цикл менять напрвление движения ...
я смотрю так это заморочки большие мож как то с другой стороны подойти к этому делу ?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






MuXa
А можешь привести пример того цикла, в течении которого надо изменять направление движения? Как он у тебя реализован?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Пионер
**

Группа: Пользователи
Сообщений: 81
Пол: Мужской
Реальное имя: Шурик

Репутация: -  0  +


MuXa , вот ! Делай так :
Код

if keypressed then begin
  key := readkey;
  if (key = #0) then key := readkey;
end;


А потом в зависимости от key изменяй координаты ...


--------------------
Двадцать пятый час в сутках может появиться всего лишь из-за небольшой ошибки в программе.
Чтобы не воспользоваться сумасшедшими возможностями, нужно быть идиотом.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Цитата
MuXa , вот ! Делай так :

Код 
Код

if keypressed then begin
 key := readkey;
 if (key = #0) then key := readkey;
end;



А потом в зависимости от key изменяй координаты ...


ВОТ ! ... это то что мне и было нужно ! спасибо !
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Бывалый
***

Группа: Пользователи
Сообщений: 234
Пол: Мужской
Реальное имя: AHTOH

Репутация: -  1  +


Цитата
так как написание процедур обработки прерываний - достаточно опасная вещ

А почему опасная ? :p2:


--------------------
Хочу в репу !

Cмотри,а то ведь получишь!
Админ.

Не получит - его фиг догонишь!
Админ №2.

P.S Вы еще третьего админа притащите сюда :D
ваш аффтар :D
Звали? :D (админ № не помню какой)

ха больше нифига не напишете
афтар

Уверен? (Moderator)
А еще можно ? (супмодер)
Хватит его мучать ! Избили уж... (админ)
Не хватит. я тоже напишу (тоже Админ)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






suriv
Малейшая ошибка - и вектор прерывания "засылается в космос" - то есть неведомо куда, результат может быть самым плачевным, вплоть до потери информации на харде... sad.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость







program MuXaZ_zmeika;
uses crt,graph;
label 1,2,3,4,5;
var
rx1,rx2,ry2,ry1,i,i1,i2,i3,i4,i5,i6,i7,gd,gm:integer;
st,st1,st2,st3:string;
sx:array[0..50] of integer;
sy:array[0..50] of integer;
key:char;
begin
rx1:=0;
rx2:=640;
ry1:=0;
ry2:=480;
writeln('BBeDuTe DJIuHHy 3Meu (1-50)');
readln(i7);
writeln('BBeDuTe DJIuHHy CKopPocTb 3Meu (1-32)');
readln(i6);
Gd:=Detect;
InitGraph(Gd, Gm, 'e:\bp\bgi');
If GraphResult <> grOk Then Halt(1);
i1:=20;
i2:=20;
for i:= 1 to 20 do
begin
 sx[i]:=1;
 sy[i]:=1;
end;

i:=0;
while i<240 do
begin
if keypressed then
begin
 key:=readkey;
 if key=#52 then i3:=1;
 if key=#50 then i3:=2;
 if key=#54 then i3:=3;
 if key=#56 then i3:=4;
 if (key=#43) or (key=#27) then i3:=9
end;

if i1>rx2 then i1:=rx1;
if i2>ry2 then i2:=ry1;
if i1<rx1 then i1:=rx2;
if i2<ry1 then i2:=ry2;

if i3=1 then i1:=i1-5;
if i3=2 then i2:=i2+5;
if i3=3 then i1:=i1+5;
if i3=4 then i2:=i2-5;
if i3=9 then goto 1;
delay(trunc(32000/i6));
setcolor(green);

line(i1,i2,i1+5,i2+5);
line(i1+5,i2,i1,i2+5);
i4:=i7+1;
while i4>1 do
begin
 sx[i4]:=sx[i4-1];
 sy[i4]:=sy[i4-1];
 i4:=i4-1;
end;
sx[1]:=i1;
sy[1]:=i2;
setcolor(black);
line(sx[i7+1],sy[i7+1],sx[i7+1]+5,sy[i7+1]+5);
line(sx[i7+1]+5,sy[i7+1],sx[i7+1],sy[i7+1]+5);
setcolor(white);
end;

1:outtextxy(20,460,'THE END');
readkey;
end.
вот я собССно чё намутил кому интересно ...
можно выбирать скорость длинну и граници поля ...

СПАСИБО всем за помшь !
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Oleg_Z, интересно, каким боком TSR относятся к "Змейке"?.. ;) :D (хотя TSR-"Змейка" - это забавно...)


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Цитата
Код

if keypressed then begin
key := readkey;
if (key = #0) then key := readkey;
end;

Расширенные коды BIOS всё же стоит обрабатывать отдельно от ASCII, в противном случае мы, например, получим дополнительное управление клавишами H, K, M, P (что, впрочем, можно рассматривать как "undocumented feature") smile.gif


if KeyPressed then
 case ReadKey of
 { обработка ASCII }
 ...
 #0:
   case ReadKey of
   { обработка расширенных кодов }
   ...
   end;    
 end;



--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гость






вот в догонку кому еще интересно ...
всё выглядит как нормальная змейка толко пака без собирания фруктов
и терь она сама в себя врезается и транспортикуется при врезании в стену ...
короче почти полноценная змея!

program MuXaZ_zmeika;
uses crt,graph;
label 1,2,3,4,5;
var
dl,dl1,start,xx,sp,yy,rx1,rx2,ry2,ry1,i,i1,i2,i3,i4,i5,i6,i7,gd,gm:integer;
st,st1,st2,st3:string;
sx:array[0..880] of integer;
sy:array[0..880] of integer;

key:char;
begin
rx1:=20;
rx2:=318;
ry1:=20;
ry2:=234;
writeln('BBeDuTe DJIuHHy 3Meu (1-50)');
readln(i7);
writeln('BBeDuTe DJIuHHy CKopPocTb 3Meu (1-32)');
readln(i6);
Gd:=Detect;
InitGraph(Gd, Gm, 'e:\bp\bgi');
If GraphResult <> grOk Then Halt(1);
setcolor(13);
SetTextStyle(2, HorizDir, 4);
outtextxy(490,450,'CDeJIaHo B Poccuu');
outtextxy(490,460,'BepboJII0K MuXauJI 812 rp.');
outtextxy(490,470,'yII MAu CePIIyXoB 2005');
SetTextStyle(12, HorizDir,1);
setcolor(12);
dl:=0;
sp:=0;
line(rx1-2,ry1-2,rx2+2,ry1-2);
line(rx1-2,ry1-2,rx1-2,ry2+2);
line(rx2+2,ry1-2,rx2+2,ry2+2);
line(rx1-2,ry2+2,rx2+2,ry2+2);

setcolor(green);

line(20,250,110,250);
line(20,265,20,250);
line(110,250,110,265);
line(110,265,20,265);

line(120,250,210,250);
line(120,265,120,250);
line(210,250,210,265);
line(210,265,120,265);

line(220,250,317,250);
line(317,250,317,265);
line(317,265,220,265);
line(220,265,220,250);

setcolor(yellow);
outtextxy(25,255,'XaBaJIo:');
outtextxy(125,255,'Pa3MeP:');
outtextxy(225,255,'CKOPOCTb:');

i:=7;
setcolor(8);
while i<=318 do
begin
i:=i+12;
line(i,20,i,234);
end;
i:=7;
setcolor(8);
while i<=233 do
begin
i:=i+12;
line(20,i,318,i);
end;

i1:=20;
i2:=20;
for i:= 1 to 50 do
begin
sx[i]:=1;
sy[i]:=1;
end;
randomize;
xx:=trunc((1590-random(1490))/5);
yy:=trunc((1170-random(1070))/5);
bar(xx,yy,xx+5,yy+5);
{knopki}
i:=0;
i3:=2;
readkey;
while i<240 do
begin
if keypressed then
begin
key:=readkey;
if key=#52 then i3:=1;
if key=#50 then i3:=2;
if key=#54 then begin  i3:=3; end;
if key=#56 then begin  i3:=4; end;
if (key=#43) or (key=#27) then i3:=9;
if key=#42 then i7:=i7+1;
if key=#47 then i6:=i6+1;
if key=#45 then i6:=i6-1;
end;


 {dvigenie}
if i3=1 then i1:=i1-12;
if i3=2 then i2:=i2+12;
if i3=3 then i1:=i1+12;
if i3=4 then i2:=i2-12;
if i3=9 then goto 1;

  {proverka udara}

for i:= 1 to i7 do
begin
if (i1=sx[i]) and (i2=sy[i]) then goto 1;
end;

  {zargranica}
if i1+10>rx2 then i1:=rx1;
if i2+10>ry2 then i2:=ry1;
if i1<rx1 then i1:=rx2-10;
if i2<ry1 then i2:=ry2-10;

 {skorost`}
if i6<>dl then begin
str(sp,st1);
setcolor(black);
outtextxy(300,255,st1);
str(i6,st1);
setcolor(11);
outtextxy(300,255,st1);
sp:=i6;
end;
if i6>0 then
delay(trunc(52000/i6)) else begin
i6:=1;
delay(trunc(52000/i6));
end;
setcolor(green);
{zmeya}
line(i1,i2,i1+10,i2);
line(i1+10,i2,i1+10,i2+10);
line(i1+10,i2+10,i1,i2+10);
line(i1,i2+10,i1,i2);
   {dlinna}
if i7<>dl then begin
str(dl,st1);
setcolor(black);
outtextxy(180,255,st1);
str(i7,st1);
setcolor(11);
outtextxy(180,255,st1);
dl:=i7;
end;

  {massiv zmei}
i4:=i7+1;
while i4>1 do
begin
sx[i4]:=sx[i4-1];
sy[i4]:=sy[i4-1];
i4:=i4-1;
end;
sx[1]:=i1;
sy[1]:=i2;
setcolor(black);
   {zatiranie zmei}
line(sx[i7+1],sy[i7+1],sx[i7+1]+10,sy[i7+1]);
line(sx[i7+1]+10,sy[i7+1],sx[i7+1]+10,sy[i7+1]+10);
line(sx[i7+1]+10,sy[i7+1]+10,sx[i7+1],sy[i7+1]+10);
line(sx[i7+1],sy[i7+1]+10,sx[i7+1],sy[i7+1]);
setcolor(green);

end;

1:outtextxy(20,460,'THE END');
readkey;
end.
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
Closed Topic Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.04.2024 22:50
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name