1. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Народ собственно в чём вопрос.
    У меня есть реугольник который двигается по нажатию клавиш и есть астероиды которые двигаются по окну программы рендомно.
    Подскажите плиз как сделать так чтоб астероиды двигались линейно о в рендомном направлении, ато у меня они можно сказать прыгают.
    Движение астероида в коде я выделил красным
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <glut.h>
     
    #define PI 3.1415926535898
     
    #pragma comment (lib, "glut32.lib")
     
    struct Vector {float x, y;};  
    Vector v1, v2, v3,v4; 
    Vector pos;
    float angle;
    struct Vec3D {float X, Y, Z;};
    class Asteroid
    {
    public:
    void Init(int N)
    {
      int i = N / 4;
      int j = N % 4;
      A.X = -0.5+i/2;
      A.Y = -0.5+j/2;
      A.Z = 0;
      B.X = i/2;
      B.Y = -0.5+j/2;
      B.Z = 0;
      C.X = -0.5+i/2;
      C.Y = j/2;
      C.Z = 0;
      D.X = i/2;
      D.Y = j/2;
      D.Z = 0;
      dx = 0;
      dy = 0;
      dz = 0;
    } 
     
    Vec3D A, B, C, D;
    float dx, dy, dz;
    
    public:
    void Draw();
    };
     
    int N = 10; 
    Asteroid AstArr[10];   //Массив астероидов
     
     
     
    //------------------------------------------------------------------------------------
    void resize(int width,int height)
    {
       glViewport(0,0,width,height);
       glMatrixMode( GL_PROJECTION );
       glLoadIdentity();
       glOrtho(-5,5, -5,5, 2,12);
       gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
       glMatrixMode( GL_MODELVIEW );
     
    }
     
    //------------------------------------------------------------------------------------
     
    Vector Rotate(Vector v,float a) // функция вращения вектора на угол а.
    {
     
    Vector r;
     
     
    a = a * (PI/180.0);
    r.x = (v.x*cos(a)) + (v.y*sin(a));
    r.y = (v.x*-sin(a)) + (v.y*cos(a));
     
     
     
     
    return r;
     
    }
     
    //------------------------------------------------------------------------------------
     
    void init() // Задаем установки прогы
    {
    v1.x = 0.3; v1.y = 0.3; // записываем статичиские кординаты фигуры
    v2.x =-0.08; v2.y = 0.08;
    v4.x = 0.08; v4.y =-0.08;
     
    }
    void Asteroid::Draw()
    {
            glBegin(GL_QUADS);
            glColor3ub(255,255,255);
                glVertex3f(A.X, A.Y, A.Z);   // Слева вверху
                glVertex3f(B.X, B.Y, B.Z);   // Справа вверху
                glVertex3f(C.X, C.Y, C.Z);   // Справа внизу
                glVertex3f(D.X, D.Y, D.Z);   // Слева внизу
            
            glEnd(); 
    }
    //------------------------------------------------------------------------------------
     
     
    void display(void)
    {
     
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
    glLoadIdentity();
     
    for (int i = 0; i < N; i++)
     {
      glLoadIdentity();
      glTranslatef(AstArr[i].dx, AstArr[i].dy, AstArr[i].dz);
      AstArr[i].Draw();
     }
     
    glLoadIdentity(); 
     
     if(GetAsyncKeyState(VK_LEFT))  angle -= 0.7; // Кнопки Влево и вправо крутят фигуру! 
     if(GetAsyncKeyState(VK_RIGHT)) angle += 0.7;
     
     if(GetAsyncKeyState(VK_UP)) { 
             Vector tmp; tmp.x = 0.004; tmp.y = 0.004;
             tmp = Rotate(tmp, angle);
             
             pos.x += tmp.x; pos.y += tmp.y;
             if(pos.x > 5.1) pos.x = -5.1;
             if(pos.x < - 5.1) pos.x = 5.1;
     
             if(pos.y > 5.1) pos.y = -5.1;
             if(pos.y < - 5.1) pos.y = 5.1;
     
     }  // Кнопки вверх и вниз меняют позицию фигуру! 
     if(GetAsyncKeyState(VK_DOWN)) {
             Vector tmp; tmp.x = -0.003; tmp.y = -0.003;
             tmp = Rotate(tmp, angle);
             pos.x += tmp.x; pos.y += tmp.y;
     
             pos.x += tmp.x; pos.y += tmp.y;
             if(pos.x > 5.1) pos.x = -5.1;
             if(pos.x < - 5.1) pos.x = 5.1;
     
             if(pos.y > 5.1) pos.y = -5.1;
             if(pos.y < - 5.1) pos.y = 5.1;
     
     }
     
     
     Vector tv1 = Rotate(v1,angle); // создаем временой вектор  для создания глобальних кординат
     Vector tv2 = Rotate(v2,angle);
     Vector tv3 = Rotate(v4,angle);
     
     
     glBegin(GL_TRIANGLES);
     
         glColor3ub(255,255,0);
        glVertex2d(tv1.x + pos.x, tv1.y + pos.y); // рисуем фигуру и добовляем позицию
             
        glVertex2d(tv2.x + pos.x, tv2.y + pos.y);
        glVertex2d(tv3.x + pos.x, tv3.y + pos.y);
            glEnd();
            
     
     
    glutSwapBuffers();
    glutPostRedisplay();
     
     
    }
     
    [COLOR=Red]void Timer(int value)
    {
    for (int i = 0; i < N; i++)
     {
       float Angle = rand() * PI/180;
      AstArr[i].dx = AstArr[i].dx + cos(Angle)-sin(Angle);
      AstArr[i].dy = AstArr[i].dy + sin(Angle)+cos(Angle);
      if (AstArr[i].dx > 5) 
               AstArr[i].dx =4.7;
      if (AstArr[i].dx < -5) 
               AstArr[i].dx =-4.7;
      if (AstArr[i].dy > 5) 
               AstArr[i].dy =4.7;
      if (AstArr[i].dy < -5) 
               AstArr[i].dy =-4.7;
    }
      glutPostRedisplay();  // Redraw windows
      glutTimerFunc(300, Timer, 0);
    }[/COLOR]
     
    //------------------------------------------------------------------------------------
    int main(int argc, char *argv[])
    {
     
     
    for (int i = 0; i < N; i++)
     {
     AstArr[i].Init(i);
     AstArr[i].Draw();
     }
     
     
     
      init();
        glutInit(&argc, argv);             
        glutInitWindowSize(800, 700);        
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
        glutCreateWindow("FrOsT");
        glutReshapeFunc(resize);
            glutTimerFunc(300, Timer, 0);
        glutDisplayFunc(display);
        glutMainLoop();
     
            return 0;
    }
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Ну так это тебе надо заюзать функцию вычисления прямой. Она очень простая.
    И вот ты для метеорита своего сразу случайным образом генеришь 2 координаты (начало и конец). Затем просто по функции линии, ты каждый отсчет времени переходишь на следующую точку. таким образом он будет лететь в случайном направлении но по прямой
     
  3. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Значит колдовать надо с этим куском
    Code:
     float Angle = rand() * PI/180;
      AstArr[i].dx = AstArr[i].dx + cos(Angle)-sin(Angle);
      AstArr[i].dy = AstArr[i].dy + sin(Angle)+cos(Angle);
     
  4. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    с этим разобрался, подскажите ещё как сделать так чтоб если астероид прикосается к треугольнику то цвет треугольника меняется скажем на красный
     
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    ну опятьже бери формулу вычисления нахождения точки в многоугольнике (или треугольнице потому что она проще). И каждый раз при отрисовывании проверяй на нахождение текущей координаты каждого астероида внутри триугольника. Если находится, то обрабатывай это как столкновение и можешь менять его цвет.
    Вот формула для проверки
    http://faqs.org.ru/forum/viewtopic.php?f=80&t=11285
     
  6. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Ага спасибо, попробую разобратся
     
  7. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Сделал вроде как должно работать но выдаёт ошибку при линковке
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <glut.h>
    
    #define PI 3.1415926535898
     
    #pragma comment (lib, "glut32.lib")
     
    
    struct Vector {float x, y;};  
    Vector v1, v2, v3,v4; 
    Vector pos;
    float angle;
    bool TestCollide();
    struct Vec3D {float X, Y, Z;};
    class Asteroid
    {
    public:
    void Init(int N)
    {
      int i = N / 4;
      int j = N % 4;
      A.X = -0.5+i/2;
      A.Y = -0.5+j/2;
      A.Z = 0;
      B.X = i/2;
      B.Y = -0.5+j/2;
      B.Z = 0;
      C.X = -0.5+i/2;
      C.Y = j/2;
      C.Z = 0;
      D.X = i/2;
      D.Y = j/2;
      D.Z = 0;
      dx = 0;
      dy = 0;
      dz = 0;
    } 
     
    Vec3D A, B, C, D;
    float dx, dy, dz;
    
    public:
    void Draw();
    };
     
    int N = 10; 
    Asteroid AstArr[10];   //Массив астероидов
     
     
     
    //------------------------------------------------------------------------------------
    void resize(int width,int height)
    {
       glViewport(0,0,width,height);
       glMatrixMode( GL_PROJECTION );
       glLoadIdentity();
       glOrtho(-5,5, -5,5, 2,12);
       gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
       glMatrixMode( GL_MODELVIEW );
     
    }
     
    //------------------------------------------------------------------------------------
     
    Vector Rotate(Vector v,float a) // функция вращения вектора на угол а.
    {
     
    Vector r;
     
     
    a = a * (PI/180.0);
    r.x = (v.x*cos(a)) + (v.y*sin(a));
    r.y = (v.x*-sin(a)) + (v.y*cos(a));
     
     
     
     
    return r;
     
    }
     
    //------------------------------------------------------------------------------------
     
    void init() // Задаем установки прогы
    {
    v1.x = 0.3; v1.y = 0.3; // записываем статичиские кординаты фигуры
    v2.x =-0.08; v2.y = 0.08;
    v4.x = 0.08; v4.y =-0.08;
     
    }
    void Asteroid::Draw()
    {
            glBegin(GL_QUADS);
            glColor3ub(255,255,255);
                glVertex3f(A.X, A.Y, A.Z);   // Слева вверху
                glVertex3f(B.X, B.Y, B.Z);   // Справа вверху
                glVertex3f(C.X, C.Y, C.Z);   // Справа внизу
                glVertex3f(D.X, D.Y, D.Z);   // Слева внизу
            
            glEnd(); 
    }
    //------------------------------------------------------------------------------------
     
     
    void display(void)
    {
     
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
    glLoadIdentity();
     
    for (int i = 0; i < N; i++)
     {
      glLoadIdentity();
      glTranslatef(AstArr[i].dx, AstArr[i].dy, AstArr[i].dz);
      AstArr[i].Draw();
     }
     
    glLoadIdentity(); 
     
     if(GetAsyncKeyState(VK_LEFT))  angle -= 0.7; // Кнопки Влево и вправо крутят фигуру! 
     if(GetAsyncKeyState(VK_RIGHT)) angle += 0.7;
     
     if(GetAsyncKeyState(VK_UP)) { 
             Vector tmp; tmp.x = 0.004; tmp.y = 0.004;
             tmp = Rotate(tmp, angle);
             
             pos.x += tmp.x; pos.y += tmp.y;
             if(pos.x > 5.1) pos.x = -5.1;
             if(pos.x < - 5.1) pos.x = 5.1;
     
             if(pos.y > 5.1) pos.y = -5.1;
             if(pos.y < - 5.1) pos.y = 5.1;
     
     }  // Кнопки вверх и вниз меняют позицию фигуру! 
     if(GetAsyncKeyState(VK_DOWN)) {
             Vector tmp; tmp.x = -0.003; tmp.y = -0.003;
             tmp = Rotate(tmp, angle);
             pos.x += tmp.x; pos.y += tmp.y;
     
             pos.x += tmp.x; pos.y += tmp.y;
             if(pos.x > 5.1) pos.x = -5.1;
             if(pos.x < - 5.1) pos.x = 5.1;
     
             if(pos.y > 5.1) pos.y = -5.1;
             if(pos.y < - 5.1) pos.y = 5.1;
     
     }
     
     
     Vector tv1 = Rotate(v1,angle); // создаем временой вектор  для создания глобальних кординат
     Vector tv2 = Rotate(v2,angle);
     Vector tv3 = Rotate(v4,angle);
     
     bool collide = TestCollide();
     
     glBegin(GL_TRIANGLES);
     
         if (collide) {
        glColor3ub(255,0,0);
     }
     else {
       glColor3ub(255,255,0);
     }
        glVertex2d(tv1.x + pos.x, tv1.y + pos.y); // рисуем фигуру и добовляем позицию
             
        glVertex2d(tv2.x + pos.x, tv2.y + pos.y);
        glVertex2d(tv3.x + pos.x, tv3.y + pos.y);
            glEnd();
            
     
     
    glutSwapBuffers();
    glutPostRedisplay();
     
     
    }
     
    void Timer(int value)
    {
    for (int i = 0; i < N; i++)
     {
       float Angle = rand() * PI/180;
      AstArr[i].dx = AstArr[i].dx + cos(Angle)-sin(Angle);
      AstArr[i].dy = AstArr[i].dy + sin(Angle)+cos(Angle);
      if (AstArr[i].dx > 5) 
               AstArr[i].dx =4.7;
      if (AstArr[i].dx < -5) 
               AstArr[i].dx =-4.7;
      if (AstArr[i].dy > 5) 
               AstArr[i].dy =4.7;
      if (AstArr[i].dy < -5) 
               AstArr[i].dy =-4.7;
    }
      glutPostRedisplay();  // Redraw windows
      glutTimerFunc(300, Timer, 0);
    }
     
    //------------------------------------------------------------------------------------
    int main(int argc, char *argv[])
    {
     
     
    for (int i = 0; i < N; i++)
     {
     AstArr[i].Init(i);
     AstArr[i].Draw();
     }
     
     
     
      init();
        glutInit(&argc, argv);             
        glutInitWindowSize(800, 700);        
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
        glutCreateWindow("FrOsT");
        glutReshapeFunc(resize);
            glutTimerFunc(300, Timer, 0);
        glutDisplayFunc(display);
        glutMainLoop();
     
            return 0;
    }
    error LNK2019: ссылка на неразрешенный внешний символ "bool __cdecl TestCollide(void)" (?TestCollide@@YA_NXZ) в функции "void __cdecl display(void)" (?display@@YAXXZ)
     
  8. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    ты юзаешь функцию TestCollide();
    Я вот вижу объявнение прототипа этой функции, а кода не вижу. и линкер тоже не видит
     
  9. revaldo666

    revaldo666 New Member

    Joined:
    28 Jul 2010
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    ага..значит bool Testollide() нужно вынести перед void display.
    Можеш подсказать что именно нужно прописывать в функции?
    ато как я понял тут присуцтвует геометрия а с ней я не очень дружу.
     
    #9 revaldo666, 29 Jul 2010
    Last edited: 29 Jul 2010