1 Востаннє редагувалося Betterthanyou (30.11.2014 17:27:50)

Тема: OpenGL обробка зіткнень графічних обєктів

Це гра з тетріс "танчики", я хочу зробить так щоб коли зіткнулись танки вони не змогли продовжувати рух один через одного, як мені так зробить адже координат танків досить багато
https://www.dropbox.com/s/wmyxgdab23gz3 … 1.exe?dl=0 - гра

void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    Player();//малює головного персонажа
    DisplayShooting();//малює снаряди 
    for (int i = 0; i < tank; i++)//малює суперників (tank=8)
    {
        if (RivalT[i].life == true)
            if (RivalT[i].Key_A == true || RivalT[i].Key_D == true)
                Rival_AD(i);
            else
                Rival_WS(i);
    }
    Limit();//нічого не малює обробляє знищення танків та снаряда снарядом 
    Pole();//малює поле
    glutSwapBuffers();
}

супротивник

void Rival_WS(int i)//якщо танк їде в перед назад
{
        int App;
        if (RivalT[i].Key_W)
            App = 0;
        else
            App = 21;

        //Begin Основна частина
        glColor3f(0, 0, 5);
        glBegin(GL_QUAD_STRIP);
        glVertex2f(0 + RivalT[i].X, 0 + RivalT[i].Y + App);
        glVertex2f(0 + RivalT[i].X, 42 + RivalT[i].Y + App);
        glVertex2f(21 + RivalT[i].X, 0 + RivalT[i].Y + App);
        glVertex2f(21 + RivalT[i].X, 42 + RivalT[i].Y + App);
        glEnd();
        glBegin(GL_QUAD_STRIP);
        glVertex2f(42 + RivalT[i].X, 0 + RivalT[i].Y + App);
        glVertex2f(42 + RivalT[i].X, 42 + RivalT[i].Y + App);
        glVertex2f(63 + RivalT[i].X, 0 + RivalT[i].Y + App);
        glVertex2f(63 + RivalT[i].X, 42 + RivalT[i].Y + App);
        glEnd();
        //End Основна частина

        //Begin Пушка
        glBegin(GL_QUAD_STRIP);
        glVertex2f(21 + RivalT[i].X, 42 + RivalT[i].Y - App * 2); RivPushkaX[i] = 21 + RivalT[i].X; RivPushkaY[i] = 42 + RivalT[i].Y - App * 2;//Обраховує місце знаходження сннаряду нового
        glVertex2f(21 + RivalT[i].X, 63 + RivalT[i].Y - App * 2);
        glVertex2f(42 + RivalT[i].X, 42 + RivalT[i].Y - App * 2);
        glVertex2f(42 + RivalT[i].X, 63 + RivalT[i].Y - App * 2);
        glEnd();
        //End Пушка

        //Begin Точка
        glColor3f(0, 1, 0);
        glBegin(GL_QUAD_STRIP);
        glVertex2f(21 + RivalT[i].X, 21 + RivalT[i].Y);    RivalS[i].X = RivalT[i].X + 21; RivalS[i].Y = RivalT[i].Y + 21;//S - використовується для обрахування місця знаходження серця противника
        glVertex2f(21 + RivalT[i].X, 42 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X, 21 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X, 42 + RivalT[i].Y);
        glEnd();
        //End Точка
}

void Rival_AD(int i)//якщо танк їде в ліво право
{
        int App;
        if (RivalT[i].Key_A)
            App = 0;
        else
            App = 21;

        //Begin Основна частина
        glColor3f(0, 0, 5);
        glBegin(GL_QUAD_STRIP);
        glVertex2f(0 + RivalT[i].X + App, 42 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X + App, 42 + RivalT[i].Y);
        glVertex2f(0 + RivalT[i].X + App, 63 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X + App, 63 + RivalT[i].Y);
        glEnd();
        glBegin(GL_QUAD_STRIP);
        glVertex2f(0 + RivalT[i].X + App, 0 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X + App, 0 + RivalT[i].Y);
        glVertex2f(0 + RivalT[i].X + App, 21 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X + App, 21 + RivalT[i].Y);
        glEnd();
        //End Основна частина

        //Begin Пушка
        glBegin(GL_QUAD_STRIP);
        glVertex2f(42 + RivalT[i].X - App * 2, 21 + RivalT[i].Y); RivPushkaX[i] = 21 + RivalT[i].X; RivPushkaY[i] = 21 + RivalT[i].Y;//Обраховує місце знаходження снаряду нового
        glVertex2f(42 + RivalT[i].X - App * 2, 42 + RivalT[i].Y);
        glVertex2f(63 + RivalT[i].X - App * 2, 21 + RivalT[i].Y);
        glVertex2f(63 + RivalT[i].X - App * 2, 42 + RivalT[i].Y);
        glEnd();
        //End Пушка

        //Begin Точка
        glColor3f(0, 1, 0);
        glBegin(GL_QUAD_STRIP);
        glVertex2f(21 + RivalT[i].X, 21 + RivalT[i].Y);    RivalS[i].X = RivalT[i].X + 21; RivalS[i].Y = RivalT[i].Y + 21;//S - використовується для обрахування місця знаходження 'серця'
        glVertex2f(21 + RivalT[i].X, 42 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X, 21 + RivalT[i].Y);
        glVertex2f(42 + RivalT[i].X, 42 + RivalT[i].Y);
        glEnd();
        //End Точка
}

головний персонаж

void Player()
{
    //Begin Основна частина
    glColor3f(0, 0, 5);
    glBegin(GL_QUAD_STRIP);
    glVertex2f(840 + PlayerT.X + keyA, 525 + PlayerT.Y + keyAD + keyS);
    glVertex2f(903 + PlayerT.X - keyD, 525 + PlayerT.Y + keyAD + keyS);
    glVertex2f(840 + PlayerT.X + keyA, 483 + PlayerT.Y + keyS);
    glVertex2f(903 + PlayerT.X - keyD, 483 + PlayerT.Y + keyS);
    glEnd();
    //End Основна частина

    //Begin Пушка
    glBegin(GL_QUAD_STRIP);
    glVertex2f(861 + PlayerT.X - keyA + keyD, 525 + PlayerT.Y - (keyS * 2) - keyA - keyD);
    glVertex2f(882 + PlayerT.X - keyA + keyD, 525 + PlayerT.Y - (keyS * 2) - keyA - keyD);
    glVertex2f(861 + PlayerT.X - keyA + keyD, 546 + PlayerT.Y - (keyS * 2) - keyA - keyD);
    glVertex2f(882 + PlayerT.X - keyA + keyD, 546 + PlayerT.Y - (keyS * 2) - keyA - keyD);
    glEnd();
    //End Пушка

    //Begin Точка
    glColor3f(0, 1, 0);
    glBegin(GL_QUAD_STRIP);
    glVertex2f(861 + PlayerT.X, 525 + PlayerT.Y);
    glVertex2f(882 + PlayerT.X, 525 + PlayerT.Y);
    glVertex2f(861 + PlayerT.X, 504 + PlayerT.Y);   PlayerS.X = 861 + PlayerT.X; PlayerS.Y = 504 + PlayerT.Y;//S - використовується для обрахування місця знаходження 'серця'
    glVertex2f(882 + PlayerT.X, 504 + PlayerT.Y);
    glEnd();
    //End Точка
}

2

Re: OpenGL обробка зіткнень графічних обєктів

Я незрозуміло написав ?

3 Востаннє редагувалося FakiNyan (01.12.2014 19:57:23)

Re: OpenGL обробка зіткнень графічних обєктів

Betterthanyou написав:

Я незрозуміло написав ?

та не гарячкуйте, зараз хлопці глянуть і підскажуть щось
p.s. коли я робив тетріс на JS, то в мене було поле у вигляді сітки. І от кожна комірки сітки приймала червоний, коли якась з частин фігури попадає в ту комірку.
І от, аби фігурка не залазила на інші фігурки, то перед її рухом я розраховував наступні координати, після чого перевіряв колір тих координат, ну і ви вже зрозуміли, якщо колір тих координат - червоний, то рухатись далі не мона.
А от якщо у вас там немає невеличкого поля, а танчики можуть їздити дуже плавно, то вам, майбуть, треба щось типу свого фіз. двигуна.
Хз, наскільки я правильно ото думаю. Але спробуйте розбити фігуру свого танчика на прімитиви, ну кубики, напркилад.
Після чого зберігайте в якомусь масиві усі ваші танчики, і перед тим, як рухатись, розраховуйте нові координати кубиків, котрі висять на вашому персонажі, і перевіряйте, чи не будуть вони перетинатися з кубами інших танчиків.
Ну і звісно, вам треба буде зберігати координати отих кубів, і змінювати їх при кожному русі.
p.s.s. то вона у вас 2d? ну тоді замість кубиків працюйте з цими, ммм, як воно, ну той, квадратиками!

Подякували: Betterthanyou1

4

Re: OpenGL обробка зіткнень графічних обєктів

ну так, розбити ігрове поле на сітку(двовимірний масив), а там траблів уже не буде

Подякували: Betterthanyou1

5

Re: OpenGL обробка зіткнень графічних обєктів

Regen написав:

ну так, розбити ігрове поле на сітку(двовимірний масив), а там траблів уже не буде

я то й писав, але якщо треба плавний, дуууже плавний рух, наприклад, по 0.1, коли розміри карти 800 на 400, наприклад, то самі ж розумієте. Матриця 800 на 400 нікому не потрібна, хоча можна і так зробити. Але я б радив 2d фізику підключити, тому що так цікавіше + можна буде усіляку гравітацію, або просто притягання якесь реалізувати.

Подякували: Betterthanyou1

6

Re: OpenGL обробка зіткнень графічних обєктів

Код дуже кривий, а фрагмент, який ви навели, мало що дає для відповіді на ваше питання. В цілому - доведеться перевіряти всі можливі зіткнення перед рухом. Прості поради:
- винесіть все малювання в окремі функції;
- трохи пограйтеся з математикою, але об'єднайте ці ваші Rival_AD і Rival_WS в одну функцію, причому зробіть її членом класу Rival (тобто буде не Rival_AD(i), а RivalT[ i ].move() );
- додайте функцію Rival::collide(Rival *rival), яка буде перевіряти, чи не відбувається зіткнення при русі, і крутіть цикл по всіх інших Rival на початку move.

Подякували: Betterthanyou1