用C语言编写英雄联盟游戏
2020-07-27纪辉进
摘 要:游戏产业发展很快,不仅是学生,很多成年人都对游戏爱不释手;C语言是实践性很强的一门课程,让学生用C语言编写英雄联盟游戏,相对于局限于教材的“填鸭式”“验证式”教学而言,项目教学对学生更有吸引力,更能激发学生对学习动力,兴趣爱好是最好的老师,学生玩着自己编写的游戏,有利于其体会到成就感,对游戏功能的更高要求促使学生进行自主学习,自己一步步去实现。这样能激发学生的学习热情,积累项目经验,达到提升学生实践动手能力的目的。
关键词:C语言;情境教学;任务驱动;项目案例;英雄联盟;游戏
中图分类号:TP311.1 文献标识码:A 文章编号:2096-4706(2020)05-0069-03
Developing League of Legends Game with C Language
JI Huijin
(Department of Information Technology,Hubei Polytechnic Institute,Xiaogan 432000,China)
Abstract:The development of the game industry is very fast and hot. Not only students,but also many adults cant let go of the game. C language is a very practical course. This paper introduces the game situation to let students write the League of Legends in C language. Compared with the teaching materials “cramming” and “verification” teaching,project-based teaching is more attractive to students and can stimulate students For learning motivation,interest and hobbies are the best teachers. Students play their own games,and their sense of achievement is expressed in words. The higher requirements for the function of the game inspire students to learn independently and realize step by step. This can stimulate studentsenthusiasm for learning,accumulate project experience,and improve studentspractical ability.
Keywords:C language;situational teaching;task driven;project cases;League of Legends(LOL);game
0 引 言
来自网络的数据显示,2018年电竞游戏市场规模达417.9亿元;中国教育部也将电竞专业纳入高等教育体系;2017年亚洲奥林匹克理事会将电子竞技纳入亚运会,2022年,电竞将作为杭州亚运会的正式比赛项目。近年来电竞游戏规模快速增长,给游戏开发产业注入无穷动力,游戏开发程序员缺口也越来越大;本文从游戏入手,培养学生的游戏编程思维和动手能力。
1 项目背景
1.1 开发环境
开发语言:C
开发工具:Visual Studio 2012/Visual C++6.0
1.2 项目需求
《英雄联盟》(简称LOL)是美国开发,在中国大陆地区由腾讯公司代理运营的英雄对战类竞技网游。游戏里拥有数百位各具特色,不同职业的英雄,游戏玩家首次登录可以选择扮演的英雄,通过打怪挣钱获取装备,也可以到商店购买武器和其他用品等,英雄之间还可以对战。
本项目就是要模拟《英雄联盟》游戏,编写简化版的英雄联盟游戏;用户首先输入用户名和密码登录,系统展示多名英雄角色供玩家选择;选择好扮演的角色后开始游戏,玩家选择是进入商店购买商品还是到野外打怪升级;购买的商品可以是武器和药水,不同的武器攻击力和防御力不同,价格也有所差别,对战时受到伤害会减少生命值和体力,不同的药水功效不一样,程序运行效果如图1所示。
2 数据模型
C语言中常用的数据类型有int、float、double、char,單独的某一种数据类型都不能描述英雄、怪兽和药品等,为了描述这些,我们必须采用结构体类型;英雄、怪兽和药品都有多个备选,因此我们采用结构体数组作为程序数据模型;为了字符串初始化和输出的便利,英雄、怪兽和药品的名字采用基类型为char的指针更加方便。相关代码如下:
struct Weapon
{//武器类型
char *name;//武器名
int attack;//攻击力
int defence;//防御力
int price;//价格
};
struct Hero
{//英雄类型
char *name;//英雄名
struct Weapon weapon;
//英雄所持武器
int blood;//血量
int money;//金币
};
struct Monst
{//怪兽类型
char *name;//怪名字
int attack;//攻击力
int defence;//防御力
int blood;//血量
int money;//金币
};
struct Good
{//商品类型
char *name;//商品名
int price;//价格
int attack;//加攻击力
int defence;//加防御力
int blood;//加血量
};
为了降低程序复杂程度,我们把程序按照功能分成多个功能模块,每个模块的功能代码封装到一个函数中,为了在各函数都能正常访问英雄、武器、怪兽和商品,需要将英雄、武器、怪兽和商品数组声明为全局变量。相关代码如下:
struct Hero heros[2],player;//英雄结构体数组,玩家
struct Weapon weapons[2];//武器结构体数组
struct Monst monsts[2],monst;//怪的结构体数组,随机怪
struct Good goods[2];//药
3 核心代码
3.1 初始化英雄、武器、怪兽和药品代码
void loading()//初始化2种武器,2位英雄,2只怪兽,2种药品,根据需要可初始化更多
{weapons[0].name="倚天剑";weapons[0].attack=28; weapons[0].defence=6;weapons[0].price=300;
weapons[1].name="屠龙刀"; weapons[1].attack=27; weapons[1].defence=8;weapons[1].price=400;
heros[0].name="周芷若";heros[0].weapon=weapons[0]; heros[0].blood=200;heros[0].money=300;
heros[1].name="张无忌";heros[1].weapon=weapons[1]; heros[1].blood=300;heros[1].money=100;
monsts[0].name="猫妖";monsts[0].attack=8;monsts[0].defence=4;monsts[0].blood=50; monsts[0].money=50;
monsts[1].name="狼妖";monsts[1].attack=12;monsts[1].defence=7; monsts[1].blood=90;monsts[1].money= 250;
goods[0].name="金创药";goods[0].price=100;goods[0].attack=0;goods[0].defence=0;goods[0].blood=150;
goods[1].name="云南药";goods[1].price=200;goods[1].attack=0;goods[1].defence=0;goods[1].blood=250;}
3.2 登录模块代码
登录时玩家根据提示输入用户名和密码,用户名和密码输入正确,程序进入下一环节;输入错误需要重新输入,直到用户名和密码都正确才进入后续流程。这里的登录账号和密码由软件内置,采用整型数据表示。也可以采用字符串表示,那么在核对用户名和密码是否正确时就需要用到strcmp函数,由于篇幅限制不在此赘述。相关代码如下:
void login(){
int username,password; do{
printf("请输入账号:");scanf("%d",&username);printf("请输入密码:"); scanf("%d",&password);
if(username!=123||password!=123)printf("账号或密码输入错误,请重新输入!\n");
}while(username!=123||password!=123);}
3.3 選择扮演角色模块代码
当游戏开始时,玩家可根据系统提示选择扮演的角色。相关代码如下:
void cosplay(){//程序列出各英雄姓名,武器,攻击力等信息,备玩家选择
int i,select; printf("序号\t姓名\t武器\t攻击力\t防御力\t价格\t血量\t金币\n");
for(i=0;i<2;i++) {
printf("%d\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n",i+1, heros[i].name,heros[i].weapon.name,heros[i].weapon.attack, heros[i].weapon.defence,heros[i].weapon.price,heros[i].blood, heros[i].money);}
printf("请选择扮演角色:"); scanf("%d",&select); player=heros[select-1];}
3.4 购买商品模块代码
由于篇幅这里只罗列出两种药品供购买,若有需要,也可以初始化和罗列更多药品和武器以供选择;在购买商品的时候,如果玩家金钱足够,完成交易后可根据购买物品的属性对玩家对应属性进行增幅提升,例如购买了武器,玩家手持的武器会发生变化,武器的攻击力也会发生变化;如果购买了药品,恢复体力的药水会增加玩家体力,恢复血量的药水会增加玩家血量;如果玩家金钱不够则无法完成交易,系统会提示玩家打怪挣钱后再来购买。相关代码如下:
void shopping(){int i,select; printf("序号\t商品名\t单价\t攻击\t防御\t血\n");
for(i=0;i<2;i++) {
printf("%d\t%s\t%d\t%d\t%d\t%d\n",i+1,goods[i].name,goods[i].price,goods[i].attack,goods[i].defence,goods[i].blood); }
printf("请输入要购买商品的序号:"); scanf("%d",&select); select--;//1,2
if(select>=0&&select<2) {
if(player.money>=goods[select].price)//买得起
{player.money=player.money-goods[select].price;
player.weapon.attack=player.weapon.attack+goods[select].attack;
player.weapon.defence=player.weapon.defence+goods [select].defence;
player.blood=player.blood+goods[select].blood;
printf("你购买了%s,%d金币,攻击力提升%d点,防御力提升%d点,血量提升%d点!\n",goods[select].name,goods [select].price,goods[select].attack,goods[select].defence,goods[select].blood); } else //买不起
{ printf("穷鬼,打怪挣钱去吧,这个地方不适合你!\ n"); }}}
3.5 战斗模块代码
前面初始化了几只怪兽,玩家在野外遇到的怪兽随机;跟怪兽战斗采用的是对战模式,即玩家攻击怪兽后怪兽如果没死会还手,还手时英雄血量会降低。相关代码如下:
void fitting(){ int r,hurt; srand((unsigned)time (NULL)); r=rand()%2; monst=monsts[r];
printf("你在野外遭遇到了%s\n",monst.name);
while(player.blood>0&&monst.blood>0) {//英雄先动手
hurt=player.weapon.attack-monst.defence;if(hurt<= monst.blood)//扛得住
{printf("%s对%s发起了攻击,造成%d点伤害,%s的血量变为%d点\n",player.name,monst.name,hurt,monst.name, monst.blood-hurt);monst.blood=monst.blood-hurt; }else //扛不住
{printf("%s对%s发起了攻击,造成%d点伤害,%s的血量变为0,%s死亡!\n",player.name,monst.name,monst.blood, monst.name,monst.name); monst.blood=0; }
//怪还手
if(monst.blood>0)
{hurt=monst.attack-player.weapon.defence;if(hurt< player.blood)
{printf("%s对%s发起了攻击,造成%d点伤害,%s的血量变为%d点\n",monst.name,player.name,hurt,player.name, player.blood-hurt);player.blood=player.blood-hurt;} else {printf ("%s對%s发起了攻击,造成%d点伤害,%s的血量变为0,%s死亡!\n",monst.name,player.name,player.blood,player.name, player.name); player.blood=0; }}}
if(player.blood>0){ player.money=player.money+ monst.money;
printf("%s胜利,得到%d金币,%s拥有%d金币!\n", player.name,monst.money,player.name,player.money); }
else printf("%s死亡,游戏结束!\n",player.name);}
3.6 新手村模块代码
玩家登录系统后即进入新手村,可以选择购买装备或出村打怪练级。相关代码如下:
void newcountryside(){
int choose; printf("*******欢迎%s进入新手村***** ***\n",player.name); do{
printf("1.购物\n2.出村打怪\n"); scanf("%d",&choose); switch(choose) {
case 1:shopping();break; case 2:fitting();break; } }while(player.blood>0);}
4 结 论
本游戏案例非常生活化,富有趣味性,把真实的游戏情境引入课程项目教学中,该项目用到了C语言的if-else流程控制结构,以及变量的声明、赋值和引用;数组的声明,赋值和引用;结构体和结构体数组;输入输出函数的用法;取随机数函数的用法;for循环的使用及遍历数组;函数的定义和调用;指针的用法;对于学有余力的学生,可以在上述功能之外采用C语言中文件的知识,用来实现游戏的存档、读档功能;另外还可以增加更多的英雄、武器、药品等,对游戏功能进行扩展,让游戏更具可玩性和趣味性。
本案例代碼总共200多行,逻辑严密,代码规模适中,自己玩自己编写的游戏,学生会更有成就感,对增强学生的学习动力、提高其动手能力大有帮助;提升了学生的逻辑思维能力,该案例的项目经验,为学习后续的软件编程课程奠定了一个良好且稳固的基础。该案例将复杂问题简化,化腐朽为神奇,让学生在学中玩,在玩中学,激发学习编程的兴趣,提升了编程的乐趣,提高了学生解决实际问题的能力,积累项目经验,可以算得上C语言程序课程教学的一个经典案例。
参考文献:
[1] 谭浩强.C程序设计:第五版 [M].北京:清华大学出版社,2017.
[2] 本·克莱蒙.C程序设计新思维:第2版 [M].赵岩,译.北京:人民邮电出版社,2018.
[3] 王亮.《C语言程序设计》循环结构教学案例研究 [J].科技视界,2018(1):60-61.
[4] 窦祥国.面向计算思维培养的高职C程序设计案例教学研究 [J].中国职业技术教育,2019(32):93-96.
[5] 李敏.以培养计算思维为主的C程序设计课程教学改革 [J].电脑知识与技术,2019,15(12):111-112.
[6] 高欢.自主学习模式下微课在高校教学中的实践研究 [D].河北:河北师范大学,2019.
作者简介:纪辉进(1977-),男,汉族,湖北黄陂人,讲师,本科,主要研究方向:软件技术教学。