实验报告终极版

时间:2024.4.8

程序设计实训报告

[黄金矿工]


一、系统界面

图1  开始游戏

图2,游戏进行时

二、功能描述

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

要求如下:

1.  游戏的初始界面如图1,单机键盘上的空格键进入游戏,进入后界面如图2,金块的总数是20,大小位置是随机的。

2.  在没有抓取状态下,钩子左右摆动,此时矿工的是静止的。当钩子摆动到一定角度,玩家可以单击键盘上的上下左右键中的下方向键控制矿工伸出长钩,抓取金子,此时矿工是向下摇动转轴。获取到金子往回拉后,矿工是不断转动转轴,知道金子拉动到钩子初始处,矿工恢复静止,钩子继续左右摇摆,直到玩家再次单击向下方向键。

3.  伸出的钩子如果碰触到金子,则钩子和金子一起往回拉,回收的速度根据抓取到的金子的大小变化而变化,金子越大,回拉的速度越慢,反之亦然。如果钩子没有碰触到金子,而是碰触到左右和下的边界,则钩子保持原来的速度往回收。

4.       抓取到的金子拉回到转轴处消失,此时金子数目减少一个。如果玩家将所有金子抓取完,游戏返回到如图1的初始界面。

椭圆: 开始
三、流程图

 

                                                

文本框: 金块与钩子碰撞拉回并删除金块       否                    是

 


四、数据结构

(说明:主要写用到的各类型的全局变量、含义)

1.       g_iGameState表示游戏状态 ,初始状态g_iGameState=0.

2.       g_fHookStartPosX存储钩子的初始X位置。

3.       n 控制金块生成,初始化为1.

4.       g_fHookStartPosY存储钩子的初始X位置。

5.       szGotGoldName[20] 当前抓到金子的名称

6.       count抓取到金子的个数。

7.       iSize金子的尺寸。

8.       g_fHookRotation钩子与地面的夹角。

9.       g_iHookRotToLeft控制钩子转向,1——从右向左 2——从左向右。

10.   g_fGoldBornMinX, g_fGoldBornMaxX, g_fGoldBornMinY, g_fGoldBornMaxY分别代表左右上下的值。

11.   g_iGoldCount金子的个数,初始化为20.

12.   g_fEmptyHookSpeed 钩子发出时速度。

13.   fRotateSpeed钩子旋转速度。

五、算法描述

游戏状态g_iGameState分为三种状态0,1,2 ,其中0表示游戏结束状态,1表示游戏初始化,2则表示游戏运行状态;

键盘控制:

1.         空格按下精灵隐藏

2.         游戏有结束状态转为初始化状态

3.         钩子开始转动,金块也显示出来

4.         利用A,D键控制钩子左右摇摆或“↓”释放钩子

5.         游戏自动进入运行状态

钩子旋转:

1.         利用fHookRotatio记录钩子的角度,flag控制钩子的旋转方向,fRotateSpeed控制钩子的摇摆速度

2.         利用fThisRotate =  fRotateSpeed * fTimeDelta和g_fHookRotation   += fThisRotate使钩子角度发生变化

3.         利用A键使钩子角度向左增加30度(源代码g_fHookRotation+=30)利用D键使钩子角度向右增加30度(源代码g_fHookRotation-=30)

4.         设置钩子旋转的角度范围0~180

5.         使用dSetSpriteRotation函数控制钩子的位置

金块显示:

1.         iSize标记金块尺寸,g_iGoldCount标记金块个数

2.         使用名为dMakeSpriteName的数组储存金块

3.         使用dCloneSprite复制金块

4.         使用dSetSpriteWidth和dSetSpriteHeight分别控制金块的宽度和高度

5.         使用dSetSpritePosition函数设置金块位置

绳子连接:

使用dDrawLine函数将钩子与矿工用绳子连接起来并设置绳子的粗细和颜色

精灵碰撞:

调用dOnSpriteColSprite函数实现钩子与金块碰撞之后的连接拉回

边界碰撞:

调用dOnSpriteColWorldLimit函数实现钩子与边界碰撞之后的弹回

六、源代码

//-----------------------------------------------------------------------------

//

//-----------------------------------------------------------------------------

#include "CommonAPI.h"

int g_iGameState=0;//游戏状态

int n=1;//控制生成金子的循环

int count=0;记录钩子抓取金子的数量

int iSize=4;//金子的大小

int flag=1;//控制钩子是否旋转

float g_fHookRotation = 0.f;    //钩子与地面的夹角

int g_iHookRotToLeft=1;//控制金子旋转方向

int g_fHookRotatio=0;金子的角度

int g_fGoldBornMinX       =       0;

int    g_fGoldBornMaxX   =       0;

int    g_fGoldBornMinY    =       0;

int    g_fGoldBornMaxY   =       0;//边界的值

int g_iGoldCount      =  20;//金子的数量

float g_fEmptyHookSpeed       = 30.f;//钩子的数量

float fRotateSpeed = 40.f;       //  摇摆速度,单位 度/秒

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

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

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

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

void GameInit(void)

{

         dSetSpriteVisible("GameBegin",0);//隐藏精灵

         if(n==1)

         {

                   int    iLoop         =       0;      //循环变量控制

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

                  

                   for( iLoop = 0; iLoop < g_iGoldCount; iLoop++ )

                   {

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

                            {

                                     iSize =       4;

                            }

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

                            {

                                     iSize =       6;

                            }

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

                            {

                                     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);

                   }

                   n++;

         }

}

void GameRun(float fTimeDelta )

{

         if(flag==1)

         {

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

         if( iHookRotToLeft )

         {                           //向左转,度数不断变大

                   g_fHookRotation     += fThisRotate;

                   if( g_fHookRotation >= 180.f )

                   {        //大于180,置为向右转,即0

                            g_fHookRotation               =       180.f;

                            iHookRotToLeft        =       0;

                   }

         }

         else

         {                 //向右转,度数不断变小

                   g_fHookRotation     -= fThisRotate;                   //小于0,置为向左转,即 1

                   if( g_fHookRotation <= 0.f )

                   {

                            g_fHookRotation               =       0.f;

                            iHookRotToLeft        =       1;

                   }

         }

         dSetSpriteRotation("GoldHook",g_fHookRotation);       //设置钩子的当前角度

         }

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

         float fStartX =  dGetSpriteLinkPointPosX("GoldMan",1);

         float fStartY = dGetSpriteLinkPointPosY("GoldMan",1);

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

         float fEndX        = dGetSpriteLinkPointPosX("GoldHook",1);

         float fEndY        = dGetSpriteLinkPointPosY("GoldHook",1);

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

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

        

}

void GameEnd()

{

         n=1;

         dSetSpriteVisible("GameBegin",1);//使游戏回到结束状态

}

///////////////////////////////////////////////////////////////////////////////////////////

//

// 主函数入口

//

//////////////////////////////////////////////////////////////////////////////////////////

int PASCAL WinMain(HINSTANCE hInstance,

                   HINSTANCE hPrevInstance,

                   LPSTR     lpCmdLine,

                   int       nCmdShow)

{

         // 初始化游戏引擎

         if( !dInitGameEngine( hInstance, lpCmdLine ) )

                   return 0;

         // 游戏初始化代码

         dSetWindowTitle("Lesson");

         g_iGoldCount=20;   //金子数量

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

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

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

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

         dSetSpriteCollisionSend("goldHook", 1);

         dSetSpriteCollisionReceive("goldTemplate", 1);

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

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

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

         while( dEngineMainLoop() )

         {

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

                   float fTimeDelta       =       dGetTimeDelta();

                   switch( g_iGameState )

                   {

                            // 初始化游戏,清空上一局相关数据

                   case 1:

                            {

                                     GameInit();

                                     g_iGameState =       2; // 初始化之后,将游戏状态设置为进行中

                            }

                            break;

                            // 游戏进行中,处理各种游戏逻辑

                   case 2:

                            {

                                     // 金子数量大于0的时候,继续游戏

                                     if( g_iGoldCount > 0 )

                                     {

                                               GameRun( fTimeDelta );

                                      }

                                     else

                                     {

                                               // 游戏结束。调用游戏结数函数并把游戏状态修改为结束状态

                                               g_iGameState =       0;

                                               GameEnd();

                                     }

                            }

                            break;

                            // 游戏结束/等待按空格键开始

                   case 0:

                   default:

                            break;

                   };

                   dSetTextValue("score",count);

                   // 执行游戏主循环

                  

         };

         // 关闭游戏引擎

         dShutdownGameEngine();

         return 0;

}

//==========================================================================

//

// 引擎捕捉鼠标移动消息后,将调用到本函数

void dOnMouseMove( const float fMouseX, const float fMouseY )

{

         // 可以在此添加游戏需要的响应函数

}

//==========================================================================

//

// 引擎捕捉鼠标点击消息后,将调用到本函数

void dOnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )

{

         // 可以在此添加游戏需要的响应函数

}

//==========================================================================

//

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

// iAltPress iShiftPress iCtrlPress 分别为判断Shift,Alt,Ctrl当前是否也处于按下状态。比如可以判断Ctrl+E组合键

void dOnKeyDown( const int iKey, const int iAltPress, const int iShiftPress, const int iCtrlPress )

{

         // 可以在此添加游戏需要的响应函数

         if(iKey==KEY_SPACE&&g_iGameState==0)

                   g_iGameState=1;

         if( KEY_DOWN == iKey)

         {        //按下↓并且游戏状态为      "1"  

                   flag=0;

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

                   dSetSpriteLinearVelocityPolar("GoldHook",g_fEmptyHookSpeed, g_fHookRotation);

                   // 播放挖金者的动作(一个胳膊往下压的动作)

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

                   //0 表示播放一次,这里胳膊往下压就是一次

         }

         if(iKey==KEY_A)

                   g_fHookRotation+=30;//按下A键使钩子向左移动30度

         if(iKey==KEY_D) g_fHookRotation-=30;//按下D键使钩子向右移动30度

}

//==========================================================================

//

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

void dOnKeyUp( const int iKey )

{

         // 可以在此添加游戏需要的响应函数

}

//===========================================================================

//

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

void dOnSpriteColSprite( const char *szSrcName, const char *szTarName )

{

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

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

         flag=0;

          iSize=dGetSpriteWidth( szTarName );

         dSpriteMoveTo("GoldHook",g_fHookStartPosX, g_fHookStartPosY, ((10.f - iSize) / 10.f) * g_fEmptyHookSpeed, 1);

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

         dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation3", 1 );    //播放拉金块的动作

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

         if(g_iGameState == 2)

         {

                   //获取钩子X方向的速度

                   float fSpeedX    =       dGetSpriteLinearVelocityX("GoldHook");

                   //获取钩子Y方向的速度

                   float fSpeedY    =       dGetSpriteLinearVelocityY("GoldHook");

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

                   if( fSpeedX < 0.00001f && fSpeedX > -0.00001f && fSpeedY < 0.00001f && fSpeedY > -0.00001f )

                   {

                            //解除金块与钩子的锚定

                            dSpriteDismount(szGotGoldName);

                            //删除获取的金块

                            g_iGoldCount--;

                            count++;

                            dDeleteSprite(szGotGoldName);

                            //回拉结束,设定状态为0

                            g_iGameState = 0;

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

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

            g_iGameState =2;

                            flag=1;

                   }

                  

         }

}

//===========================================================================

//

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

// iColSide : 0 左边,1 右边,2 上边,3 下边

void dOnSpriteColWorldLimit( const char *szName, const int iColSide )

{       

        flag=0;

//碰到边界的为钩子时

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

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

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

                   g_iGameState = 2;

             flag=1;

}

}

更多相关推荐:
实验报告 范本

研究生实验报告范本实验课程实验名称实验地点学生姓名学号指导教师范本实验时间年月日一实验目的熟悉电阻型气体传感器结构及工作原理进行基于聚苯胺敏感薄膜的气体传感器的结构设计材料制作材料表征探测单元制作与测试实验结果...

实验报告范本

学生实验报告书实验课程名称开课学院指导教师姓名学生姓名学生专业班级200200学年第学期实验教学管理基本规范实验是培养学生动手能力分析解决问题能力的重要环节实验报告是反映实验教学水平与质量的重要依据为加强实验过...

实验报告范本

AMT执行机构实验报告实验对象NJ7150变速箱总成实验内容第四代选换档执行机构高低温实验报告人审核批准报告时间20xx苏州绿控传动科技有限公司第四代选换档执行机构高低温试验报告一实验装置零部件清单二已填写完整...

实验报告范本

实验报告范本,内容附图。

实验报告范本

开放实验室报告1234

实验报告范本

学生实验报告书实验课程名称开课学院指导教师姓名学生姓名学生专业班级200200学年第学期实验教学管理基本规范实验是培养学生动手能力分析解决问题能力的重要环节实验报告是反映实验教学水平与质量的重要依据为加强实验过...

实验报告范例

Word排版示例22实验目的1掌握资源管理器和我的电脑的基本操作2掌握文件和文件夹的浏览选择操作3掌握文件和文件夹的新建复制移动删除操作4掌握文件和文件夹的查找操作实验内容1资源管理器的操作2文件和文件夹的操作...

计算机实验报告模板

实验报告实验序号实验项目名称

深大实验报告模板

深圳大学实验报告课程名称学院实验时间实验报告提交时间教务部制深圳大学学生实验报告用纸注1报告内的项目或内容设置可根据实际情况加以调整和补充2教师批改学生实验报告时间应在学生提交实验报告时间后10日内

综合实验报告样本

专业综合实验报告宋体一号加粗居中请注意行距的区别实验项目名称所属课程名称专业综合实验学生姓名学号专业宋体小三加粗居中20xxXXXX西安工业大学综合实验报告实验题目宋体三号加粗居中摘要小三号宋体加粗居中小四宋体...

实验报告样本

SqlServer实验报告数学与信息技术学院实验报告实验课程名称MSSQLServer数据库技术实验实验项目名称数据表与表数据专业班级14计科接1学号姓名张凯旭指导教师SqlServer实验报告数据表与表数...

实验报告格式及相关要求

本科生实验报告实验课程机械工程测试学院名称核技术与自动化工程学院专业名称机械工程及自动化学生姓名学生学号指导教师实验地点8103实验室实验成绩填写说明1适用于本科生所有的实验报告印制实验报告册除外2专业填写为专...

实验报告范本(52篇)