я хотел бы знать как в цикле фиксировать нажатие кнопки не останавливая при этом цикл ...
т.е. например в теле цикла х имзеняется по форуле x:=x+1; ... нажал что нада
а цикл всё идёт и ёдет ... но уже x:=x+2; ... вот так вот ...
за ответы заранее благодарен !
Для какого компилятора? Если ТР (не под Windows) - то написанием своего обработчика прерывания 09Н
<< то написанием своего обработчика прерывания 09Н >>
а можно об этом поподробней ?...
Вот каркас (так как написание процедур обработки прерываний - достаточно опасная вещь, я не буду писать ничего кроме "каркаса" программы с коментариями ):
uses Dos, Crt;P.S. А для чего это нужно, более конкретно можно описать? Возможно есть другой, более безопасный способ...
var
Int09Save : Pointer;
{$F+}
procedure KbdHandler; interrupt;
begin
{Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу
и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается
"настоящее" прерывание 9Н}
end;
{$F-}
begin
GetIntVec($09,Int09Save); { Запоминание настоящего вектора прерывания }
SetIntVec($09,Addr(KbdHandler)); { и подмена его своей процедурой обработки}
{здесь расположен тот цикл, в течении которого нужно отслеживать нажатия на клавиши}
SetIntVec($09,Int09Save); { Возврат настоящего вектора прерывания }
end.
procedure KbdHandler; interrupt;
begin
{Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу
и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается
"настоящее" прерывание 9Н}
end;
а зачем такие трудности? Может быть тело цикла выполняется за довольно малое время, и достаточно обойтись
If Keypressed then begin c:=ord(readkey); {выполняем что нужно} end;
Зачастую этот вопрос возникает, когда важно знать не то, нажималась ли какая-то клавиша перед выполнением очередной итерации цикла, а то, нажата ли она именно сейчас, или нет. Например, это важно в играх. Кроме того, через Keypressed нельзя отследить Ctrl, Shift, Alt etc. Я раньше все хотел написать какую-нить игрушку на ТР, и всякий раз упирался в клавиатуру. В конце концов я таки написал свой корявый обработчик Int09... после чего уперся в другие проблемы. <_< ...и они меня обломали.
Отсюда вывод: работать с прерываниями в паскале - фигня, юзайте асм, проблем будет меньше.
Глупость. все разговоры о том, что в Паскале что-то хуже делать чем где-то еще упираются в неправилое проектирование программы.
... или недостаточный уровень умений программинга на данном языке.
народ я то хотел змейку намутить ...
типа не прерывая цикл менять напрвление движения ...
я смотрю так это заморочки большие мож как то с другой стороны подойти к этому делу ?
MuXa
А можешь привести пример того цикла, в течении которого надо изменять направление движения? Как он у тебя реализован?
MuXa , вот ! Делай так :
suriv
Малейшая ошибка - и вектор прерывания "засылается в космос" - то есть неведомо куда, результат может быть самым плачевным, вплоть до потери информации на харде...
вот я собССно чё намутил кому интересно ...
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.
Oleg_Z, интересно, каким боком TSR относятся к "Змейке"?.. ;) :D (хотя TSR-"Змейка" - это забавно...)
if KeyPressed then
case ReadKey of
{ обработка ASCII }
...
#0:
case ReadKey of
{ обработка расширенных кодов }
...
end;
end;
вот в догонку кому еще интересно ...
всё выглядит как нормальная змейка толко пака без собирания фруктов
и терь она сама в себя врезается и транспортикуется при врезании в стену ...
короче почти полноценная змея!
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.
MuXa , если хочеш , то можеш посмотреть мой вариант змейки.
Вот тут :
http://forum.pascal.net.ru/index.php?showtopic=3681
Флейм пошёл жестокий...