近日里学习了关于win32编程的相关知识,利用这些知识制作了一款贪吃蛇小游戏,具体细节还是分模块来叙述

前期准备:在网上找到一些贪吃蛇的游戏素材图片,以及具体的逻辑框图

在正式写功能之前,先把一系列环境配置好,配置环境总体来说分为以下几步:

  1. 图片转化为bmp格式( Bitmap )二进制流
  2. 将图片加载到内存中,在加载内存中也分为三步
  • 导入资源

  • 将.rc文件代码中的绝对路径修改为相对路径(可不改,如果打包发给别人的话,不一定能保证对方存储文件的路径和你一致,我这里是将素材存储到 .c 文件的上一级当中)

  • 在.c文件中利用LoadBitmap() 函数加载位图进内存,其中参数的意义就不赘述了,直接通过vs自带帮助文档进行查看,并且自定义一个 位图句柄 去接着函数返回的地址,引用宏的时候别忘了引入头文件
     Hbitmap_BackGroup = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
Hbitmap_Apple = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP2));
Hbitmap_SnackHead = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP3));
Hbitmap_SnackHead_Up = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP5));
Hbitmap_SnackHead_Down = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP7));
Hbitmap_SnackHead_Left = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP6));
Hbitmap_SnackHead_Right = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP4));

现在就正式进入编写小游戏的阶段

先来分析一下贪吃蛇游戏的功能

  1. 显示背景
  2. 显示蛇
  3. 显示苹果
  4. 移动
  5. 吃苹果
  6. 生成新苹果
  7. 蛇长个
  8. 撞墙死亡
  9. 自咬死亡

逻辑上还是很清晰很简单的,接下来就是按功能实现

第一个,显示背景,首先一打开游戏就会有背景,那么只有重绘能实现,想要画图的话,必须获取窗口环境句柄(HDC),用完再去释放, 但是在win32中如何将我的背景位图,贴到HDC当中呢,查询后了解,在win32中贴图是以像素点为单位,一个像素点一个像素点的去传输到HDC当中,那么就得创建一个兼容性的HDC,再为兼容性DC选择我的背景位图,再分像素点进行传输

     HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc); //创建兼容性DC
SelectObject(hdc_compatible,Hbitmap_BackGroup); //为兼容性DC选择背景位图
BitBlt(hdc,,,,,hdc_compatible,,,SRCCOPY); //按像素点进行传输
DeleteDC(hdc_compatible); //删除兼容性DC
return;

第二个,显示蛇,首先以蛇的图片大小构建一个虚拟的坐标网(也可以不建,但像素点太小定位太麻烦),以我这个为例背景图是600*600的大小,蛇头,蛇身,苹果大小都是30*30大小,那么就是长宽都为0~19的坐标网,蛇的长个很容易想到可以用链表的添加进行实现,那么就把蛇身做成一个双向链表(为什么双向,在移动的时候就明白了),在添加链表后,再进行先蛇头后蛇身的贴图,上下左右用枚举类型

enum FX {UP,DOWN,LEFT,RIGHT}; enum FX fx = RIGHT;

 void AddNode(int x,int y)
{
Snack *pTemp = (Snack *)malloc(sizeof(Snack));
pTemp->x = x;
pTemp->y = y;
pTemp->pLast = NULL;
pTemp->pNext = NULL; if(pHead == NULL)
{
pHead = pTemp;
}
else
{
pEnd->pNext = pTemp;
pTemp->pLast = pEnd;
}
pEnd = pTemp;
}
void ShowSnack(HDC hdc)
{
Snack *pMark = pHead->pNext;
HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc);
switch (fx)
{
case UP:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Up);
break;
case DOWN:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Down);
break;
case LEFT:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Left);
break;
case RIGHT:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Right);
break;
default:
break;
}
BitBlt(hdc,pHead->x*,pHead->y*,,,hdc_compatible,,,SRCCOPY); while(pMark)
{
SelectObject(hdc_compatible,Hbitmap_SnackHead);
BitBlt(hdc,pMark->x*,pMark->y*,,,hdc_compatible,,,SRCCOPY);
pMark = pMark->pNext;
}
DeleteDC(hdc_compatible);
}

第三个,显示苹果,直接贴图即可

 void ShowApple(HDC hdc)
{
HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc);
SelectObject(hdc_compatible,Hbitmap_Apple);
BitBlt(hdc,apple.x*,apple.y*,,,hdc_compatible,,,SRCCOPY);
DeleteDC(hdc_compatible);
}

第四个,移动,win32中有个定时器的功能,每隔一段时间就向窗口发送定时器消息,那么蛇的坐标只要挨个代替前一个贴图就会实现移动的效果,但是问题就在于是从蛇头向蛇尾去遍历坐标变化,还是从蛇尾向蛇头变化,在几次尝试后发现还是蛇尾向蛇头,因为如果蛇头向蛇尾的话,蛇头坐标都改变了,而下一个蛇身就找不到蛇头的地址,就会出现蛇头蛇尾分家的情况,这也就是为什么做成双向链表的原因

 void Move()
{
Snack *pMark = pEnd;
while(pMark != pHead)
{
pMark->x = pMark->pLast->x;
pMark->y = pMark->pLast->y;
pMark = pMark->pLast;
}
switch (fx)
{
case UP:
pHead->y--;
break;
case DOWN:
pHead->y++;
break;
case LEFT:
pHead->x--;
break;
case RIGHT:
pHead->x++;
break;
}
}

第五个,吃苹果,也就是当蛇头坐标和苹果坐标重合的时候代表吃到苹果了,一个判断就搞定了

 BOOL IfEatApple()
{
if(pHead->x == apple.x && pHead->y == apple.y)
return TRUE;
return FALSE;
}

第六个,生成新苹果,利用随机数给苹果生成一个新的坐标,但是后期给室友测试的时候发现一个问题,这个苹果坐标的随机数在蛇长长之后会随到蛇身上,这个是需要改进的地方,所以就得每随机一次就得判断是否和蛇的所有坐标重合,没有的话,才把随机的x,y拿出来去贴图

void NewApple()
{
Snack *pMark = pHead;
int x;
int y;
do
{
x = rand() % + ;
y = rand() % + ;
pMark = pHead;
while(pMark)
{
if(pMark->x == x && pMark->y == y)
break;
pMark = pMark->pNext;
}
}while(pMark);
apple.x = x;
apple.y = y;
}

第七个,蛇长个,添加链表即可,但是贴图坐标只要给到窗口以外,这样不影响游戏体验

AddNode(-,-);

第八个,撞墙死亡,给蛇头的坐标规定一个界限即可

 BOOL IfBumpWall()
{
if(pHead->x == || pHead->x == || pHead->y == || pHead->y == )
return TRUE;
return FALSE;
}

第九个,自咬死亡,判断蛇头坐标是否等于自身坐标即可

 BOOL IfEatSelf()
{
Snack *pMark = pHead->pNext;
while(pMark)
{
if(pMark->x == pHead->x && pMark->y == pHead->y)
return TRUE;
pMark = pMark->pNext;
}
return FALSE;
}

至此,功能函数就完成了,接下来就是在回调函数里进行逻辑连接的过程了,在后期给多个朋友进行试玩测试的时候,也发现了不少的bug在此也一并写出

1.键盘上下左右的键码VK_加上对应的大写英文

2.由于贴图是连续的,上一次贴图无法销毁,那么就得用一层背景图,一层蛇图,一层苹果图的方式,实现游戏的实际效果

3.当蛇向右运行的时候,快速按下向上+向右的按键,会显示游戏结束,针对这个问题,是这样分析的,在一个定时器周期内,出现了两次按键反馈,也就会变成向左,那么蛇就出现自咬的情况,处理的办法就是人为的规定在一个定时器周期内只允许出现一次键盘消息,设置一个标记,没进定时器的时候为TURE,进过定时器为FALSE,此时键盘内的第二次快速按下的消息就无效了

4.暴力玩法,当屏幕内蛇几乎占满时,窗口会出现闪烁的问题,在进行查阅后,发现是因为重绘是有一个刷新周期的,我的所有贴图没在一个周期内贴完,屏幕就会出现闪烁的现象,要想处理这个bug,可以用双缓冲技术,也就是为当前HDC创建一个兼容性HDC,再为这个兼容性HDC,再创建一个兼容性HDC,两个兼容性HDC之间进行多次贴图操作,那么在一个重绘周期内,一次就把第一次的兼容性DC给贴上就可以了,满足一个刷新周期内图贴完的要求,具体实现的话,在以后深入学习c++的过程中继续完善。

完整代码如下(图片素材在文件里,有兴趣的可以自行下载):

1.贪吃蛇.rc

 // Microsoft Visual C++ generated resource script.
//
#include "resource.h" #define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h" /////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS /////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
// TEXTINCLUDE
BEGIN
"resource.h\0"
END TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END #endif // APSTUDIO_INVOKED /////////////////////////////////////////////////////////////////////////////
//
// Bitmap
// IDB_BITMAP1 BITMAP "..\\she\\背景.bmp" //得用相对路径
IDB_BITMAP2 BITMAP "..\\she\\苹果.bmp"
IDB_BITMAP3 BITMAP "..\\she\\蛇身.bmp"
IDB_BITMAP4 BITMAP "..\\she\\蛇头0.bmp"
IDB_BITMAP5 BITMAP "..\\she\\蛇头1.bmp"
IDB_BITMAP6 BITMAP "..\\she\\蛇头2.bmp"
IDB_BITMAP7 BITMAP "..\\she\\蛇头3.bmp"
#endif // 中文(简体,中国) resources
///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
// /////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

2.resource.h

 //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 贪吃蛇.rc 使用
//
#define IDB_BITMAP1 101
#define IDB_BITMAP2 102
#define IDB_BITMAP3 103
#define IDB_BITMAP4 104
#define IDB_BITMAP5 105
#define IDB_BITMAP6 106
#define IDB_BITMAP7 107 // Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

3.Snack.c

 #include <Windows.h>
#include <time.h>
#include "resource.h" typedef struct NODE
{
int x;
int y;
struct NODE *pLast;
struct NODE *pNext;
}Snack,Apple; Snack *pHead;
Snack *pEnd;
Apple apple = {,,NULL,NULL};
enum FX {UP,DOWN,LEFT,RIGHT};
enum FX fx = RIGHT;
BOOL g_flag = TRUE; //设置标记,避免在一个定时器周期内有两次动作 HBITMAP Hbitmap_BackGroup;
HBITMAP Hbitmap_Apple;
HBITMAP Hbitmap_SnackHead;
HBITMAP Hbitmap_SnackHead_Up;
HBITMAP Hbitmap_SnackHead_Down;
HBITMAP Hbitmap_SnackHead_Left;
HBITMAP Hbitmap_SnackHead_Right; void ShowBackGround(HDC hdc); //显示背景
void AddNode(int x,int y); //添加蛇身
void ShowSnack(HDC hdc); //显示蛇
void Move(); //移动蛇
void ShowApple(HDC hdc); //显示苹果
BOOL IfEatApple(); //判断是否吃到苹果
void NewApple(); //随机出现新苹果
BOOL IfBumpWall(); //判断是否撞墙
BOOL IfEatSelf(); //判断是否自咬 LRESULT CALLBACK MyWNDPROC(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
HWND hwnd;
MSG msg;
//1.窗口设计
WNDCLASSEX ex;
ex.style = (UINT)NULL;
ex.cbSize = sizeof(ex);
ex.cbClsExtra = ;
ex.cbWndExtra = ;
ex.hInstance = hInstance;
ex.hIcon = NULL;
ex.hCursor = NULL;
ex.hbrBackground = CreateSolidBrush(RGB(,,));
ex.hIconSm = NULL;
ex.lpfnWndProc = &MyWNDPROC;
ex.lpszMenuName = NULL;
ex.lpszClassName = "aa"; Hbitmap_BackGroup = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
Hbitmap_Apple = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP2));
Hbitmap_SnackHead = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP3));
Hbitmap_SnackHead_Up = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP5));
Hbitmap_SnackHead_Down = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP7));
Hbitmap_SnackHead_Left = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP6));
Hbitmap_SnackHead_Right = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP4)); AddNode(,);
AddNode(,);
AddNode(,); //2.注册
RegisterClassEx(&ex);
//3.创建
hwnd = CreateWindow(ex.lpszClassName,"贪吃蛇",WS_OVERLAPPEDWINDOW,,,,,NULL,NULL,hInstance,NULL);
//4.显示
ShowWindow(hwnd,SW_SHOW); SetTimer(hwnd,,,NULL); srand((unsigned int)time()); //消息循环
while(GetMessage(&msg,NULL,,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return ;
} LRESULT CALLBACK MyWNDPROC(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT paintstruct;
switch(message)
{
case WM_CLOSE:
PostQuitMessage();
break;
case WM_PAINT:
hdc = BeginPaint(hWnd,&paintstruct);
ShowBackGround(hdc);
ShowSnack(hdc);
ShowApple(hdc); EndPaint(hWnd,&paintstruct);
break;
case WM_TIMER:
g_flag = TRUE;
Move();
if(IfBumpWall() || IfEatSelf())
{
KillTimer(hWnd,);
MessageBox(hWnd,"GAME OVER","提示",MB_OK);
}
if(IfEatApple()) //判断是否吃到苹果
{
NewApple(); //随机一个新苹果
AddNode(-,-); //长个
}
hdc = GetDC(hWnd);
ShowBackGround(hdc); //层层覆盖
ShowSnack(hdc);
ShowApple(hdc);
ReleaseDC(hWnd,hdc);
break;
case WM_KEYDOWN:
if(g_flag == TRUE)
{
switch(wParam)
{
case VK_UP:
if(fx != DOWN)
{
fx = UP;
}
break;
case VK_DOWN:
if(fx != UP)
{
fx = DOWN;
}
break;
case VK_LEFT:
if(fx != RIGHT)
{
fx = LEFT;
}
break;
case VK_RIGHT:
if(fx != LEFT)
{
fx = RIGHT;
}
break;
}
}
g_flag = FALSE;
hdc = GetDC(hWnd);
ShowBackGround(hdc);
ShowSnack(hdc);
ShowApple(hdc);
ReleaseDC(hWnd,hdc);
break;
} return DefWindowProc(hWnd,message,wParam,lParam);
}
void ShowBackGround(HDC hdc)
{
HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc); //创建兼容性DC
SelectObject(hdc_compatible,Hbitmap_BackGroup); //为兼容性DC选择背景位图
BitBlt(hdc,,,,,hdc_compatible,,,SRCCOPY); //按像素点进行传输
DeleteDC(hdc_compatible); //删除兼容性DC
return;
}
void AddNode(int x,int y)
{
Snack *pTemp = (Snack *)malloc(sizeof(Snack));
pTemp->x = x;
pTemp->y = y;
pTemp->pLast = NULL;
pTemp->pNext = NULL; if(pHead == NULL)
{
pHead = pTemp;
}
else
{
pEnd->pNext = pTemp;
pTemp->pLast = pEnd;
}
pEnd = pTemp;
}
void ShowSnack(HDC hdc)
{
Snack *pMark = pHead->pNext;
HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc);
switch (fx)
{
case UP:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Up);
break;
case DOWN:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Down);
break;
case LEFT:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Left);
break;
case RIGHT:
SelectObject(hdc_compatible,Hbitmap_SnackHead_Right);
break;
default:
break;
}
BitBlt(hdc,pHead->x*,pHead->y*,,,hdc_compatible,,,SRCCOPY); while(pMark)
{
SelectObject(hdc_compatible,Hbitmap_SnackHead);
BitBlt(hdc,pMark->x*,pMark->y*,,,hdc_compatible,,,SRCCOPY);
pMark = pMark->pNext;
}
DeleteDC(hdc_compatible);
}
void Move()
{
Snack *pMark = pEnd;
while(pMark != pHead)
{
pMark->x = pMark->pLast->x;
pMark->y = pMark->pLast->y;
pMark = pMark->pLast;
}
switch (fx)
{
case UP:
pHead->y--;
break;
case DOWN:
pHead->y++;
break;
case LEFT:
pHead->x--;
break;
case RIGHT:
pHead->x++;
break;
}
}
void ShowApple(HDC hdc)
{
HDC hdc_compatible;
hdc_compatible = CreateCompatibleDC(hdc);
SelectObject(hdc_compatible,Hbitmap_Apple);
BitBlt(hdc,apple.x*,apple.y*,,,hdc_compatible,,,SRCCOPY);
DeleteDC(hdc_compatible);
}
BOOL IfEatApple()
{
if(pHead->x == apple.x && pHead->y == apple.y)
return TRUE;
return FALSE;
}
void NewApple()
{
Snack *pMark = pHead;
int x;
int y;
do
{
x = rand() % + ;
y = rand() % + ;
pMark = pHead;
while(pMark)
{
if(pMark->x == x && pMark->y == y)
break;
pMark = pMark->pNext;
}
}while(pMark);
apple.x = x;
apple.y = y;
}
BOOL IfBumpWall()
{
if(pHead->x == || pHead->x == || pHead->y == || pHead->y == )
return TRUE;
return FALSE;
}
BOOL IfEatSelf()
{
Snack *pMark = pHead->pNext;
while(pMark)
{
if(pMark->x == pHead->x && pMark->y == pHead->y)
return TRUE;
pMark = pMark->pNext;
}
return FALSE;
}

2019-05-16 11:32:24 编程小菜鸟自我反省,望大佬能多提意见和建议,谢谢!!!

Win32小游戏--贪吃蛇的更多相关文章

  1. 第一个windows 小游戏 贪吃蛇

    最近用dx尝试做了一个小的贪吃蛇游戏,代码放到github上面:https://github.com/nightwolf-chen/MyFreakout 说一下自己实现的过程: 首先,我把蛇这个抽象成 ...

  2. JavaScript面向对象编程小游戏---贪吃蛇

    1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. ​ 2 这个demo是采用了 ...

  3. 用Canvas制作小游戏——贪吃蛇

    今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ...

  4. 使用JavaScript实现简单的小游戏-贪吃蛇

    最近初学JavaScript,在这里分享贪吃蛇小游戏的实现过程, 希望能看到的前辈们能指出这个程序的不足之处. 大致思路 首先要解决的问题 随着蛇头的前进,尾巴也要前进. 用键盘控制蛇的运动方向. 初 ...

  5. python【控制台】小游戏--贪吃蛇

    传统贪吃蛇相信大家都玩过,也是一款很老很经典的游戏,今天我们用python控制台实现 项目有很多bug没有解决,因为本人一时兴起写的一个小游戏,所以只是实现可玩部分功能,并没有花较多的时间和精力去维护 ...

  6. 手把手教学h5小游戏 - 贪吃蛇

    简单的小游戏制作,代码量只有两三百行.游戏可自行扩展延申. 源码已发布至github,喜欢的点个小星星,源码入口:game-snake 游戏已发布,游戏入口:http://snake.game.yan ...

  7. Java_GUI小游戏--贪吃蛇

    贪吃蛇游戏:是一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或 ...

  8. Java经典小游戏——贪吃蛇简单实现(附源码)

    一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...

  9. 用Python实现童年小游戏贪吃蛇

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中.

随机推荐

  1. Oracle通过一个字段的值将一条记录拆分为多条记录

    前言 之前遇到了一次这样的需求,当时没有记录,这一次又赶上了,简单的记录一下. 本文个人拙见,若有出入,请指出--来自菜的颤抖 场景 表A中存放了集装箱的信息,一个集装箱一条记录,表B中存放了对于集装 ...

  2. Qt 中的对象模型(Object Model)

    原标题:Qt 中的对象模型(Object Model)90不太后,余生皆折腾 本节内容主要讲了 Qt 对象模型比标准 C++ 对象模型多了什么内容,并介绍了组成 Qt 对象模型基础的相关的类.最后说明 ...

  3. shared_ptr 引用计数

    https://zh.cppreference.com/w/cpp/memory/shared_ptr 引用计数

  4. ubuntu下安装ftp服务

    1. 安装vsftpd $ sudo apt-get install vsftpd 2. 创建一个用户user-ftp用于ftp服务 $ sudo adduser user-ftp 3.创建一个文件/ ...

  5. 【439】Tweets processing by Python

        参数说明: coordinates:Represents the geographic location of this Tweet as reported by the user or cl ...

  6. redis和memcache对比

    1.性能方面:没有必要过多的关心性能,因为二者的性能都已经足够高了.由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached ...

  7. Vue学习笔记十三:Vue+Bootstrap+vue-resource从接口获取数据库数据

    目录 前言 SpringBoot提供后端接口 Entity类 JPA操作接口 配置文件 数据库表自动映射,添加数据 写提供数据的接口 跨域问题 前端修改 效果图 待续 前言 Vue学习笔记九的列表案例 ...

  8. 【转】百万年薪挖了p8,难道是水货?

    大厦新搬进来一家创业公司,老板红光满面地提着果篮上楼拜访,说是刚拿到了投资人的钱,正准备扩充团队大干一场.那个时候的他踌躇满志,顾盼生辉.当时我想,能在这个大环境下拿到投资的公司,做的产品应该是有前景 ...

  9. 【Leetcode_easy】985. Sum of Even Numbers After Queries

    problem 985. Sum of Even Numbers After Queries class Solution { public: vector<int> sumEvenAft ...

  10. react——Table组件

    /* * 构建数据列 * */ tableColumns = (currentData) => { let group = lodashGroupBy(currentData, 'level1' ...