实验报告终极版

  • 格式:doc
  • 大小:164.50 KB
  • 文档页数:11

程序设计实训报告 [黄金矿工] 1 一、系统界面

图1 开始游戏 图2,游戏进行时 2

二、功能描述 玩家通过键盘的按键控制矿工抓取金块,将钩子碰触到的金块抓取过来。 要求如下: 1. 游戏的初始界面如图1,单机键盘上的空格键进入游戏,进入后界面如图2,金块的总数是20,大小位置是随机的。 2. 在没有抓取状态下,钩子左右摆动,此时矿工的是静止的。当钩子摆动到一定角度,玩家可以单击键盘上的上下左右键中的下方向键控制矿工伸出长钩,抓取金子,此时矿工是向下摇动转轴。获取到金子往回拉后,矿工是不断转动转轴,知道金子拉动到钩子初始处,矿工恢复静止,钩子继续左右摇摆,直到玩家再次单击向下方向键。 3. 伸出的钩子如果碰触到金子,则钩子和金子一起往回拉,回收的速度根据抓取到的金子的大小变化而变化,金子越大,回拉的速度越慢,反之亦然。如果钩子没有碰触到金子,而是碰触到左右和下的边界,则钩子保持原来的速度往回收。 4. 抓取到的金子拉回到转轴处消失,此时金子数目减少一个。如果玩家将所有金子抓取完,游戏返回到如图1的初始界面。

三、流程图

否 是 开始

按空格隐藏

使钩子旋转 显示金块

伸出钩子 判断金块是否与钩子碰撞

金块与钩子碰撞拉回并删除金块 钩子与边界碰撞并弹回 如果抓取金子个数等于20 3

四、数据结构 (说明:主要写用到的各类型的全局变量、含义) 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函数控制钩子的位置 4

金块显示: 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) 5

{ 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; 6

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,