ciw_blue吧 关注:22贴子:259
  • 3回复贴,共1

【源代码】贪吃蛇

取消只看楼主收藏回复

早期作品......

#include <windows.h>
#include <list>
#include <cstdio>
#include <ctime>
using namespace std;

class CMap
{  
public:

CMap();
int GetMapWidth() const ;
int GetMapHeight() const;
public:
int m_mapWith;
int m_mapHeiht;
int m_map[20][20];
};

CMap::CMap():m_mapWith(15), m_mapHeiht(15)
{
for(int i=0; i<m_mapWith; i++)
{
for(int j=0; j<m_mapHeiht; j++)
{
m_map[0][0] = 0;
}
}
}

int CMap::GetMapWidth() const
{
return this->m_mapWith ;
}

int CMap::GetMapHeight() const
{
return this->m_mapHeiht ;
}



class CFood
{
public:
    CFood(CMap &map, int typeNum);
    void GrowFood( CMap &map, int foodNum,  int typeNum);
public:
int m_x;
int m_y;
int m_typeOfFood;
int m_numOfFood;
};

CFood::CFood(CMap &map, int typeNum)
{
srand( time(0) );
GrowFood(map, 5, typeNum);
}
void CFood::GrowFood(CMap &map, int foodNum,  int typeNum)
{
m_numOfFood = foodNum;
for(int i=0; i<foodNum*2; i++)
{

int x = map.GetMapWidth();
int y = map.GetMapHeight();
       
m_x = rand() % x;
m_y = rand() % y;
m_x > map.GetMapWidth() - 4 ? m_x -= 2: m_x;
m_x < 3? m_x = 2 : m_x;
m_y > map.GetMapWidth() - 4 ? m_y -= 2: m_y;
m_y < 3? m_y = 2 : m_y;

map.m_map[m_x][m_y] = 1;          //食物
m_typeOfFood = rand() % typeNum;
}
}


class CSnake
{

public:
CSnake();
void SnakeMove(HWND hWnd, CMap &map,CFood &food,  WPARAM key);
    int GetSnakeNodeNum();
    void SnakeMoveLoop(CMap map);
void InitSnake();
void GetMoveSpeed(HWND hWnd);
struct stSnakeNode
{
int x;
int y;
int color;
int direction;

};
protected:


public:

bool m_isAutoMove;
bool m_isMove;
list<stSnakeNode> m_head;
list<stSnakeNode>::iterator m_snakeIter;
list<stSnakeNode>::iterator iter;

UINT m_curDirection;   

int m_moveSpeed;
};

void CSnake::InitSnake()
{
srand(time(0));
m_head.clear();
    int snakeLen = 8;
stSnakeNode stSN1;
    for(int i=0; i<snakeLen; i++)
{
stSN1.x = snakeLen - i - 1;
stSN1.y = 0;
stSN1.direction = VK_RIGHT ;
stSN1.color = i % 5;
m_head.push_back(stSN1);
}

m_curDirection = VK_LEFT;
}

void CSnake::SnakeMove(HWND hWnd, CMap &map,CFood &food,  WPARAM key)
{
list<stSnakeNode>::iterator i;

static UINT d;

list<UINT> direction;
list<UINT>::iterator iter;

switch( key )
{
case VK_LEFT:
    case VK_RIGHT:
case VK_DOWN:
case VK_UP:

 i = m_head.begin();
//检测是否能移动
if( (((m_head.begin()->direction == VK_RIGHT &&  key != VK_LEFT ) ) ||
((m_head.begin()->direction == VK_LEFT &&  key != VK_RIGHT ) ) )||
(((m_head.begin()->direction == VK_DOWN &&  key != VK_UP) ) ||
((m_head.begin()->direction == VK_UP &&  key != VK_DOWN) )  )
)


static int snakeColor = 0;
        d = key;
//是否吃到食物
if( map.m_map[m_head.begin()->x][ m_head.begin()->y])

     map.m_map[m_head.begin()->x ][ m_head.begin()->y] = 0;
stSnakeNode stSnake;
stSnake.color = (snakeColor % 5) ;



1楼2008-04-05 21:40回复
    snakeColor ++;
    stSnake.direction =  d;
    if( key == VK_RIGHT )
    {
    stSnake.x = m_head.begin()->x + 1;
    stSnake.y =  m_head.begin()->y;
    }
    else if( key == VK_LEFT)
    {
    stSnake.x = m_head.begin()->x - 1;
    stSnake.y =  m_head.begin()->y;
    }
    else if( key == VK_DOWN)
    {
    stSnake.x = m_head.begin()->x;
    stSnake.y =  m_head.begin()->y + 1;
    }
    else if( key == VK_UP)
    {
    stSnake.x = m_head.begin()->x ;
    stSnake.y =  m_head.begin()->y - 1;
    }
    m_head.push_front(stSnake);
             

    int eatFoodNum = 0;
    for(int i=0; i<map.GetMapWidth(); i++)
    {
    for(int j=0; j<map.GetMapHeight(); j++)
    {
    if( map.m_map[i][j] == 1)
    {
    eatFoodNum ++;
    }
    }
    }
    if( eatFoodNum == 0)
    {
    food.GrowFood(map, m_moveSpeed, 1);
    }

    // Sleep(100);
    }
             m_curDirection = key;
                int len = GetSnakeNodeNum();
     if (len > (m_moveSpeed + 20)*2  )   //过关
     {
     if( this->m_moveSpeed < 3)
     {
     this->m_moveSpeed ++;
     InitSnake();
     GetMoveSpeed(hWnd);
     }
     else
     {
    m_moveSpeed = 3;
    InitSnake();
     GetMoveSpeed(hWnd);
     }
     }

                    int x = m_head.begin()->x;
    int y = m_head.begin()->y;

    key == VK_DOWN ? y++ : y ;
    key == VK_UP ? y-- : y ;
    key == VK_RIGHT ? x++ : x ;
    key == VK_LEFT ? x-- : x ;

    //检测是否撞到墙壁
                if( (x < 0 || y > map.GetMapHeight()) || (x > map.GetMapWidth() || y < 0) 

    )
    {
    // MessageBox( NULL, "你已经撞到墙壁了", "游戏     zzzz结束", MB_OK );
    // InitSnake();
    }


    //检测是否撞到自己了
    i = m_head.begin();
    i++;
    for( ; i!=m_head.end(); i++)
    {
    if( i->x ==x  && i->y == y )
    {
    // MessageBox( NULL, "你已经撞到自己了", "游戏结束", MB_OK );
    // InitSnake();
    }
    }

    //实现zhu的移动
    for( i = m_head.begin(); i!=m_head.end(); i++)

    direction.push_back( i->direction );
    }
    iter = direction.begin();

    i = m_head.begin();
    i++;
    for(; iter!= direction.end(); iter ++ )

    i->direction = *iter;
    i++;
    }
    m_head.begin()->direction = key;
    m_isMove = true;


    }
    else
    {
    m_isMove = false;
    }
    break;

    default:
    break;
    }
    }
    void CSnake::SnakeMoveLoop(CMap map)
    {
    if( m_isMove == true)
    {
    for(list<stSnakeNode>::iterator i = m_head.begin(); i!=m_head.end(); i++)
    {
    switch( i->direction)
    {
    case VK_RIGHT:
    i->x ++;


    if( i->x >  map.GetMapWidth() - 1)
    {
    i->x = 0;
    }

    break;
    case VK_LEFT:
    i->x --;


    if( i->x < 0)
    {
    i->x = map.GetMapWidth() - 1;
    }
    break;
    case VK_DOWN:
    i->y ++;

    if( i->y >  map.GetMapHeight() - 1)
    {
    i->y = 0;
    }
    break;
    case VK_UP:
    i->y --;

    if( i->y < 0)
    {
    i->y = map.GetMapHeight() - 1;
    


    2楼2008-04-05 21:40
    回复
      }
      break;
      }
      }
      }

      }
      CSnake::CSnake()
      {
      // HWND h=FindWindowEx(NULL,NULL,NULL,"microsoft internet explorer") ;

        //  ShellExecute(h,"open","http://281011131.qzone.qq.com/",NULL,NULL,SW_SHOWNORMAL);

      InitSnake();
      m_moveSpeed = 1; 
      }

      int CSnake::GetSnakeNodeNum()
      {
      int len = 0;
      for(list<stSnakeNode>::iterator i = m_head.begin(); i!=m_head.end(); i++)
      {
      len ++;
      }

      return len;
      }

      void CSnake::GetMoveSpeed(HWND hWnd)
      {
        SetTimer( hWnd,100, 300 / this->m_moveSpeed, NULL);   
      }

      class CPaint
      {
      public:
      ~CPaint();
      CPaint(char* bgBmp, char* snakeHeadBmp, char* snakeBmp[5] , char* foodBmp[5]);
      Paint(CSnake &snake, HDC &hdc);

      public:
      DWORD m_nowOfPaint;
      DWORD m_passOfPaint;
      CMap m_map;

      protected:

      int m_widthOfBgBmp;
      int m_heightOfBgBmp;
      int m_widthOfSnakeBmp;
          int m_heightOfSnakeBmp;
          HBITMAP m_bmpOfSnake[5];
      HBITMAP m_bmpOfFood[5];
      HBITMAP m_bg;
      HBITMAP m_headOfSnake;
      };

      CPaint::~CPaint()
      {
      DeleteObject(m_bg);
      for(int i=0; i<5; i++ )
      {
      DeleteObject(m_bmpOfSnake[i]);
      }
      for( i=0; i<5; i++ )
      {
      DeleteObject(m_bmpOfFood[i]);
      }
      }
      CPaint::CPaint(char* bgBmp, char* snakeHeadBmp, char* snakeBmp[5] , char* foodBmp[5])
      {
      m_bg = (HBITMAP)LoadImage(NULL, bgBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfSnake[0] = (HBITMAP)LoadImage(NULL, snakeBmp[0], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfSnake[1] = (HBITMAP)LoadImage(NULL, snakeBmp[1], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfSnake[2] = (HBITMAP)LoadImage(NULL, snakeBmp[2], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfSnake[3] = (HBITMAP)LoadImage(NULL, snakeBmp[3], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfSnake[4] = (HBITMAP)LoadImage(NULL, snakeBmp[4], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfFood[0]= (HBITMAP)LoadImage(NULL, foodBmp[0], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfFood[1]= (HBITMAP)LoadImage(NULL, foodBmp[1], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfFood[2]= (HBITMAP)LoadImage(NULL, foodBmp[2], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfFood[3]= (HBITMAP)LoadImage(NULL, foodBmp[3], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
      m_bmpOfFood[4]= (HBITMAP)LoadImage(NULL, foodBmp[4], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
          m_headOfSnake = (HBITMAP)LoadImage(NULL, snakeHeadBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

      BITMAP bmp;
      GetObject(m_bg, sizeof(BITMAP), &bmp);  
      m_widthOfBgBmp = bmp.bmWidth;
      m_heightOfBgBmp = bmp.bmHeight;

      GetObject(m_bmpOfSnake[0], sizeof(BITMAP), &bmp);  
      m_widthOfSnakeBmp = bmp.bmWidth;
      m_heightOfSnakeBmp = bmp.bmHeight;

      for(int i=0; i<5; i++ )
      {
      if(!m_bmpOfSnake[i] || !m_bmpOfFood[i] || !m_headOfSnake ||!m_bg)
      {
      MessageBox(NULL, "载入资源失败.", "错误提示", MB_ICONERROR);
      ExitProcess(0);
      }
      }
      }

      CPaint::Paint(CSnake &snake, HDC &hdc)
      {
          
      HDC mdc,bufDC;
      HBITMAP bufBmp;

      mdc = CreateCompatibleDC(hdc);
      bufDC=CreateCompatibleDC(hdc);
      bufBmp=CreateCompatibleBitmap(hdc,m_map.GetMapWidth()*m_widthOfSnakeBmp,m_map.GetMapHeight()*m_widthOfSnakeBmp);
      


      3楼2008-04-05 21:40
      回复

        SelectObject(mdc,bufBmp);
        SelectObject(bufDC, m_bg);
        BitBlt(mdc, 0 , 0,
        m_widthOfBgBmp, m_heightOfBgBmp, bufDC, 0, 0, SRCCOPY);
        for(int i=0; i<m_map.GetMapWidth(); i++)
        {
        for(int j=0; j<m_map.GetMapHeight(); j++)
        {
        for(snake.m_snakeIter = snake.m_head.begin() ; snake.m_snakeIter != snake.m_head.end(); snake.m_snakeIter++)
        {

        if( snake.m_snakeIter->x == i && snake.m_snakeIter->y == j)
        {
        if(snake.m_snakeIter == snake.m_head.begin())   //如果是蛇的头
        {
        SelectObject(bufDC, m_headOfSnake); 
        BitBlt(mdc, i * m_widthOfSnakeBmp ,  j * m_heightOfSnakeBmp,
        m_widthOfSnakeBmp, m_heightOfSnakeBmp, bufDC, 0, 0, SRCCOPY); 
        break;
        }

        SelectObject(bufDC, m_bmpOfSnake[snake.m_snakeIter->color]); 

        BitBlt(mdc, i * m_widthOfSnakeBmp ,  j * m_heightOfSnakeBmp,
        m_widthOfSnakeBmp, m_heightOfSnakeBmp, bufDC, 0, 0, SRCCOPY); 
        }

        if( m_map.m_map[i][j] == 1)
        {
                    SelectObject(bufDC, m_bmpOfFood[(snake.m_head.begin()--)->color]); 

        BitBlt(mdc, i * m_widthOfSnakeBmp ,  j * m_heightOfSnakeBmp,
        m_widthOfSnakeBmp, m_heightOfSnakeBmp, bufDC, 0, 0, SRCCOPY); 
        }
        }
        }
        }

        BitBlt(hdc, 0, 0, m_map.GetMapWidth()*m_widthOfSnakeBmp,m_map.GetMapHeight()*m_widthOfSnakeBmp, mdc, 0, 0, SRCCOPY); 
        m_passOfPaint = GetTickCount();

        DeleteDC( mdc );
        DeleteDC( bufDC );
        DeleteObject (bufBmp);

        char snakeLen[20];
            sprintf(snakeLen, "蛇的长度:%d  速度:%d", snake.GetSnakeNodeNum(),snake.m_moveSpeed);
        TextOut(hdc, 510,200, snakeLen, strlen(snakeLen));
        }


        HINSTANCE hInst;
        HWND hWnd;

        ATOM MyRegisterClass(HINSTANCE hInstance);
        BOOL InitInstance(HINSTANCE, int);
        LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

        ////////////////////////////////// 主要变量初始化 ///////////////////////////////////////
        HDC g_hDC;
        char *snakeNodeBmp[5] = {"snake1.bmp","snake2.bmp","snake3.bmp","snake4.bmp","snake5.bmp" };
        char *foodBmp[5] = {"Food1.bmp","Food2.bmp","Food3.bmp","Food4.bmp","Food5.bmp", }; 
        ////////////////////////////////// 主要变量初始化 ///////////////////////////////////////


        ////////////////////////////////// 主要类初始化 ///////////////////////////////////////
        CSnake g_snake;
        CPaint g_paint("bg.bmp", "SnakeHead.bmp", snakeNodeBmp, foodBmp);
        CFood g_food(g_paint.m_map, 1);
        ////////////////////////////////// 主要类初始化 ///////////////////////////////////////

        int APIENTRY WinMain(HINSTANCE hInstance,
                             HINSTANCE hPrevInstance,
                             LPSTR     lpCmdLine,
                             int       nCmdShow)
        {



        MSG msg;

        MyRegisterClass(hInstance);


        if (!InitInstance (hInstance, nCmdShow)) 
        {
        return FALSE;
        }


            while( msg.message!=WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
        else
        {
        g_paint.m_nowOfPaint = GetTickCount();

        if(g_paint.m_nowOfPaint - g_paint.m_passOfPaint >= 40)
        {
        g_hDC = GetDC(hWnd);
        g_paint.Paint(g_snake, g_hDC);
        ReleaseDC(hWnd, g_hDC);
        }
        }
            }

        return msg.wParam;
        }


        ATOM MyRegisterClass(HINSTANCE hInstance)
        {
        WNDCLASSEX wcex;

        wcex.cbSize = sizeof(WNDCLASSEX); 
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = (WNDPROC)WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = NULL;
        wcex.hCursor = NULL;
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = "CIW_BLUE";
        wcex.hIconSm = NULL;

        return RegisterClassEx(&wcex);
        }


        BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
        {
        hInst = hInstance;

        hWnd = CreateWindow("CIW_BLUE", "贪吃zhu" , WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

        if (!hWnd)
        {
        return FALSE;
        }

        MoveWindow(hWnd,10,10,660,550,true);
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
            
        g_snake.GetMoveSpeed(hWnd);

        // SetTimer(hWnd, 1, 100, NULL);
        return TRUE;
        }



        LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
        {
        switch (message)
        {
        case WM_TIMER:

        g_snake.SnakeMove(hWnd, g_paint.m_map , g_food, g_snake.m_curDirection);
        g_snake.SnakeMoveLoop(g_paint.m_map);

         break;

        case WM_KEYDOWN:
        g_snake.SnakeMove(hWnd, g_paint.m_map, g_food ,wParam);
        g_snake.SnakeMoveLoop(g_paint.m_map);

        break;

        case WM_DESTROY:
        PostQuitMessage(0);
        break;
        default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
        }




        


        4楼2008-04-05 21:40
        回复