项目来源:老九君

项目名称:精忠报国之笑傲江湖

视频课地址:网易云课堂

基本功能/架构:


第二天

  • 今天看得比较快,基本把这个项目结束了吧,明天再仔细看一下有没有遗漏的这项目就应该算是结束了.项目难度的话一般,主要是windows的函数调用以前不知道的话刚看可能会蒙头,同样需要源码的同学私聊或者评论我私发给你,因为这毕竟不是我写的,接下来后天开始应该会开始一个tinyhttp的github项目模仿,欢迎继续关注
  • 简易目录

    • 1.COORD windows.h头文件

    • 2.conio.h getch()函数

    • 3. game.c showMap()函数

    • 4.怪物计数与打印

    • 5.随机攻击力 stblib.h


1.COORD windows.h头文件

纵观项目,从player(玩家),monster(怪物),martial(门派)这几个关键结构体的定义和功能地图的切换的到怪物与地图的匹配(哪些怪物在哪些地图)还有地图描述信息的显示,全都使用了COORD结构,有关代码在后面
一开始看到这个地方特别疑惑,因为我在所有文件里都Ctrl F查询了,都没有找到COORD这样一个结构体的声明,最后才发现这是一个windows api里封装好的结构体,可以直接用,只有int x和int y两个成员,作用是表示一个字符在控制台屏幕上的坐标,其定义如下:

typedef struct _COORD {SHORT X; // horizontal coordinate 水平坐标
SHORT Y; // vertical coordinate 竖直坐标
} COORD;

简单来说,COORD就像是给我们的控制台以左上角为(0,0)点建造了一个坐标系(只不过这个坐标系和平面直角坐标系的第四象限有点相似,但是又不同,Y也是向正方向增大的),例如我们在定义地图时某个地图坐标为(4,3),在后面要显示着地图相关信息的时候只要看怪物所在地图坐标横纵坐标是否与(4 , 3)一致即可.
注意:在项目中COORD并没有用来在屏幕上显示,更多的像是两个参数进行匹配,这不是c语言的标准库,不用太在意,会用就好

  • 结构体的定义
/* 门派 */
typedef struct _martial{int id;         //门派编号- - -COORD hqCoord;  //总部坐标(X-行,Y-列),与正常坐标轴相反- - -
}Martial;
/* 玩家结构 */
typedef struct _player{int id;- - -COORD currCoord;//玩家当前坐标(X-行,Y-列),与正常坐标轴相反Bag bag;
}Player;
/* 怪物 */
typedef struct _monster{int id;- - -COORD mCoord;   //怪物坐在地图坐标(X-行,Y-列),与正常坐标轴相反
}Monster;
  • 功能的实现
/* 显示怪物:怪物与地图的匹配 */
void ShowMonster()
{- - - //遍历怪物数组,找到所有跟玩家坐标相同的怪物int monsterCount = sizeof(monsters)/ sizeof(Monster);int monsterIndex[9];//最多9个怪物int currCount = 0;//当前地图的怪物总数for(i = 0; i < monsterCount; i++){if(X == monsters[i].mCoord.X && Y == monsters[i].mCoord.Y && monsters[i].state != 0)//判断怪物所在地图XY坐标与当前地图XY坐标是否相等{//显示怪物- - - }}
}/* 地图描述信息的显示  */
void ShowMap()
{Clear(MARGIN_X, 3);//地图的起始位置固定为MARGIN_X, 3int i = 0, j = 0;char * martialIntro = NULL;//门派介绍for(; i < 8; i++){SetPosition(MARGIN_X, 3 + i);printf("|  ");for(j = 0; j < 8; j++){if(i == X && j == Y){SetColor(13, 15);}else{SetColor(10, 0);}printf("%-9s", Maps[i][j]);SetColor(10, 0);}printf(" |\n");}
/* 地图的切换  */
while(1){- - -printf("请输入选择或四方向移动:");key = GetKey();//等待用户输入if(key == 38){//上X--;}else if(key == 39){//右Y++;}else if(key == 40){//下X++;}else if(key == 37){//左Y--;}- - -//总共只有8行8列 防止越界if(X > 7) X = 0;if(X < 0) X = 7;if(Y > 7) Y = 0;if(Y < 0) Y = 7;ShowMap();}SetColor(15, 0);//InitializeGame();//ShowPlayer();return 0;

2.conio.h getch()函数

  • getch()函数
  • 在项目中,所有功能都是由键盘上的数字键和上下左右方向键来进行选择和控制的,我们固然可以使用getchar()然后转int用ANCII进行判断,但是所有正常的函数都是回显函数,即我们输入的内容在控制台是会打出来的,所以这时需要使用到conio.h中getch()函数
  • getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
    while(1){//死循环等待输入7退出游戏- - -key = GetKey();//等待用户输入if{}- - -}

3. game.c showMap()函数

在项目中有这样一个功能:将所在地图的文字突出显示,如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBvNXVGm-1584329343725)(:/a1ff842a16c746e4b22126b325ba33a5)]

这个功能也是靠windows.h中封装的函数SetConsoleTextAttribute(handle ,int)实现,能控制前景色和后景色,可见在这个项目里使用了大量的windows api,问题是找了半天还没找到官方文档(官网的我就没查到…就查到一个winbase,但winbase只是windows的一部分啊),太难了!

/* 控制颜色  */
void SetColor(int ForeColor, int BackGroundColor)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);                    //获取当前窗口句柄SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//设置颜色
}/* 打印地图并突出当前地图 */
void ShowMap()
{Clear(MARGIN_X, 3);//地图的起始位置固定为MARGIN_X, 3int i = 0, j = 0;char * martialIntro = NULL;//门派介绍for(; i < 8; i++){SetPosition(MARGIN_X, 3 + i);//SetPosition是一个控制光标的函数,主要是靠windows.h中封装的函数实现printf("|  ");for(j = 0; j < 8; j++){if(i == X && j == Y){SetColor(13, 15);//SetColor是一个改变输出颜色(能控制前景色和后景色)的函数,主要也是靠windows.h中封装的函数实现}else{SetColor(10, 0);}printf("%-9s", Maps[i][j]);SetColor(10, 0);}printf(" |\n");}- - -//地图信息打印}

4.怪物计数与打印

  • 在项目里面,筛选怪物以及打印怪物的方式很值得学习
    – 1.首先使用for循环遍历所有monsters数组里的monster结构体,判断坐标是否相等,相等则currCount++并将这个monster的索引存入一个int 数组:monsterIndex[currCount] = i 就是这句 很精髓
    – 2.然后在每个for循环要结束之前判断一次当前计数器currCount(符合条件的monster)是否==9,等于则退出for循环
    – 3.凑足9个怪物后,再使用一个for循环将刚才存怪物索引的int 数组遍历出来,并用取出来的索引去从monsters数组里取出信息打印出来
  • 下面是实现,虽然说实话有点花里胡哨和多余,但是思想值得借鉴
    //遍历怪物数组,找到所有跟玩家坐标相同的怪物int monsterCount = sizeof(monsters)/ sizeof(Monster);//值得学习的数组长度计算方式-> 总长度/单位长度int monsterIndex[9];//最多9个怪物int currCount = 0;//当前地图的怪物总数for(int i = 0; i < monsterCount; i++){if(X == monsters[i].mCoord.X && Y == monsters[i].mCoord.Y && monsters[i].state != 0)//判断坐标相等{monsterIndex[currCount] = i;//将符合条件的怪物索引放进一个新的数组里currCount++;if(currCount == 9) break;//新的数组里数量达到9时达到页面最多显示的怪物数,退出当前循环}}if(currCount == 0){- - -}//判断无怪物则打印无怪物提示信息//打印怪物信息for (int i = 0; i < currCount; i++){printf("%d.%s(%s)\t\t", i + 1, monsters[i].name, levelNames[monsters[i].level - 1]);if(i % 3 == 0)//换行以及重新定位光标{SetPosition(MARGIN_X, 14 + i / 3);}}

5.随机攻击力 stblib.h

  • 在项目中武器和防具的攻击力和防御力都是在最大值和最小值之间摇摆不定的,因此在每一轮战斗时需要获取中间的一个随机数作为当前攻击力和防御力,结构体定义如下:
/* 游戏道具 - 武器、防具、消耗品、卡片 */
typedef struct _prop{int id;         //道具编号- - -union{//联合 - 多选1int minAttack; //如果是武器,就对应攻击力int minDefence;//如果是防具,就对应防御力int minPower;  //如果是血瓶等消耗品,就对应增加的能量值};union{//联合 - 多选1int maxAttack; //如果是武器,就对应攻击力int maxDefence;//如果是防具,就对应防御力int maxPower;  //如果是血瓶等消耗品,就对应增加的能量值};char desc[200]; //道具的功能描述
}Prop;
  • 产生随机数我们需要使用C语言标准库<stdlib.h>中的rand(void)函数,返回一个0到常量RAND_MAX (不同实现中值可能不同,但至少32767)的整数值
  • 假如我们想产生一个0到49的随机数,就该这么写
 rand() % 50//对50取模(余数)rand() % (a +1) //a是一个整数,对a+1取模,a+1是长度
  • 假如我们想产生一个19到25的随机数,就该这么写
 rand() % 7 + 19//对50取模(余数)rand() % (a - b +1) + b //产生一个a与b之间的整数,b<a ,a - b +1是长度,b是偏移量
  • 所以项目中要产生一个最大最小值之间的攻击力或者防御力也是特别简单了
 int playerAttack = rand() % (currPlayer->weapon.maxAttack - currPlayer->weapon.minAttack + 1) + currPlayer->weapon.minAttack;

C语言项目-精忠报国-第二天-COORD windows.h头文件/conio.h getch()函数/game.c showMap()函数 文字突出/怪物计数与打印/随机攻击力 stblib.h相关推荐

  1. c语言中的stdbool.h头文件,【C语言】中的stdbool.h头文件

    C语言中的stdbool.h头文件 一.相关基础知识 二.具体内容 Win7下安装的VS2015中的stdbool.h的位置为: F:\Program Files (x86)\Microsoft Vi ...

  2. c语言windows.h头文件详解

    如果c语言库里没有某个头文件 只需要将下好的头文件放入下面的路径即可 windows.h头文件包含的函数及其用法 1.GetAsyncKeyState()()//通过函数来判断按键按下的状态 主要用法 ...

  3. graphics.h头文件_C语言图形(graphics.h头文件功能和示例)

    graphics.h头文件 C中的颜色说明 (Color Description in C) setbkcolor sets the background to the color specified ...

  4. C语言不要重复包含.h头文件和.c文件

    1.不要重复包含头文件 --以上出自<C语言程序设计:现代方法(第2版)> f3.h //#ifndef AE_OK #define AE_OK 0 typedef int ngx_int ...

  5. c语言 自动包含头文件,C语言不要重复包含.h头文件和.c文件

    http://blog.csdn.net/unix21/article/details/8450235 2012 1.不要重复包含头文件 --以上出自<C语言程序设计:现代方法(第2版)> ...

  6. c语言头文件格式图片_c语言中的.h头文件的格式

    #ifndef __digital_h__ #define __digital_h__ #ifndef __cplusplus extern "C"{ #endif #ifdef  ...

  7. Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件

    第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...

  8. c语言intrins头文件,结合单片机学习板学习c语言之流水灯制作 intrins.h头文件

    原标题:结合单片机学习板学习c语言之流水灯制作 intrins.h头文件 目的:实现流水灯. 本文引用地址:http://www.eepw.com.cn/article/201608/294948.h ...

  9. C语言高级知识锦集(一)——头文件的格式

    漫谈头文件 头文件对于刚入门的新人来说是个陌生的东西,什么是头文件呢?它和我们写的.c文件有什么区别呢?这个问题对于我来说有段认识的过程 #include <stdio.h> 早期我接触C ...

最新文章

  1. 奥运会志愿者需要做哪些工作?
  2. Date String转换
  3. 爬虫好学吗python-python爬虫容易学吗
  4. 计算机视觉开源库OpenCV之图像翻转
  5. 记录完全分布式开发zookeeper hadoop flume kafka hbase
  6. 【SpringBoot】添加自定义浏览器图标 favicon.ico
  7. F5定时切换维护页面
  8. HDU1999不可摸数-暴力打表
  9. 【Hihocoder - offer编程练习赛86 - C】跳数游戏(STLset或map预处理,dp)
  10. 使用ISA Server保护内部的web服务器
  11. 职场人际关系该如何拿捏
  12. c# task添加顺序_关于c#:Task和async等待所需的指导
  13. Solr 通过fl可以设置需要返回的字段
  14. 2:数据库的CURD
  15. 例4.1 特殊乘法 - 九度教程第39题(数位拆解)
  16. Oracle OCP和MySQL OCP认证考试内容有哪些?
  17. dojo省份地市级联之地市Dao接口类(四)
  18. 税控盘版开票助手开发
  19. 增粉的各种方法【微信 / 微博 增加粉丝的108种方法】
  20. DataGridView控件绑定数据源时:用户sa登录失败

热门文章

  1. Elasticsearch的节点与分片
  2. 高并发情况下保证高可用性
  3. kali linux 安装驱动安装教程,Kali Linux 安装英伟达显卡过程实录
  4. 微博数据爬虫——获取特定ID的热门转发用户列表(五)
  5. vw 前端_【前端适配】vw+rem自适应适配方案
  6. 认识微型计算机 ppt,全国“xx杯”计算机应用基础类说课大赛优秀作品:认识微型计算机的组成 2.ppt...
  7. 数据库的安装卸载与使用
  8. JVM - 直接内存
  9. Redis基本操作命令(图文详解)
  10. Html和css的class和id的命名,[HTML] CSS Id 和 Class选择器