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

📄 baiscobj.cpp

📁 碰撞检测.,用c++ opengl 实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 学程序编游戏系列丛书
// 唐明理 E_mail: cqtmL@163.com
//====================================================================
#include "stdafx.h"
#include "baiscobj.h"
#include "anmobj.h"
#include "../include/BITMAP.H"
#include "mdlobj.h"
extern mdlobj	m_mdlobj;

extern GLfloat	r;       //飞机盘旋角度
float  gao=1.8f;
extern CString	test;    //场景信息
extern anmobj* m_anmobj;
extern HWND		hWnd;    //窗口句柄,主定义在主程序
extern bool		Lbutdown;//鼠标左键,主定义在主程序
int	   rnshu=0;   //人数计数

//////////////////////////////////////////////////////////////////////
baiscobj::baiscobj()
{	g_eye[0]= MAP;//
	g_eye[2]=-MAP;//
	g_Angle=0;//
	g_elev=-0;//
//A、设置数据目录
	char	appdir[256];
	GetCurrentDirectory(256,appdir);
	CString dir=appdir;
	if(dir.Right(8)!="运行程序")
	SetCurrentDirectory("../运行程序");
	m_mdlobj.InitGL(0,"data/mdl模型/qian1.mdl");
//B、调入场景文件和相关贴图
	g_imageData = LoadBit("data/images/Terrain1.bmp",&g_bit);	//调等高地形图
	LoadT8("data/images/sand0.bmp",	 g_cactus[0]);	//地面帖图
	LoadT8("data/images/1RBack.bmp",g_cactus[2]);	//天空贴图后
	LoadT8("data/images/1Front.bmp",g_cactus[3]);	//天空贴图前
	LoadT8("data/images/1Top.bmp",	 g_cactus[4]);	//天空贴图顶
	LoadT8("data/images/1Left.bmp", g_cactus[5]);	//天空贴图左
	LoadT8("data/images/1Right.bmp",g_cactus[6]);	//天空贴图右
	LoadT16("data/images/CACTUS0.BMP",g_cactus[11]);    //树1帖图
	LoadT16("data/images/CACTUS1.BMP",g_cactus[12]);    //树2帖图
	LoadT16("data/images/CACTUS2.BMP",g_cactus[13]);    //树3帖图
	LoadT16("data/images/CACTUS3.BMP",g_cactus[14]);    //树4帖图
	InitTerrain(5);//初始化地面
//D、调入3DS模型
	m_3ds=new CLoad3DS();
	load3dobj("data/3ds/","航天发射台.3DS",0);
	load3dobj("data/3ds/","直升机0.3ds",1);//car.3ds
	load3dobj("data/3ds/","飞机1.3ds",2);//car.3ds
//C、初始化3D动画模型
	m_anmobj->model[0]=NULL;	m_anmobj->model[1]=NULL;
	m_anmobj->texture[0]=NULL;	m_anmobj->texture[1]=NULL;
	m_anmobj->getobj("data/模型/士兵0/");					//士兵模型士兵0
	for(int i=0;i<RNSHU;i++)
	{m_anmobj->man[i].qd[0]=MAP+80+rand()%20;	//起点manqdx
	 m_anmobj->man[i].qd[1]=MAP-10+i*1;//
	 m_anmobj->man[i].zd[0]=MAP+20-rand()%5;	//终点manzdx
	 m_anmobj->man[i].zd[1]=MAP-10+i*1;//
	 m_anmobj->man[i].dz=1;				//初始动作,跑。
	 m_anmobj->man[i].death=0;
	}
//E、射击、爆炸初始化
	LoadT16("data/images/explosion.bmp",g_cactus[15]);  //粒子帖图
    isExplosion = true;                                 //
	explosion=NULL;                                     //
	Explosion(0,0,0,1,1);                               //爆炸初始化
//F、
	inputSys = new CInputSystem;                        //初始化鼠标类变量
	bool useDInput =
		inputSys->Initialize(hWnd,(HINSTANCE)GetModuleHandle(NULL),
					   true,IS_USEKEYBOARD|IS_USEMOUSE);//初始化鼠标接口
	Lbutdown=false;                                     //没按鼠标左键
	rocketX=0,rocketZ=0,rocketY=2000;                   //子弹位置初值
	rad_xz=0;                                           //视角(弧度)清0
	Expl=0;                                             //子弹距离计数清0
//G、
	srand(100);//产生树的固定随机数种子
	for(i=0;i<TREESL;i++)						//树的数量			
	{objposi[i].x= RAND_COORD((MAP_W-1)*MAP_SCALE);	//位置x
	 objposi[i].z= RAND_COORD((MAP_W-1)*MAP_SCALE);	//位置z
	 objposi[i].size=5.0f+rand()%5;					//大小2-4随机
	 objposi[i].h=-objposi[i].size/10;				//深浅
	 objposi[i].cactus=rand()%4+11;					//树形随机4种
	}

	glEnable(GL_TEXTURE_2D);
}
baiscobj::~baiscobj()
{	for(int i=0;i<16;i++) glDeleteTextures(1, &g_cactus[i]);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
//场景===========================================================
void baiscobj::light0()
{	GLfloat light_position[] = {1.0,5.0,1.0,1.0};
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);
}
BOOL baiscobj::DisplayScene()//摄像漫游
{ float speed=0.5f;						//步长
  int mouseX, mouseY;	                    //定义鼠标的轨迹变化量X、Y
  inputSys->Update();                       //清除鼠标接口
  inputSys->GetMouseMovement(mouseX,mouseY);//获取鼠标的轨迹变化量X、Y
  g_Angle +=  mouseX*.2f;                   //场景方位角加上鼠标轨迹变化量X
  g_elev  += -mouseY*.2f;                   //场景俯仰角加上鼠标轨迹变化量Y
  float x=g_eye[0],y=g_eye[2],z=g_eye[2];
  if (KEY_DOWN(VK_SHIFT))  speed   =speed*2;//按SHIFT时的加速true
  if (KEY_DOWN(VK_LEFT))   g_Angle-=speed*2;//左转,方位角-
  if (KEY_DOWN(VK_RIGHT))  g_Angle+=speed*2;//右转,方位角+
  rad_xz = float (3.13149* g_Angle/180.0f);	//计算左右旋转角度
  if (KEY_DOWN(33))		   g_elev +=speed;	//Page UP  键
  if (KEY_DOWN(34))		   g_elev -=speed;	//Page Down键
  if (g_elev<-360)		   g_elev  =-360;	//仰俯角
  if (g_elev> 360)		   g_elev  = 360;	//仰俯角
  if (KEY_DOWN(VK_UP))						//前进
  { g_eye[2]+=(float)sin(rad_xz)*speed;			//视点的x分量
    g_eye[0]+=(float)cos(rad_xz)*speed;			//视点的Z分量
  }
  if (KEY_DOWN(VK_DOWN))					//后退
  { g_eye[2]-=(float)sin(rad_xz)*speed;			//视点的x分量
    g_eye[0]-=(float)cos(rad_xz)*speed;			//视点的Z分量
  }
 //控制到摄像机不离开地面
  if(g_eye[0]<  MAP_SCALE)			g_eye[0]=  MAP_SCALE;
  if(g_eye[0]> (MAP_W-2)*MAP_SCALE)	g_eye[0]= (MAP_W-2)*MAP_SCALE;
  if(g_eye[2]<-(MAP_W-2)*MAP_SCALE)	g_eye[2]=-(MAP_W-2)*MAP_SCALE;
  if(g_eye[2]> -MAP_SCALE)			g_eye[2]= -MAP_SCALE;
  g_eye[1] =GetHeight((float)g_eye[0],(float)g_eye[2])+gao;//设置摄像机对地位置高
  //摄像机的方向
  g_look[0] = (float)(g_eye[0] +100*cos(rad_xz));	//目标点X分量
  g_look[2] = (float)(g_eye[2] +100*sin(rad_xz));	//目标点Z分量
  g_look[1] = g_eye[1] +g_elev;				//目标点Y分量
  //建立modelview矩阵方向
  gluLookAt(g_eye[0],g_eye[1],g_eye[2],		//视点
			g_look[0],g_look[1],g_look[2],	//目标点
			0.0,1.0,0.0						//视点方向
		   );
  ////////////////////////////////////////////////////////////////
  int r0=abs((int)g_Angle);
  test.Format("[方位=%03d X=%3.0f y=%3.0f 高=%2.1f 俯仰角=%2.0f,re=%03.0f]",
		  r0%360,g_eye[0],-g_eye[2],g_eye[1],g_elev,r);
  r+=1.0f;if(r>360) r=0;

  if (KEY_DOWN(' ')||Lbutdown==true)	//空格或鼠标左键射击
  {rocketX=g_eye[0],rocketZ=g_eye[2];
   rocketY=GetHeight(rocketX, rocketZ)+1.6f;
   m_mdlobj.fire(1);
   fire();								//射击
   sndPlaySound("data/images/explode1.wav",SND_ASYNC);//枪声
  }
  zangan(x,z);//碰撞绕行
  return TRUE;
}
//==========================================================================
void baiscobj::InitTerrain(float h)//建立地域数组
{ int index = 0;
  int Vertex;
  for (int z = 0; z < MAP_W; z++)
   for (int x = 0; x < MAP_W; x++)
    { Vertex = z * MAP_W + x;
      g_terrain [Vertex][0] = float(x)*MAP_SCALE;	//地域数据X分量
//      g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);//Y分量,山的高度
	  g_terrain [Vertex][1] = h + FRAND * h;		//Y分量,随机产生山的高度
      g_terrain [Vertex][2] = -float(z)*MAP_SCALE;	//地域数据Z分量
      g_texcoord[Vertex][0] = (float) x;			//索引数组x
     g_texcoord[Vertex][1] = (float) z;				//索引数组z
     g_index [index++] = Vertex;					//顶点数组1维
     g_index [index++] = Vertex+ MAP_W;
   }
  glEnableClientState(GL_VERTEX_ARRAY);				//允许使用地域数组
  glVertexPointer    (3,GL_FLOAT,0,g_terrain);		//装入地域数据
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);		//允许使用索引数组
  glTexCoordPointer  (2,GL_FLOAT,0,g_texcoord);		//装入索引数组
}
void baiscobj::DrawSand()//显示随机山势
{ glBindTexture(GL_TEXTURE_2D, g_cactus[0]);//地贴图
  glTexEnvf    (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//放大采用线性滤波
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  for (int z = 0; z < MAP_W-1; z++)
    glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]);
	//显示由顶点数组指定的面。
}
float baiscobj::GetHeight(float x, float z)// 取地面高度
{ 	float CameraX = x/MAP_SCALE;              //计算在那一块
	float CameraZ =-z/MAP_SCALE;              //计算在那一块
	int Col0 = int(CameraX);                  //块的列号
	int Row0 = int(CameraZ);                  //块的行号
	int Col1 = Col0 + 1;                      //相邻列
	int Row1 = Row0 + 1;                      //相邻行
	if (Col1 > MAP_W)	Col1 = 0;             //相邻列大于地块数,取首列
	if (Row1 > MAP_W)	Row1 = 0;             //相邻行大于地块数,取首行
	if (Col0 <	0)		Col0 = 0;             //相邻列大于地块数,取首列
	if (Row0 <	0)		Row0 = 0;             //相邻行大于地块数,取首行
	if (Col1 <	0)		Col1 = 0;             //相邻列大于地块数,取首列
	if (Row1 <	0)		Row1 = 0;             //相邻行大于地块数,取首行
	float h00=g_terrain[Col0 + Row0*MAP_W][1];//获取块四角的高度
	float h01=g_terrain[Col1 + Row0*MAP_W][1];
	float h11=g_terrain[Col1 + Row1*MAP_W][1];
	float h10=g_terrain[Col0 + Row1*MAP_W][1];
	float tx =CameraX - int(CameraX);         //求块内X偏移位置
	float ty =CameraZ - int(CameraZ);         //求块内Z偏移位置
	float txty = tx * ty;                     //以下为双线性插值(内插)计算
	return h00*(1.0f-ty-tx+txty) 
			+ h01*(tx-txty)
			+ h11*txty
			+ h10*(ty-txty);                  //返回插值计算值,为所求点的高度。
}
void baiscobj::CreateSkyBox(int a,int wi,int he,int le)//显示天空
{	float width =MAP*wi;		// 天空盒宽
	float height=MAP*he;		// 天空盒高
	float length=MAP*le;		// 天空盒长
	float x = MAP  -width /2;	// 天空的位置x
	float y = MAP/a-height/2;	// 天空的位置y
	float z = -MAP -length/2;	// 天空的位置z
///////////////////////////////////////////////////////////////////////////////
	texture(g_cactus[2]);		// 设置BACK贴图左
	glBegin(GL_QUADS);			// 多组独立填充四边形	
		glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,		 z);
		glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z); 
		glTexCoord2f(0.0f,1.0f); glVertex3f(x,		y+height,z);
		glTexCoord2f(0.0f,0.0f); glVertex3f(x,		y,		 z);
	glEnd();
	texture(g_cactus[3]);		// 设置FRONT贴图右
	glBegin(GL_QUADS);			// 多组独立填充四边形
		glTexCoord2f(1.0f,0.0f); glVertex3f(x,		y,		 z+length);
		glTexCoord2f(1.0f,1.0f); glVertex3f(x,		y+height,z+length);
		glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z+length); 
		glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,		 z+length);
	glEnd();
/*	texture(g_cactus[1]);		// 设置BOTTOM贴图底
	glBegin(GL_QUADS);			// 多组独立填充四边形	
		glTexCoord2f(1.0f,0.0f); glVertex3f(x,		y,		z);
		glTexCoord2f(1.0f,1.0f); glVertex3f(x,		y,		z+length);
		glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y,		z+length); 
		glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,		z);
	glEnd();*/
	texture(g_cactus[4]);		// 设置TOP贴图顶
	glBegin(GL_QUADS);			// 多组独立填充四边形		
		glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
		glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y+height,z+length); 
		glTexCoord2f(1.0f,0.0f); glVertex3f(x,		y+height,z+length);
		glTexCoord2f(1.0f,1.0f); glVertex3f(x,		y+height,z);
	glEnd();
	texture(g_cactus[5]);		// 设置LEFT贴图前
	glBegin(GL_QUADS);			// 多组独立填充四边形
		glTexCoord2f(1.0f,1.0f); glVertex3f(x,		y+height,z);	
		glTexCoord2f(0.0f,1.0f); glVertex3f(x,		y+height,z+length); 
		glTexCoord2f(0.0f,0.0f); glVertex3f(x,		y,		 z+length);
		glTexCoord2f(1.0f,0.0f); glVertex3f(x,		y,		 z);		
	glEnd();
	texture(g_cactus[6]);		// 设置RIGHT贴图后
	glBegin(GL_QUADS);			// 多组独立填充四边形		
		glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,		 z);
		glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,		 z+length);
		glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z+length); 
		glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
	glEnd();
}
void baiscobj::texture(UINT textur)//设置贴图滤波
{	glBindTexture  (GL_TEXTURE_2D, textur);// 设置贴图
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); //缩小采用线性滤波
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//放大采用线性滤波
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
//组合图形=================================================================
void baiscobj::picter(float x,float y,float z)//组合图形
{y=GetHeight(x,z);
 glPushAttrib(GL_CURRENT_BIT);//保存现有颜色属实性
 glDisable(GL_TEXTURE_2D);
 glPushMatrix();//平台==============================
	glTranslatef(x,y+0.5f,z);		//平台的定位
	glColor3f(0.0f,1.0f,0.2f);		//绿色
	auxSolidCube(1);				//方台(边长)
	glTranslatef(0.0f,0.8f,0.0f);	//架的位置调整,上升0.8
	glColor3f(0.0f,0.0f,1.0f);		//蓝色
	auxSolidBox(.2f,1.3f,.2f);		//长方架(宽、高、长)
 glPopMatrix();
 glPushMatrix();//雷达==============================
	glTranslatef(x,y+2.5f,z);		//雷达的定位1
	glRotatef(r-90,0.0,1.0,0.0);	//雷达旋转2
	//=======================================
	glColor3f(1.0f,1.0f,1.0f);		//白色
	glRotatef(45, 1.0, 0.0, 0.0);	//盘的角度调整,仰30度
	auxWireCone(1.5,0.6f);			//线园锥盘(底半径、高)
	//=======================================
	glRotatef(180, 1.0, 0.0, 0.0);	//杆的角度调整,反方向转
	glTranslatef(0.0f,0.0f,-0.7f);  //杆的位置调整,缩进一点

⌨️ 快捷键说明

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