一个游戏公司的面试题(下)

题目在以前的那个文章里http://blog.csdn.net/Lsaint/archive/2006/06/24/830510.aspx
现在看以前写的code真的好烂-_-|| 难怪当时有人评论说出题的人是疯子 做题的是傻子...
虽然这个评论被我删了 但我现在还是比较同意后半句的~
那又怎样呢?
我知道现实和梦想隔很远 而我也知道我有一双翅膀可以飞过这个差距!
下面是代码 已经完全实现了题目的要求

 struct LSAINT//移动物体结构
{
 int dir; //移动方式
 int x , y , // 图片坐标
  bmpNUM; // 图片序号
 int vx , vy; // 移动速度
 HBITMAP bmp; // 位图句柄
};

int NUM = 0; //移动物体数目
bool RightDown = false; //右键是否按下

LSAINT lsaint[20]; //移动物数组

HWND hWnd = NULL;

HDC hdc , //屏幕DC
mdc , //内存DC
bufdc; //缓冲DC

RECT rect; //屏幕矩形
POINT CursorPos; // 鼠标位置

HBITMAP bmp[2], // 先载入所有位图句柄 供随机选择
map, // 地图
mbmp; // 内存位图

DWORD   tNow, tPre;   // 动画循环计时

void KeyAction(int dir); //按键响应函数
void LButtonAction();

void MyPaint(); //绘图
//================================
void Game_Init();//初始化游戏
void Game_Main();//游戏主函数
void Game_Over();//释放游戏资源
//================================


LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
 switch( msg )
 {
 case WM_KEYDOWN:
  switch (wParam)
  {
  case VK_ESCAPE:
   PostQuitMessage( 0 );
   break;
  case '1'://按键1
   KeyAction(1);
   break;
  case '2'://按键2
   KeyAction(2);
   break;
  case '3'://按键3
   KeyAction(3);
   break;
  }
  break;

 case WM_RBUTTONDOWN: // 右键按下
  RightDown = true;
  break;
 case WM_RBUTTONUP:  // 右键弹起
  RightDown = false;
  break;
 case WM_LBUTTONDOWN: // 左键按下
  LButtonAction();
  break;

 case WM_DESTROY:
  PostQuitMessage( 0 );
  return 0;
 }
 return DefWindowProc( hWnd, msg, wParam, lParam );
}


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
 // Register the window class
 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
  GetModuleHandle(NULL), NULL, NULL, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL,
  "Game", NULL };
 RegisterClassEx( &wc );

 // Create the application's window
 hWnd = CreateWindow( "Game", "lSaint's Game",
  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
  NULL, NULL, wc.hInstance, NULL );

 //=========================================
 Game_Init();//初始化游戏
 //=========================================

 // Show the window
 ShowWindow( hWnd, SW_SHOWDEFAULT );
 MoveWindow( hWnd,22,22,800,600,1 );
 UpdateWindow( hWnd );

 // Enter the message loop
 MSG msg;
 ZeroMemory( &msg, sizeof(msg) );
 while( msg.message!=WM_QUIT )
 {
  if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  {
   TranslateMessage( &msg );
   DispatchMessage( &msg );
  }
  //=========================================
  Game_Main();//游戏主函数
  //=========================================
 }
 //=========================================
 Game_Over();//释放游戏资源
 //=========================================
 UnregisterClass( "Game", wc.hInstance );
 return 0;
}

void Game_Init()
{
 hdc = GetDC( hWnd );  // 屏幕DC
 GetClientRect(hWnd,&rect); // 屏幕矩形

 mdc = CreateCompatibleDC( hdc );
 bufdc = CreateCompatibleDC ( hdc );

 srand( (unsigned)time( NULL ) );

 bmp[0] = (HBITMAP)LoadImage( NULL,_T("sprite0.bmp"),IMAGE_BITMAP,32,47,LR_LOADFROMFILE );
 bmp[1] = (HBITMAP)LoadImage( NULL,_T("sprite1.bmp"),IMAGE_BITMAP,32,47,LR_LOADFROMFILE );
 bmp[2] = (HBITMAP)LoadImage( NULL,_T("sprite2.bmp"),IMAGE_BITMAP,32,47,LR_LOADFROMFILE );

 mbmp = CreateCompatibleBitmap ( hdc , 800 , 600);
 map = (HBITMAP)LoadImage( NULL,_T("bg.bmp"),IMAGE_BITMAP,800,600,LR_LOADFROMFILE );
}

void KeyAction(int dir)
{ //随机初始化结构体
 if(NUM<=20)
 {
  lsaint[NUM].bmpNUM = rand()%3;
  lsaint[NUM].dir = dir;
  lsaint[NUM].x = rand()%750;
  lsaint[NUM].y = rand()%550;
  lsaint[NUM].bmp = bmp[lsaint[NUM].bmpNUM];
  lsaint[NUM].vx = 20;
  lsaint[NUM].vy = 20;
  NUM++;
 }
 else
  MessageBox(hWnd,"已达到图片最大数量","提示",0);
}

void LButtonAction() // 点击图片 弹出对话筐显示图片名字
{
 GetCursorPos(&CursorPos);
 ScreenToClient(hWnd,&CursorPos);
 char str[12];
 for(int i=NUM;i>=0;i--)
 {
  if(lsaint[i].x-16<CursorPos.x&&lsaint[i].x+44>CursorPos.x
   &&lsaint[i].y-24<CursorPos.y&&lsaint[i].y+70>CursorPos.y)
  {
   sprintf_s(str,"sprite%d.bmp",lsaint[i].bmpNUM);
   MessageBox(hWnd,str,"图片文件名",MB_OK);
   break;
  }
 }
}

void MyPaint()
{
 SelectObject( mdc ,mbmp );
 SelectObject(bufdc,map);
 BitBlt(mdc,0,0,800,600,bufdc,0,0,SRCCOPY);

 if(!RightDown) // 右键没有按下时,水平垂直移动
 {
  for(int i=0;i<NUM;i++)
  {
   SelectObject( bufdc , lsaint[i].bmp );
   BitBlt(mdc,lsaint[i].x,lsaint[i].y,32,47,bufdc,0,0,SRCCOPY);

   switch(lsaint[i].dir)
   {
   case 1:// 水平移动
    lsaint[i].x+=lsaint[i].vx;
    if( lsaint[i].x >= (rect.right) )
    {
     lsaint[i].x = rect.right;
     lsaint[i].vx = -lsaint[i].vx;
    }
    else if(lsaint[i].x <= 0)
    {
     lsaint[i].x = 0;
     lsaint[i].vx = -lsaint[i].vx;
    }
    break;

   case 2:// 垂直移动 
    lsaint[i].y+=lsaint[i].vy;
    if( lsaint[i].y > (rect.bottom+30) )
    {
     lsaint[i].y = rect.bottom;
     lsaint[i].vy = -lsaint[i].vy;
    }
    else if(lsaint[i].y <= 0)
    {
     lsaint[i].y = 0;
     lsaint[i].vy = -lsaint[i].vy;
    }
    break;

   case 3:// 随机移动
    if(rand()%2==0)
     lsaint[i].dir = 1;
    else
     lsaint[i].dir = 2;
    break; 

   }//end switch 
  }//end for
 }
 else // 右键按下时 图片向右键点飞去
 {
  for(int i=0;i<NUM;i++)
  {
   SelectObject( bufdc , lsaint[i].bmp );
   BitBlt(mdc,lsaint[i].x,lsaint[i].y,32,47,bufdc,0,0,SRCCOPY);

   GetCursorPos(&CursorPos);
   ScreenToClient(hWnd,&CursorPos);

   if(lsaint[i].x>CursorPos.x)
    lsaint[i].x-=20;
   else
    lsaint[i].x+=20;

   if(lsaint[i].y>CursorPos.y)
    lsaint[i].y-=20;
   else
    lsaint[i].y+=20;
   // 修正图片在临近时的坐标 避免来回晃动
   if( lsaint[i].x-CursorPos.x<32&&lsaint[i].x-CursorPos.x>0 ||
    lsaint[i].x-CursorPos.x>-32&&lsaint[i].x-CursorPos.x<0 )
     lsaint[i].x = CursorPos.x;
   if( lsaint[i].y-CursorPos.y<47&&lsaint[i].y-CursorPos.y>0 ||
    lsaint[i].y-CursorPos.y>-47&&lsaint[i].y-CursorPos.y<0 )
     lsaint[i].y = CursorPos.y;
    
  }

 }

 BitBlt( hdc,0,0,800,600,mdc,0,0,SRCCOPY );
 tPre = GetTickCount();
}

void Game_Main()
{
 tNow = GetTickCount();
 if (tNow-tPre >= 400)
  MyPaint( );
}

void Game_Over() // 释放资源
{
 DeleteDC(mdc);
 DeleteDC(bufdc);
 for(int i=0;i<2;i++)
  DeleteObject(bmp[i]);
 DeleteObject(map);
 DeleteObject(mbmp);
 ReleaseDC(hWnd,hdc); //释放屏幕DC
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值