⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 openGL的3D的小球碰撞游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    //2. A x + B y + C z + D = 0
    //1.->2. A (x1 + u (x2 - x1)) + B (y1 + u (y2 - y1)) + C (z1 + u (z2 - z1)) + D = 0
    //
    //                   (a*p1[0] + b*p1[1] + c*p1[2] + d)
    // u =     ___________________________________________________________
    //          a*(p1[0] - p2[0]) + b*(p1[1] - p2[1]) + c*(p1[2] - p2[2])
    /*
       p1    |    p2
       +---->|----+
         u   |
             | plane defined using origin po and normal pn
    */
    
   
}

//return length of the vector defined by point p1 and p2
float vectorLength(float* p1, float* p2)
{
    float x = p1[0] - p2[0];
    float y = p1[1] - p2[1];
    float z = p1[2] - p2[2];

    return sqrtf(x*x + y*y + z*z);
}

//move ball based on current movement vector
//do collision detection when necessary
//do collison dectection for paddle
void moveBall_paddle()
{
	int i ;

    //check missing hit between g_ballPosition and g_lastBallPosition
   for(i = 0; i<1;  i++)
    {
        float u = pointPlaneIntersection(g_lastBallPosition, g_ballPosition, g_wallCenter[i], g_wallNormal[i]);
        if (u < 0.0f || u > 1.0f)//what happens when u < 0.0 or > 1.0? see comments in pointPlaneIntersection()
            continue;

        if (g_speedControl)
            g_step = g_lastStep;

        u = (1.0f - u)*g_step;

        //get intersection point
        float intersect[3];
        for (int j = 0; j < 3; j++)
            intersect[j] = g_lastBallPosition[j] + u*g_ballVector[j];

		//if missing hit paddle 
		if (  intersect[0] <= (g_wallCenter[0][0] + g_wallHalfThickness - g_wallSize[0][0])
		    || intersect[0] >= (g_wallCenter[0][0] + g_wallSize[0][0] -g_wallHalfThickness)
			|| intersect[1] >= (g_wallCenter[0][1] + g_wallSize[0][0] -g_wallHalfThickness)
			|| intersect[1] <= (g_wallCenter[0][1] + g_wallHalfThickness - g_wallSize[0][1]) )
		{
			g_misses ++ ;
            g_currentGame = -1;
            continue;
		}

		else
		{
			//get reflection vector
			float reflect[3];
			reflection(g_ballVector, g_wallNormal[i], reflect);

			for (int j = 0; j < 3; j++)
			{
				g_lastBallPosition[j] = intersect[j];
				g_ballPosition[j] = intersect[j] + u*reflect[j];
				g_ballVector[j] = reflect[j];
			}
	        
			//remember which wall we just hit
			g_wallHit = i;

			if (g_speedControl)
			{
				g_step += g_reflect;
				g_step = g_step > g_maxStep ? g_maxStep : g_step;
			}
		}
        return;
    }

    //no missing hit, predict next step and do collision detection
    float newPosition[3];
    for (int i = 0; i < 3; i++)//predict next ball position
        newPosition[i] = g_ballPosition[i] + g_step*g_ballVector[i];

  for(int i = 0; i<1; i++)
    {
        float u = pointPlaneIntersection(g_ballPosition, newPosition, g_wallCenter[i], g_wallNormal[i]);
        if (u < 0.0f || u > 1.0f)
            continue;

        u = (1.0f - u)*g_step;

        float intersect[3];
        for (int j = 0; j < 3; j++)//intersection point
            intersect[j] = g_ballPosition[j] + u*g_ballVector[j];
       
        if (  intersect[0] <= (g_wallCenter[0][0] + g_wallHalfThickness - g_wallSize[0][0])
		    || intersect[0] >= (g_wallCenter[0][0] + g_wallSize[0][0] -g_wallHalfThickness)
			|| intersect[1] >= (g_wallCenter[0][1] + g_wallSize[0][0] -g_wallHalfThickness)
			|| intersect[1] <= (g_wallCenter[0][1] + g_wallHalfThickness - g_wallSize[0][1]) )
		{
			g_misses ++ ;
			g_currentGame = -1;
            continue;
		}
		else
		{   
			float reflect[3];//reflection vector
			reflection(g_ballVector, g_wallNormal[i], reflect);

			for (int j = 0; j < 3; j++)//update ball position
			{
				g_lastBallPosition[j] = g_ballPosition[j];
				g_ballPosition[j] = intersect[j] + u*reflect[j];
				g_ballVector[j] = reflect[j];
			}

			g_wallHit = i;

			if (g_speedControl)
			{
				//increase ball speed
				g_lastStep = g_step;
				g_step += g_reflect;
				g_step = g_step > g_maxStep ? g_maxStep : g_step;
			}
	   }
        return;
    }

    //no hit at all, move ball forward and wait for next frame
    for (int i = 0; i < 3; i++)
    {
        g_lastBallPosition[i] = g_ballPosition[i];
        g_ballPosition[i] = newPosition[i];
    }

    if (g_speedControl)
    {
        //reduce ball speed
        g_lastStep = g_step;
        if (g_step > g_minStep)
            g_step *= g_damper;
    }
}

// ball hitting walls
void moveBall()
{
	switch(g_currentGame){
		case 0 :
			break;
		case 1: //ball is in the court, do collision detection
			{
				// ball hitting on paddle
				moveBall_paddle(); 
				//ball hitting on walls
			for (int i = 1; i < 6; i++)
			{
				float u = pointPlaneIntersection(g_lastBallPosition, g_ballPosition, g_wallCenter[i], g_wallNormal[i]);
				if (u < 0.0f || u > 1.0f)//what happens when u < 0.0 or > 1.0? see comments in pointPlaneIntersection()
					continue;

				if (g_speedControl)
					g_step = g_lastStep;

				u = (1.0f - u)*g_step;

				//get intersection point
				float intersect[3];
				for (int j = 0; j < 3; j++)
					intersect[j] = g_lastBallPosition[j] + u*g_ballVector[j];

				//get reflection vector
				float reflect[3];
				reflection(g_ballVector, g_wallNormal[i], reflect);

				for (int j = 0; j < 3; j++)
				{
					g_lastBallPosition[j] = intersect[j];
					g_ballPosition[j] = intersect[j] + u*reflect[j];
					g_ballVector[j] = reflect[j];
				}

				//remember which wall we just hit
				g_wallHit = i;

				if (g_speedControl)
				{
					g_step += g_reflect;
					g_step = g_step > g_maxStep ? g_maxStep : g_step;
				}
				return;
			}

			//no missing hit, predict next step and do collision detection
			float newPosition[3];
			for (int i = 0; i < 3; i++)//predict next ball position
				newPosition[i] = g_ballPosition[i] + g_step*g_ballVector[i];

			for (int i = 1; i < 6; i++)
			{
				float u = pointPlaneIntersection(g_ballPosition, newPosition, g_wallCenter[i], g_wallNormal[i]);
				if (u < 0.0f || u > 1.0f)
					continue;

				u = (1.0f - u)*g_step;

				float intersect[3];
				for (int j = 0; j < 3; j++)//intersection point
					intersect[j] = g_ballPosition[j] + u*g_ballVector[j];

				float reflect[3];//reflection vector
				reflection(g_ballVector, g_wallNormal[i], reflect);

				for (int j = 0; j < 3; j++)//update ball position
				{
					g_lastBallPosition[j] = g_ballPosition[j];
					g_ballPosition[j] = intersect[j] + u*reflect[j];
					g_ballVector[j] = reflect[j];
				}

				g_wallHit = i;

				if (g_speedControl)
				{
					//increase ball speed
					g_lastStep = g_step;

					g_step += g_reflect;
					g_step = g_step > g_maxStep ? g_maxStep : g_step;
				}
				return;
			}

			//no hit at all, move ball forward and wait for next frame
			for (int i = 0; i < 3; i++)
			{
				g_lastBallPosition[i] = g_ballPosition[i];
				g_ballPosition[i] = newPosition[i];
			}

			if (g_speedControl)
			{
				//reduce ball speed
				g_lastStep = g_step;
				if (g_step > g_minStep)
					g_step *= g_damper;
			}
	}
			break;
			//ball is out of court
		case -1:
			{
					if (g_misses <= threshold)
					{
						//no missing hit, predict next step and do collision detection
						float newPosition[3];
						for (int i = 0; i < 3; i++)//predict next ball position
							newPosition[i] = g_ballPosition[i] + g_step*g_ballVector[i];
						//no hit at all, move ball forward and wait for next frame
						for (int i = 0; i < 3; i++)
						{
							g_lastBallPosition[i] = g_ballPosition[i];
							g_ballPosition[i] = newPosition[i];
						}

						if (g_ballPosition[2] > 60.0f)
						{
							g_ballPosition[0] = 0.0f;
							g_ballPosition[1] = 50.0f; 
							g_ballPosition[2] = 0.0f;

							g_lastBallPosition[0] =0.0f;
							g_lastBallPosition[1] =50.0f; 
							g_lastBallPosition[2] =0.0f; 
							
							g_ballVector[0] = 1.0;
							g_ballVector[1] = 0.8;
							g_ballVector[2] = -0.9;

							g_step = 0.06f;
							g_lastStep = 0.06f;
							g_speedControl = false;
							g_currentGame = 0;
						}

						if (g_speedControl)
						{
							//reduce ball speed
							g_lastStep = g_step;
							if (g_step > g_minStep)
								g_step *= g_damper;
						}
					  glColor3f(0.0, 1.0, 1.0f);
					  drawString("Press: 's' to start", -20, 80);
					  drawString(" you have losed one time", -50, 70);
	             }
			else
			{
				//no missing hit, predict next step and do collision detection
				float newPosition[3];
				for (int i = 0; i < 3; i++)//predict next ball position
					newPosition[i] = g_ballPosition[i] + g_step*g_ballVector[i];
				//no hit at all, move ball forward and wait for next frame
				for (int i = 0; i < 3; i++)
				{
					g_lastBallPosition[i] = g_ballPosition[i];
					g_ballPosition[i] = newPosition[i];
				}

				if (g_speedControl)
				{
					//reduce ball speed
					g_lastStep = g_step;
					if (g_step > g_minStep)
						g_step *= g_damper;
				}

		    	}
			}
			break;
        }
        
		for (int i = 0; i < 3; i++)
	{
		position0[i] = g_ballPosition[i];
		spotDirection[i] = g_ballPosition[i] - position2[i];
	}

	}

//draw wire sphere at current position and angle
void drawBall()
{
    glMatrixMode(GL_MODELVIEW);
     glDepthMask(GL_TRUE);
	glDisable(GL_BLEND);
    glPushMatrix();
    glTranslatef(g_ballPosition[0], g_ballPosition[1], g_ballPosition[2]);
    
    glRotatef(g_frameCount, 1.0f, 0.0f, 0.0f);
	 glTexCoord2f(0.0f, 0.0f);
    glutSolidSphere(5.0f, 150.0f, 150.0f);

    glPopMatrix();
}




void loadModel(char* pFileName)
{
 
    FILE* pFile = NULL;
    fopen_s(&pFile, pFileName, "r");

    int numVertex = 264, numPolygon;
    char line[1024];

    fgets(line, 1023, pFile);

    char seps[] = " \t";
    char *token, *next_token;

    token = strtok_s(line, seps, &next_token);
    token = strtok_s(NULL, seps, &next_token);
    numVertex = atoi(token);
    token = strtok_s(NULL, seps, &next_token);
    numPolygon = atoi(token);

    //alloc memory for vertices
    float* pVertexBuffer = (float*)malloc(sizeof(float)*numVertex*3);

    for (int i = 0; i < numVertex; i++)
    {
        fgets(line, 1023, pFile);
        token = strtok_s(line, seps, &next_token);
        pVertexBuffer[i*3] = (float)atof(token);
        token = strtok_s(NULL, seps, &next_token);
        pVertexBuffer[i*3+1] = (float)atof(token);
        token = strtok_s(NULL, seps, &next_token);
        pVertexBuffer[i*3+2] = (float)atof(token);
    }

       g_displayList = glGenLists(1);
    glNewList(g_displayList, GL_COMPILE);

    //glColor3fv(g_blue);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    int index;

    for (int i = 0; i < numPolygon; i++)
    {
        fgets(line, 1023, pFile);        
        
        token = strtok_s(line, seps, &next_token);
        numVertex = atoi(token);
        //glMaterialfv(GL_FRONT, GL_EMISSION, emission);
        glBegin(GL_POLYGON);
        for (int j = 0; j < numVertex; j++)
        {
            token = strtok_s(NULL, seps, &next_token);
            index = atoi(token) - 1;

            glVertex3f(pVertexBuffer[index*3], pVertexBuffer[index*3+1], pVertexBuffer[index*3+2]);
        }
        glEnd();

    }

    glEndList();
    
    free(pVertexBuffer);
    fclose(pFile);
}

void LightMapTable()
{
    float size = 80.0f;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -