贪吃蛇
来源:互联网 发布:linux listen函数 编辑:程序博客网 时间:2024/03/29 22:31
#include<windows.h>
#include<iostream>
#include<time.h>
using namespace std;
//------豆的 结构体------
typedef struct BeanNode
{
int x;
int y;
}BeanNode;
//------蛇的 结构体------
typedef struct snakeNode
{
int x;
int y;
struct snakeNode* pNext;
}snakeNode;
//------蛇的全局变量 常量 宏 枚举------
enum dir{UP,DOWN,LEFT,RIGHT}; //定义方向
dir ditcetion=UP; //默认初始方向是向上
const int LEN=30; //画蛇 画豆的 长宽高!
int isEat=FALSE; //是否吃豆
int isDead=FALSE; //是否死了
snakeNode *snakeHead=NULL; //蛇头
snakeNode *snakeTail; //蛇尾
BeanNode bean; //豆
int snackLenght; //蛇的长度
//------蛇的 函数声明------
//初始化游戏
void createGame();
//画屏幕
void drawGame();
//蛇移动
void snakeMove();
//出豆
void createBean();
//吃豆
void eatBean();
//蛇死
void snakeDead();
//------应用程序的全局变量------
char className[20]="clever"; //设计出窗口图纸的名字
HDC hdc; //设备的句柄
HINSTANCE hIns; //应用程序的实例句柄
HWND Hwnd; //窗口句柄
HBRUSH newHbrush;
HBRUSH oldHbrush;
//应用程序的函数声明
LRESULT CALLBACK wndProc(HWND hWnd,UINT message,WPARAM wParm,LPARAM lParam); //回调函数
//应用程序的主函数
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wndClass;
HWND hWnd;
MSG msg;
hIns=hInstance;
wndClass.cbClsExtra=0;
wndClass.cbSize=sizeof(WNDCLASSEX);
wndClass.cbWndExtra=0;
wndClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wndClass.hCursor=NULL;
wndClass.hIcon=NULL;
wndClass.hIconSm=NULL;
wndClass.hInstance=hInstance;
wndClass.lpfnWndProc=wndProc;
wndClass.lpszClassName=className;
wndClass.lpszMenuName=NULL;
wndClass.style=CS_VREDRAW|CS_HREDRAW;
RegisterClassEx(&wndClass);
hWnd=CreateWindow(className,"贪吃蛇",WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,400,100,600,600,NULL,NULL,hInstance,NULL);
Hwnd=hWnd;
if(!hWnd)
{
MessageBox(hWnd,"创建窗口没有成功!","ERROR!",MB_OK);
}
else
{
ShowWindow(hWnd,nShowCmd);
}
//================游戏初始化区==============
createGame(); //初始化蛇
createBean(); //初始化豆
//================消息循环================
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK wndProc(HWND hWnd,UINT message,WPARAM wParm,LPARAM lParam)
{
switch(message)
{
case WM_PAINT:
hdc=GetDC(hWnd);
Rectangle(hdc,0,0,600,600); //铺平
TextOut(hdc,240,200,"贪吃蛇游戏!",11); //菜
TextOut(hdc,240,350,"1. 按回车键开始",15); //
TextOut(hdc,240,390,"2. 按空格键暂停",15); //单
break;
case WM_DESTROY:
ReleaseDC(hWnd,hdc); //退出的时候 要释放 设备
PostQuitMessage(0);
break;
case WM_KEYDOWN:
{
switch(wParm)
{
case VK_RETURN: //按下回车 开始游戏
SetTimer(hWnd,1,200,NULL);
break;
case VK_UP: //向上走
if(ditcetion!=DOWN) //如果 蛇当前方向是向下 则不能下上走
{
ditcetion=UP;
}
break;
case VK_DOWN:
if(ditcetion!=UP)
{
ditcetion=DOWN;
}
break;
case VK_LEFT:
if(ditcetion!=RIGHT)
{
ditcetion=LEFT;
}
break;
case VK_RIGHT:
if(ditcetion!=LEFT)
{
ditcetion=RIGHT;
}
break;
}
}
break;
case WM_TIMER: //计时器
{
snakeMove(); //蛇移动
drawGame(); //画屏幕
}
break;
}
return DefWindowProc(hWnd,message,wParm,lParam);
}
//----------蛇的函数体-------------
//初始化游戏
void createGame()
{
snackLenght=4; //初始化四节蛇
for(int i=0;i<snackLenght;i++)
{
snakeNode *tempNode=(snakeNode*)malloc(sizeof(snakeNode));
tempNode->x=300;
tempNode->y=300+i*LEN;
tempNode->pNext=NULL;
if(!snakeHead) //如果蛇头还灭有
{
snakeHead=tempNode; //第一个初始化的节点 赋给蛇头 确定蛇头
}
else
{
snakeTail->pNext=tempNode;
}
snakeTail=tempNode; //确定尾节点
}
}
//画屏幕
void drawGame()
{
ReleaseDC(Hwnd,hdc);
//铺屏
hdc=GetDC(Hwnd);
Rectangle(hdc,0,0,600,600);
ReleaseDC(Hwnd,hdc);
//画蛇
hdc=GetDC(Hwnd);
newHbrush=CreateSolidBrush(RGB(150,130,78));
oldHbrush=(HBRUSH)SelectObject(hdc,newHbrush);
snakeNode *tempHead=snakeHead;
while(tempHead) //循环蛇 画蛇
{
Rectangle(hdc,tempHead->x,tempHead->y,tempHead->x+LEN,tempHead->y+LEN);
tempHead=tempHead->pNext;
}
DeleteObject(oldHbrush);
ReleaseDC(Hwnd,hdc);
//画豆
hdc=GetDC(Hwnd);
newHbrush=CreateSolidBrush(RGB(123,30,78));
oldHbrush=(HBRUSH)SelectObject(hdc,newHbrush);
if(isEat==TRUE) //如果吃豆了 就从新 生成一个豆
{
createBean();
isEat=FALSE;
snackLenght++;
}
Ellipse(hdc,bean.x,bean.y,bean.x+LEN,bean.y+LEN); //画豆
DeleteObject(oldHbrush);
ReleaseDC(Hwnd,hdc);
//蛇挂没挂
if(isDead==TRUE) //如果蛇挂了 铺屏 打印 蛇死了 关掉计时器
{
hdc=GetDC(Hwnd);
newHbrush=CreateSolidBrush(RGB(34,130,78));
oldHbrush=(HBRUSH)SelectObject(hdc,newHbrush);
Rectangle(hdc,0,0,600,600);
TextOut(hdc,250,300,"GameOver!",9);
KillTimer(Hwnd,1);
DeleteObject(oldHbrush);
DeleteObject(oldHbrush);
ReleaseDC(Hwnd,hdc);
}
}
//蛇移动
void snakeMove()
{
snakeNode *tempNode=(snakeNode*)malloc(sizeof(snakeNode)); //创建一个新的节点 储存蛇要移动的那个坐标
snakeNode *tempHead=snakeHead; //弄一个临时的 头结点 为了删除尾巴用
switch(ditcetion)
{
case UP: //如果向上 就将蛇头上面那个节点的坐标 储存到新申请的那个节点
{
tempNode->x=snakeHead->x;
tempNode->y=snakeHead->y-LEN;
tempNode->pNext=snakeHead;
}
break;
case DOWN: //如果向下 就将蛇头下面那个节点的坐标 储存到新申请的那个节点
{
tempNode->x=snakeHead->x;
tempNode->y=snakeHead->y+LEN;
tempNode->pNext=snakeHead;
}
break;
case LEFT: //如果向左 就将蛇头左面那个节点的坐标 储存到新申请的那个节点
{
tempNode->x=snakeHead->x-LEN;
tempNode->y=snakeHead->y;
tempNode->pNext=snakeHead;
}
break;
case RIGHT: //如果向右 就将蛇头右面那个节点的坐标 储存到新申请的那个节点
{
tempNode->x=snakeHead->x+LEN;
tempNode->y=snakeHead->y;
tempNode->pNext=snakeHead;
}
}
snakeHead=tempNode; //最后 将头结点 指向新的节点 (头结点 有新的值了 蛇 就开始移动了)
//判断是否吃豆
eatBean();
//如果没有吃豆
if(FALSE==isEat)
{
int i=1;
while(i<snackLenght-1)
{
tempHead=tempHead->pNext;
i++;
}
free(snakeTail);
snakeTail=tempHead;
tempHead->pNext=NULL;
}
//如果吃豆了 就不删除节点了
//判断是否撞车了
snakeDead();
}
//出豆
void createBean()
{
srand((unsigned)time(NULL)); //用随机数 生成一个豆
bean.x=rand()%20*LEN; //这个屏幕横着 最多可以有20个豆
bean.y=rand()%20*LEN; //这个屏幕竖着 最多可以有20个豆
}
//吃豆
void eatBean()
{
if((bean.x==snakeHead->x)&&(bean.y==snakeHead->y)) //如果蛇头和豆重合了 就说明 吃豆了 isEat=TRUE
{
isEat=TRUE;
}
}
//蛇死
void snakeDead()
{
//撞墙死
if(((snakeHead->x)>570)||((snakeHead->y)>570)||(snakeHead->x<0)||(snakeHead->y<0))//如果蛇头和墙重合了 就说明 蛇死了 isDead=TRUE
{
isDead=TRUE;
}
//撞身上死
snakeNode *tempHead=snakeHead; //弄一个临时的蛇头
tempHead=tempHead->pNext; //将他指向第二个节点
while(tempHead) //从第二个节点循环蛇
{
if((snakeHead->x==tempHead->x)&&(snakeHead->y==tempHead->y)) //如果蛇头 和蛇身的坐标重合了 那么蛇自己就把自己干掉了 isDead=TRUE
{
isDead=TRUE;
break;
}
tempHead=tempHead->pNext;
}
}
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- poj3273Monthly Expense(二分)
- boost lexical_cast
- poj3468 A Simple Problem with Integers(线段树)
- Android多点触摸的判断
- [SQL Native Client] 命名管道提供程序:无法打开与 Sql Server 的连接[2]
- 贪吃蛇
- 外包服务的Java
- 请推开我
- Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definitio
- 自己动手写CPU之第五阶段(5)——测试逻辑、移位与空指令的实现
- 关于UIView的userInteractionEnabled属性
- 提高Web服务器性能
- 以太网OAM(802.1ag和Y.1731)
- LVS集群系统网络核心原理分析