Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: помогите с тетрисом  (Прочитано 9520 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
secans
Гость
« : 23-02-2008 21:13 » 

пишу от лица своего друга (сам он не может), пишет тетрис под borland C++ for Dos v 3.11

есть 1 вопрос про осуществление движения фигур.

алгоритм всем известен: если ничего не нажато, то фигура сдвинулась вниз, если игрок нажал на перемещение, то фигура сдвинулась в сторону и вниз.

вопрос собственно в следующем: какой функцией (или как-то иначе) можно считать клавишу и если игрок не нажимал бы её что бы фигура двигалась дальше а не зависала и не ждала, когда же пользователь соблаговолит нажать что-нибудь...

рабочая версия пока такая:
Код:
#include<conio.h>
#include<stdio.h>
#include<dos.h>
void game();
void sozdaniye_pole();
void vivod_pole();
int zapysk_figyri();

int n=12,m=12;
unsigned char a[20][20],b[20][20];

void main(void)
{
clrscr();
game();
getch();
}



void sozdaniye_pole()
{
int i=1,j=1;
for(i=1;i<=n;i++)
   for(j=1;j<=m;j++)
      if((i==1) || (i==12))
a[i][j]=205;
      else
if((j==1) || (j==12))
  a[i][j]=186;
else
  a[i][j]=' ';
a[1][1]=201;
a[1][12]=187;
a[12][1]=200;
a[12][12]=188;
for(i=1;i<=n;i++)
  for(j=1;j<=m;j++)
    b[i][j]=a[i][j];
vivod_pole();
}

void vivod_pole()
{clrscr();
printf("\n\n\n\n\n");
for(int i=1;i<=n;i++)
  {printf("\n");
   printf("\t\t\t\t");
   //delay(200);
  for(int j=1;j<=m;j++)
    printf("%c",b[i][j]);  }
}

int zapysk_figyri()
{int y[5],x[5],f1=0,f2=2,A,i,j;
char c,k;
y[1]=1;
y[2]=2;
y[3]=3;
x[1]=6;
x[2]=6;
x[3]=6;
while(f1!=1)
{for(i=1,j=1;i<=3;i++)
  b[y[i]][x[j]]='*';

vivod_pole();
f2=2;
while(f2!=3)
{
c=getch();
if(((x[3]==11) && (c==54)) || ((x[3]==2) && (c==52)))
  c=50;
A=c-48;
switch(A)
{case 2: y[1]++;
y[2]++;
y[3]++;
f2=3;break;
 case 4: x[1]--;
x[2]--;
x[3]--;
f2=3;break;
 case 6: x[1]++;
x[2]++;
x[3]++;
f2=3;break;
}   }
for(i=1;i<=n;i++)
  for(j=1;j<=m;j++)
    b[i][j]=a[i][j];
/*k=a[i3][j3];
printf("\t\t\t%c%d",k,k);
getch(); */
if((a[y[3]][x[3]]=='*') || (a[y[3]][x[3]]==205))
  f1=1;}

return 0;}


void game(void)
{int f=0;
sozdaniye_pole();
//while(f!=1)
f=zapysk_figyri();
}

тут фигура из 3 вертикальных ячеек, управление стрелками на цифрах (те что справа) для движения вниз жать 2, влево 4 и вправо 6. Реализовать постоянное падение не проблема, но как тогда двигать фигуру не ясно....
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 23-02-2008 21:46 » 

secans, для начала - простая идея. Фигуру всегда двигать вниз по таймеру, при этом если пользователь нажал кнопку "вправо" или "влево" - фигуру сдвигать только в соответствующую сторону, без всяких "вниз" (в тетрисе ведь можно за один такт хоть из конца в конец поля по горизонтали фигуру успеть переместить). Ну и защитить доступ к данным критической секцией, чтобы не было коллизий. Словом, осваивайте многопоточность Улыбаюсь
« Последнее редактирование: 23-02-2008 21:47 от Вад » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 23-02-2008 21:59 » 

Вад, окстись! DOS и критические секции...

secans, неблокируемый ввод для таких вещей существует. Читать из stdin. Правда, не знаю, реализованно ли такое в runtime-библиотеке BC3.1...
Если нет такого, то напрямую обращаться к сервисам DOS через ассемблерные вставки.

Код: (ASM)
mov al, 6
mov dl, 0ffh
int 21h
ZF указывает на наличие данных. В AL возвращается код клавиши. Если код AL == 0, то надо вызвать сервис еще раз, для получения "расширенного" кода для управляющих клавиш, F-клавиш и комбинаций с Alt, Ctrl и Shift.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 23-02-2008 22:01 » 

Вад,
Цитата
borland C++ for Dos v 3.11
Так что многопоточность тут слабо поможет. Хотя идея с таймером нормальная. Подцепить на таймер движение вниз, а движение влево вправо уже осушествлять кнопками в основном модуле.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 23-02-2008 22:14 » 

Упс, слово Dos в начале я и пропустил Улыбаюсь Праздник влияет, видимо.
Тогда таймер оставляем. Если сложно, можно проще: проверять ввод пользователем (делать нечто типа kbhit), а между делом выполнять короткие sleep-ы. Если пользователь нажал "вправо"/"влево", всё также двигаем горизонтально. По прохождении некоторого интервала времени производим сдвиг вниз.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines