陆地与线的碰撞

来源:互联网 发布:淘宝开店需要多少钱 编辑:程序博客网 时间:2024/04/19 15:09

--------西昌.何雨锋 陆地与线的碰撞

//第一人称射击,鼠标点中,成功

#include "stdafx.h"
#include "tv3dcpp.h"
#include <math.h>
#include "flag2.h"

ITVEngine engine1;             //引擎
ITVInputEngine input1;         //输入引擎
ITVScene scene1;               //场景
ITVGlobals global1;            //全球变量
ITVAtmosphere atmos1;          //环境
ITVCamera cam1;
ITVScreen2DImmediate imt1;
ITVMesh flash1;                 //用来做枪的闪光
TV_COLLISIONRESULT col1;
ITVLandscape land1;            //陆地
ITVTextureFactory fac1;        //纹理工厂?

int i;

char ch1[10];

D3DVECTOR pos1;                //D3D是DX中的3D位置,这里只用这结构来得到地图中的起始位置

ITVActor2 man2;                 //用来读取mdl的模型
ITVActor2 weapon1;              //用来读取自己手上的武器

D3DVECTOR vector1,vector2,vector3;   //2,3是用来装鼠标抓的点的
D3DVECTOR wfp;                   //用来装开火的火焰位置
D3DVECTOR vecnow;
flag1 flaga;
void render();
void input();
void unload();

double xrot=0;                 //
double yrot=0;
double zrot=0;
double xpos=0;                 //主角位置
double ypos=0;
double zpos=0;
double lookx=0;                //主角视点
double looky=0;
double lookz=0;
double xangle=0;
double yangle=0;
double arcc=0;
double timeleft;
float me_walk = 0.0;            //前后移动变量
float me_strafe = 0.0;          //左右移动变量
float me_updown=0.0;


long oldweapon;               //用来记录过去的时间点
bool shot;                      //用来记录是否正在射击

void draw_axis(void);
LRESULT CALLBACK WndProc(HWND wpHWnd, UINT msg, WPARAM wParam, LPARAM lParam);

//建立一个窗体
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 HWND WindowHandle;
// HINSTANCE hInst;
 
 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "TV3D Tutorial", NULL };
  RegisterClassEx(&wc);

 WindowHandle = CreateWindow( "TV3D Tutorial", "第一人称射击",
                              WS_OVERLAPPEDWINDOW, 100, 100, 640, 480,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

 // there is a problem creating the window
 if (WindowHandle ==  NULL)
 {
  MessageBox(NULL, "Unable to Create a Window", "Error", MB_OK);
  return false;
 }

 
  ShowWindow  (WindowHandle, 1);
  UpdateWindow (WindowHandle);
  SetFocus  (WindowHandle);
  ShowCursor  (TRUE);

 //初始化COM?
 CoInitialize(NULL);

 engine1 = CreateTVEngine();
 
 //Engine Running boolean
 double Gamma = 0.0;
 MSG msg;
 
 //将引擎初始化到窗体中
    engine1->SetDebugFile("debug.txt");
 engine1->ShowDriverDialog();
 engine1->Init3DWindowedMode ((long)WindowHandle, true);

 //打开显示FPS开关
 engine1->put_DisplayFPS(tvtrue);
   
 //使用角度而非幅度
 engine1->SetAngleSystem(TV_ANGLE_DEGREE);
 //将输入引擎、场景、全球变量、环境实例化
 input1 = CreateTVInputEngine();  
 scene1=CreateTVScene();
 global1=CreateTVGlobals();
 atmos1=CreateTVAtmosphere();
    fac1=CreateTVTextureFactory();
 man2=CreateTVActor2();
 weapon1=CreateTVActor2();
 cam1=CreateTVCamera();
 imt1=CreateTVScreen2DImmediate();
 char path[256];
 char srchpath[256];
 
 HMODULE Module = (HMODULE)hInstance;
 GetModuleFileName(Module,path,255);

 AppPath(path,srchpath); 
 //设置资源文件的路径
 
 engine1->SetSearchDirectory(srchpath);
 engine1->SetAngleSystem (TV_ANGLE_DEGREE);
 long texture1;


  fac1->LoadTexture("..//..//..//Media//water.bmp","water1",-1,-1,TV_COLORKEY_NO,tvtrue,tvtrue);
 fac1->LoadTexture("..//..//..//Media//snowpar.bmp", "snow",-1,-1,TV_COLORKEY_BLACK,tvtrue,tvtrue);
 fac1->LoadTexture("..//..//..//Media//expl1.jpg","flash",-1,-1,TV_COLORKEY_BLACK,tvtrue,tvtrue);
 scene1->LoadTexture("..//..//..//Media//up.jpg",-1,-1,"box_up");
    scene1->LoadTexture("..//..//..//Media//down.jpg",-1,-1,"box_down");
    scene1->LoadTexture("..//..//..//Media//left.jpg",-1,-1,"box_left");
    scene1->LoadTexture("..//..//..//Media//right.jpg",-1,-1,"box_right");
    scene1->LoadTexture("..//..//..//Media//front.jpg",-1,-1,"box_front");
    scene1->LoadTexture("..//..//..//Media//back.jpg",-1,-1,"box_back");

    scene1->LoadTexture("..//..//..//Media//down.jpg",-1,-1,"wall1");

 scene1->LoadTexture("..//..//..//Media//terrain3.jpg",-1,-1,"map1");
 //读天空材质并将其取名,然后用atmos的天空盒功能显示六面天空
    atmos1->SkyBox_SetTexture(global1->GetTex("box_front"),global1->GetTex("box_back"),global1->GetTex("box_left"),global1->GetTex("box_right"),global1->GetTex("box_up"),global1->GetTex("box_down"));
    atmos1->SkyBox_Enable(tvtrue,tvtrue);
 atmos1->Rain_Init(100,fac1->GetItem("snow"),-4,0,0,2,30,10,2000,5,0);
 atmos1->Rain_Enable(tvtrue);
 //建立一个凹吐之地
 land1=CreateTVLandscape();
 land1->GenerateHugeTerrain("..//..//..//Media//height1.jpg",TV_PRECISION_LOW,16,16,500,500,tvtrue);
    land1->SetTerrainScale(1,3,1,tvfalse);
   
 land1->CreateDynTextures(128,128,tvfalse,tvtrue);
 land1->SetTexture(global1->GetTex("map1"),1);
 land1->SetTextureScale(1,1,1);
 land1->DynDrawTexture(global1->GetTex("map1"),5000,5000,1,1,global1->RGBA(170,200,170,0.1),tvtrue,tvfalse,1,1,1,1); 
 


 flaga.init_flag();
    man2->Load("..//..//..//Media//asianb02.mdl","body",tvfalse,tvtrue);

 man2->SetAnimationID(5);
 man2->SetScale(3,3,3);
 

 man2->SetPosition(2000,land1->GetHeight(2000,2000)+20,2000);
 man2->SetRotation(0,0,0);
 man2->PlayAnimation(50);
    //man2->SetAnimation(2); 
    weapon1->Load("..//..//..//Media//v_shotgun.mdl","body",tvfalse,tvtrue);
 weapon1->SetAnimationByName("idle");
 weapon1->PlayAnimation(1);
 //weapon1->SetScale(1,1,2);
 weapon1->SetPosition(xpos,ypos,zpos);
 shot=false;
 xrot=1;yrot=1;zrot=1;
 xpos=pos1.x;
 ypos=pos1.y;
 zpos=pos1.z;
 ypos=3;zpos=15;
    scene1->SetCamera(xpos,ypos,zpos,xrot,yrot,zrot);//相机位即我位
 scene1->SetViewFrustum (60, 10000);
    cam1=scene1->GetCamera();
 flash1=scene1->CreateBillboard(fac1->GetItem("flash"),-1,-1,-1,5,5,"falshx",tvtrue,(enum TrueVision3D::CONST_D3DBLEND) D3DBLEND_ZERO,(enum TrueVision3D::CONST_D3DBLEND) D3DBLEND_ONE,0,tvfalse);
 while( msg.message!=WM_QUIT)
 {
  if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  {
   TranslateMessage( &msg );
   DispatchMessage( &msg );
  }
  else
  {
   render();
   input();
  }
 }  

 //Uninitialize the variables
 unload();

 //Exit sucessfully
 return 0;
}

//渲染
void render()
{
 engine1->Clear(false);

    atmos1->Atmosphere_Render();
 scene1->RenderAllMeshes(tvfalse);
       
 land1->Render(tvtrue,tvtrue);        
    man2->Render();
    flaga.render_flag();
    weapon1->Render();

 
   
   

 scene1->DrawText("x",100,100,RGBA(100,100,100,0.9));

 scene1->DrawText("y",100,200,RGBA(100,100,100,0.9));

 scene1->DrawText("z",100,300,RGBA(100,100,100,0.9));

    ltoa(lookx,ch1,5);
 scene1->DrawText(ch1,300,100,RGBA(100,100,100,0.9));
    ltoa(looky,ch1,5);
 scene1->DrawText(ch1,300,200,RGBA(100,100,100,0.9));
 ltoa(lookz,ch1,5);
 scene1->DrawText(ch1,300,300,RGBA(100,100,100,0.9));

 scene1->DrawText("第一人称射击",350,10,global1->RGBA(1,0,0,1));
 scene1->DrawText("实验制作:何雨锋。西昌",380,22,global1->RGBA(1,0,0,1));
    draw_axis();
 engine1->RenderToScreen ();  

}


void input()
{
 if(input1->IsKeyPressed(TV_KEY_ESCAPE))  //Check if ESCAPE has been pressed.
 { 
  PostQuitMessage(0);
 }
 if(input1->IsKeyPressed(TV_KEY_UP))
     me_walk=0.2;
 if(input1->IsKeyPressed(TV_KEY_DOWN))
     me_walk=-0.2;
    if(input1->IsKeyPressed(TV_KEY_LEFT))
     me_strafe =0.2;
 if(input1->IsKeyPressed(TV_KEY_RIGHT))
     me_strafe = -0.2;

 

 if(input1->IsKeyPressed(TV_KEY_W))
        me_walk = 1;

    if(input1->IsKeyPressed(TV_KEY_S))
        me_walk = -1;

    if(input1->IsKeyPressed(TV_KEY_A))
        me_strafe =1;

    if(input1->IsKeyPressed(TV_KEY_D))
        me_strafe = -1;
    if(input1->IsKeyPressed(TV_KEY_C))
        me_updown=-1;
 if(input1->IsKeyPressed(TV_KEY_SPACE))
        me_updown=1;

    long mousex = 0; long mousey = 0;
    int mouse_b1 = 0; int mouse_b2 = 0; int mouse_b3 = 0;  
    long mouse_old = 0; long mouse_new = 0;
    mouse_old = mouse_new;


    input1->GetMouseState(&mousex,&mousey,(short *)&mouse_b1,(short *)&mouse_b2,(short *)&mouse_b3,&mouse_old);
   
   


    xangle = xangle - ((float)mousey / 100.0f);
    yangle = yangle - ((float)mousex / 100.0f);
    if(xangle > 1.3f) xangle = 1.3f;
    if(xangle < -1.3f) xangle = -1.3f;
 if(me_walk > 0)
 {
        me_walk = me_walk - 0.05f;
        if(me_walk < 0) me_walk = 0;
 }
    if(me_walk < 0)
 {
        me_walk = me_walk + 0.05f;
        if(me_walk > 0) me_walk = 0;
 }

    if(me_strafe > 0)
 {
        me_strafe = me_strafe - 0.05f;
        if(me_strafe < 0) me_strafe = 0;
 }
    if(me_strafe < 0)
 {
        me_strafe = me_strafe + 0.05f;
        if(me_strafe > 0) me_strafe = 0;
 }
 timeleft=engine1->TimeElapsed();
    //不知道hl中是否也这样写的呢?上下移动是否与鼠标无关?
    xpos = xpos + (cosf(yangle) * me_walk * timeleft) + (cosf(yangle + 3.141596f / 2.0f) * me_strafe * timeleft);
    zpos = zpos + (sinf(yangle) * me_walk * timeleft) + (sinf(yangle + 3.141596f / 2.0f) * me_strafe * timeleft);
 ypos = ypos + me_updown*10;
 me_updown=0;
 lookx = xpos + cosf(yangle);
    looky = ypos + tanf(xangle);
    lookz = zpos + sinf(yangle); 

 scene1->SetCamera(xpos,ypos,zpos,lookx,looky,lookz);

    weapon1->SetPosition(xpos,ypos,zpos);
   
    weapon1->SetRotation(0,180-yangle*180/3.14,-xangle * 180 / 3.14);
  

    if(mouse_b1&&shot==false)
 {
  weapon1->SetAnimationByName("pump");
  weapon1->PlayAnimation(16);
     shot=true;
  oldweapon=engine1->TickCount();
  vector1=global1->VScale(&(global1->Vector(cos(yangle),-1, sin(yangle))),3); 
  wfp=global1->VAdd(&(global1->Vector(xpos, ypos,zpos)),&vector1);
        flash1->SetPosition(wfp.x,wfp.y,wfp.z);
        flash1->Enable(tvtrue);
  input1->GetAbsMouseState(&mousex,&mousey,(short *)&mouse_b1,(short *)&mouse_b2,(short *)&mouse_b3);
      
  global1->MousePickVector(mousex,mousey,&vector2,&vector3);  
  scene1->AdvancedCollision(&vector2,&vector3,&col1,TV_COLLIDE_LANDSCAPE,TV_TESTTYPE_ACCURATETESTING,tvtrue);
        if(col1.hascollided)
  {
     man2->SetPosition(col1.collisionimpact.x,col1.collisionimpact.Y,col1.collisionimpact.Z);
  }
       
  //global1->MovePoint(&vector3,&vector2,-xangle * 180 / 3.14,90-yangle*180/3.14,2000);

  //vector3=global1->Vector(180-yangle*180/3.14*vector3.x,180-yangle*180/3.14*vector3.y,-xangle * 180 / 3.14*vector3.z); 
 
 }


 if(shot&&(engine1->TickCount()-oldweapon)>50)
 { //控制枪光的长短
  flash1->Enable(tvfalse);
 } 

 if(shot&&(engine1->TickCount()-oldweapon)>500)
 { 
  shot=false;
  mouse_b1=NULL;
  weapon1->SetAnimationID(1);
  mouse_b1=0;
 }   

 if(input1->IsKeyPressed(TV_KEY_R))
 {
  weapon1->SetAnimationByName("reload");
  weapon1->PlayAnimation(18);
  shot=false;
 }


}

void unload()
{

 man2->Release();
 man2=NULL;
    scene1->DestroyAllMeshes();
    scene1->Release();
    scene1=NULL;
 input1->Release();
 input1=NULL;
 engine1->Release;
 engine1=NULL;
 CoUninitialize();
}

LRESULT CALLBACK WndProc(HWND wpHWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

 switch(msg)
 { 
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   return 0;
  } break;


  default:break;
 }


 return DefWindowProc(wpHWnd, msg, wParam, lParam);

}


void draw_axis(void)
{
 imt1->ACTION_Begin2D();
 imt1->DRAW_Line3D(0,0,0,50,0,0,-1,-1);
 imt1->DRAW_Line3D(0,0,0,0,50,0,RGBA(0,1,0,1),RGBA(0,1,0,1));
 imt1->DRAW_Line3D(0,0,0,0,0,50,RGBA(0.5,0.5,0.5,1),RGBA(0.5,0.5,0.5,1));
 imt1->DRAW_Line3D(vector2.x,vector2.y,vector2.z,vector3.x,vector3.y,vector3.z,RGBA(0.5,0.5,0.5,1),RGBA(0,1,0,1));
 //man2->SetPosition(vector3.x,vector3.y,vector3.z);
 imt1->ACTION_End2D();
}

原创粉丝点击