Нужна помощь в игре в боулинг в OpenGL Stack Overflow

Я создаю игру в боулинг на openGL C ++.

То, что я сделал до сих пор, я нарисовал чашу и три точки (препятствия).

Чаша перемещается при нажатии клавиши.

Я хочу создать иллюзию, что когда чаша сталкивается с этими препятствиями, они должны быть сброшены. Для этого у меня есть код как когда координаты X и Y шара и этих препятствий одинаковы, то координаты X и Y препятствия увеличиваются, чтобы создать иллюзию их выпадения.

Предложите немного логики.

Это мой код: —

    #include <GL/glut.h>
#include <cmath>
#include <stdio.h>
float posX = 0.01, posY = -0.1, posZ = 0,

bx1 = 0.01, by1 = 0.1,
bx2 = 0.06, by2 = 0.1,
bx3 = 0.10, by3 = 0.1;

GLfloat rotation = 90.0;
double x, y, angle;
#define PI 3.1415926535898
GLint circle_points = 50;

void bottle() {
glColor3f(0.0, 0.0, 1.0);
glPointSize(9.0);
glBegin(GL_POINTS);
glVertex3f(bx1, by1, 0.0);
glEnd();

glBegin(GL_POINTS);
glVertex3f(bx2, by2, 0.0);

glEnd();
glBegin(GL_POINTS);
glVertex3f(bx3, by3, 0.0);

glEnd();

glFlush();

}

void circ() {
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
for (int i = 0; i <= 300; i++) {
angle = 2 * PI * i / 300;
x = cos(angle) / 20;
y = sin(angle) / 20;
glVertex2d(x, y);
}
glEnd();
}

void display() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
bottle();
glPopMatrix();

glPushMatrix();
glTranslatef(posX, posY, posZ);
circ();
glPopMatrix();
glutSwapBuffers();
}

float move_unit = 0.02f;
void keyboardown(int key, int x, int y) {
switch (key) {
case GLUT_KEY_RIGHT:
posX += move_unit;
break;
case GLUT_KEY_LEFT:
posX -= move_unit;
break;
case GLUT_KEY_UP:
posY += move_unit;
break;
case GLUT_KEY_DOWN:
posY -= move_unit;
break;
default:
break;
}
if ( posX == bx1 || posX == bx2  ) {

bx1 -= 0.02,by1 += 0.06;
bx2 = 0.02,
by2 += 0.08;
bx3 = 0.04,
by3 += 0.04;

}

glutPostRedisplay();
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Practice 1");
glutDisplayFunc(display);
glutSpecialFunc(keyboardown);
glutMainLoop();
}

0

Решение

Вместо вызова функции circ () внутри дисплея вы можете вызвать

glutIdleFunc(nameOfYourChoice);

в вашей основной функции после функции клавиатуры. Так что эта функция вызывается снова и снова.
В приведенной выше функции (nameOfYourChoice) вы можете манипулировать любыми переменными, которые вы хотите для х и у. Таким образом, в этой функции вы можете проверить, не было ли столкновения между объектами, и, если появляются коллизии, вы можете «отбрасывать» вещи, в этом примере, через x и y в этой функции.
В конце этой функции вы должны вызвать

glutPostRedisplay();

Теперь, если вы хотите снова установить эти ящики, вы можете использовать таймеры (также с вашим временным шагом), а затем через некоторое время вы можете снова поставить эти ящики с помощью x и y. Для этого вам также понадобится bool переменные, чтобы знать, было ли столкновение.

Так происходит столкновение:

bool flagBox1 = true;

время прошло:

bool flagBox1 = false;
//code to put back the dropped object

код в (nameOfYourChoice) функции:

if(flagBox1){
//proceed to your actions...
}

Все эти изменения вы передадите им в своей функции отображения, как вы сделали для цирка с

glTranslatef(box1posX, box1posY, box1posZ);
glTranslatef(box2posX, box2posY, box2posZ);
glTranslatef(box3posX, box3posY, box3posZ);

Тогда сделайте их.

Хорошей практикой является изменение всех ваших «изменяемых» переменных с шагом, подобным временному шагу.
Таким образом, движение отверстия будет зависеть от этого временного шага.

0

Другие решения

Во-первых, перемещение объектов в дискретных интервалах (что-то вроде ‘posX + = move_unit;’) просто не способ анимации в наши дни. Вместо этого вы должны измерить время, прошедшее с момента последнего обновления / кадра, и переместить объект в соответствии с этим. Поэтому, если вы хотите перемещать свой мяч со скоростью 50 единиц в секунду, вы должны написать «posX + = 50.0 * passTime;». Это гарантирует, что движение не станет быстрее или медленнее при изменении fps.

Во-вторых, то, о чем вы спрашиваете, это вращение вектора. Самый общий способ сделать это — создать матрицу вращения и умножить ее на вектор, просто Google-матрицу вращения. В вашем простом случае должно быть достаточно рассчитать координаты полюса, используя sin () и cos (). Вы также можете использовать Matrix-Stack из OpenGL, изучить glRotate (), glPushMatrix () и т. Д.

В-третьих, ваш вопрос носит очень общий характер, и фрагмент кода больше нельзя называть фрагментом кода. Держите ваши вопросы точными и короткие фрагменты.

0

По вопросам рекламы [email protected]