【问题标题】:Object doesn't seems to collide using AABB collision method对象似乎没有使用 AABB 碰撞方法发生碰撞
【发布时间】:2015-10-17 13:46:58
【问题描述】:

我是opengl的新手。我正在做一个简单的 2D 射击游戏,并使用 AABB 碰撞来做物体和子弹之间的碰撞。我为我的飞机和广场进行了碰撞,但它似乎不起作用。可以帮我检查一下我的问题吗?

#include <iostream>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>

using namespace std;

#define SPACEBAR 32

class Plane {
public:
    GLfloat x = 0.05f;
    GLfloat y = 0.95f;
    GLfloat width = 0.05f;
    GLfloat height = 0.10f;
    GLfloat moveX = 0.0f;
    GLfloat moveY = 0.0f;

    void drawPlane(GLfloat, GLfloat, GLfloat, GLfloat);
};

class Enemy {
public:
    GLfloat x, y;
    GLfloat width, height;
    GLfloat sqrMoveX, sqrMoveY;

    void drawEnemySqr(GLfloat, GLfloat, GLfloat, GLfloat);
};

Plane plane;
Enemy enemy;

GLfloat XMax, XMin, YMax, YMin;
GLdouble clipAreaXLeft, clipAreaXRight, clipAreaYBottom, clipAreaYTop;

int refreshMills = 30;

float RandomNumberX() {
    float Min = -1.0f;
    float Max = 1.0f;

    return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
}

float RandomNumberY() {
    float Min = 0.7f;
    float Max = 1.0f;

    return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
}

void Timer(int value) {
    glutPostRedisplay();
    glutTimerFunc(refreshMills, Timer, 0);
}

bool collision(GLfloat x1, GLfloat y1, GLfloat w1, GLfloat h1, 
               GLfloat x2, GLfloat y2, GLfloat w2, GLfloat h2) {
    if ((x1 < (x2 + w2)) && 
        ((x1 + w1) > x2) && 
        (y1 < (y2 + h2)) && 
        ((h1 + y1) > y2)) {
        return true;
    }
    else {
        return false;
    }
}

void initGL() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void Plane :: drawPlane(GLfloat planeX, GLfloat planeY, GLfloat planeWidth, GLfloat planeHeight) {
    glTranslatef(moveX, moveY, 0.0f);

    glBegin(GL_POLYGON);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2f(-(planeX), -(planeY));
    glVertex2f(planeX, -(planeY));
    glVertex2f(planeX + planeWidth, -(planeY - planeHeight));
    glVertex2f(planeX - (planeWidth), -(planeY - (planeHeight + 0.20f)));
    glVertex2f(-(planeX + planeWidth), -(planeY - planeHeight));
    glEnd();

    if (moveX > XMax) {
        moveX = XMax;
    }
    else if (moveX < XMin) {
        moveX = XMin;
    }
    if (moveY > YMax) {
        moveY = YMax;
    }
    else if (moveY < YMin) {
        moveY = YMin;
    }
}

void Enemy :: drawEnemySqr(GLfloat enemyX, GLfloat enemyY, GLfloat enemyWidth, GLfloat enemyHeight) {
    glTranslatef(sqrMoveX, sqrMoveY, 0.0f);

    glBegin(GL_QUADS);
    glColor3f(1.0f, 0.0f, 1.0f);
    glVertex2f(enemyX, enemyY);
    glVertex2f(enemyX + enemyWidth, enemyY);
    glVertex2f(enemyX + enemyWidth, enemyY + enemyHeight);
    glVertex2f(enemyX, enemyWidth + enemyY);
    glEnd();

    sqrMoveY -= 0.0005f;

    if (sqrMoveY < -1.8f) {
        sqrMoveX = RandomNumberX();
        sqrMoveY = RandomNumberY();
    }

    glutPostRedisplay();
}

void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);

    glPushMatrix();
    plane.drawPlane(plane.x, plane.y, plane.width, plane.height);
    glPopMatrix();

    glPushMatrix();
    enemy.drawEnemySqr(0.0f, 0.0f, 0.3f, 0.3f);
    glPopMatrix();

    if (collision(plane.moveX, plane.moveY, plane.width, plane.height, 
                  enemy.sqrMoveX, enemy.sqrMoveY, enemy.width, enemy.height) == true) {
        enemy.sqrMoveY = -2.0f;
    }

    glutSwapBuffers();
}

void keyButton(int key, int x, int y) {
    switch (key) {
    case GLUT_KEY_RIGHT:
        plane.moveX += 0.05f;
        break;
    case GLUT_KEY_LEFT:
        plane.moveX += -0.05f;
        break;
    case GLUT_KEY_UP:
        plane.moveY += 0.05f;
        break;
    case GLUT_KEY_DOWN:
        plane.moveY += -0.05f;
        break;
    default:
        break;
    }

    glutPostRedisplay();
}

int main(int argc, char** argv) {
    srand(time(NULL));
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(480, 640);
    glutInitWindowPosition(50, 50);
    glutCreateWindow("Plane Shooting Game");

    glutDisplayFunc(display);
    glutIdleFunc(idle);
    glutReshapeFunc(reshape);
    glutTimerFunc(25, Timer, 0);
    glutSpecialFunc(keyButton);
    initGL();
    glutMainLoop();
    return 0;
}

【问题讨论】:

  • 我认为您的collision 需要更广泛的测试。乍一看,它似乎只测试对象 #1 是否完全在对象 #2 内。
  • 是的,我需要更多的测试,因为这个功能的碰撞还不完美。感谢您的评论!

标签: c++ opengl collision-detection aabb


【解决方案1】:

你在这行有问题:

if (collision(plane.moveX, plane.moveY, plane.width, plane.height, 
              enemy.sqrMoveX, enemy.sqrMoveY, enemy.width, enemy.height) == true)

您必须将plane.xplane.yenemy.xenemy.y 传递给碰撞函数,而不是plane.moveXplane.moveYenemy.sqrMoveXenemy.sqrMoveY

【讨论】:

  • 有效!我将我的平面的x和y坐标更改为0.0f,并将显示函数中碰撞函数的变量输入更改为plane.x + plane.moveX和plane.y + plane.moveY。然后碰撞起作用!感谢您的帮助!
  • 除了这些人以外,你应该回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
相关资源
最近更新 更多