码迷,mamicode.com
首页 > 编程语言 > 详细

贪吃蛇c++

时间:2016-10-06 10:41:44      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

借用了俄罗斯方块中的界面类,写的很快

5个文件,共能基本实现,有一些功能懒得写了

用到了数据结构_双向链表

 

  1 //2016/10/5
  2 //c++和windows 简单api函数   贪吃蛇
  3 //一言难尽
  4 //下次设个随机数生成器,在界面设置食物就好了
  5 //再写个eatfood函数,先移动重,然后在里面在链表尾部添加一个节点,再重绘就结束了
  6 //哎,有空把食物颜色设置一下好了
  7 #include"Interface.h"
  8 #include"snake.h"
  9 #include <windows.h>
 10 #include<random>
 11 #include<iostream>
 12 
 13 #define TIMER_SEC 1
 14 #define TIMER_UPDATE 2
 15 
 16 
 17 
 18 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 19 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 20     PSTR szCmdLine, int iCmdShow)
 21 {
 22 
 23 
 24     static TCHAR szAppName[] = TEXT("俄罗斯方块");
 25     HWND hwnd;
 26     MSG msg;
 27     WNDCLASS wndclass;
 28     wndclass.style = CS_HREDRAW | CS_VREDRAW;
 29     wndclass.lpfnWndProc = WndProc;
 30     wndclass.cbClsExtra = 0;
 31     wndclass.cbWndExtra = 0;
 32     wndclass.hInstance = hInstance;
 33     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 34     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 35     wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
 36     wndclass.lpszMenuName = NULL;
 37     wndclass.lpszClassName = szAppName;
 38     if (!RegisterClass(&wndclass))
 39     {
 40         MessageBox(NULL, TEXT("This program requires Windows NT!"),
 41             szAppName, MB_ICONERROR);
 42         return 0;
 43     }
 44     hwnd = CreateWindow(szAppName, // window class name
 45         TEXT("俄罗斯方块"), // window caption
 46         WS_OVERLAPPEDWINDOW, // window style
 47         50, // initial x position
 48         10, // initial y position
 49         700, // initial x size
 50         700, // initial y size
 51         NULL, // parent window handle
 52         NULL, // window menu handle
 53         hInstance, // program instance handle
 54         NULL); // creation parameters
 55     ShowWindow(hwnd, iCmdShow);
 56     UpdateWindow(hwnd);
 57     while (GetMessage(&msg, NULL, 0, 0))
 58     {
 59         TranslateMessage(&msg);
 60         DispatchMessage(&msg);
 61     }
 62     return msg.wParam;
 63 }
 64 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 65 {
 66     static int cxClient, cyClient;
 67     static Interface face(hwnd, BLOCK_NON_EXISTENT);
 68     static snake snk(15,15);
 69     static int guide = 3;
 70     static std::default_random_engine e_x;
 71     static std::default_random_engine e_y;
 72     static std::uniform_int_distribution<unsigned> u(0, 21);
 73     static std::uniform_int_distribution<unsigned> u_2(0, 21);
 74 
 75     PAINTSTRUCT ps;
 76     //HDC hdc;
 77     //RECT rect;
 78     switch (message)
 79     {
 80     case WM_CREATE:
 81         SetTimer(hwnd, TIMER_SEC, 500, NULL);
 82         SetTimer(hwnd, TIMER_UPDATE, 2000, NULL);    
 83         return 0;
 84     case WM_SIZE:
 85         cxClient = LOWORD(lParam);
 86         cyClient = HIWORD(lParam);
 87         face.changeSize(cxClient, cyClient);
 88         return 0;
 89     case WM_TIMER:
 90         switch (wParam)
 91         {
 92         case TIMER_SEC:
 93             if (!snk.move(guide, face))
 94             {
 95                 KillTimer(hwnd, TIMER_SEC);
 96             }
 97             InvalidateRect(hwnd, NULL, true);
 98             break;
 99         case TIMER_UPDATE:
100             face.set_food(u(e_x), u(e_x));
101             InvalidateRect(hwnd, NULL, true);
102             break;
103         }
104         return 0;
105     case WM_KEYDOWN:
106         switch (wParam)
107         {
108         case VK_RIGHT:
109             //ter.Right_Movement(face);
110             if (guide == 4)
111                 break;
112             guide = 2;
113             if (!snk.move(guide, face))
114             {
115                 KillTimer(hwnd, TIMER_SEC);
116             }
117             InvalidateRect(hwnd, NULL, true);
118             break;
119         case VK_LEFT:
120             if (guide == 2)
121                 break;
122             guide = 4;
123             if (!snk.move(guide, face))
124             {
125                 KillTimer(hwnd, TIMER_SEC);
126             }
127             InvalidateRect(hwnd, NULL, true);
128             break;
129         case VK_UP:
130             if (guide == 3)
131                 break;
132             guide = 1;
133             if (!snk.move(guide, face))
134             {
135                 KillTimer(hwnd, TIMER_SEC);
136             }
137             InvalidateRect(hwnd, NULL, true);
138             break;
139         case VK_DOWN:
140             if (guide == 1)
141                 break;
142             guide = 3;
143             if (!snk.move(guide, face))
144             {
145                 KillTimer(hwnd, TIMER_SEC);
146             }
147             InvalidateRect(hwnd, NULL, true);
148             break;
149         }
150     case WM_PAINT:
151         snk.draw(face);
152         face.drawBlock(ps, BLACK_BRUSH, GRAY_BRUSH);
153         return 0;
154     case WM_DESTROY:
155         KillTimer(hwnd, TIMER_SEC);
156         /*    KillTimer(hwnd, TIMER_UPDATE);*/
157         PostQuitMessage(0);
158         return 0;
159     }
160     return DefWindowProc(hwnd, message, wParam, lParam);
161 }

 

 

 

 

 

 

 

 1 class snake
 2 {
 3 public:
 4     snake(int _x, int _y, int len = 6);
 5     bool move(int guide,const Interface &face);
 6     void insert(int _x, int _y);
 7     void inital(int _x = 5, int _y = 5);
 8     void draw(Interface &face);
 9 private:
10     bool inspect(int _x,int _y,const Interface &face);         //检查有无出界或者碰撞
11     int length = 0;
12     Node *head = nullptr;
13     Node *rear = nullptr;
14 };

 

 

 

 

 

 

 

 

 

  1 #include"snake.h"
  2 snake::snake(int _x, int _y, int len)
  3 {
  4     rear = head = new Node;
  5     inital(_x, _y);
  6     int i;
  7     for (i = 0; i < len - 1; i++)
  8     {
  9         insert(++_x, _y);
 10     }
 11 }
 12 void snake::insert(int _x, int _y)
 13 {
 14     Node *p = new Node;
 15     p->x = _x;
 16     p->y = _y;
 17     rear->next = p;
 18     p->before = rear;
 19     rear = p;
 20     length++;
 21 }
 22 
 23 void snake::inital(int _x, int _y)
 24 {
 25     Node *p = new Node;
 26     p->x = _x;
 27     p->y = _y;
 28     rear->next = p;
 29     p->before = rear;
 30     rear = p;
 31     length++;
 32 }
 33 
 34 bool snake::move(int guide,const Interface &face)
 35 {
 36     Node *q = rear;
 37     Node *p = q->before;
 38     if (q == nullptr)
 39         return false;
 40     //开始检查
 41     int inspect_x = head->next->x;
 42     int inspect_y = head->next->y;
 43     switch (guide)
 44     {
 45     case 1: inspect_x++; break;
 46     case 2: inspect_y++; break;
 47     case 3: inspect_x--; break;
 48     case 4: inspect_y--; break;
 49     default:
 50         break;
 51     }
 52     if (inspect(inspect_x, inspect_y, face) == false)
 53     {
 54         return false;
 55     }
 56     if (face.isBlock[inspect_x][inspect_y] == BLOCK_FOOD)
 57     {
 58         Node *n = new Node;
 59         rear->next = n;
 60         n->before = rear;
 61         rear = n;
 62         q = rear;
 63         p = rear->before;
 64     }
 65     //结束检查
 66     int _x = head->next->x;
 67     int _y = head->next->y;
 68     while (p != head)
 69     {
 70         q->x = p->x;
 71         q->y = p->y;
 72         p = p->before;
 73         q = p->next;
 74     }
 75     p = p->next;
 76     switch (guide)
 77     {
 78     case 1: p->x = _x + 1; p->y = _y; break;
 79     case 2: p->x = _x; p->y = _y + 1; break;
 80     case 3: p->x = _x - 1; p->y = _y; break;
 81     case 4: p->x = _x; p->y = _y - 1; break;
 82     default:
 83         break;
 84     }
 85     
 86     return true;
 87 }
 88 
 89 void snake::draw(Interface &face)  //写入但不显示,显示让interface去完成
 90 {
 91     face.clear();
 92     Node *p = head->next;
 93     while (p != nullptr)
 94     {
 95         face.isBlock[p->x][p->y] = BLOCK_FASTENED;
 96         p = p->next;
 97     }
 98 }
 99 
100 
101 bool snake::inspect(int _x, int _y,const Interface &face)
102 {
103     if (_x >= face.cx || _x < 0 || _y >= face.cy || _y < 0)
104     {
105         return false;
106     }
107     Node *p = head->next;
108     while (p != nullptr)
109     {
110         if (_x == p->x && _y == p->y)
111         {
112             return false;
113         }
114         p = p->next;
115     }
116     return true;
117 }

 

 

 

 

 

 

 1 #ifndef TETERFACE
 2 #define TETERFACE
 3 
 4 constexpr int BLOCK_FASTENED = 1;     //方块状态存在固定
 5 constexpr int BLOCK_FALL = 2;         //下降
 6 constexpr int BLOCK_FOOD = 3;         //食物
 7 constexpr int BLOCK_NON_EXISTENT = 0;  //
 8 
 9 #include<Windows.h>
10 #include<random>
11 class Interface
12 {
13     //friend class Tetris;
14     friend class snake;
15 public:
16     Interface(HWND, int b_ = true);
17     void drawBlock(PAINTSTRUCT&, int fnObject_1 = BLACK_BRUSH, int fnObject_2 = GRAY_BRUSH, int fnObject_3 = BLACK_BRUSH);
18     void changeSize(unsigned, unsigned);
19     bool checkState();
20     void set_food(int _x, int _y);
21     void clear();          //特殊化为不清楚食物
22 private:
23     static const size_t cx = 22, cy = 22, c = 0;  //12 + 4行8列
24     void Sink(unsigned);
25     int isBlock[cy + c][cx] = {};
26     HWND hwnd;                      //界面内容代号
27     unsigned int width = 0, height = 0;     //设置界面的高度和宽度
28 };
29 #endif

 

 

 

 

 

 

 

 

  1 #include"interface.h"
  2 
  3 static const size_t cx, cy;
  4 
  5 Interface::Interface(HWND hd, int b_ /*= BLOCK_FASTENED*/) :hwnd(hd)
  6 {
  7     for (auto &row : isBlock)
  8     {
  9         for (auto &col : row)
 10         {
 11             col = b_;
 12         }
 13     }
 14 }
 15 
 16 void Interface::drawBlock(PAINTSTRUCT &ps, int fnObject_1, int fnObject_2, int fnObject_3)
 17 {
 18     //HDC hdc = GetDC(hwnd);    //用了这个占用cpu大
 19     HDC hdc = BeginPaint(hwnd, &ps);
 20     HBRUSH hBrush_1 = (HBRUSH)::GetStockObject(fnObject_1); //方块画刷
 21     HBRUSH hBrush_2 = (HBRUSH)::GetStockObject(fnObject_2); //方块画刷
 22     HBRUSH hBrush_3 = (HBRUSH)::GetStockObject(fnObject_3); //食物画刷
 23     RECT rect;
 24     unsigned Block_h = height / cy;
 25     unsigned Block_w = width / cx;
 26     for (size_t i = 0; i < cy; ++i)
 27         for (size_t j = 0; j < cx; ++j)
 28         {
 29             if (isBlock[i][j] == BLOCK_FASTENED ||
 30                 isBlock[i][j] == BLOCK_FALL ||
 31                 isBlock[i][j] == BLOCK_FOOD)
 32             {
 33                 //以后可以在这里定义内嵌厚度
 34                 rect.left = j * Block_w + 2;
 35                 rect.top = (cy - i - 1) * Block_h + 2;
 36                 rect.right = (j + 1) * Block_w - 2;
 37                 rect.bottom = (cy - i) * Block_h - 2;
 38                 FrameRect(hdc, &rect, hBrush_1);
 39                 if (isBlock[i][j] == BLOCK_FOOD)
 40                 {
 41                     FillRect(hdc, &rect, hBrush_3);
 42                 }
 43                 else
 44                 {
 45                     FillRect(hdc, &rect, hBrush_2);
 46                 }    
 47             }
 48         }
 49     EndPaint(hwnd, &ps);
 50 }
 51 
 52 
 53 void Interface::changeSize(unsigned wh, unsigned ht)
 54 {
 55     width = wh;
 56     height = ht;
 57 }
 58 
 59 
 60 bool Interface::checkState()
 61 {
 62     for (size_t i = 0; i < cx; i++)
 63     {
 64         if (isBlock[cy][i] != BLOCK_NON_EXISTENT)
 65             return false;
 66     }
 67     bool isFull;
 68     for (size_t i = 0; i < cy; i++)
 69     {
 70         isFull = true;
 71         for (size_t j = 0; j < cx; j++)
 72         {
 73             if (isBlock[i][j] != BLOCK_FASTENED)
 74             {
 75                 isFull = false;
 76                 break;
 77             }
 78         }
 79         if (isFull && i != cy - 1)
 80         {
 81             Sink(i);
 82             i--;                //i不可少
 83         }
 84         else if (isFull && i == cy - 1)
 85         {
 86             for (size_t i = 0; i < cx; i++)
 87             {
 88                 isBlock[cy - 1][i] = BLOCK_NON_EXISTENT;
 89             }
 90         }
 91     }
 92     return true;
 93 }
 94 
 95 
 96 void Interface::Sink(unsigned line)
 97 {
 98     for (size_t i = line + 1; i < cy; ++i)
 99     {
100         for (size_t j = 0; j < cx; j++)
101         {
102             isBlock[i - 1][j] = isBlock[i][j];
103         }
104     }
105 }
106 
107 void Interface::clear()
108 {
109     for (size_t i = 0; i < cy + c; i++)
110     {
111         for (size_t j = 0; j < cx; j++)
112         {
113             if(isBlock[i][j] != BLOCK_FOOD)
114                 isBlock[i][j] = BLOCK_NON_EXISTENT;
115         }
116     }
117 }
118 
119 void Interface::set_food(int x, int y)
120 {
121     if (isBlock[x][y] != BLOCK_FASTENED)
122     {
123         isBlock[x][y] = BLOCK_FOOD;
124     }
125 }

 

贪吃蛇c++

标签:

原文地址:http://www.cnblogs.com/7-29/p/5933442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!