Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > [C/C++]Движение: управляемое и неуправляемое


Автор: DevilHell 9.2.2009, 18:41
Задана задача. Тренажер теннесиста. 3 стены в форме буквы "П". теннесист подает мячи и отбивает их. считать сколько отбил, сколько пропустил.
А проблема вот в чем. Стены сделал. Сделал теннесиста (подобие - как выглядет не важно). Сделал движение теннеста. (лево-право, больше не надо). Теннесист движется от нажатий кнопок лево-право через функцию getch().  
Но как сделать движение мяча? через getch() программа ждет нажания клавиши. А мне надо что бы мяч двигался не зависимо от теннесиста. А теннесиста двигать по мере надобности.
Как это организовать?

Среда С++ под ДОС

Код если надо. (Мяча нет)
Код


#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <math.h>

// Class Figure
class Figure
{
protected:
  int Color;
  int CenterX;
  int CenterY;
public:
  Figure(int iCenterX, int iCenterY)
  {
    Color = 9;
    CenterX = iCenterX;
    CenterY = iCenterY;
//    cout<<"Constructor of Figure\n";
  }
  void SetNewColor(int NewColor)
  {
    Hide();
    Color=NewColor;
    Show();
  }
  virtual void Show() = 0;
  virtual void Hide()
  {
    int prev_col = Color;
    Color=getbkcolor();
    Show();
    Color = prev_col;
  }
  void Move(int DeltaX, int DeltaY)
  {
    Hide();
    CenterX+=DeltaX;
    CenterY+=DeltaY;
    Show();
  };
  virtual ~Figure(){/*cout <<"Destructor of Figure\n";*/};
};

// Class Rectangle
class Rectangle: virtual public Figure
{
private:
  int h; // height
  int w; // width
public:
  Rectangle(int iCenterX, int iCenterY, int ih, int iw) :
    Figure(iCenterX, iCenterY)
  {
     h = ih;
     w = iw;
//     cout<<"Constructor of Rectangle\n";
  }
  void Show();
  ~Rectangle(){/*cout<<"Destructor of Rectangle\n";*/};
};


//Class Oval
class Oval: virtual public Figure
{
private:
    int RadiusX;
    int RadiusY;
    int X1,Y1;
public:
  Oval(int iCenterX, int iCenterY, int iRadiusX, int iRadiusY) :
  Figure(iCenterX, iCenterY)
   {
    X1 = iCenterX;
    Y1 = iCenterY;
    RadiusX = iRadiusX;
    RadiusY = iRadiusY;
//    cout<<"Create class Oval \n";
   }
  void Show();
  ~Oval(){/*cout<<"Del class Oval \n";*/}
}; //end class Oval


//class Krest+Oval
class My_new: public Rectangle, public Oval
{
   public:
   My_new(int iCenterX, int iCenterY,int ih, int iw, int iRadiusX, int iRadiusY, int X1, int Y1):
   Figure(iCenterX, iCenterY), Rectangle(iCenterX,iCenterY,ih,iw), Oval(/*iCenterX,iCenterY,*/X1,Y1,iRadiusX,iRadiusY)
   {
//    cout<<"Constructor of My\n";
//    cout<<"****************\n";
   };
   void Show()
   {
    Rectangle::Show();
    Oval::Show();
   }
  ~My_new(){/*cout<<"Destructor of My_new\n";*/}
}; // End Krest+Oval


// Methods of Rectangle
void Rectangle::Show()
{
  int prev_color=getcolor();
  setcolor(Color);
  rectangle(CenterX, CenterY, CenterX+w, CenterY+h);
  setcolor(prev_color);
}

//Methods of Oval
void Oval::Show()
 {
   int prev_color=getcolor();
   setcolor(Color);
   ellipse(X1, Y1, 0, 360, RadiusX, RadiusY);
   setcolor(prev_color);
 }

// Main function 
int main()
{ Again:
  int gdriver = DETECT, gmode, errorcode;
  initgraph(&gdriver, &gmode,
     "c:\\work\\tc\\bgi");
  errorcode = graphresult();
  if (errorcode != grOk)
  {
     cerr<<"Graphics error";
     cerr<<grapherrormsg(errorcode);
     exit(1);
  };
  int Key;
  Figure *F;
 F=new Rectangle(50,70,20,350);
 F->Show();
 F=new Rectangle(50,70,300,20);
 F->Show();
 F=new Rectangle(380,70,300,20);
 F->Show();
           //движение менять 95 и 85
    F=new My_new(95,370,10,20,15,8,85,375);
     F->Show();
   int Cpram = 95;
   int Coval = 85;
   int Shag=10;
   int Kod;
   int color = 0;
  clrscr;

  do
   {
    Kod=getch();
     switch (Kod)
     {
      case 77: {   F->SetNewColor(color);

         F=new My_new(Cpram,370,10,20,15,8,Coval,375);
          F->SetNewColor(color);
         F->Show();
         Cpram = Cpram + Shag;
         Coval = Coval + Shag;
         F=new My_new(Cpram,370,10,20,15,8,Coval,375);
         F->Show();
        break;
           }                  //1
      case 75: {F->SetNewColor(color);

         F=new My_new(Cpram,370,10,20,15,8,Coval,375);
          F->SetNewColor(color);
         F->Show();
         Cpram = Cpram - Shag;
         Coval = Coval - Shag;
         F=new My_new(Cpram,370,10,20,15,8,Coval,375);
         F->Show();
        break;
           }             //2
    };  //закрытие выбора
    } // зарытие тела цикла
    while (Kod!=27);


//  getch();
  return 0;}



Автор: Earnest 9.2.2009, 18:47
Насколько я помню, в досе есть какая-то функция, которая опрашивает клавиатуру и сразу возвращает управление. Второй вариант - прерывание. Имя функции и номер прерывания - не помню, но найти в документации, думаю, сможешь.
Если будешь использовать функцию, то нужно организовать код как цикл перемещения мяча + опрос клавиатуры и если надо, перемещение игрока. Если прерывание - то перемещение игрока отдельно пишешь.

Автор: GoldFinch 9.2.2009, 18:48
я хз как это в С++ но тебе надо функцию ДОС которая не ждет символ с клавиатуры, а возвращает его наличие в буфере клавиатуры
наверное такая библиотечная функция есть, а если нет - юзай функции ДОС

Добавлено через 39 секунд
Earnest, почти синхронно

Автор: Earnest 9.2.2009, 18:52
Есть, точно, я использовала, но так давно, что как будто в другой жизни. И прерывания тоже... 
Ах как это все просто в Досе было... возможностей кот наплакал, зато все под контролем... smile 

Автор: Sartorius 9.2.2009, 19:11
kbhit()

Автор: DevilHell 9.2.2009, 22:00
Большое всем спасибо. Очень помогли.  smile 

Автор: DevilHell 9.2.2009, 23:01
Начал пробывать делать. 
kbhit() - работает не так как надо. она действительно возращает нажатые клавиши. Но не все. Клавиши со стрелками не сканируются. 
Может еще есть какие функции?
Или как можно сделать через прерывания? (На С++ начал писать 2 месяца назад)

Автор: Sartorius 10.2.2009, 11:37
Цитата(DevilHell @  10.2.2009,  00:01 Найти цитируемый пост)
Клавиши со стрелками не сканируются. 

При нажатии стрелки в буффер попадает два символа 0x00  и код стрелки. Проверяй на 0 и читай буффер еще раз.

Автор: DevilHell 10.2.2009, 14:04
А можно пример? я не знаю как это сделать и как мне получить код клавиши для дальнейшего использования. 
Использую такой пример. Что надо поменять?
Код

  #include <stdio.h>
      #include <conio.h>
      main()
      {
        printf("Приготовившись, нажмите любую клавишу\n");
        while(!kbhit());
        printf("\n Была нажата клавиша (%c)\n", getch());
      }

Автор: w1zard350 4.5.2009, 17:28
Пример:
Код

#include <stdio.h>
#include <conio.h>
main()
{
    if(kbhit())
    {
         key = getch();
         if (key == 0)
             key = getch();
    }
}

Сейчас занимаюсь тем же - управление с клавы под досом и тема для меня очень актуальна. Никак не могу найти в инете решения. Вот здесь прочитал про прерывания, я не шарю что это и как с этим работать, но видимо пришел момент к изучению smile

Автор: zim22 4.5.2009, 19:34
Цитата(w1zard350 @  4.5.2009,  17:28 Найти цитируемый пост)
управление с клавы под досом и тема для меня очень актуальна

ответ http://forum.vingrad.ru/forum/topic-256303.html

Автор: w1zard350 6.5.2009, 10:02
Это не то, что мне надо. Мне нужно реализовать, чтобы можно было работать сразу с многими клавишами, т.е. "зажатыми". Ответ нашел здесь: dklab.ru/doc/keyboard.html

Автор: DevilHell 6.5.2009, 22:05
я реализовал вот так. 
Код

do
{
do
{
// тело цикла
}
while (!kbhit());
     Kod=getch();

    switch (Kod)
     {
      case 77: {   //клавиша право
        break;
           }                  
      case 75: {   // клавиша влево
        break;
           }             //2
    };  //закрытие выбора
while (!kbhit());


правда тут получилось одно "НО". Kod принимает код клавиши только на 2-м цикле. Но для меня например это не существенно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)