✅ 操作成功!

黄金矿

发布时间:2023-06-16 作者:admin 来源:文学

黄金矿

黄金矿

-

2023年3月19日发(作者:dliste)

C语言课程设计报告

机房名称

时间

学院

专业班级

姓名

学号

指导教师

2

小游戏“黄金矿工”设计报告

目录

C语言课程设计报告........................................1

一、课题简述.............................................3

二、功能需求.............................................4

Ⅰ.程序大体流程图:..................................4

Ⅱ.部分函数介绍.......................................5

Funcode接口介绍......................................5

三、总体设计.............................................8

1.下图为主函数及各级嵌套函数的流程图,部分省略。......8

2、操作使用说明......................................10

四、详细设计............................................11

1.主函数模块WinMain()函数模块.......错误!未定义书签。

2.部分自己设置定义的函数.............................15

五、运行相关界面及简介..................................26

六、程序运行测试及遇到问题的解决方案....................32

七、成员分工表..........................................34

八、总结与体会..........................................35

九、教师评语............................................36

C语言课程设计报告

一、课题简述

通过一年的c语言程序设计的学习,我们仅仅掌握了c语言最基本的知识,还有很多内容是

我们没有涉及的。所以通过c语言课程设计的学习实践活动和实际演练,使我们能够在实际操作

中提高运用c语言解决问题的能力和程序设计的能力。

得知本次课程设计任务是小游戏的设计,我们既兴奋又不安,兴奋是十分期待自己亲手做出

的游戏,不安的是我们对funcode这个软件很不了解。幸好这次实践的过程,让我们从做平时简

单的小程序过渡到现在的综合应用程序,将学过的c语言知识融入新接触到的funcode操作中,

不仅能巩固所学的知识,还能加强对新事物的接受及应用的本领,在不断的挑战问题中大大的提

升自己,同时也是对c语言程序设计这门课的深入理解的过程。

而什么样的小游戏是我们能实现而又不乏趣味呢?经过反复思考、讨论,我们小组设计了“黄

金矿工”这样一个小游戏:

玩家通过键盘的按键控制矿工抓取金块,将钩子碰触到的金块抓取过来。

1.单机键盘上的空格键进入游戏,金块的总数是20,钻石的总数是2,炸弹的总数是3,石

头的总数是4,大小位置是随机的。

2.在没有抓取状态下,钩子左右摆动,此时矿工的是静止的。当钩子摆动到一定角度,玩家

可以单击键盘上的上下左右键中的下方向键控制矿工伸出长钩,抓取金子等——抓到一个金子金

子加20分,钻石加50分且拉回速度变快,石头加5分且拉回速度变慢,抓到炸弹不加分且炸弹

会爆炸。此时矿工是向下摇动转轴。获取到金子等往回拉后,矿工是不断转动转轴,直到金子拉

动到钩子初始处,矿工恢复静止,钩子继续左右摇摆,直到玩家再次单击向下方向键。如果钩子

没有碰触到金子,而是碰触到左右和下的边界,则钩子保持原来的速度往回收。

3.加入计分和计时系统。60秒倒计时时间内抓取的金子越多得分越高。

接下来,我们开始思索,要如何实现这些功能,如何将所有功能连接在一起。于是我们先用

funcode熟悉小游戏制作的操作,认真按照老师给我们的实验指南进行练习,反复阅读其内容,

并用vc6.0进行对各种小游戏源代码的简单探索。当然,由于技术原因,我们想要设计的软件只

是局限于对游戏功能的实现,而实际中正式的欢迎界面,游戏说明等优美的图片,我们并没有进

行设计,包括刚开始拟定的金子运动、玩家升级等也取消了。然而,这并不影响我们制作小游戏

的热情,而且我们根据其具体的功能进行了组员之间的分工合作。

4

二、功能需求

Ⅰ.程序大体流程图:

图1.游戏模块图

空格键

开始游戏

金子、钻石、石头、炸弹随机分布;

钩子摇摆;

计时器倒计时60秒

计分器显示为0分

下键抓取

金子钻石石头炸弹

计分器加20分计分器加50分计分器加5分;

拉升速度减缓

计分器加0分

炸弹爆炸

计时器减为0

钩子停止抓取;

游戏结束

按回车键,所有

数据清零,回到

初始状态

C语言课程设计报告

Ⅱ.部分函数介绍

本实验用到的API

externfloatdGetScreenLeft();/*获取世界边界之左边X坐标*/

externfloatdGetScreenTop();/*获取世界边界之上边Y坐标*/

externfloatdGetScreenRight();/*获取世界边界之右边X坐标*/

externfloatdGetScreenBottom();/*获取世界边界之下边Y坐标*/

externvoiddSetSpriteWidth(constchar*szName,constfloatfWidth);/*设置精灵外形宽度*/

externfloatdGetSpriteWidth(constchar*szName);/*dGetSpriteWidth:获取精灵外形宽度*/

externintdRandomRange(constintiMin,constintiMax);/*获取一个位于参数1到参数2之间的随机数*/

externvoiddSetSpriteRotation(constchar*szName,constfloatfRot);/*设置精灵的旋转角度*/

externvoiddSetSpriteLinearVelocityPolar(constchar*szName,constfloatfSpeed,constfloatfPolar);

/*设置精灵移动速度*/

externintdAnimateSpritePlayAnimation(constchar*szName,constchar*szAnim,constintiRestore);

/*精灵播放动画*/

externfloatdGetSpriteLinkPointPosX(constchar*szName,constintiId);

/*获取精灵链接点X坐标。链接点是依附于精灵的一个坐标点*/

externfloatdGetSpriteLinkPointPosY(constchar*szName,constintiId);

/*获取精灵链接点Y坐标。链接点是依附于精灵的一个坐标点*/

externvoiddDrawLine(constfloatfStartX,constfloatfStartY,constfloatfEndX,constfloatfEndY,constfloat

fLineWidth,constintiLayer,constintiRed,constintiGreen,constintiBlue,constintiAlpha);

/*dDrawLine:两点之间画线*/

Funcode接口介绍

externvoiddOnSpriteColSprite(constchar*szSrcName,constchar*szTarName);

/*精灵与精灵碰撞后将被调用的函数*/

externintdSpriteMountToSpriteLinkPoint(constchar*szSrcName,constchar*szDstName,constintiPointId);

/*将一个精灵绑定到另一个精灵上,绑定位置为指定*的链接点,暂时的成为另一个精灵的一部分,跟随其

运动等*/

externfloatdGetSpritePositionX(constchar*szName);/*获取精灵X坐标*/

externfloatdGetSpritePositionY(constchar*szName);/*获取精灵Y坐标*/

6

funcode函数

(1)/*主函数入口*/

intPASCALWinMain(HINSTANCEhInstance,

HINSTANCEhPrevInstance,

LPSTRlpCmdLine,

intnCmdShow)

{

/*初始化游戏引擎*/

if(!dInitGameEngine(hInstance,lpCmdLine))

return0;

/*在此使用API更改窗口标题*/

dSetWindowTitle("Lesson");

/*引擎主循环,处理屏幕图像刷新等工作*/

while(dEngineMainLoop())

{

/*获取两次调用之间的时间差,传递给游戏逻辑处理*/

floatfTimeDelta=dGetTimeDelta();

/*执行游戏主循环*/

GameMainLoop(fTimeDelta);

};

/*关闭游戏引擎*/

dShutdownGameEngine();

return0;

}

(2)/*引擎捕捉键盘按下消息后,将调用到本函数*/

voiddOnKeyDown(constintiKey,constintiAltPress,constintiShiftPress,constintiCtrlPress)

(3)/*引擎捕捉键盘弹起消息后,将调用到本函数*/

voiddOnKeyUp(constintiKey)

(4)/*引擎捕捉到精灵与精灵碰撞之后,调用此函数*/

voiddOnSpriteColSprite(constchar*szSrcName,constchar*szTarName)

(5)/*引擎捕捉到精灵与世界边界碰撞之后,调用此函数.*/

voiddOnSpriteColWorldLimit(constchar*szName,constintiColSide)

C语言课程设计报告

其它函数

(1)出现金块、钻石、炸弹、石头,并增加其碰撞属性

voidAppear();

(2)画出链接钩子的线

voidline();

(3)重置游戏初始状态

voidbegin();

(4)游戏结束后,清楚剩余金块、钻石、炸弹、石头

voidDisappear();

8

三、总体设计

I.下图为主函数及各级嵌套函数的流程图,部分省略。

C语言课程设计报告

主函数入口

IntPASCALWinMain()

设置游戏窗口名字

dSetWindowTitle("Lesson")

引擎主循环

dEngineMainLoop()

执行游戏主循环

GameMainLoop()

g_iGameState=0g_iGameState=1g_iGameState=2g_iGameState=3

游戏初始界

面;

初始化游戏

执行

dOnKeyDown

函数

调用Appear()

生成金子等;

钩子自由摆

动;

调用

dOnKeyDown,

钩子运动;

调用

dOnSprite

-ColSprite、

dOnSprite-

ColWorldLimit

实现抓取

时间到

游戏结束

时间减为0

g_iGameState=4

精灵消失

所有数据重

回到初始状

自动跳转

10

图2.主函数流程图

II、操作使用说明

玩家通过键盘的按键控制矿工抓取金块,将钩子碰触到的金块抓取过来。

1.单机键盘上的空格键进入游戏,金块的总数是20,钻石的总数是2,炸弹的总数是3,石头的

总数是4,大小位置是随机的。

2.在没有抓取状态下,钩子左右摆动,此时矿工的是静止的。当钩子摆动到一定角度,玩家可以

单击键盘上的上下左右键中的下方向键控制矿工伸出长钩,抓取金子等——抓到一个金子金子加20

分,钻石加50分且拉回速度变慢,石头加5分且拉回速度变慢,抓到炸弹不加分且炸弹会爆炸。此

时矿工是向下摇动转轴。获取到金子等往回拉后,矿工是不断转动转轴,知道金子拉动到钩子初始处,

矿工恢复静止,钩子继续左右摇摆,直到玩家再次单击向下方向键。如果钩子没有碰触到金子,而是

碰触到左右和下的边界,则钩子保持原来的速度往回收。

3.存在计分和计时系统。60秒倒计时时间内抓取的金子越多得分越高。

精灵与精灵碰撞

void

dOnSpriteColSpr

ite()

显示消失及爆炸动画加分

键盘按下

VoiddOnKeyDown()

开始游戏

case

KEY_SPACE

钩子下降

Case

KEY_DOWNN

状态转换

Case

KEY_ENTER

C语言课程设计报告

四、详细设计

1.变量定义部分

变量定义是一个完整的程序中不可或缺的内容。在本次游戏编写中,我们根据程序需要,

也不可缺少的设置了许多变量,下面我们简单介绍一下全局变量和主函数之中的部分变量:

(1)定义全局变量

///////////////////初始化物品数量////////////////////////////////////////

intg_iGoldCount=20;//金子数量

intg_iBombCount=3;//炸弹数量

intg_iDiaCount=2;//钻石数量

intg_iStoneCount=4;//石头数量

////////////////////////////初始化计时计分///////////////////////////////

floatg_iGameScore=0;//初始化得分

floatg_fGameTime=60.f;//计时,设定初始计时

boolg_bStart=0;//计时,定义开始计时的状态

////////////////////////////设置钩子自由旋转的定义///////////////////////////////

floatg_fHookRotation=0.f;

intg_iGameState=0;//定义游戏初始状态

floatg_fEmptyHookSpeed=15.f;//定义钩子的速度

///////////////////////////设置钩子抓精灵的定义////////////////////////////////

floatg_fHookStartPosX;//存储钩子的初始X位置

floatg_fHookStartPosY;//存储钩子的初始Y位置

charszGotGoldName[20];//当前抓到金子的名称

charszGotBombName[3];//当前抓到炸弹的名称

charszGotDiaName[2];//当前抓钻石的名称

charszGotStoneName[2];//当前抓石头的名称

12

(2)主函数之中的局部变量

//////////////////////////设置钩子摇摆///////////////////////////////////

constfloatfRotateSpeed=45.f;//摇摆速度,单位度/秒

intiHookRotToLeft=1;//钩子摆动的方向:1←;0→

/////////////////////////设置钩子抓金子///////////////////////////////////

g_fHookStartPosX=dGetSpritePositionX("goldhook");//获取钩子的初始X坐标

g_fHookStartPosY=dGetSpritePositionY("goldhook");//获取钩子的初始Y坐标

dSetSpriteWorldLimitMode("goldhook",WORLD_LIMIT_NULL);//初始化钩子与世界边界

碰撞的模式为NULL

2.主函数模块WinMain()函数模块

实现初始化游戏引擎,执行引擎主循环,处理屏幕图像刷新等工作,包括获取两次调用

之间的时间差,传递给游戏逻辑处理等。我们通过主函数实现设置初始化游戏状态、钩子摇

摆、钩子抓金子、炸弹、石头、钻石等内容。在本游戏中我们设计了5种游戏状态,分别为

g_iGameState等于0、1、2、3、4。其中,状态0为游戏初始状态,状态1和2为游戏运行

状态,状态3为游戏结束状态,状态4为过渡到初始状态时运用的一个调整状态。

步骤详细介绍:

第一步,游戏初始化,显示初始界面需要的精灵

if(!dInitGameEngine(hInstance,lpCmdLine))//初始化游戏引擎

return0;

dSetWindowTitle("黄金矿工");//设置窗口名字

dSetWindowTitle("Lesson");

begin();//调用函数,初始游戏,显示初始精灵

第二步,游戏是一直进行的,因此游戏的重点是在while循环中。While循环中使用“float

fTimeDelta=dGetTimeDelta();”获取两次调用之间的时间差,传递给游戏逻辑处理,

达到不断循环。下面介绍一下此循环中使用的语句。

①游戏倒计时,倒计时结束后实现状态跳转到结束状态

/////////////////////////////////////////////////////////////////倒计时/////////////////////////////////////////////////////////////////

if(g_bStart)//判断游戏是否开始

C语言课程设计报告

{

g_fGameTime-=fTimeDelta;//设置游戏时间

if(g_fGameTime>0)//判断游戏是否结束

{

dSetTextValue("Time",(int)(g_fGameTime));//设置精灵"时间"显示数值

}

if(g_fGameTime<=0&&(g_iGameState==2||g_iGameState==1))

//判断游戏是否结束,且在运行状态1或2时,其他状态不执行

{

g_iGameState=3;//变成状态3,实现游戏结束

}

}

②钩子的自由摆动,此过程是在状态0和1时准备抓金子时出现的

////////////////////////////////////////////////////////////////////钩子自由摆动////////////////////////////////////////////////////

floatfThisRotate=fRotateSpeed*fTimeDelta;//本次旋转的角度

if(g_iGameState==0||g_iGameState==1)

{

floatfThisRotate=fRotateSpeed*fTimeDelta;

if(iHookRotToLeft)

{

g_fHookRotation+=fThisRotate;

if(g_fHookRotation>=180.f)

{

g_fHookRotation=180.f;

iHookRotToLeft=0;

}

}

else

{

g_fHookRotation-=fThisRotate;

14

if(g_fHookRotation<=0.f)

{

g_fHookRotation=0.f;

iHookRotToLeft=1;

}

}

dSetSpriteRotation("goldhook",g_fHookRotation);//设置钩子的旋转角度

}

③钩子抓金子,钩子抓金子为状态2,不需要钩子自由摆动

/////////////////////////////////////////////////////////////////钩子抓金子///////////////////////////////////////////////////////////

if(g_iGameState==2)

{

floatfSpeedX=dGetSpriteLinearVelocityX("goldhook");//获取钩子X方向的速度

floatfSpeedY=dGetSpriteLinearVelocityY("goldhook");//获取钩子Y方向的速度

if(fSpeedX-0.00001f&&fSpeedY

-0.00001f)//当速度接近为0时,即可判定其已到达初始点

{

dSpriteDismount(szGotGoldName);//解除金块与钩子的锚定

dDeleteSprite(szGotGoldName);//删除获取的金块

g_iGameState=1;//回拉结束,设定状态为1,钩子摆动

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation2",0);

//播放矿工的动画,即准备拉金子的动画

}

}

④游戏状态3,显示游戏时间停止

if(g_iGameState==3)

{

dSetSpriteVisible("over",1);//若结束显示Timeover

}

C语言课程设计报告

⑤游戏状态为4时,实现过渡到游戏状态为1

if(g_iGameState==4)

{

begin();//调用重置游戏初始化所需精灵

g_iGameState=0;//实现游戏状态跳转到初始状态0

g_iGameScore=0;//重置游戏分数为0

g_fGameTime=60.f;//重置倒计时时间为60

g_bStart=0;//停止先前状态中的倒计时

dSetTextValue("score",(int)0);//重置游戏分数为0

dSetTextValue("time",(int)60);//重置倒计时时间为60

dSetSpriteVisible("over",0);//隐藏Timeover

dSetSpriteVisible("score",1);//出现计分装置

dSetSpriteVisible("time",1);//出现计时装置

}

⑥由于钩子的连线也是一直在游戏运行时存在的,故也应放入此循环中

////////////////////////////////////////////////////////设置与钩子链接的线//////////////////////////////////////////////////////

line();//调用画线的函数

第四步,游戏结束,关闭游戏引擎,主函数完成

dShutdownGameEngine();//关闭游戏引擎

return0;

3.有关系统给定的函数的设置

(1)dOnKeyDown()函数的详述,对于系统内我们主要使用此函数。我们使用空格键控制游

戏开始,方向下键控制钩子下落,回车键实现从结束状态到开始状态的过渡。

///////////////////////////////////////按下空格游戏开始///////////////////////////////////////////////

g_fEmptyHookSpeed=15.f;//为之后调整绳子速度做准备

if(iKey==KEY_SPACE&&g_iGameState==0)//按下空格键且游戏状态为0时

{

g_iGameState=1;//游戏状态变为1

16

dSetSpriteVisible("GameBegin",0);//消失游戏开始

dSetSpriteVisible("HJKG",0);//消失“黄金矿工”

Appear();//调用函数出现金子等东西

g_bStart=1;//计时开始的条件

}

////////////////////////////////////////////按下下键钩子下降///////////////////////////////////////////

if(iKey==KEY_DOWN&&g_iGameState==1)//按下下键且游戏状态为1时

{

g_iGameState=2;//置游戏状态为2,可用于控制钩子是否摆动

dSetSpriteLinearVelocityPolar("goldhook",g_fEmptyHookSpeed,g_fHookRotation);

//以当前朝向给钩子一个向前的速度

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation1",0);

//播放挖金者的动作(一个胳膊往下压的动作),0表示播放一次,这里胳膊下压

就是一次

}

////////////////////////////////按下回车键跳转到初始状态///////////////////////////////////////////

if(iKey==KEY_ENTER&&g_iGameState==3)//按下回车键且游戏状态为3

{

DisAppear();//调用函数消除金子等东西

g_iGameState=4;//游戏状态变为4

}

(2)dOnSpriteColSprite()函数是引擎捕捉到精灵与精灵碰撞之后被调用的,这个函数也是

我们本次编程中的重点函数,用于钩子碰到金子等东西之时,同时增加积分系统于此函数之

中,每当碰撞发生,对于不同的东西产生不同的加分,其中金子加20分,钻石加50分,石

头加5分,炸弹不加分。并且调整了抓石头是与抓其他物品时的速度不同,还未炸弹消失过

程中附加了粒子效应。以下是函数详述:

voiddOnSpriteColSprite(constchar*szSrcName,constchar*szTarName)

{

///////////////////////发起者为goldhook,接受者含有GoldBlock字段/////////////////////////////////////////

if(strcmp(szSrcName,"goldhook")==0&&strstr(szTarName,"GoldBlock")!=NULL)

C语言课程设计报告

{

if(dGetSpriteIsMounted(szTarName)==0)

g_iGameScore+=20;

dSpriteMountToSpriteLinkPoint(szTarName,"goldhook",2);//将金块锚定在钩子上

dSpriteMoveTo("goldhook",g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);

//使钩子向初始位置移动,即会拉

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3",1);

//播放拉金块的动作

strcpy(szGotGoldName,szTarName);//复制并保存当前抓取到金块的名称

g_fEmptyHookSpeed=15.f;

}

g_iGameState=2;//表示绳索回拉//2表示回拉状态,用于控制金块的回拉和删除

//////////////////////////发起者为goldhook,接受者含有DiaBlock字段///////////////////////////////////////

if(strcmp(szSrcName,"goldhook")==0&&strstr(szTarName,"DiaBlock")!=NULL)

{

if(dGetSpriteIsMounted(szTarName)==0)

g_iGameScore+=50;

dSpriteMountToSpriteLinkPoint(szTarName,"goldhook",2);//将钻石锚定在钩子上

dSpriteMoveTo("goldhook",g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);

//使钩子向初始位置移动,即会拉

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3",1);

//播放拉钻石的动作

strcpy(szGotGoldName,szTarName);//复制并保存当前抓取到钻石的名称

g_fEmptyHookSpeed=25.f;//提高拉钻石速度

}

g_iGameState=2;//表示绳索回拉//2表示回拉状态,用于控制金块的回拉和删除

/////////////////////////////////发起者为goldhook,接受者含有BombBlock字段//////////////////////////////

if(strcmp(szSrcName,"goldhook")==0&&strstr(szTarName,"BombBlock")!=NULL)

{

dDeleteSprite(szGotBombName);//炸弹消失

18

floathPosX=dGetSpritePositionX("goldhook");

floathPosY=dGetSpritePositionY("goldhook");

dPlayEffect("bigbang",2.f,hPosX,hPosY,0.f);//跟随钩子增加粒子效应

dSpriteMoveTo("goldhook",g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);

//使钩子向初始位置移动,即会拉

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3",1);

//播放拉炸弹的动作

strcpy(szGotGoldName,szTarName);//复制并保存当前抓取到炸弹的名称

g_fEmptyHookSpeed=15.f;

}

g_iGameState=2;//表示绳索回拉//2表示回拉状态,用于控制金块的回拉和删除

///////////////////////////////////发起者为goldhook,接受者含有StoneBlock字段/////////////////////////////

if(strcmp(szSrcName,"goldhook")==0&&strstr(szTarName,"StoneBlock")!=NULL)

{

if(dGetSpriteIsMounted(szTarName)==0)

g_iGameScore+=5;

dSpriteMountToSpriteLinkPoint(szTarName,"goldhook",2);//将石头锚定在钩子上

dSpriteMoveTo("goldhook",g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);

//使钩子向初始位置移动,即会拉

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3",1);

//播放拉钻石的动作

strcpy(szGotGoldName,szTarName);//复制并保存当前抓取到石头的名称

g_fEmptyHookSpeed=5.f;//减缓拉石头的速度

}

g_iGameState=2;//表示绳索回拉//2表示回拉状态,用于控制金块的回拉和删除

//////////////////////////////////////////////////////////////计分///////////////////////////////////////////////////////////////////////

dSetTextValue("score",g_iGameScore);

}

iteColWorldLimit()引擎捕捉到精灵与世界边界碰撞之后,调用此函数。此函数相对

比较简单,用于处理钩子未抓到物品碰到世界边界时的处理。

C语言课程设计报告

voiddOnSpriteColWorldLimit(constchar*szName,constintiColSide)

{

if(strcmp(szName,"goldhook")==0)

{

dSpriteMoveTo(szName,g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);

//碰到边界的为钩子时

dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3",1);

//同样设置为回拉,只是没有碰到金子

g_iGameState=2;

}

}

4.部分自己设置定义的函数

(1)定义金子、钻石、炸弹、石头显示的函数Appear(),其内还添加了少许碰撞属性。这

也是我们组本次编程较突出的地方。

voidAppear()

{

//与显示金子有关的定义

intg_fGoldBornMinX=0;

intg_fGoldBornMaxX=0;

intg_fGoldBornMinY=0;

intg_fGoldBornMaxY=0;

//与炸弹有关的定义

intg_fBombBornMinX=0;

intg_fBombBornMaxX=0;

intg_fBombBornMinY=0;

intg_fBombBornMaxY=0;

//与钻石有关的定义

intg_fDiaBornMinX=0;

20

intg_fDiaBornMaxX=0;

intg_fDiaBornMinY=0;

intg_fDiaBornMaxY=0;

//与石头有关的定义

intg_fStoneBornMinX=0;

intg_fStoneBornMaxX=0;

intg_fStoneBornMinY=0;

intg_fStoneBornMaxY=0;

///////////////////////////////////////////////////////////设置金子/////////////////////////////////////////////////////////////

g_fGoldBornMinX=dGetScreenLeft()+5;//金子左边界

g_fGoldBornMaxX=dGetScreenRight()-5;//金子右边界

g_fGoldBornMinY=dGetScreenTop()+20;//金子上边界

g_fGoldBornMaxY=dGetScreenBottom()-5;//金子下边界

intiLoop=0;//循环变量控制

intiSize=4,iPosX=0,iPosY=0;//iSize表示金块大小的变量

dSetSpriteCollisionSend("goldhook",1);//钩子抓金子的定义

dSetSpriteCollisionReceive("goldTemplate",1);

//在WinMain的复制金子前给金块加上接受碰撞属性

for(iLoop=0;iLoop

{

if(iLoop<10)//生成10个小金块,大小为4

{

iSize=4;

}

elseif(iLoop>=10&&iLoop<16)//生成6个中金块,大小为6

{

iSize=6;

}

else//生成4个大金块,大小为8

{

C语言课程设计报告

iSize=8;

}

//初始化金子精灵实例

char*tmpName;

tmpName=dMakeSpriteName("GoldBlock",iLoop);//生成金块名字

dCloneSprite("goldTemplate",tmpName);

dSetSpriteWidth(tmpName,(float)iSize);//设置金块的宽度

dSetSpriteHeight(tmpName,(float)iSize);//设置金块的高度

//设置金子精灵位置

iPosX=dRandomRange(g_fGoldBornMinX,g_fGoldBornMaxX);

iPosY=dRandomRange(g_fGoldBornMinY,g_fGoldBornMaxY);

dSetSpritePosition(tmpName,(float)iPosX,(float)iPosY);

}

//////////////////////////////////////////////设置炸弹/////////////////////////////////////////////////////////////////////////

g_fBombBornMinX=dGetScreenLeft()+10;//炸弹左边界

g_fBombBornMaxX=dGetScreenRight()-8;//炸弹右边界

g_fBombBornMinY=dGetScreenTop()+13;//炸弹上边界

g_fBombBornMaxY=dGetScreenBottom()-10;//炸弹下边界

inteLoop=0;//循环变量控制

inteSize=6,ePosX=0,ePosY=0;//eSize表示炸弹大小的变量

dSetSpriteCollisionSend("goldhook",1);//钩子抓炸弹定义

dSetSpriteCollisionReceive("bombTemplate",1);

//在WinMain的复制炸弹前给炸弹加上接受碰撞属性

for(eLoop=0;eLoop

{

if(eLoop<2)//生成2个大炸弹,大小为8

{

eSize=8;

}

else//生成1个小炸弹,大小为6

22

{

eSize=6;

}

//初始化炸弹精灵实例

char*tmpName;

tmpName=dMakeSpriteName("BombBlock",eLoop);//生成炸弹名字

dCloneSprite("bombTemplate",tmpName);

dSetSpriteWidth(tmpName,(float)eSize);//设置炸弹的宽度

dSetSpriteHeight(tmpName,(float)eSize);//设置炸弹的高度

//设置炸弹精灵位置

ePosX=dRandomRange(g_fBombBornMinX,g_fBombBornMaxX);

ePosY=dRandomRange(g_fBombBornMinY,g_fBombBornMaxY);

dSetSpritePosition(tmpName,(float)ePosX,(float)ePosY);

}

/////////////////////////////////////////////////////设置钻石///////////////////////////////////////////////////////////////////

g_fDiaBornMinX=dGetScreenLeft()+16;//钻石左边界

g_fDiaBornMaxX=dGetScreenRight()-15;//钻石右边界

g_fDiaBornMinY=dGetScreenTop()+20;//钻石上边界

g_fDiaBornMaxY=dGetScreenBottom()-18;//钻石下边界

intmLoop=0;//循环变量控制

intmSize=4,mPosX=10,mPosY=20;//mSize表示钻石大小的变量

dSetSpriteCollisionSend("goldhook",1);//钩子抓钻石定义

dSetSpriteCollisionReceive("diaTemplate",1);

//在WinMain的复制钻石前给钻石加上接受碰撞属性

for(mLoop=0;mLoop

{

mSize=4;//生成2个钻石,大小为4

//初始化钻石精灵实例

char*tmpName;

tmpName=dMakeSpriteName("DiaBlock",mLoop);//生成钻石名字

C语言课程设计报告

dCloneSprite("diaTemplate",tmpName);

dSetSpriteWidth(tmpName,(float)mSize);//设置钻石的宽度

dSetSpriteHeight(tmpName,(float)mSize);//设置钻石的高度

//设置钻石精灵位置

mPosX=dRandomRange(g_fDiaBornMinX,g_fDiaBornMaxX);

mPosY=dRandomRange(g_fDiaBornMinY,g_fDiaBornMaxY);

dSetSpritePosition(tmpName,(float)mPosX,(float)mPosY);

}

/////////////////////////////////////////////////////////////设置石头///////////////////////////////////////////////////////////

g_fStoneBornMinX=dGetScreenLeft()+15;//石头左边界

g_fStoneBornMaxX=dGetScreenRight()-15;//石头右边界

g_fStoneBornMinY=dGetScreenTop()+20;//石头上边界

g_fStoneBornMaxY=dGetScreenBottom()-20;//石头下边界

intbLoop=0;//循环变量控制

intbSize=4,bPosX=10,bPosY=20;//bSize表示石头大小的变量

dSetSpriteCollisionSend("goldhook",1);//钩子抓石头定义

dSetSpriteCollisionReceive("stoneTemplate",1);

//在WinMain的复制石头前给石头加上接受碰撞属性

for(bLoop=0;bLoop

{

bSize=8;//生成4块石头,大小为8

//初始化石头精灵实例

char*tmpName;

tmpName=dMakeSpriteName("StoneBlock",bLoop);//生成石头名字

dCloneSprite("stoneTemplate",tmpName);

dSetSpriteWidth(tmpName,(float)bSize);//设置石头的宽度

dSetSpriteHeight(tmpName,(float)bSize);//设置石头的高度

//设置石头精灵位置

bPosX=dRandomRange(g_fStoneBornMinX,g_fStoneBornMaxX);

bPosY=dRandomRange(g_fStoneBornMinY,g_fStoneBornMaxY);

24

dSetSpritePosition(tmpName,(float)bPosX,(float)bPosY);

}

}

(2)设置钩子连线的函数line()

voidline()

{

//首先,从矿工精灵上获取一个缆绳链接点作为绳子的起始点(该链接点在编辑器里编辑好)

floatfStartX=dGetSpriteLinkPointPosX("GoldMan",1);

floatfStartY=dGetSpriteLinkPointPosY("GoldMan",1);

//绳子终点在钩子精灵上获取(该链接点在编辑器里编辑好)

floatfEndX=dGetSpriteLinkPointPosX("goldhook",1);

floatfEndY=dGetSpriteLinkPointPosY("goldhook",1);

//在这两点之间划线.线的颜色红绿蓝值都为50,即灰色;255表示不透明,2.0f表示线的

粗细,0表示所在的层

dDrawLine(fStartX,fStartY,fEndX,fEndY,2.f,0,50,50,50,255);

(3)设置金块等东西消失的函数Disappear()

voidDisAppear()

{

//删除金块

for(intiLoop=0;iLoop

{

char*tmpName;

tmpName=dMakeSpriteName("GoldBlock",iLoop);//生成金块名字

dDeleteSprite(tmpName);

}

//删除炸弹

for(inteLoop=0;eLoop

{

char*tmpName;

tmpName=dMakeSpriteName("BombBlock",eLoop);//生成炸弹名字

dDeleteSprite(tmpName);

}

//删除钻石

for(intmLoop=0;mLoop

{

char*tmpName;

tmpName=dMakeSpriteName("DiaBlock",mLoop);//生成钻石名字

C语言课程设计报告

dDeleteSprite(tmpName);

}

//删除石头

for(intbLoop=0;bLoop

{

char*tmpName;

tmpName=dMakeSpriteName("StoneBlock",bLoop);//生成石头名字

dDeleteSprite(tmpName);

}

}

(4)游戏初始begin(),出现需要出现的东西

voidbegin()

{

dSetSpriteVisible("HJKG",1);

dSetSpriteVisible("GameBegin",1);//定义初始精灵

dSetSpriteVisible("over",0);//不显示TIMEOVER

}

注意:完整的源程序代码和整个文件夹(包括.exe文件的)提交电子稿。

26

五、运行相关界面及简介

Ⅰ.运行程序进入游戏的第一个场景:左上方是倒计时系统,由60秒逐渐递减;右上方是计

分系统,钩子抓取金子等时会自动加分。

图2

Ⅱ、按下空格键,金子,钻石,炸弹及石头自由分布;矿工手中的钩子不停地循环转动;

倒计时系统开始倒计时。

图3

C语言课程设计报告

Ⅲ.待到合适时机,按下键,钩子开始运动,抓取金子等。

①抓到金子时,金子随钩子一起返回矿工手中并消失,积分系统自动加20分

图4

②抓到钻石时,钻石随钩子一起返回矿工手中并消失,且绳子速度加快,积分系统

自动加50分

图5

28

③抓到炸弹时,炸弹爆炸,不加分,钩子回去

图6

⑤抓到石头时,钻石随钩子一起返回矿工手中并消失,但钩子的速度减缓,积分系统自

动加5分

图7

C语言课程设计报告

⑤碰到边界时,钩子按原路返回矿工手中,但钩子的速度不变。

图8

Ⅳ.当计时器倒数到0时,游戏结束。计分系统不再加分。

图9

30

图10

Ⅴ.按下回车键,返回初始状态

图11

C语言课程设计报告

VI.制作过程中

附图12.制作中

32

六、程序运行测试及遇到问题的解决方案

(1)在该小游戏的设计中,我们最初的想法非常丰富,希望向游戏中添加许多不必要

的因素,比如运动的金子等。很快我们发现这些功能很难实现、没有太大意义且显得界面杂

乱,由此,我们定下基本思路。

(2)程序运行中,首先遇到的问题,就是对funcode十分不了解,不知道该如何下手。

幸亏老师助我们一臂之力,不仅给了我们funcode教程,而且不厌其烦的解答我们的疑问。

通过对funcode中一些简单游戏的应用,我们在短时间内基本掌握了funcode的操作。

(3)金子等精灵的定义,自动复制相对较容易,我们很快便完成了。但是到了编写钩子

绕轴自由摆动时,我们遇到了麻烦,完全不知道该怎么设置。后来经老师的指点,我们定义

了钩子速度和状态,调用了一系列的函数,经过多次尝试,终于钩子转起来了。

(4)在做钩子抓金子的时候,也是丈二和尚摸不着头脑,不知道怎么设置连接钩子和矿

工之间的线、金子随钩子运动,以及最后消失的动画。我们询问了几个同学,同时也向老师

求助,终于搞清楚关键点在哪里----原来是要调用精灵碰撞精灵的函数—dOnSpriteColSprite!

认识到这一点之后,我们的工作进展顺利,一口气把金子、钻石、石头、炸弹与钩子之间的

碰撞全设置好了。

(5)后来我们想,钩子碰到炸弹的时候,炸弹应当爆炸,所以我们就展开了对炸弹爆炸

效果的研究。我们从头文件里找到了可以调用的dPlayEffect函数,按照规则填写。但是游

戏中的三个炸弹爆炸时,爆炸效果竟都在同一个地方!我们再次请教老师,发现我们把爆炸

效果的位置定义成了全局变量,无法随时改变,所以经过老师点拨我们把爆炸效果位置定为

钩子的位置,用这种方法,钩子触碰到炸弹时炸弹就会爆炸。不足之处在于必须等到钩子收

回了,炸弹才会消失。至今没有找到原由。

(6)在编辑钩子和石头碰撞时,我们希望给游戏增加难度,让钩子回拉的速度减慢,但

下一次放钩子速度不变。开始的时候,我们在精灵碰撞函数dOnSpriteColSprite中分别对有

关石头等精灵的if语句进行设置,改变钩子速度。但运行的时候,我们发现抓取完石头后,

钩子速度一直是慢的,直到抓到别的精灵为止。针对这个问题,我们求助了老师,老师查看

了程序,指导我们要在dOnSpriteColSprite函数中定义一个全局变量,而不是仅在if语句中

定义钩子速度。于是我们调整程序,按照以上方法执行,终于钩子的速度如人所愿,抓石头

变慢,不抓石头常速。

C语言课程设计报告

(7)最后,当倒计时为0时,我们希望界面上的精灵全部消失,只留下timeover一句。

但是经过各种努力,都无法完成这个构想,只能让这些精灵呆在原地。当倒计时完成后,钩

子抓取东西之后便不放了,东西不会消失,由此分数便固定了。可是我们对这个结果不满意,

又经过对流程的改动以及对老师的询问,我们将各个状态用g_iGameState这个参数进行切

换,终于,倒计时结束后精灵消失,只有分数和timeover显现于界面。如果按下回车键,游

戏又会回到初始界面。

(8)接下来便是计分和计时系统。对于计分和计时系统,必须定义初始变量,尤其是在

重新变为初始状态时,否则将无法运行。对于计时应该注意g_Start的值不然会导致倒计时

无法进行。而计分应该为不同的东西设置不同的分数。本来还想使不同大小的金子有不同的

分数,但发现实现此功能比较困难,于是经过多次尝试,放弃了。

(9)由于刚开始编程的时候没有考虑以后,所以我们编的程序杂乱无章,没有条理。为

了解决这个问题,我们对程序进行了封装,封装到一个个函数中去。以这种方法,我们的程

序渐渐的有调理了起来。逻辑也清楚起来。

(10)还有一些小错误就是“;”或“{}”的缺失,某次编译竟出现17各错误,经过一

番细心的检查,发现缺少一个“{”,解决了这些问题;然后,对数组的应用也不是那么得心

应手,通过翻看教材,询问老师的情况下,得到了满意的效果;接下来,在把funcode的几

个函数原型与程序结合起来时,也遇到一点麻烦,不过经过仔细思考,查看游戏案例,这也

就不是问题了。

运行过程中还有一些问题,在这里就不一一细加说明了。

34

七、成员分工表

姓名学号报告分工模块个数及模块代码行

总体设计

详细设计

总结与体会

(1)按下空格键开始游戏

(2)显示金子等物品

(3)计分、计时系统

(4)函数整体整合,以及各个状态之间

的转换,逻辑关系处理

250行以

课题简述

功能需求

总体设计

程序运行测试及

遇到问题的解决

方案

(1)钩子静止时左右摇摆

(2)钩子抓取金子等精灵动作

(3)dOnSpriteColSprite函数--钩子与

精灵碰撞的动画、炸弹的粒子效应

以及dOnSpriteColWorldLimit碰

到边界的处理

250行以

C语言课程设计报告

八、总结与体会

只有在实践中才能更为全面地掌握知识,十天的软件课程设计让我们感受非常深,同

时也加强了对C语言程序设计的理解。

在大一上学期,我们学习了基础的C语言程序设计课程,对于C语言这种东西只是了

解了表面的语句规则等,仅仅会编写简单的代码,这些是远远不够的。这次课让我扩展了知

识,开拓了视野,知道了C语言的另一面。

从起初的不敢下手,到之后开始操作,到遇到问题,到问题被解决,再到一个较为完

善的程序出现,是一次挑战机会,一次实践过程,一次自主学习。有寻找不到错误的苦恼,

有成功完成一个函数的喜悦,这苦乐一同促成了我们黄金矿工游戏的成功编写。对于编程,

我们想重点谈谈以下几点:

第一,要想编好一个程序首先应该设计好,必须有一个整体的思路。盲目的编程,只

能导致胡乱的代码让自己摸不清头脑,越编越无从下手。透彻分析游戏和问题,之后我们需

要想好我们的游戏需要被赋予的功能,除了编写提示里提示的东西,我们需要添加显示石头

等其他东西,粒子效应,计时计分系统等内容。之后根据所需要的功能设计出基本的流程图,

包括所需用到的函数,需自己定义的函数,运行前后的条件等一系列内容。只有做好这些,

才能为自己有条理的编程打下坚实的基础。

第二,是否清楚程序过程,注释是关键,条理是必须。大型的编程项目常常是团队和

做而成的,为了他人和自己调试、检查、补充的方便,提高编程效率,我们需要尽可能多的

增加注释内容。同时,我们在编程过程中遇到了条理不清晰,使老师和自己都很难看懂程序,

这是就需要学会空行,比如:为了醒目,可以一个大括号占一行;为了清晰,多级if条件

句注意开头空出不同的格数等。

第三,编程序必须持之以恒,耐心细心。作为一个程序员,首先应该具备的就是细心,

因为一个分号的丢失就很可能导致很多错误,代码一长,有时很难检测出来。我们在编程过

程中也遇到了非常多的错误,有时真的想放弃,心里很烦,但是要想成功,必须坚持下去,

冷静的检查分析并改正错误。在这次编程的过程中,我们也和老师学习到了些检查错误的方

法,如:增加断点查找,不让某一语句执行查找其他语句,用if条件句查找错误等。

第四,团队合作是基础。本次编程是分组进行的,我们两人一组,合理分工,高效的

完成了编程工作。在初期,我们通过查找资料,细致讨论,较为详细的设计出了我们程序的

基本内容。编程过程中,在队友遇到问题时,两人一同查找错误的速度就加快了很多,在交

36

流中解决问题也显得容易了许多。要知道,一个大型的程序仅仅通过一个人的力量是非常困

难的,因此,无论是编程,还是今后的学习工作我们都必须学会团结协作。

第五,学会查找,学会学习。本次课上,我们首先在老师的帮助下认识了funcode系统,

之后学习了系统提供的一些资料。由于对C语言不是很熟悉,我们还查阅了许多其他资料

和寻求老师的帮助。这样的自主学习过程,能加深对学习内容的认识理解,是一个快乐的过

程。

虽然我们十分努力的编程,但程序仍有不足之处:

第一,粒子效应随钩子,只能尽可能的接近炸弹,不能完全在炸弹上实现。我们的经验

不足还不能调试好这样的问题。第二,由于时间不足,动金块与静止金块碰撞不易调试,在

多次尝试下,放弃了此功能。

总之,学习的路是永无止境的,虽然本次软件课程设计课的时间不长,我们也不可能通

过它知道C语言的全部,但是我们可谓收获颇丰,不仅仅是在编程上,还有今后的学习工

作中。同时,我们今后也会不断自主学习,探索学习,接受挑战,迎难而上,只有这样我们

今后才能成为祖国需要的人才。

最后,感谢两位助教老师,程序的成功离不开你们的帮助与鼓励。

九、教师评语

👁️ 阅读量:0