woaidaima2016 发表于 2017-6-13 11:20:39

【78】8台球【源码】

http://img.woaidaima.com//upload/image/20170522/1495415013106019441.pnghttp://img.woaidaima.com//upload/image/20170522/1495415014901063400.png

#include "StdAfx.h"
#include ".\ballrender.h"
//
// floatSta_friction = 0.003f; //球的滑动摩擦系数
// floatRou_friction = 0.00022f; //球的滚动摩擦系数
// floatXuan_friction = 0.00014f;//球的旋切摩擦系数
//
// floatSta_friction = 0.00299f; //球的滑动摩擦系数
// floatRou_friction = 0.00030f; //球的滚动摩擦系数
// floatXuan_friction = 0.0002f;//球的旋切摩擦系数
floatdt=1.0f ;
floatSta_friction = 0.003f; //球的滑动摩擦系数
floatRou_friction = 0.00022f; //球的滚动摩擦系数
floatXuan_friction = 0.00014f;//球的旋切摩擦系数
// floatSta_friction = 1.003f; //球的滑动摩擦系数
// floatRou_friction = 0.00025f; //球的滚动摩擦系数
// floatXuan_friction = 0.00019f;//球的旋切摩擦系数




Vector3 light;
Vector3Pos;
BYTE mapX;
float diff ;
Vector3 ver;
short FJC ;

HTEXTURE      texLight=0;
HTEXTURE      texShadow=0;
HTEXTURE      texBall=0;

CHgeSprite*      pSpriteShadow=NULL;
CHgeSprite*      pSprite=NULL;
CHgeSprite*   pSpriteLight=NULL;

CBallRender::CBallRender(void)
{   
    Iz =M*banjin*banjin*2/5;
    SENSTA_FRICTION = Sta_friction * 1.f + Sta_friction * M / Iz * banjin * banjin;//滑动摩擦最小检测阀值
    SENROU_FRICTION = Rou_friction * 1.f;//滚动摩擦最小检测阀值

    BALL_State=4;   //球静止
    BALL_bEnable=true ;//    是否有效
    BALL_V=Vector3(0);
    BALL_Vang=Vector3(0);
    BALL_Orientation=matrix3_identity();   
    BALL_bIsRedraw =false;   
    BALL_bIsInit =false;
    tex = NULL;
    offsetx = 0;
    offsety = 0;
    banJin = 16;
    zhiJin = 32;
    binhole = false;
    pSpriteLight = NULL;
    m_pIGameFrameView = NULL;
}

CBallRender::~CBallRender(void)
{   
//    m_GraphHelper->Free();
}

//应用力
void CBallRender::ApplyForce(Vector3 force,Vector3 colpos)
{
    floatdt=1.0f ;
    apply_impulse (force* dt, colpos);
}

void CBallRender::apply_impulse(Vector3 impulse ,Vector3 colpos)//摩擦力
{
    Vector3 Ra , vatmp ;

    BALL_V+= (impulse/ M);//线速度
    if(impulse.Z!=0.0&&abs(impulse.Z)>1)
    {
      BALL_V.X /= impulse.Z;
      BALL_V.Y /= impulse.Z;
    }
    BALL_V.Z = 0 ; //不能够向下

    Ra= colpos- Ball_Pos;

    vatmp = cross(Ra, impulse) / Iz    ;
    BALL_Vang+=vatmp;//角速度

    static Vector3 temp = BALL_V;
    TRACE("BALL_Vang.X=%f,BALL_Vang.Y=%f,BALL_Vang.Z=%f",BALL_Vang.X,BALL_Vang.Y,BALL_Vang.Z);
    TRACE("BALL_V.X=%f,BALL_V.Y=%f,BALL_V.Z=%f",BALL_V.X,BALL_V.Y,BALL_V.Z);
    TRACE("增量:x = %f,y = %f,z = %f",BALL_V.X - temp.X,BALL_V.Y - temp.Y,BALL_V.Z-temp.Z);
    temp = BALL_V;
}

void CBallRender::Reset(int _ballNo,Vector3 _ballPos,bool _enable)
{
    Ball_Pos =_ballPos;
    BallNo =_ballNo;
    BALL_bEnable =_enable;
}

void CBallRender::Init(int _ballNo,Vector3 _ballPos)
{
    HGE* pHge = NULL;
    if (NULL != m_pIGameFrameView)
      pHge = m_pIGameFrameView->GetHge();
   
//    ASSERT(NULL != pHge);
    if (NULL == pHge) return;

    Ball_Pos =_ballPos;//Vector3(rand()%700+20,rand()%500+20,0);   
    BallNo =_ballNo;   
    if (tex)
    {
      BALL_bEnable = true;
      return;
    }

    //tex = m_GraphHelper->Texture_Create(zhiJin,zhiJin);
    tex =pHge->Texture_Load("TaiQiu\\pic\\mask1.bmp");
    Vector3ran = NormaliseVector(Vector3(ranged_random(.1f,2),ranged_random(.1f,2),ranged_random(.1f,2)));
    BALL_Orientation = rotation_matrix (ranged_random(1,800), ran);    // 设置每个球的随机方位

    HTEXTUREtexMask;
    texMask = pHge->Texture_Load(("TaiQiu\\pic\\mask1.bmp"));
    if (texBall==0)
    {   
      texLight = pHge->Texture_Load(("TaiQiu\\pic\\TEX_Specular25.bmp"));   
      texBall = pHge->Texture_Load(("TaiQiu\\pic\\TEX_BALL.bmp"));
      texShadow = pHge->Texture_Create(zhiJin,zhiJin);
      //pSpriteShadow2 = new CHgeSprite (_T("TaiQiu\\pic\\Ball_Shadow.png"));

      pSpriteShadow = new CHgeSprite(texShadow,0,0,zhiJin,zhiJin);
      pSpriteShadow->SetHotSpot(16,16);
      pSpriteShadow->SetColor(0xff000000);

      DWORD *ptex = pHge->Texture_Lock(tex,false);
      DWORD *ptexmask = pHge->Texture_Lock(texMask);
      DWORD *ptexlight = pHge->Texture_Lock(texLight,false);
      DWORD *ptexShadow = pHge->Texture_Lock(texShadow,false);
      for(int i=0;i<zhiJin;i++)
      {
            for(int j=0;j<zhiJin;j++)
            {
                DWORD col = ptexmask;
                BYTE *p = (BYTE*)&col;
                BYTE c = ((int)*(p)+6*(int)*(p+1)+3*(int)*(p+2))/10;    //设置透明度      
                col = ptex;
                ptex = SETA(ptex,c);
                //ptexlight = SETA(ptexlight,c);
                col = ptex;
                //ptex = SETG(ptex,0XFF);//设置绿色?
                  //ptex = SETR(ptex,100);//设置绿色?
                  //ptex = SETB(ptex,165);//设置绿色?
                p =(BYTE*)&ptexShadow;
                *(p+3)=c/2;
            }
      }
    /*    for(int i=0;i<25;i++)
      {
            for(int j=0;j<25;j++)
            {
                DWORD col = ptexlight;
                BYTE c = 0;
                if(col==0xff000000)
                  c = 0;
                else c = 0xff;
                ptexlight = SETA(ptexlight,c);
            }
      }*/
      pHge->Texture_Unlock(tex);
      pHge->Texture_Unlock(texMask);
      pHge->Texture_Unlock(texLight);
      pHge->Texture_Unlock(texShadow);   

      light = Vector3(800/2,520/2,-500);

      float X,Y,Z;
      //法线预处理   
      for(int i=0;i<zhiJin;i++)
      {
            for(int j=0;j<zhiJin;j++)
            {
                mapX =0;
                X =i-banJin+0.5;
                Y =j-banJin+0.5;
                ver.X =X;//法线
                ver.Y =Y;
                Z = banJin*banJin-(X*X + Y*Y);      
                if (Z>=0)
                {
                  ver.Z = -sqrtf(Z);
                  mapX = 1;
                }
            }
      }
    }

    DWORD *ptex = pHge->Texture_Lock(tex,false);
    DWORD *ptexmask = pHge->Texture_Lock(texMask);      
    for(int i=0;i<zhiJin;i++)
    {
      for(int j=0;j<zhiJin;j++)
      {
            DWORD col =ptexmask;
            BYTE*p =(BYTE*)&col;
            BYTE c=((int)*(p)+6*(int)*(p+1)+3*(int)*(p+2))/10;
      /*    DWORD temp = GETA(col);      
            if(col==0xff000000)
                temp = 0;
            else temp = c;*/
            col =ptex;            
            ptex =SETA(ptex,c);            
            col =ptex;
      //    ptex =SETG(ptex,0xFF);      
            //    ptex = SETR(ptex,100);//设置绿色?
            //    ptex = SETB(ptex,165);//设置绿色?
      }
    }
    pHge->Texture_Unlock(tex);
    pHge->Texture_Unlock(texMask);
    pHge->Texture_Free(texMask);

    pSprite = new CHgeSprite(tex,0,0,zhiJin,zhiJin);
    pSprite->SetHotSpot(banJin,banJin);   
    pSprite->SetZ(0.6f);

    pSpriteLight = new CHgeSprite(texLight,0,0,25,25);
    pSpriteLight->SetHotSpot(banjin,banjin);   
    pSpriteLight->SetZ(0.6f);

    //int height = m_GraphHelper->Texture_GetHeight(tex,true);
    //CString str;
    //str.Format("zhiJin=%d,texHeight=%d,spriteHeight=%d,spriteWidth=%d",zhiJin,height,pSprite->GetHeight(),pSprite->GetHeight());
    //AfxMessageBox(str);
}


void CBallRender::Moveball()
{
    if    (BALL_bEnable==false) return;

    if (BALL_V.X==0&&BALL_V.Y==0&&BALL_V.Z==0
      &&BALL_Vang.X==0&&BALL_Vang.Y==0&&BALL_Vang.Z==0)
    {
      return ;
    }
    else
    {
      BALL_bIsRedraw =true;
    }

    Vector3 tool_ver, tra_ver, Normaliz;
    tra_ver = cross(BALL_Vang, Vector3(0, 0, banjin));
    tool_ver = (BALL_V+tra_ver) ;   
   
    if ((tra_ver.mag() < SENROU_FRICTION) && (Vector3(BALL_V.X, BALL_V.Y).mag() < SENROU_FRICTION))
    {
      BALL_State = 3;   //水平方向静止 灰
      BALL_V = Vector3(0, 0, 0);
      BALL_Vang.X = 0;   BALL_Vang.Y = 0 ;
    }
    else if (tool_ver.mag() < SENSTA_FRICTION)
    {
      TRACE("滚动摩擦");
      BALL_State = 2;   //滚动摩擦 绿
      Normaliz = NormaliseVector(BALL_V);
      apply_impulse (Normaliz*(-M * Rou_friction), Ball_Pos);
      BALL_Vang.X = BALL_V.Y / banjin;
      BALL_Vang.Y = -BALL_V.X / banjin;
    }
    else
    {
      TRACE("滑动摩擦");
      BALL_State = 1 ;//滑动摩擦 红
      Normaliz = NormaliseVector(tool_ver);   
      apply_impulse ( Normaliz*(-M * Sta_friction ), (Ball_Pos+Vector3(0, 0, banjin))    );
    }

    //旋切摩擦
    if (fabs(BALL_Vang.Z) < Xuan_friction)
      BALL_Vang.Z = 0 ;
    else
    {
      if (BALL_Vang.Z > 0)
            BALL_Vang.Z-=Xuan_friction ;
      else
            BALL_Vang.Z +=Xuan_friction;
    }

    if ((BALL_State == 3) && (BALL_Vang.Z == 0))BALL_State = 4; //完全静止 黑

    Ball_Pos+= (BALL_V* dt);
    Matrix3 Mtmp ;
   Vector3 & rot = BALL_Vang;

    Mtmp=dt * Matrix3(      0,rot, -rot,
                      -rot,       0,rot,
                     rot, -rot,       0 ) * BALL_Orientation;
   
    BALL_Orientation += Mtmp;
    BALL_Orientation.orthonormalise();
}

void CBallRender::Move()
{      
    Moveball();      
}
void CBallRender::UpdateBallTex()
{
    HGE* pHge = NULL;
    if (NULL != m_pIGameFrameView)
      pHge = m_pIGameFrameView->GetHge();

    ASSERT(NULL != pHge);
    if (NULL == pHge) return;

    int i,j;
    float IncX , IncY,lng;
    float X , Y , XYmag2;


    IncX = Ball_Pos.X - (INT)Ball_Pos.X;
    IncY = Ball_Pos.Y- (INT)Ball_Pos.Y;
    if(IncX!=0||IncY!=0)
    {
      int i=0;
      i++;
    }

    //    法线预处理
    for (i=0;i<33;i++)
    {
      for (j=0;j<33;j++)
      {


            mapX = 0 ;
            X =i - IncX - (banJin-0.5);
            Y = j - IncY - (banJin-0.5);
            Pos.X =X ;
            Pos.Y =Y ;

            XYmag2=(X*X + Y*Y);
            lng = banJin*banJin - XYmag2 ;
            if (lng > 0    )
            {
                Pos.Z = -sqrtf(lng)    ;
                mapX = 1 ;
            }


            //    边缘反锯齿
            lng = banJin - sqrtf(XYmag2) ;
            if (fabs(lng) < 0.4714f)
                CALEFJC (X, Y, i, j );
      }
    }
    //'计算漫反射
    Vector3 lightdir;
    lightdir = light-Ball_Pos;
    lightdir.normalise();

    for (i=0;i<zhiJin+1;i++)
    {
      for (j=0;j<zhiJin+1;j++)
      {

            if (mapX != 0)
            {
                diff = dot(Pos, lightdir) / banJin    ;
                if (diff < 0) diff = 0 ;
                diff = 0.3 + 0.7 * diff    ;
            }

      }
    }

    Matrix3 Mtmp ;
    Mtmp= transpose (BALL_Orientation);//反矩阵

    Vector3 pos;
    DWORD *ptex = pHge->Texture_Lock(tex,false);
    DWORD *ptexBall = pHge->Texture_Lock(texBall);
   
    int tempNo = BallNo-14;
    int offx =BallNo%4;
    int offy =BallNo/4;
    int mPitch =64*16;
    DWORD * inoff =ptexBall+offy*64*4*64+offx*64;   
    float tempNum = 31.5;
    int ballDraw_X, ballDraw_Y;
    ballDraw_X = (INT)Ball_Pos.X - banJin;
    ballDraw_Y = (INT)Ball_Pos.Y - banJin; // '左下角坐标
    for(int i=0;i<zhiJin;i++)
    {
      for(int j=0;j<zhiJin;j++)
      {
            //转换点
            pos= Mtmp *Pos;            
            if (mapX!=0)
            {
                if (pos.Z >0)
                {   
                  BYTE ca =GETA(ptex);
                  GetFitColor((tempNum-pos.X),(tempNum+pos.Y),inoff,mPitch,&ptex);
                  ptex =SETA(ptex,ca);
                }
                else
                {
                  BYTE ca =GETA(ptex);                  
                  GetFitColor((tempNum-pos.X),(tempNum-pos.Y),inoff,mPitch,&ptex);
                  ptex =SETA(ptex,ca);
                }

                MIX_multself1((BYTE*)&ptex,(INT)(diff*255));//'漫反射混合

               
                BYTE*P= ((BYTE*)&ptex);

                if (mapX == 2)
                {
                  //与地面混合
                  MIX_APLC((BYTE*)&ptex,P, FJC);
                }
            }            
      }
    }
    pHge->Texture_Unlock(tex);
    pHge->Texture_Unlock(texBall);
}


void CBallRender::Render()
{   
    if (BALL_bEnable==false) {
      return ;
    }
    if (BALL_bIsInit==false)
    {
      UpdateBallTex();
      BALL_bIsInit =true;
    }
    else if (BALL_bIsRedraw) {
      UpdateBallTex();
      BALL_bIsRedraw =false;
    }
    float PntX , PntY;
    float H, dx, dy;
    H = -light.Z;
    dx = Ball_Pos.X - light.X;
    dy = Ball_Pos.Y - light.Y;
    PntX = dx * (5 + H) / H + light.X;
    PntY = dy * (5 + H) / H + light.Y;
   
    //画阴影
    pSpriteShadow->SetBlendMode(BLEND_DEFAULT);
    pSpriteShadow->SetTexture(texShadow);
    //pSpriteShadow->Render(PntX+offsetx,PntY+offsety);
    pSpriteShadow->SetColor(ARGB(255,255,255,255));
    pSpriteShadow->RenderEx(PntX+offsetx,PntY+offsety,0,0.9,0.9);
    pSpriteShadow->SetColor(ARGB(125,0,0,0));
    pSpriteShadow->RenderEx(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety,0,0.88,0.88);


    //画球
    pSprite->SetBlendMode(BLEND_DEFAULT);
    pSprite->SetTexture(tex);
//    pSprite->Render(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety);
    pSprite->RenderEx(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety,0,0.8,0.8);
    //
    ////画高亮
    //pSpriteLight->SetTexture(texLight);
    //pSpriteLight->SetBlendMode(BLEND_MODE_COLORMUL );   
    //pSpriteLight->Render(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety);
   

}
void CBallRender::RenderEx()
{   
    if (BALL_bEnable==false) {
      return ;
    }
    if (BALL_bIsInit==false)
    {
      UpdateBallTex();
      BALL_bIsInit =true;
    }
    else if (BALL_bIsRedraw) {
      UpdateBallTex();
      BALL_bIsRedraw =false;
    }
    float PntX , PntY;
    float H, dx, dy;
    H = -light.Z;
    dx = Ball_Pos.X - light.X;
    dy = Ball_Pos.Y - light.Y;
    PntX = dx * (banJin + H) / H + light.X;
    PntY = dy * (banJin + H) / H + light.Y;
    ////
    ////画阴影
    //pSpriteShadow->SetBlendMode(BLEND_MODE_DEFAULT);
    //pSpriteShadow->SetTexture(texShadow);
    //pSpriteShadow->Render(PntX+offsetx,PntY+offsety);
    //画球
    pSprite->SetBlendMode(BLEND_DEFAULT);
    pSprite->SetTexture(tex);
    pSprite->RenderEx(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety,3.1415926,0.8,0.8);
////    画高亮
    //pSprite->SetTexture(texLight);
    //pSprite->SetBlendMode(BLEND_MODE_COLORMUL );   
    //pSprite->Render(Ball_Pos.X+offsetx,Ball_Pos.Y+offsety);

}

boolCBallRender:: IsStop()
{
    return BALL_State == 4;
}
boolCBallRender:: MouseMoveIn(float x,float y)
{
    x = x - offsetx;
    y = y - offsety;
    float xLength = x - this->Ball_Pos.X;
    float yLength = y - Ball_Pos.Y;
    float length = sqrt(xLength*xLength + yLength*yLength);
    return length<banjin-1;
}

voidCBallRender::CALEFJC    (FLOAT Xf, FLOAT Yf ,INT Ni ,INT Nj)
{
    int i,j;
    Vector3 Toolver(0,0,0);
    FLOAT Xs, Ys;
    int Numin=0;// '落在里面

    for (i=0;i<3;i++)
    {
      for (j=0;j<3;j++)
      {

            Xs = Xf + (FLOAT)i *0.33333f- 0.33333f    ;
            Ys = Yf + (FLOAT)j * 0.33333f - 0.33333f    ;
            if (sqrtf(Xs* Xs + Ys*Ys) < banJin)
            {
                Toolver += CALEPOS(Xs, Ys);
                Numin = Numin + 1 ;
            }

      }
    }

    if (Numin > 0)
    {
      Toolver.normalise();
      Toolver *= banJin ;
      Pos = Toolver ;
      mapX = 2    ;
      FJC = Numin;
    }

}

void CBallRender::SetView(IUnknownEx* pIUnknownEx)
{
   if (NULL != pIUnknownEx)
   {
         m_pIGameFrameView = /*GET_OBJECTPTR_INTERFACE*/QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITQView);
         ASSERT(m_pIGameFrameView != NULL);
   }
}下载地址(回复可见):
**** Hidden Message *****

解压密码默认为:www.woaidaima.com


李赛赛 发表于 2019-4-26 15:08:23

既然你诚信诚意的推荐了,那我就回复了!

他乡 发表于 2019-6-26 02:49:13

既然你诚信诚意的推荐了,那我就回复了!

gaying01 发表于 2022-4-14 11:06:30

感謝分享

kkhg 发表于 2022-12-8 14:22:35

谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢

l912418881 发表于 2023-2-24 10:26:54

谢谢谢谢谢谢谢
页: [1]
查看完整版本: 【78】8台球【源码】