Home > database >  I have made my own collision checker system for a demo but my collisions are not interacting properl
I have made my own collision checker system for a demo but my collisions are not interacting properl

Time:07-14

So I have made a simple demo for rect collision checking but when it comes to stopping the objects from going through each other, my code leaves a small gap between the two objects for no apparent reason even though there should be no space left when the objects collide. I do not fully know why this happens yet but I know the bug is in the checkCollisionRect() function as it is the one that is in charge of handling the behaviour of the rects.

Code:

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

#define or ||
#define and &&
#define pCharacter "%c \n"
#define pInteger "%d \n"
#define pFloat "%f \n"
#define pDouble "%lf \n"
#define pUnsighned "%u \n"
#define pString "%s \n"

/*
format string:| input type:
      %c      | character
      %d      | digit (integer)
      %f      | float
      %lf     | double
      %u      | unsigned
      %s      | string
*/

int width=1000; //Screen width
int height=500; //Screen height
int px=200; //Player pos x
int py=100; //Player pos y
float playerSpeed=5.0;

void drawRect(int tlx,int tly,int boxWidth,int boxHeight){
 glBegin(GL_POLYGON);
 glVertex2f(tlx,tly boxHeight); //Bottom Left
 glVertex2f(tlx,tly); //Top Left
 glVertex2f(tlx boxWidth,tly); //Top Right
 glVertex2f(tlx boxWidth,tly boxHeight); //Bottom Right
 glEnd();
}

void checkCollisionRect(x1,y1,w1,h1,x2,y2,w2,h2){
 if(x1>x2 w2 or x1 w1<x2 or y1>y2 h2 or y1 h1<y2){
  glColor3f(0,1,0);
 }
 else{
  glColor3f(1,0,0);
  if(x1<x2 w2 and x1 w1>x2 and y1<y2 h2){
   py-=playerSpeed;
   printf("top\n");
  }
  if(y1 h1>y2 and y1<y2 h2 and x1<x2 w2){
   px-=playerSpeed;
   printf("left\n");
  }
  if(x1<x2 w2 and x1 w1>x2 and y1 h1>y2){
   py =playerSpeed;
   printf("bottom\n");
  }
  if(y1 h1>y2 and y1<y2 h2 and x1 w1>x2){
   px =playerSpeed;
   printf("right\n");
  }
 }
}
    
void drawSquare(px,py,size){
 glPointSize(size);
 glBegin(GL_POINTS);
 glVertex2i(px,py);
 glEnd();
}

void Buttons(unsigned char key,int x,int y){
 if(key=='a'){px-=playerSpeed;}     
 if(key=='d'){px =playerSpeed;} 
 if(key=='w'){py-=playerSpeed;}
 if(key=='s'){py =playerSpeed;}
}               
 
void display(){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 //-----------------------Draw----------------------
 checkCollisionRect(px,py,10,10,200,200,100,100);
 drawRect(200,200,100,100); //rect
 drawRect(px,py,10,10); //player
 //-------------------------------------------------
 glutSwapBuffers();
 glutPostRedisplay();
}

void init(){
 glClearColor(0.3,0.3,0.3,0);
 gluOrtho2D(0,width,height,0);
}

void main(int argc, char** argv){ 
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(width,height);
 glutCreateWindow("OpenGL");
 init();
 glutDisplayFunc(display);
 glutKeyboardFunc(Buttons);
 glutMainLoop();
}

CodePudding user response:

The problem is your checkCollisionRect function does not do the necessary tests for your purpose:

  • x1,w1,y1,h1 is the player rectangle

  • x2,w2,y2,h2 is the playfield inside which the player rectangle is constrained.

  • to check if the player is inside the playfield, use:

    if (x1 >= x2 && x1 w1 <= x2 w2 && y1 >= y2 && y1 h1 <= y2 h2)
    
  • each of these comparisons correspond to the player hitting one of the walls:

    if (x1 < x2)        // player hit the left wall
    if (x1 w1 > x2 w2)  // player hit the right wall
    if (y1 < y2)        // player hit the top wall
    if (y1 h1 > y2 h2)  // player hit the bottom wall
    

Here is a modified version:

void checkCollisionRect(x1, y1, w1, h1, x2, y2, w2, h2) {
    if (x1 >= x2 && x1 w1 <= x2 w2 && y1 >= y2 && y1 h1 <= y2 h2)
        glColor3f(0, 1, 0);
    } else {
        glColor3f(1, 0, 0);
        if (x1 < x2) {       // player hit the left wall
            px  = playerSpeed;
        }
        if (x1 w1 > x2 w2) { // player hit the right wall
            px -= playerSpeed;
        }
        if (y1 < y2) {       // player hit the top wall
            py  = playerSpeed;
        }
        if (y1 h1 > y2 h2) { // player hit the bottom wall
            py -= playerSpeed;
        }
    }
}

CodePudding user response:

I have fixed the issue, what I did was as soon as you with the opposite rectangle you will get stuck in that coordenate until you move even slightly, this achieves pixel perfect collision but causes some minor problems when colliding at the edges.

void checkCollisionRect(x1, y1, w1, h1, x2, y2, w2, h2){
    if(x1>x2 w2 or x1 w1<x2 or y1>y2 h2 or y1 h1<y2){
        glColor3f(0, 1, 0);
        }
    else{
        glColor3f(1, 0, 0);
        if (x1 < x2) {       // player hit the left wall
            px = x2-w1;
            printf("left\n");
            printf(pInteger, px);
        }
        if (x1 w1 > (x2 w2)) { // player hit the right wall
            px = x2 w2;
            printf("right\n");
        }
        if (y1 < y2) { // player hit the top wall
            py = y2-h1;
            printf("top\n");
        }         
        if (y1 h1 > (y2 h2)) { // player hit the bottom wall
            py = y2 h2;          
            printf("bottom\n");
        }
    }
}

  • Related