[Pascal] graph, пишу игру, есть вопросы.

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
the Gray Maybe
Сообщения: 12
Зарегистрирован: 05 фев 2008, 20:35

есть несколько вопросов:
1. как сделать реакцию на нажатие клавиши? (тоесть не нажимать enter каждий раз после ввода "w")
2. посмотрите что у меня со скоростью, немогу придумать как чтоб скажем x овая скорасть при нажатии "a" если есть сначала уменьшалась, а потом увеличивалась?
вот код, так понятней будет в чем заковыка:

Код: Выделить всё

Program graph18;
uses graph,crt;
var gd,gm,b,c,vv,f,ly,lx,y,x:integer;
    key:string;
    ny,nx:byte;
begin
clrscr;
writeln('ўлЄ«озЁ puto switcher!');
writeln('гЇа ў«Ґ*ЁҐ - WASD');
writeln('ўл©вЁ - g');
readln;
gd:=detect;
initgraph(gd,gm,'E:\TP\UNITS');
 begin


x:=100;
y:=100;
ly:=y;
lx:=x;

repeat
c:=c+1;
readln(key);
setcolor(1);
begin
if key='w' then
 begin
  ly:=y;
  ny:=ny+5;
  y:=y-ny;
  clrscr;
 setbkcolor(7);

   for vv:=y to ly do
   begin
   setcolor(7);
    circle(x,ly,2);
    circle(x,ly,1);

   delay(0);
   setcolor(1);
   ly:=ly-1;
    circle(x,ly,2);
    circle(x,ly,1);


   end;
 end;


 if key='s' then
 begin
  ly:=y;
  ny:=ny+5;
  y:=y+ny;
  clrscr;

   for vv:=ly to y do
   begin
   setcolor(7);
   circle(x,ly,2);
    circle(x,ly,1);
   delay(0);
   setcolor(1);
   ly:=ly+1;
   circle(x,ly,2);
    circle(x,ly,1);
   end;
 end;

 if key='a' then
 begin
  lx:=x;
  nx:=nx+5;
  x:=x-nx;
  clrscr;

   for vv:=x to lx do
   begin
   setcolor(7);
   circle(lx,y,2);
    circle(lx,y,1);
   delay(0);
   setcolor(1);
   lx:=lx-1;
   circle(lx,y,2);
    circle(lx,y,1);
   end;
 end;

 if key='d' then
 begin
   lx:=x;
  nx:=nx+5;
  x:=x+nx;
  clrscr;
      for vv:=lx to x do
   begin
   setcolor(7);
   circle(lx,y,2);
    circle(lx,y,1);
   delay(0);
   setcolor(1);
   lx:=lx+1;
   circle(lx,y,2);
    circle(lx,y,1);
   end;
end;


end;
until (key='g'){ or
((x in[ 200..250 ])and(y in [200..250]))            }

 end;
 readln;
 closegraph;
{
 if ((x in[ 200..250 ])and(y in [200..250])) then
 writeln('Є®*Ґж');
 readln;      }
end.
the Gray Maybe
Сообщения: 12
Зарегистрирован: 05 фев 2008, 20:35

плюс интересны какиенибудь идеи интересные, ( я собирался что то вроде лабиринта сделать)
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

по поводу чтения нажатий клавиш:
либо так:

Код: Выделить всё

If keypressed then begin
                   ch:=readkey;
                   If Ch=#0 then ch:=readkey;
                   if ch='w' then <нажали W>;
                   if ch='s' then <нажали S>;
end;
либо используйте функцию ReadKeyWord
function ReadKeyWord : word; assembler; asm mov ah,00; int 16h end;
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Насчет скорости - написать функцию, которая будет приостанавливать работу ровно на Х миллисекунд. Вроде бы есть функция GetTime - получаешь текущее время и делаешь repeat until текущее время больше, чем на Х отличается от первоначально взятого. Delay - не лучший выход, потому что он построен на тиках процессора, поэтому на медленных компах программа будет идти медленно, а на быстрых чересчур быстро (сам видел Арканоид, написанный с использованием этой функции - играть почти невозможно).
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):Вроде бы есть функция GetTime - получаешь текущее время и делаешь repeat until текущее время больше, чем на Х отличается от первоначально взятого.
Ага, вот только в районе полуночи играть не рекомендую.
Неплохой вариант с задержкой, если использовать прерывание таймера. Стандартный обработчик увеличивает на единицу содержимое памяти размером в двойное слово по адресу $40:$6C каждое такое прерывание. Стандартно в ДОСе оно вырабатывается 18,2 раза в секунду. Обратиться к памяти из паскаля можно очень легко используя массив memb, memw который отражается на оперативную память первого мегабайта.

Код: Выделить всё

ticks := memw[$40:$6c];
repeat until (memw[$40:$6c] - ticks)>18;
It's a long way to the top if you wanna rock'n'roll
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

somewhere писал(а):Обратиться к памяти из паскаля можно очень легко используя массив memb, memw который отражается на оперативную память первого мегабайта.

Код: Выделить всё

ticks := memw[$40:$6c];
repeat until (memw[$40:$6c] - ticks)>18;
Еще один вариаент - объявление переменной, имеющий абсолютный адрес ("наложение" объявляемой переменной на указанный адрес):

Код: Выделить всё

var wTicks : word absolute $40:$6c;
Тогда приведенный выше текст будет выглядеть:

Код: Выделить всё

var wTicks : word absolute $40:$6c;
      ticks : word;
begin
  ticks := wTicks;
  repeat until (wTicks - ticks)>18;
end.
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

ребята, ничего не хочу сказать, но в моей программе из далёкого прошлого эта переменная (Ticks) - это 32 разрядное число, а не 16 (не word)!!

Код: Выделить всё

procedure PressDelay(HundSecond : longInt);
var
  Ticks      : LongInt  absolute 0:$46c;
  W          : word;
begin
  HundSecond:=round(HundSecond * 0.185) +Ticks;
  repeat  until KeyPressed  or (Ticks>HundSecond);
end;
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Ну а я так и сказал - двойное слово, а word написал для примера просто обращения к памяти.
It's a long way to the top if you wanna rock'n'roll
Ответить