• 简单的贪吃蛇


    近期都在忙着复习考试,忙里偷闲,抽空写了个贪吃蛇。没时间写具体的思路了,代码里有比較具体的凝视,有兴趣的同学能够自己看看。(感觉写的相对来说还是比較简短的。假设有什么写的不好或是不正确的地方,欢迎各位指出)。

    在写这个贪吃蛇时,我省去了非常多不必要的功能。仅仅实现了最主要的功能,界面也比較粗糙,游戏功能也不见得非常完好,仅仅是为了用尽量少的代码来实现主体功能,大家能够在这个基础上进行改动和完好。




    /*--------------------------------------------------------------
    名称: 简单的贪吃蛇
    开发环境:VC++ 6.0
    类型:控制台应用程序
    完毕时间:2014.06.20
    开发原则:大道至简,仅仅实现了最主要的功能。没有加入什么复杂的功能
    作者:风语
    运用的技术:双缓存。防止闪屏
    ---------------------------------------------------------------*/
    #include <windows.h>
    #include <time.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define CMD_UP			1
    #define CMD_DOWN		2
    #define CMD_LEFT		4
    #define CMD_RIGHT		8
    #define CMD_QUIT		16
    
    const int MAXN = 1000;
    bool flag, tag;
    int num, dir, score, a[MAXN];//num表示蛇节点的数目,dir表示蛇前进方向(0,1,2,3)(上下左右)
    POINT d[4] = {{0, -10}, {0, 10}, {-10, 0}, {10, 0}};//方向向量
    POINT food, node[MAXN];//node蛇的节点坐标
    POINT wall[10] = {{20, 10}, {460, 10}, {460, 350}, {20, 350}, {20, 10},
    				{39, 29}, {441, 29}, {441, 331}, {39, 331}, {39, 29}};//墙
    HDC hdc = NULL, mdc = NULL;//mdc内存dc
    HWND hwnd = FindWindow("ConsoleWindowClass", NULL);//窗体句柄
    HBRUSH hbrush;//画刷
    HPEN hpen;//画笔
    HBITMAP	bmp;//位图
    
    void CreateFood()		//产生食物
    {
    	if(tag) return; //tag == true,表明食物存在
    	while(!tag)//直到产生的食物在有效位置为止
    	{
    		food.x = 10 * (rand() % 40) + 40;
    		food.y = 10 * (rand() % 30) + 30;
    		Rectangle(mdc, food.x, food.y, food.x + 10, food.y + 10);
    		tag = true;
    		//检測食物是否产生在蛇身上,假设在,标记食物为不存在
    		for(int i = 0; i < 4 * num; i++)
    		{
    			if(food.x == node[i].x && food.y == node[i].y)
    			{
    				tag = false;
    				break;
    			}
    		}
    		
    	}
    }
    
    void Gotoxy(int x,int y)    //设置光标的位置
    {
          COORD coord;
          coord.X = x - 1;
    	  coord.Y = y - 1;
          SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
    
    void GameInit()		//游戏初始化
    {
    	srand(unsigned(time(NULL)));
    	num = 6; dir = 3; score = 0;
    	flag = true;//flag==true标记游戏能够进行
    	tag  = false;
    	system("color F0");//设置控制台背景和前景颜色
    
    	hdc = GetDC(hwnd);
    	mdc = CreateCompatibleDC(hdc);//创建兼容dc
    	bmp	= CreateCompatibleBitmap(hdc, 640, 480);//创建兼容位图
    	SelectObject(mdc, bmp);
    
    	hbrush = CreateSolidBrush(RGB(0, 255, 0));  
    	SelectObject(mdc, hbrush); 
    
    	RECT rect;//将mdc背景色设置为白色
    	GetClientRect(hwnd, &rect);	
    	hbrush = CreateSolidBrush(RGB(255, 255, 255)); 
    	FillRect(mdc, &rect, hbrush); 
    
    	Polygon(mdc, wall, 10);//绘制墙
    
    	Gotoxy(45, 25);
    
    	int t = 4 * num - 1;//初始化蛇
    	node[t].x   = 40; node[t].y   = 30;
    	node[t-1].x = 40; node[t-1].y = 40;
    	node[t-2].x = 50; node[t-2].y = 40;
    	node[t-3].x = 50; node[t-3].y = 30;
    	for(int i = t - 4; i >= 0; i--)
    	{
    		node[i].x = node[i + 4].x + 10;
    		node[i].y = node[i + 4].y;
    	}
    	for(i = 0; i < MAXN; i++)
    	{
    		a[i] = 4;
    	}
    }
    
    void GetDir()		//依据用户输入,获取蛇,新的移动方向
    {  
        int c = 0;  
    	if (GetAsyncKeyState(VK_UP)		& 0x8000)	c |= CMD_UP;  
        if (GetAsyncKeyState(VK_DOWN)	& 0x8000)	c |= CMD_DOWN;  
        if (GetAsyncKeyState(VK_LEFT)	& 0x8000)	c |= CMD_LEFT;  
        if (GetAsyncKeyState(VK_RIGHT)	& 0x8000)	c |= CMD_RIGHT;  
        if (GetAsyncKeyState(VK_ESCAPE)	& 0x8000)	c |= CMD_QUIT; 
    	
    	if (c & CMD_UP)		if(1 != dir) dir = 0;
        if (c & CMD_DOWN)	if(0 != dir) dir = 1;
        if (c & CMD_LEFT)	if(3 != dir) dir = 2;
        if (c & CMD_RIGHT)	if(2 != dir) dir = 3;
        if (c & CMD_QUIT)   flag = false; 
    }
    
    void Release()		//释放资源
    {
    	DeleteObject(hbrush);  
    	DeleteObject(hpen);
    	DeleteObject(bmp);
    	DeleteDC(mdc);
    	ReleaseDC(hwnd, hdc);
    }
    
    void MoveHead()		//蛇的头结点的移动
    {
    	for(int i = 0; i < 4; i++)
    	{
    		node[i].x += d[dir].x;
    		node[i].y += d[dir].y;
    	}
    }
    
    void Translate()//传递蛇身,前一个节点的位置是下一个节点下一步要到的位置
    {
    	for(int i = 4 * num - 1; i >= 4; i--)
    	{
    		node[i].x = node[i-4].x;
    		node[i].y = node[i-4].y;
    	}
    }
    
    void GameOver()		//游戏结束与否
    {
    	if(node[0].x > 440 || node[0].x < 50 || node[0].y > 320 || node[0].y < 30)
    		flag = false;//撞墙
    	for(int i = 4; i < 4 * num; i += 4)//咬自己
    	{
    		if(node[0].x == node[i].x && node[0].y == node[i].y && 
    			node[2].x == node[i+2].x && node[2].y == node[i+2].y)
    		{
    			flag = false;
    			return;
    		}
    	}
    }
    
    void PaintSnake()			//绘制出蛇
    {
    	PolyPolygon(mdc, node, a, num);
    }
    
    void EatFood()		//检測蛇是否吃到食物
    {
    	if(node[0].x == food.x + 10 && node[0].y == food.y)
    	{
    		tag = false;
    		num++;
    		score += 10;
    	}
    }
    
    int main()
    {
    	GameInit();
    	while(flag)
    	{
    		GetDir(); 
    		Translate();
    		MoveHead();	
    		EatFood();
    
    		GameOver();
    
    		/*绘制出蛇*/
    		hpen = (HPEN)GetStockObject(BLACK_PEN);
    		SelectObject(mdc, hpen);
    		hbrush = CreateSolidBrush(RGB(0, 0, 0));  
    		SelectObject(mdc, hbrush);  
    
    		CreateFood();
    		PaintSnake();
    
    		BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);//将图像从内存dc复制到当前窗体
    		if(!flag) break;
    
    		/*擦除蛇运动留下的阴影*/
    		hpen = (HPEN)GetStockObject(WHITE_PEN);
    		SelectObject(mdc, hpen);
    		hbrush = CreateSolidBrush(RGB(255, 255, 255));  
    		SelectObject(mdc, hbrush);
    		PaintSnake();	
    
    		char str[256];//绘制得分
    		sprintf(str, "score : %d", score);
    		TextOut(mdc, 465, 200, str, strlen(str));
    		Sleep(80);
    	}
    	Gotoxy(40, 25);
    	Sleep(3000);
    	Release();
    	return 0;
    }
    


  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10498173.html
  • Copyright © 2020-2023  润新知