贪吃蛇c++

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

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 }
时间: 2024-10-13 00:46:19

贪吃蛇c++的相关文章

安卓贪吃蛇项目包!!

我在博客上看见很多有关于安卓开发贪吃蛇的博文,但是都不知道他们所用的软件.版本是什么,所以在自己下载的软件上运行的时候总是出不来结果,作为一只安卓课程老师只上了一节课就让我们自己做课程设计的菜鸟来说,这是何其困哪的一件事,安卓什么也不懂,运行环境也是一点也不熟悉.我们老师要求我们用eclipse来运行,有没有人是用这个做过的啊?求帮助!!真的是不会了,找了很多的项目包运行的时候都会出错,永远不会出现贪吃蛇的界面,宝宝真的快疯了.还附上了我所用的软件,有没有好心人解答下这个问题. 本来打算私聊项目

JS贪吃蛇游戏

<!DOCTYPE html><html> <head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <title>JS贪吃蛇游戏</title>    <style>    * {        margin: 0;    

Java版贪吃蛇(比较完善的版本)

很认真的写的一个java版的贪吃蛇游戏,图形界面,支持菜单操作,键盘监听,可加速,减速,统计得分,设定运动速度,设定游戏背景颜色等!应该没有Bug了,因为全被我修改没了.哈哈. 下面是项目各包及类的层次关系: 游戏的主要运行界面截图如下: 下面是部分代码,详细源码见此链接:http://pan.baidu.com/s/1bnubnzh //Snake类: package com.huowolf.entities; import java.awt.Color; import java.awt.Gr

UESTC_贪吃蛇 CDOJ 709

相信大家都玩过贪吃蛇游戏吧. 在n×m的迷宫中,有着一条长度不超过9的贪吃蛇,它已经将所有的食物吃光了,现在的目标是移动到出口. 它走的时候不能碰到自己的身体,也不能碰到墙壁.(如果贪吃蛇的长度>3并且下一步要走到自己的尾部,是合法的) 问它能不能走到出口,如果能,最少要移动几步? Input 数据包含多组数据,请读入到文件末尾EOF 每组数据第一行包含两个整数n,m(1≤n,m≤15)代表迷宫的大小. 接下来n行,每行包含一个长度为m的字符串,来表示迷宫. 字符串中仅包含..#.@.1 ~ 9

javascript之【贪吃蛇系列】第一弹:简单的贪吃蛇实现

参考博客:http://blog.csdn.net/sunxing007/article/details/4187038 以上博客是参考,毕竟第一次做,真让自己盲人摸象做不出来. 不过我在其上做了一些改进,界面等效果看起来更好一些. 下图是在Chrome上运行的效果,但是火狐和IE会不兼容,onkeydown事件不能正确调用 这里用了一张图把贪吃蛇制作过程的思想画了出来,画的有点简陋: 下面就是把代码发上来,上边有详细的解释: <html> <head> <title>

游戏开发(一)——控制台 贪吃蛇

贪吃蛇游戏设计中主要需要注意的几点: 1:坐标的定义:定义为左上角为(0,0),向右为x正方向,向下为y正方向 2:蛇的设计, 蛇身:m_body,这里用的是链表(是之前写好的双链表),一个节点就是蛇身的一节 每节蛇身的属性包括x,y坐标:column_x,row_y,x表示在地图上的第几列,y表示在地图上的第几行 蛇有一个属性叫朝向,也就是当前在往上.下.左.右的哪个方向移动:m_forward 蛇的动作有:Turn,转向.转向有个判断,就是不能向相反的方向转,比如本来向上运动,按向下键,是无

《结对-贪吃蛇游戏-开发环境搭建过程》

贪吃蛇开发环境搭建 Python和pygame的安装过程 成员0:2015035107074-孔令辉 成员1:2015035107067-张旭 1.去官网下载python和pygame.(需注意自己电脑是32位的还是64位的,我的是64位的,就下了个64位的) 2.安装pythone 和 pygame. 3.安装完成后,查看环境变量配置情况:计算机->属性->高级系统设置->环境变量->系统变量->Path. 4.在命令提示符中输入:python,验证是否安装成功,若提示是无

结对-贪吃蛇-设计文档

编程项目:贪吃蛇 成员:徐宏璇.邵瀚庆 搭建环境:安装Python.pygame 项目步骤: 1).设计游戏窗口 2).绘制贪吃蛇.实物      3).添加开始.暂停.退出按钮 4).添加计分板.剩余可玩次数.时间等辅助功能 5).完善代码,检查错误 流程图:  

用Java开发贪吃蛇游戏

贪吃蛇游戏的设计步骤: Part 1: 设计游戏图纸 画出900*700的白色窗口 在窗口上添加画布 在画布上添加标题 在画布上添加黑色游戏区 Part 2: 放置静态的蛇:一个头.两个身体 加上开始提示:按空格键开始游戏 让蛇动起来:监听Timer事件,平移数据 实现游戏暂停 实现转向功能 Part 3: 添加食物 吃掉食物 添加死亡条件 实现“重新开始”功能 添加分数和长度 游戏图纸如下: 蛇及游戏框的素材如下:                              Snake主类: 1

BASH贪吃蛇

写得烂,别喷 #!/usr/bin/env bash#set -x#set -e cmd=$1        #捕获第一个参数pid=$$        #当前脚本的进程pidmsg=msg       #消息管道文件space=0       #空白wall='x'      #墙壁my_box='B'    #我的箱子other_box='O' #其他的箱子box_length=30 #地图宽box_height=20 #地图高#颜色定义color_red=31color_green=32c