zoukankan      html  css  js  c++  java
  • C语言新手写扫雷攻略2

    接下来是游戏的功能设计,要有扫雷的基本功能,左键点击雷区,右键红旗标记,并且可以统计雷数,可以重新开始,以下是游戏的功能初始

    void Game(void)
    {
    	while (1)
    	{
    		if (FLAG == 1)
    		{
    			GameBegin();//绘制出游戏界面并判断是否玩过和重新开始
    			GamePlay();//游戏过程的函数
    			if (AGAIN == 1)
    			{
    				AGAIN = 0;
    				continue;
    			}
    		}
    		FLAG = 0;
    		if (m.uMsg == WM_LBUTTONDOWN)//鼠标左键按下事件
    		{
    			MouseGetXY();
    			if (MouseX > 90 && MouseX<110 && MouseY>5 && MouseY < 25)
    			{
    				FLAG = 1;
    				continue;
    			}
    		}
    		if (_kbhit())//判断有按键退出
    		{
    			break;
    		}
    	}
    }

    此处FLAG是游戏失败后是否重新开始的标志,第一次开始也是如此,而AGAIN是游戏中途并没有玩完又想重新开始的标志,第一次玩首先要绘制游戏界面,下面是绘制函数

    void GameBegin(void)
    {
    	int i, j;
    	cleardevice();
    	PLAY = 1;
    	mineNUM = 0;
    	setfillstyle(BS_SOLID);//此处用法和TC不同
    	setfillcolor(WHITE);
    	bar(0, 0, 200, 230); //设置背景区域
    	for (i = 0; i < 10; i++) //绘制每个雷区(小格)
    	{
    		for (j = 0; j < 10; j++)
    		{
    			DrawEmpty(i, j, 0, LIGHTGRAY);
    		}
    	}
    	DrawSmile();//画出中间的笑脸
    	srand((unsigned)time(NULL));//根据时间给随机数不同的种子数
    	for (i = 0; i < 10; i++)
    	{
    		for (j = 0; j < 10; j++)
    		{
    			
    			Mine[i][j].num = rand() % 8;//随机数产生范围0-7
    			
    			if (Mine[i][j].num == 1)
    			{
    				mineNUM++;
    			}
    			else
    			{
    				Mine[i][j].num = 2;
    			}
    			printf("%3d", Mine[i][j].num);
    			Mine[i][j].flag = 0;
    		}
    		printf("
    ");
    		_stprintf_s(randmineNUM, _T("%d"), mineNUM);//将minrNUM转换成字符串类型
    		setbkcolor(WHITE);
    		setcolor(RED);
    		settextstyle(16, 0, _T("0"));
    		outtextxy(2, 2, randmineNUM);
    		
    	}  mineNUM = 100 - mineNUM;
    }

    其中的绘图函数和TC的名字功能相同,但所传递的参数都有简化,DrawEmpty()函数是画小格的函数,其中的坐标需要从屏幕坐标转换成窗口的坐标,需要了解坐标之间的转换

    比方说以屏幕左上角建立坐标系,起点是(0,0),窗口顶点屏幕坐标(x,y),窗口内一点P的屏幕坐标是(xP,yP),则P点的以窗口为原点窗口内坐标是(xP-x,yP-y)

    void DrawEmpty(int i, int j, int mode, int color) //画出16*16的小格
    {
    	setfillstyle(BS_SOLID);
    	setfillcolor(color);
    	if (mode == 0)
    	{
    		bar(10 + j * 20 - 8, 40 + i * 20 - 8, 10 + j * 20 + 8, 40 + i * 20 + 8);
    	}
    	else if (mode == 1)
    	{
    		bar(10 + j * 20 - 7, 40 + i * 20 - 7, 10 + j * 20 + 7, 40 + i * 20 + 7);
    	}
    }

    这个通过for循环画出100个小格

    接下来要画中间的黄色笑脸

    void DrawSmile(void)
    {
    	setfillstyle(BS_SOLID);
    	setfillcolor(YELLOW);
    	fillellipse(90, 5, 110, 25);//绘制椭圆(笑脸)函数,参数为椭圆外切矩形的左上右下角坐标
    	setfillstyle(BS_SOLID);
    	setfillcolor(BLACK);//画眼睛
    	fillellipse(93, 13, 97, 17);
    	fillellipse(103, 13, 107, 17);
    	bar(97, 20, 103, 21);//画嘴巴
    }

    这些是基本的绘图函数,是了解C比较好的,虽然不及MFC的封装,但是可以了解WinAPI的基本原理就是类似

    界面画好后还要布置地雷,这个功能简陋,利用随机数函数创建出地雷,雷数是不可控制的,可以用while循环判断10个雷停止,但很费时间,也可以改种算法伪随机布雷,即限定每个区域最多有几个雷

    srand函数是随机数种子数的生成,随着时间的变化产生不同的种子数,需要用到time.h这个头文件

    rand()与n求余就是生成0-(n-1)范围内的随机数,具体数学算法自行百度

    下面的sprintf是用的宽字符,vs2013是c11标准,其他编译器可以使用sprintf(),用于转换剩余的雷数变成字符串显示

    具体函数的语法参考EasyX的官方帮助,今天就到这了!

  • 相关阅读:
    mina:IoBuffer 常用方法(转载)
    js:对象之间的复制
    jquery与angular的交互
    javax.crypto.BadPaddingException: Given final block not properly padded
    jstree:重新加载数据集,刷新树
    TCP 握手 -> 微服务
    eclipse 中添加source
    02 IO
    为什么常用 Map<> map = new HashMap()
    自组织 Self-Orginaztion
  • 原文地址:https://www.cnblogs.com/acgpiano/p/3980162.html
Copyright © 2011-2022 走看看