中国石油大学(华东) 程序设计实训
“黄金矿工”实验报告 报告
游戏截图
图一:开始游戏
图二:按下空格键开始游戏,出现金块,钩子转动
图三:按下J键,钩子停止转动,开始下放,抓取金块
图四:抓完金块后返回初始界面
功能描述
1、 2、
游戏运行,初始界面出现“空格开始”的提示。 玩家按下空格键,开始游戏。
3、 游戏开始后,界面随机出现20个大小不同的金子,并且钩 子开始
转动。
4、 5、 6、
按下J键,钩子停止转动,下放,抓取金子。 抓到金子后,返回到初始位置,被抓到的金子消失。 用户继续按下J键,继续抓取金子,直到金子被抓取完,
这样一局游戏完成。
7、
一局游戏完成后,屏幕重新出现“空格开始”的标志,用
户按下空格可以继续游戏,如此往复。
流程图:
数据结构:
1、g_fGoldBornMinX 2、 g_fGoldBornMaxX 3、 4、
金子左边界
金子右边界 金子上边界 金子下边界
g_fGoldBornMi nY g_fGoldBornMaxY
5、g_iGoldCount 屏幕中金子数目
6、
g_iGameState
设置游戏状态 7、szGotGoldName[20] 当前抓到金子的名称 8、 g_fHookRotation 钩子的转动的角速度
9、 g_fEmptyHookSpeed 钩子的下放的初始速度 10、g_fHookStartPosX 存储钩子的初始 X 位置 11、g_fHookStartPosY
存储钩子的初始 Y 位置
算法描述:
游戏状态g_iGameState分为三种状态0, 1,2,其中0表示游戏 结束状态, 1 表示游戏初始化, 2 则表示游戏运行状态;
0 1 的转换为“空格开始” ;
1
2 的转换自然发生,即游戏初始化函数后会自动将游戏状态
从 1 置为 2;
2表示游戏运行状态,在该状态,按下J键可以抓取金子;
2
0 的转换为当金子全被抓完后会自动将游戏状态从 2 置为 0;
金子精灵的初始化:
1 、创建金子精灵的对象;
2、 生成大小为 4 的小金块 10 个、 大小为 6 的中金块 6 个、大小 为的大金块 4 个,并保存 tmpName 数组中,随机获取每个金子 的坐标;3、 隐藏“空格开始”精灵;
8
4、设置屏幕中剩下的金子数目为 20,每当被抓走的一块金子消失 后屏幕
中剩下的金子数目减 1;
5、当屏幕中剩下的金子数目为 0 时,一局游戏结束,返回初始界 面,“空
格开始”精灵出现;
6、重新进行金子精灵的初始化 ; dOnKeyDownc(onst int
iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress ) 游戏开始和控制按钮:
1、游戏还未开始,即游戏状态为 0,如果空格按被下,则将游戏 状态改为 1,此时对程序的数据进行初始化, “空格开始”精灵消失, 金子出现,钩子
转动;
2、 游戏状态为0时并按下空格键后,,如果按下J键,钩子开始 下放抓金
子,当抓到金子后,游戏的状态变为 2游戏正式开始运行;
3、 游戏状态为 2 时,钩子抓住金子后,按照金子的大小设置金子 的速度,
金子越大,回拉速度越小;
4、当钩子和金子回到初始位置后,被抓的金子消失;
源代码:
在Mai n.cpp文件中
// ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- #include \"CommonAPI.h\" #include \"stdio.h\" #include \"string.h\" void DrawHookLine();
0; 0; int g_fGoldBornMaxX = int
0; g_fGoldBornMinY = int
0;
g_fGoldBornMaxY = int g_iGoldCount = 20; int g_iGameState=2; int flag=1; int flagnum=0;
char szGotGoldName[20] float g_fHookRotation = 0.f; float g_fEmptyHookSpeed
; // 当前抓到金子的名称 =35.f; float fTimeDelta;
float g_fHookStartPosX; // 存储钩子的初始 X 位置 float g_fHookStartPosY; // 存储钩子的初始 Y 位置 /////////////////////////////////////////////////////////////////////////////////////////// // // 主函数入口 //
//////////////////////////////////////////////////////////////////////////////////////////
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int
{
nCmdShow)
// 初始化游戏引擎
if( !dInitGameEngine( hInstance, lpCmdLine ) )
return 0; // 游戏初始化代码
dSetWindowTitle(\" 黄金矿工 \"); g_fGoldBornMinX g_fGoldBornMaxX g_fGoldBornMinY
= = =
dGetScreenLeft() + 5; dGetScreenRight() - 5; dGetScreenTop() + 20;
//金子左边界 //金子右边界 //金子上边界
g_fGoldBornMaxY = dGetScreenBottom() - 5; // 金子下边界
g_fHookStartPosX = dGetSpritePositionX(\"GoldHook\"); g_fHookStartPosY = dGetSpritePositionY(\"GoldHook\"); // 获取钩子的初始 // 获取钩子的初始
X坐标 Y坐标
dSetSpriteCollisionSend(\"goldHook\dSetSpriteCollisionReceive(\"goldTemplate\const float fRotateSpeed = 45.f; // 摇摆速度,单位 度/秒
int iHookRotToLeft = 1;
// 钩子摆动的方向:1 — ; 0
float fTimeDelta = dGetTimeDelta(); // 引擎主循环,处理屏幕图像刷新等工作 while( dEngineMainLoop() )
{
// 获取两次调用之间的时间差,传递给游戏逻辑处理 float fTimeDelta = dGetTimeDelta(); DrawHookLine(); // 执行游戏主循环 if(g_iGameState == 0)
{
float fThisRotate = fRotateSpeed * fTimeDelta; if( iHookRotToLeft )
{
g_fHookRotation += fThisRotate; if( g_fHookRotation >= 180.f )
{
g_fHookRotation = 180.f;
iHookRotToLeft =
0;
}
}
else
{
g_fHookRotation -= fThisRotate; if( g_fHookRotation <= 0.f )
{
g_fHookRotation = 0.f;
iHookRotToLeft =
1;
}
}
dSetSpriteRotation(\"GoldHook\
}
else if(g_iGameState == 1)
{
dAnimateSpritePlayAnimation(\"goldMan\
播放拉金块的动作
〃获取钩子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); // 删除获取的金块
//
dDeleteSprite(szGotGoldName);
// 回拉结束,设定状态为 0 g_iGameState = 0;
// 播放矿工的动画,即准备拉金子的动画 if(flagnum) {g_iGoldCount--;
}
}
}
// 播放挖金者的动作 (恢复初始守候动作 ) dAnimateSpritePlayAnimation(\"goldMan\\"GolderManAnimation2\
{
g_iGameState = 0;
dSetSpriteVisible(\"GameBegin\g_iGoldCount = 20; flag=1;
}
}; dAnimateSpritePlayAnimation(\"goldMan\// 关闭游戏引擎 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 = 1; // 初始化之后,将游戏状态设置为进行中 dSetSpriteVisible(\"GameBegin\
// 生成金子 int int if(flag)
{
iLoop iSize =
= 0; // 循环变量控制
4, 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\生
成 金 块 名字
dCloneSprite(\"goldTemplate\dSetSpriteWidth(tmpName,(float)iSize);
// 设 置 金 块
的宽度
dSetSpriteHeight(tmpName,(float)iSize); // 设 置 金 块
的高度
// 设置金子精灵位置 iPosX
g_fGoldBornMaxX);
iPosY
g_fGoldBornMaxY);
dSetSpritePosition(tmpName,(float)iPosX, (float)iPosY); flag=0;
} }
= =
dRandomRange(g_fGoldBornMinX, dRandomRange(g_fGoldBornMinY,
if(g_iGoldCount==0) {
flag=1; g_iGoldCount=20;
}
}
if( iKey == KEY_DOWN &&g_iGameState ==0 ) {
//按下J并且游戏状态为 g_iGameState =
\"0\"
2; //置游戏状态为 2,可用于控制钩子是否摆动
// 以当前朝向给钩子一个向前的速度
dSetSpriteLinearVelocityPolar(\"GoldHook\
// 播放挖金者的动作 (一个胳膊往下压的动作 )
dAnimateSpritePlayAnimation(\"goldMan\//0 表示播放一次,这里胳膊往下压就是一次
}
}
//=========================================================================
//
// 引擎捕捉键盘弹起消息后,将调用到本函数 void dOnKeyUp( const int iKey )
{
// 可以在此添加游戏需要的响应函数
}
//=========================================================================
//
// 引擎捕捉到精灵与精灵碰撞之后,调用此函数
void dOnSpriteColSprite( const char *szSrcName, const char *szTarName )
{
// 发起者为 GoldHook ,接受者含有 GoldBlock 字段
if(strcmp(szSrcName,\"GoldHook\")== 1 && strstr(szTarName,\"GoldBlock\")!=NULL ) {
dSpriteMountToSpriteLinkPoint( szTarName, \"GoldHook\将金块锚定 在钩
子上
dSpriteMoveTo(\"GoldHook\
g_fEmptyHookSpeed, 1); // 使钩子向初始位置移动,即会拉
strcpy(szGotGoldName,szTarName); // 复制并保存当前抓取到金块的名 称 //发起者为GoldHook,接受者含有 GoldBlock字段
// 根据金子大小,计算钩子的往回收的速度,越大的越慢。
// 算法:之前设置的金子大小为 4,6,8,用 10 减去该大小再除以 10, 得到
3 个小 // 数: 0.6,0.4,0.2.该小数乘以空钩子的速度即得到挂接不同金子后的实际速度 float fWidth = dGetSpriteWidth( szTarName );
float fSpeed =
((10.f - fWidth) / 10.f) * g_fEmptyHookSpeed;
// 钩子往初始位置移动
dSpriteMoveTo( \"goldhook\dAnimateSpritePlayAnimation(\"goldMan\播放拉
金块的动作
g_iGameState = 1; flagnum=1;
}
}
//=========================================================================
//
// 引擎捕捉到精灵与世界边界碰撞之后,调用此函数 . // iColSide : 0 左边, 1 右边, 2 上边, 3 下边
void dOnSpriteColWorldLimit( const char *szName, const int iColSide ) {
if(strcmp(szName,\"GoldHook\")!=0)
{
// 碰到边界的为钩子时 dSpriteMoveTo(szName,g_fHookStartPosX, g_fHookStartPosY,
g_fEmptyHookSpeed, 1);
dAnimateSpritePlayAnimation(\"goldMan\
// 播 放
拉金块的动作
// 同样设置为回拉,只是没有碰到金子 g_iGameState = 1; flagnum=0;
}
}
void DrawHookLine()
// 首先,从矿工精灵上获取一个缆绳链接点作为绳子的起始点 // 辑器里编辑好 )
float fStartX
(该链接点在编
= dGetSpriteLinkPointPosX( \"GoldMan\
float fStartY = dGetSpriteLinkPointPosY( \"GoldMan\// 绳子终点在钩子精灵上获取 (该链接点在编辑器里编辑好 ) float fEndX float = dGetSpriteLinkPointPosX( \"GoldHook\
= dGetSpriteLinkPointPosY( \"GoldHook\fEndY
// 在这两点之间划线 .线的颜色红绿蓝值都为 50,即灰色 dDrawLine( fStartX, fStartY, fEndX, fEndY, 2.f, 0, 50, 50, 50, 255 );
}
8、 游 戏 运 行
初 试 界 面 现 格 开 始的 提 示 , 出 ‘ 空 '
学号 姓名 任务 成绩 解决程序结构布局问题; 解决画线函数问题; 写实验报告; 解决捕捉到精灵与精灵碰撞问题; 解决捕捉到精灵与世界边界碰撞问题; 解决捕捉键盘按下消息问题; 同一个问题可以用不同的代码解决,如 该程序中的画线部分; 部分程序代码在程序中不能实现,可能 是该软件的bug; 编程过程中加深了对全局变量和局部 变量的了解; 要理解函数的意义,不然会弄乱; 程序要写清晰明快,不然在检查的时候 会很麻烦; 随着对该软件的理解,对C语言中的结 构函数有了更深的了解; 评阅教师签名
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务