Domanda

I am creating a bowling game in openGL C++.

What I have done so far that I have drawn a bowl and three points(obstacles).

The bowl is moved upon key-pressed.

I want to make illusion that when the bowl hits those obstacles, they should be dropped. To do this, I have code like when the X and Y co-ordinates of the ball and of those obstacles are same, then the obstacle's X and Y co-ordinates are incremented to make illusion that they are dropped.

Suggest some logic.

This is my code: -

    #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();
}
È stato utile?

Soluzione

Instead of calling circ() function inside display you could call

glutIdleFunc(nameOfYourChoice);

in your main function after keyboard function. So that function is calling again and again. In the above function (nameOfYourChoice) you can manipulate any variables you want for x's and y's. So in that function you can check if there was a collision between objects and if appear collisions you can "drop" things, in this example boxes, via x's and y's in that function. At the end of that function you have to call

glutPostRedisplay();

Now if you want to get those boxes up again you can use timers(also with your time-step) and then after a certain amount of time you can put those boxes up again via x's and y's obviously.For that you also will need bool variables to know if there was a collision.

So collision happens:

bool flagBox1 = true;

time passed:

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

code in (nameOfYourChoice) function:

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

All those changes you will pass them in your display function as you did for the circ with

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

Then render them.

A good practice is to change all your "changeable" variables with a step like a time-step. In that way the hole movement will be depending on that time-step.

Altri suggerimenti

First, moving objects in discrete intervals (something like 'posX += move_unit;') just isn't the way animation is done these days. Instead you should measure the time that passed since the last update/frame and move the object according to that. So if you want to move your ball 50 units per second you would write 'posX += 50.0 * passedTime;'. This guarantees that the movement does not get any faster or slower if fps changes.

Second, what you are asking about is rotating a vector. The most general way of doing this is creating a rotation-matrix and multiplying it with the vector, just google rotation-matrix. In your simple case it should be sufficient to calculate the pole's coordinates using sin() and cos(). You also could use the Matrix-Stack of OpenGL, have look into glRotate(), glPushMatrix() etc.

Third, your question is very general, and the code snippet cant be called snippet anymore. Keep your questions precise and the snippets short.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top