版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验教学实验:海底世界实现鱼来回游动学习目标用代码响应“精灵与世界边界碰撞”事件;如何让精灵调头运动;复习选择结构;学习应用dSetSpriteFlipX和dSetSpriteFlipY函数;学习应用strcmp函数。在“入门”一章中,我们学会了如何设计游戏界面,也知道简单地编一点小程序。从这章开始,我们开始用代码写稍微复杂一些的小游戏。在这个实验中,我们还是使用seafish项目。到目前为止,我们能让yellowfish游动了,但是它游出屏幕以后就不再回来了。现在,我们要求它游到屏幕左边界时;就调头向右游动;游到右边界时,就调头向左游动。Stepl:创建C语言工程,工程的名字起为seafish,然后添加相应的精灵,鱼和背景图片。Step2:让鱼水平游动在WinMain的游戏初始化部分:先将yellowfish改为水平游动。修改dSetWindowTitle中的内容,将下列代码添加到dSetWindowTitle函数的下边:dSetWindowTitle(,,seafish,/); 〃游戏的名字为seafishdSetSpriteLinearVelocity("yellowfish”,10,0); 〃初始化yellowfish的X方向速度Step3:设置鱼的世界边界在“入门”一章,我们已经学习了精灵与世界边界碰撞事件(具体查看“项目改进”之“精灵与世界边界的碰撞”)。在界面中将yellowfish的世界边界设计得与可见区域重合,然后将“限制模式”改为NULLo现在我们通过代码实现精灵与世界边界碰撞模式的设置:在step2的代码下面添加以下代码:dSetSpriteWorldLimitMode(,,yellowfish,/,WORLD_LIMIT_NULL);〃将碰撞模式设置为NULLStep4:精灵与世界边界碰撞的响应函数这个响应函数就是dOnSpriteColWorldLimit函数,函数定义在Main.cpp文件中。WinMain函数中,每次循环调用dEngineMainLoop函数时,引擎会检查是否有精灵与世界边界碰撞事件发生。如果有,再检测限制模式是否是NULL。如果是NULL,就调用该函数并执行函数内部代码。函数定义如下:voiddOnSpriteColWorldLimit(constchar*szNamezconstintiColSide)其中,szName是与世界边界碰撞的精灵的名称。iColSide用来表示与哪个边界碰撞,0-左边界,1-右边界,2-上边界,3-下边界。因此,对该事件的处理代码,我们只需要写在这个函数中就可以了。Step5;判断鱼碰到了那个边界由step4可以知道,关于精灵与世界边界碰撞的处理都写在dOnSpriteColWorldLimit中,那么判断也应写在该函数中,代码如下:if(0==iColSide)dSetSpriteLinearVelocity("yellowfish",10,0);)elseif(l==iColSide)dSetSpriteLinearVelocity("yellowfish",-10,0);)Step6:鱼碰到右边界后调头运行step5可以看到精灵虽然反向游动了,但是头还没有调转。这里我们学习两个新的API,用来将精灵沿着X轴或Y轴调转。/*dSetSpriteFlipX:设置精灵图片X方向翻转显示参数szName:精灵名字参数iFlipX:1翻转0不翻转(恢复原来朝向)7externvoiddSetSpriteFlipX(constchar*szName,constintiFlipX);/*dSetSpriteFlipY:设置精灵图片Y方向翻转显示*参数szName:精灵名字*参数iFlipY:1翻转0不翻转(恢复原来朝向)7externvoiddSetSpriteFlipY(constchar*szName,constintiFlipY);如果我们要让yellowfish在X方向上来回的游动,应该怎么过办呢??在step5中的if-elseif语句中添加代码如下:if(0==iColSide)dSetSpriteFlipXf^yellowfish^0);//yellowfish不进行水平翻转,可以试试不加〃这句有什么效果dSetSpriteLinearVelocityC'yellowfish",10,0);elseif(l==iColSide)dSetSpriteFlipX(//yellowfishw,1);//yellowfish进行水平翻转dSetSpriteLinearVelocity("yellowfish",-10z0);)Step7:根据名称判断精灵我们这个实验中,目前只对yellowfish进行处理。但是在以后的实验中,我们会对多个精灵进行处理。因此,我们在处理某个精灵时,有必要根据精灵名称先进行判断。我们要用到strcmp函数对精灵名称进行判断。该函数是C语言标准库函数,所在头文件为String.%所以我们需要在Main.cpp顶部增加一句:#include<String.h>;函数原型是:externintstrcmp(constchar*sl,constchar*s2);当si指向的字符串和s2指向的字符串相等时,函数返回值为0o如果与世界边界发生碰撞的精灵名称为yellowfish,代码实现如下:if(strcmp(szName,"yellowfish*)==0)()szName是发生碰撞的精灵名称,它与字符串yellowfish一致,说明发生碰撞的精灵是yellowfisho如果是精灵yellowfish与右边界发生碰撞,实现代码如下:if(strcmp(szNamezz/yellowfish//)==1)(if(iColSide==0){dSetSpriteLinearVelocityJszName^O^);dSetSpriteFlipXJszName,0);)elseif(iColSide==1)(dSetSpriteLinearVelocityfszName^lO^);dSetSpriteFlipXfszName,1);))在函数dSetSpriteLinearVelocity和dSetSpriteFlipX中,第一个参数,我们都直接使用szName,因为我们已经对这个变量做了判断,所以可以直接使用。另外,使用变量,而不是直接使用常量“yellowfish",当我们修改判断条件时,比如改成判断是bluefish,相应代码就不必修改了,显得更加灵活。
练习:1、完成yellowfish碰到上下边界的情况处理;2、要求bluefish也在屏幕中间来回游动;3、如果要求yellowfish游出屏幕,但很快又游回来应该如何处理。键盘控制鱼游动一学习目标用代码响应“键盘按下”和“键盘弹起”事件;了解键盘常量:复习switch-case语句;初步了解调试;在这个实验中,我们还是使用seafish项目。到目前为止,我们能让bluefish游动并且掉头了,但是却无法控制鱼的走向,本节中我们将学习如何通过键盘的WSAD来控制bluefish的上下左右移动。Stepl:键盘常量首先我们来学习键盘的常量定义,打开CommonAPl.h(该文件位于:、实验项目路径\SourceCode\Header),找到enumKeyCodes,其中定义了键盘上的按键对应的常量定义。enum是枚举类型,本质是整型变量,通过枚举类型将一类相关联的的标识组合起来,增加程序的可读性和可维护性。这里说明常用的按键及其命名规则:KEY_+按键标识,常用的介绍如下:英文字母与数字:变量 键盘上的键TOC\o"1-5"\h\zKEY_A AKEY_B BKEY__1 1KEY_2 2键盘上的键BACKSPACETAB键盘上的键BACKSPACETABENTERCONTROLALTSHIFTESCSPACEKEYDOWN这节中我们要用到的显然就是KEY_W,KEY_S,KEY_A,KEY_DStep2;键盘按下与键盘松开响应函数要想用WSAD来控制小鱼,那么必须捕捉键盘的输入,在funCode中,我们利用dOnKeyDown来捕捉按键按下的操作,dOnKeyUp来捕捉按键放开的操作事件函数声明如下:/*dOnKeyDown:键盘被按下后将被调用的函数,可在此函数体里(Main.cpp)增加自己的响应代码参数iKey:被按下的键,值见enumKeyCodes宏定义参数iAItPress,iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)*/externvoiddOnKeyDown(constintiKey,constintiAItPress,constintiShiftPress,constintiCtrlPress);/*dOnKeyUp:键盘按键弹起后将被调用的函数,可在此函数体里(Main.cpp)增加自己* 的响应代码*参数iKey:弹起的键,值见enumKeyCodes宏定义*/externvoiddOnKeyllpfconstintiKey);Step3:思路阐述利用WSAD来控制鱼的上下左右移动,那么我们再按下相应的按键时,需要给鱼儿设置一个对应方向的速度。如按下W,设置一个向左的速度。同时当松开按键时其对应方向的速度应该置为0oStep4:代码详解(1).选择bluefish,如下图(2),按下键盘的操作应该在dOnKeyDown函数中完成。我们先定义4个变量,用来表示鱼游动的四个方向上的速度。代码如下:floatfSpeedUp=0,fSpeedDown=0,fSpeedLeft=0,fSpeedRight=0;可以用if-else语句,或者switch-case语句来判断按下什么键,并且根据按下的键,把速度值保存到相应的变量中。代码如下:switch(iKey)IcaseKEY_W:fSpeedUp=-10.f;break;caseKEYA:fSpeedLeft=-15.f;break;caseKEY_S:fSpeedDown=10.f;break;caseKEYD:fSpeedRight=15.f;break;I同样在dOnKeyDown事件函数中调用dSetSpriteLinearVelocity函数,设置bluefish的速度,代码如下。dSetSpriteLinearVelocity(*bluefish*,fSpeedLeft+fSpeedRight,fSpeedUp+fSpeedDown);思考:为什么水平方向速度是左方向速度加右方向速度;垂直方向速度是上方向速度加下方向速度。运行程序,看看游戏效果。进一步,我们还需要让鱼跟随方向键而调头。比如,按D键,鱼朝向右方;按左键,鱼朝向左方。在dSetSpriteLinearVelocity函数卜.添加代码如下:if((fSpeedLeft+fSpeedRight)>0)dSetSpriteFlipX(*bluefish*»false); //向右游、图片不需要翻转elseif((fSpeedLeft+fSpeedRight)<0)dSetSpriteFlipX(*bluefish*,true); //向左游,图片需要翻转保存代码,再次运行游戏,看看游戏效果。(3).当我们按下WASD键中的某一个键时,bluefish就朝某个方向游动。现在,我们希望当松开WASD键中的任一个键时,bluefish就将该方向的速度设置为0。键盘松开的操作在dOnKeyUp函数中完成。请同学们考虑,代码应该如何完成?键盘控制鱼游动二学习目标掌握全局变量和局部变量:在上一节中,我们用WASD键来控制bluefish上下左右游动。但是,我们发现bluefish只能是直线运动,不能斜着游动。原因在哪里?我们如何让bluefish也能斜着游动呢。Stepl:全局变量和局部变量简答的说,全局变量是在这个文件中都可以使用的变量,它常常定义在文件开始处,在任何函数的外面。而局部变量只是在局部范围内使用的变量,当离开了这个范围那么,该变量就会被自动销毁,不能再利用。如下所示:intg_x=3;voidf()(Intb=4;}voidg(){}其中g_x就是全局变量,它可以在函数g()中被调用,而b只能在函数f中使用,离开了f.那么它就会被销毁。Step2s思路阐述WSAD控制鱼的上下左右移动相信同学们都已经了解了。然而在上述实验中,如果同时按下WD为何鱼不会向斜向上的方向移动呢。这就需要结合局部变量和全局变量的知识了。floatfSpeedllp=0,fSpeedDown=O,fSpeedLeft=O,fSpeedRight=0;都是局部变量,当每次进入函数时,他们都会被重新初始化为0,离开时则被销毁。所以当同时按下WD时,OnKeyDown就会被调用两次,所以他无法保存前一次的速度值,因此速度只能是上下左右了。如果把速度方向替换为全局变量,他们的作用域是全局,那么是否就可以实现斜上斜下方等操作呢。我们不妨来尝试一下。Step3:代码详解.用/**/将上一个实验的代码给注释掉,如图在dOnKeyDown中/••«••••floatFSpeedUp-B.fSpeedDown■••FSpeedLeft-teFSpeedRight>0;switch(iKe9)<caseKEV_W:(Speedup-break;caseKEYA:FSpeedLeFt--15.F;caseKEV_S:FSpeedDown=10.F;break;caseKEY_D:FSpeedRight=15.F;break;>iF((FSpeedLeft♦fSpeedRight)>0)dSetSpriteFlipX(',blueFish**tFalse);elseif((fSpeedLeFt♦FSppedRight)<0)dSetSpriteFlipX("bluefisho.true);dSetSpriteLinearUelocityCblueFish*',fSpeedLeft♦FSpeedRight,FSpeedUp♦fSpeedDovn);在dOnKeyUp中/»iFCiKey==KEV_W||iKey==KEV_A||iKep==KEV_S||iKey==KEV_D)dSetSpriteLinearUelocity("bluefish"v0,0);*/.在main.cpp开始部分定义全局变量// Itinclude,'ComnonAPI.h',"include<math.h>Floatg_FSpeedUp»0.F;floatg_fSpeedDown=O.f;Floatg_FSpeedLeft=0.F;floatg_fSpeedRight=O.F;//〃〃/〃〃〃/〃/〃/〃〃〃〃/〃〃〃/〃〃〃〃,〃主函数入口//〃〃〃〃〃/〃〃〃〃〃〃〃〃〃〃〃〃〃〃〃/〃,分别表示上卜.左右的速度,全局变量要在函数外部声明,我们--般在include语句卜.方,其他函数顶部,这样文件中的所有函数都能使用这些变量。根据匈牙利命名法,g表示作用域为全局,1表示浮点数,其他的则是描述符。练习:1,参考“键盘控制鱼游动一”中的代码,修改dOnKeyDown函数和dOnKeyUp函数。运行程序,要求按下组合键,比如WD、WA等,bluefish可以斜着游动。并思考为什么?用鼠标控制鱼游动学习目标用代码响应“鼠标滑动”事件;学习使用dSetSpritePosition,dGetSpritePositionX>dGetSpritePositionY,dSpriteMoveTo函数;学习使用sqrt函数;用全局变量作条件判断。在上一节中,我们利用全局变量实现了鱼的斜线方向上的移动,至此键盘操作控制鱼游动已基本实现。接下来我们来实现用鼠标来控制鱼的移动,要点如下:1、鼠标移动到哪里,鱼就移动到哪里。2、根据鼠标在鱼的前后方,控制鱼调头;3、鱼游动的速度,根据鼠标移动的快慢而快慢;4、程序刚启动时,鱼的位置出现在鼠标位置上。Stepl:鼠标移动事件的响应函数及其他API鼠标移动事件函数为/*dOnMouseMove:鼠标移动后将被调用的函数,可在此函数体里(Main.cpp)增加自己的响应代码参数fMouseX,fMouseY:为鼠标当前坐标*/externvoiddOnMouseMove(constfloatfMouseX,constfloatfMouseY);精灵移动函数:/*dSpriteMoveTo:让精灵按照给定速度移动到给定坐标点参数szName:精灵名字参数fPosX:移动的目标X坐标值参数fPosY:移动的目标Y坐标值参数fSpeed:移动速度参数iAutoStop:移动到终点之后是否自动停止,1停止0不停止/externvoiddSpriteMovefb(constchar*szName,constfloatfPosX,constfloatfPosY,constfloatfSpeed,constintiAutoStop);获得精灵szName的X坐标:/*dGetSpritePositionX:获取精灵X坐标参数szName:精灵名字返回值:精灵的X坐标/externfloatdGetSpritePositionX(constchar*szName);获得精灵szName的Y坐标:/*dGetSpritePositionY:获取精灵Y坐标参数szName:精灵名字返回值:精灵的X坐标VexternfloatdGetSpritePositionY(constchar*szName);设置精灵坐标:/*dSetSpritePosition:设置精灵位置参数szName:精灵名字参数fPosX:X坐标参数fPosY:Y坐标/externvoiddSetSpritePosition(constchar*szName,constfloatfPosX,constfloatfPosY);Step2:“鱼跟着鼠标移动”思路阐述要想让鱼跟着鼠标移动,必须捕捉鼠标的坐标位置,通过dOnMouseMove可以捕捉到鼠标在窗口中的位置,然后可以通过设置dSpriteMoveT。来让鱼向目标点(鼠标所在位置)移动,即可实现鱼跟着鼠标移动。Step3:“鱼跟着鼠标移动”代码详解.添加一条新的鱼,如下图:起名为followMouseFish,世界边界参数为STICKY(2).鱼跟随鼠标移动在鼠标移动事件函数dOnMouseMove中添加代码dSpriteMoveToC'followMouseFish",fMouseX,fMouseY,30,1);编译运行,即可实现鱼跟着鼠标走,游到鼠标位置后,停止不动。说明:这里速度为30,可根据情况自行设定.通过鼠标移动控制鱼的朝向现在我们发现虽然鱼可以跟着鼠标移动了,但是当鼠标在鱼的后面时,鱼是倒着游,并且没有转头,现在我们就来解决这个问题。当鼠标移动时,我们就比较鱼和鼠标的X坐标。当鼠标的X坐〈鱼的X坐标,说明鼠标在左,鱼在右,应该让鱼朝向左。当鼠标的*坐>鱼的X坐标,说明鼠标在右,鱼在左,应该让鱼朝向右。鼠标的坐标可以通过dMouseMove中的参数获得,鱼的X坐标可通过dGetSpritePositionX来获取。在dOnMouseMove中添加如下代码:floatfFishX=dGetSpritePositionX(*followMouseFish*);if(fMouseX<fFishX)|dSetSpriteFlipX("followMouseFish*,true); I礼标在♦的后头,设置找头IelsedSetSpriteFlipX("followMouseFish”,false);3编译运行即可实现鱼跟着鼠标移动,并且可以实现鱼转头。.根据鼠标移动的快慢设置鱼移动的速度思路:要判断鼠标移动的快慢需要一个参照物,这里我们不妨利用鱼为参照点。只要在鼠标移动时算出鼠标和鱼之间的距离d。d越大,说明鼠标移动的速度越大,d越小,鼠标移动的速度越小。进而可以通过d来自定义设置鱼移动的速度。这里不妨设为fFishSpeed=5*sqrt(d).代码实现:在前面的基础上,在dOnMouseMove中的fFishX卜添加:floatfFishY=dGetSpritePositionYCfollowMouseFish*);floatdistance=sqrt((fMouseX-fFishX)*(fMouseX-fFishX)+(fMouseY-fFishY)*(fMouseY-fFishY));floatspeed=5*sqrt(distance);说明:其中sqrt为标准库函数中的开方,需要在文件顶部引入头文件:#include<math.h>然后修改dSpriteMoveTo中的速度值,将30替换为speed。接着,编译运行即可。.开始运行时鱼的位置处于鼠标位置上鼠标位置只能在dOnMouseMove中捕捉,我们通过dSetSpritePosition来设置鱼的初始位置,即鼠标所在位置。在dOnMouseMove中添加I:dSetSpritePosition(*followMouseFish*,fMouseX,fMouseY);编译运行!开始时鱼的确和鼠标在一起,然而不管如何移动鼠标,鱼总是和鼠标在一起!前面的效果都消失了!
问题在于,我们只是让程序启动时让鱼和鼠标在一起,而不是总是在一起。所以我们定义一个全局变量g_iStart=O。当第•次运行dOnMouseMove时,置其为1;这样之后无论怎么移动鼠标,都不会再运行dSetSpritePosition函数了。代码如下所示:在文件开头定义全局变量intg_iStart=0;在dOnMouseMove中,修改为如下代码:if(g_iStart==0) 〃第一次时为0,将与位|g-iStart=1;置其为1,以后就再也不会进入了dSetSpritePosition(dRandomRange:获取一^个位于参数iMindRandomRange:获取一^个位于参数iMin到参数iMax之间的随机数,即[iMinjMax]返回值:int,范围iMin-iMax参数iMin:小于iMax的整数参数iMax:大于iMin的整数复制多条鱼学习目标从模板复制出多个精灵;复制精灵时,精灵的命名规则;随机数的应用。作为海底世界的最后一个实验,我们要实现复制多条鱼。我们新建一个鱼精灵作为模板,命名为rockfishTemplate,并将其拖到主窗口外面。▼程序接口>乩不屑性▼程序接口>乩不屑性名字 rockfishTemplate然后复制该模板得5条同样的鱼,并命名为rockfishO,rockfishl,rockfish2。最后为他们随机设置一个纵向坐标Y,让他们来回游动!/*Stepl:本实验用到的/*返回值:1克隆成功。克隆失败。失败的原因可能在地图中未找到对应名字的精灵参数szSrcName:地图中用做模板的精灵名字参数szMyName:新的精灵名字7externintdCloneSprite(constchar*szSrcName,constchar*szMyName);等等。/**等等。/**dRandomRange(constintiMin,constintiMax);externintdRandomRange(constintiMin,constintiMax);/*dMakeSpriteName:将前面的字符串与后面的数字整合成一个字符串。参数szPrev:一个非空字符串,最长不能超过20个英文字符。名字前面的字符。参数ild:一个数字返回值:返回一个字符串,比如传入(收**",2),则返回、**2"/externchar*dMakeSpriteName(constchar*szPrev,constintild);/*找出str2字符串在strl字符串中第一次出现的位置(不包括str2的串结束符)。返回值:返回该位置的指针,如找不到,返回空指针。strstr(szName,"feichong")!=NULL说明szName中包含feichong/externchar*strstr(char*strl,char*str2);Step2模板的建立如下图所示,添加rockfishTemplate,并将其拖出窗口,并设置其世界边界为NULLStep3:复制多条鱼并设置随机位置调用dCloneSprite函数从rockfishTemplate模板复制出多条鱼,然后通过dRandomRange来随机得到纵向坐标,最后利用dSetSpritePositionY来为复制出来的鱼设置各自的Y坐标,将下列代码添加到while循环以前:for(inti=0;i<3;i++)//生成待拷贝鱼的名字char*destFish=dMakeSpriteName(*rockfish*,i);//拷贝rockfishTemplate到destFishdCloneSprite(*rockfishTemplate*,destFish);//随机产生鱼的纵坐标floattmpY=dRandomRange(-37,37);〃设置拷贝得到的鱼的Y坐标dSetSpritePositionY(destFish,tmpY);dSetSpriteLinearVelocity(destFish,15,0);Step3:给这些鱼处理与世界边界的碰撞最后在dOnSpriteColWorldLimit中添加新生成精灵的碰撞处理。因为这些鱼的名称中都包含“rockfish”的子字符串,可以通过strstr函数来判断这些精灵的名称。代码如下:if(strstr(szName,"rockfish")!=NULL)//如果了串中包含rockfishif(iColSide==0)I________dSetSpriteLinearVelocity(szName,10,0);dSetSpriteFlipX(szName,false);Ielseif(iColSide==1){ dSetSpriteLinearVelocity(szName,-10,0);dSetSpriteFlipX(szName,true);}编译运行即可,最后的效果图如下所示:实验:黄金矿工完成本实验后,可以实现矿工抓金子并计分的效果,如卜.所示:
复制金块学习目标学习应用dGetScreenLeft,dGetScreenRight,dGetScreenTop,dGetScreenBottom学习应用srand函数。这节我们实现黄金矿工的金块随机分布,并设置不同金块的大小,为后续的抓取金块做好准备。Stepl:图片资源导入新建一个新的项目,取名为GoldenManDemo。添加如图所示资源到环境中:bactgroundmage 〜郎加到1:制(3关闭窗”时释放郎加到1:制(3关闭窗”时释放ftl片费劭适用低配置机零)Step2:本实验用到的API/*dGetScreenLeft:获取世界边界之左边X坐标返回值:左边界X坐标/externfloatdGetScreenLeft();/*dGetScreenTop:获取世界边界之上边Y坐标返回值:上边界Y坐标/externfloatdGetScreenTop();/*dGetScreenRight:获取世界边界之右边X坐标返回值:右边界X坐标7externfloatdGetScreenRight();/*dGetScreenBottom:获取世界边界之下边Y坐标返回值:下边界Y坐标*/externfloatdGetScreenBottom();/*dSetSpriteWidth:设置精灵外形宽度参数szName:精灵名字参数fWidth:宽度值,大于07externvoiddSetSpriteWidth(constchar*szName,constfloatfWidth);/*dGetSpriteWidth:获取精灵外形宽度参数szName:精灵名字返回值:精灵宽度值7externfloatdGetSpriteWidth(constchar*szName);/*dRandomRange:获取一个位于参数1到参数2之间的随机数返回值:int,范围iMin-iMax参数iMin:小于iMax的整数*参数iMax:大于iMin的整数VexternintdRandomRange(constintiMin,constintiMax);Step3:思路阐述要实现金块的随机分布,首先需要利用模板复制一定数量的金块,然后将他们随机布置在窗口中,可以通过dSetSpritePosition来设置金块的横纵坐标。接下来要面临的问题就是,如何获取窗口中不同位置的坐标。利用dGetScreenLeft,dGetScreenRight,dGetScreenBottom»dGetScreenTop来获取窗口的范围,然后使用dRandomRange在该范围中随机一个新的坐标。对于金块的大小设置,可以利用dSetSpriteHeight和dSetSpriteWidth来实现。Step4:代码详解首先定义全局变量,定义如下全局变量:TOC\o"1-5"\h\zint g_fGoldBornMinX = 0;int g_fGo1dBornMaxX = 0;int gfGoldBornMinY = 0;int g_fGo1dBornMaxY = 0;int g__iGoldCount = 0;金块布置属于初始化工作,在WinMain的初始化部分添加如卜代码:dSetWindowTitle("黄金矿工");g_iGoldCount=20;〃金子数量gfGo1dBornMinX = dGetScreenLeft()+5; 〃金子左边界g_fGoldBornMaxX = dGetScreenRight()-5; 〃金f右边界
g_fGo1dBornMinY=dGetScreenTopO+20;〃金子上边界gfGoldBornMaxY=dGetScreenBottom()-5;〃金子下边界利用循环生成20个金子,以goldTcmplale为模板intiLoopwintiLoopw〃循环变量控制if(iLoop<10)tmpName=dMakeSpriteName(*GoldBlock*»iLoop);//生成金块名字〃设置金块的宽度〃设置金块的高度if(iLoop<10)tmpName=dMakeSpriteName(*GoldBlock*»iLoop);//生成金块名字〃设置金块的宽度〃设置金块的高度intiSize4,iPosX=0,iPosY=0;〃iSize表示金块大小的变intiSizefor(iLoop=0;iLoop<giGoldCount;iLoop++)〃生成10个小金块,大小为4dCloneSprite(*goldTemplate*,tmpName);dSetSpriteWidth(tmpName,(float)iSize);dSetSpritelleight(tmpName,(float)iSize);〃设置金子精灵位置iPosX二dRandomRange(g_fGoldBornMinX,g_fGoldBornMaxX);iPosY= dRandomRange(gfGoldBornMinY,g_fGoldBornMaxY);dSetSpritePosition(tmpName,(float)iPosX,(float)iPosY);编译运行,可得到如下所示的效果:
练习:1.自定义金子的大小和数量;旋转钩子学习目标学习应用dSetSpriteRotation函数学会利用屏幕刷新时间flimeDelta来实现一些复杂的操作。这节我们实现黄金矿工的钩子180度来回转动,这样矿工就可以控制抓取范围了,也为后面的抓取金子做好准备。Stepl:图片资源导入点击添加一个新的动画垢辑资源画©Ei网回画I国V型态转耳V型态转耳(Sprites)添加GolderManAnimationl,GolderManAnimation2,GolderManAnimation3到环境中,添加完后效果如图:v动画精灵v动画精灵(Sprites)名字将GolderManAnimation2拖进屏幕,并取名为GoldMan,如F图所示:名字GoldMan同理,将静态精灵中的钩子,拖进屏幕,按初始界面排放。并在右侧的“编辑”中设置名称如F:钩子布置好后的效果如F:Step2:本实验用到的API/*dSetSpriteRotation:设置精灵的旋转角度参数szName:精灵名字参数fRot:旋转角度,范围0-360VexternvoiddSetSpriteRotation(constchar*szName,constfloatfRot);Step3:思路阐述实现钩子的180度来回摆动,其实就是不断地设置钩子与地面的夹角从0—180度不断地变化,可以利用dSetSpriteRotation来进行设置。为了使钩子以恒定的速度来回摆动,我们可以自定义一个初始化速度speed,然后利用游戏屏幕刷新的时间仃imeDelta来实现,即speed*fTimeDelta即为当前钩子所在的角度位置。Step4:代码及注释首先定义全局变量,定义如下全局变堂floatgfHookRotation=0.f; :Jf-q地面的上年 ;在WinMain的初始化部分,即金块分布的for循环下方添加:constfloatfRotateSpeed=45.f; 二匚,中位支杪intiHookRotToLeft=1; 〃钩子投动的方向:1-:0-*由于钩子摆动在游戏过程中一直进行,所以应该将摆动的代码置于while循环中,在floatfTimeDelta=dGetTimeDeltaO;下方添加如下代码:gfHookRotation = 180.f;TOC\o"1-5"\h\ziHookRotToLeft= 0;Elseg_fHookRotation = 0.f;iHookRotToLeft= 1;dSetSpriteRotation(*GoldHook*,gfHookRotation);编译运行,可得到如下所示的效果:
练习:1.使钩子从左往右进行旋转释放绳索学习目标学习应用dSetSpriteLinearVelocityPolar,dAnimateSpritePlayAnimation函数学会利用全局变量来控制游戏的运行状态。这节我们实现黄金矿工在某一角度放下绳索的操作,为之后的真正抓取金子做好准备Stepl:图片资源编辑打开funcode,单击地图上的矿工精灵图像,在显示框的上面五个选择左数第二个“编辑此精灵的链接点”,如图所示
按如图所示依次单击这位置显示0,保存即可。同上,点击地图上的钩子精灵,选择“编辑此精灵的链接点”,依次单击这个位置显示0,最后保存即可。Step2:本实验用到的API/*dSetSpriteLinearVelocityPolar:按角度朝向设置精灵移动速度参数szName:精灵名字参数fSpeed:移动速度参数fPolar:角度朝向*/externvoiddSetSpriteLinearVelocityPolar(constchar*szName,constfloatfSpeed,constfloatfPolar);/*dAnimateSpritePlayAnimation:动画精灵播放动画参数szName:精灵名字参数szAnim:动画名字参数iRestore:播放完毕后是否恢复当前动画.1恢复0不恢复返回值:是否播放成功,1:成功0:不成功*/externintdAnimateSpritePlayAnimation(constchar*szName,constchar*szAnimzconstintiRestore);/*dGetSpriteLinkPointPosX:获取精灵链接点X坐标。链接点是依附于精灵的一个坐标点,可以在编辑器里增加或者删除参数szName:精灵名字参数ild:链接点序号,第一个为1,后面依次递加*/externfloatdGetSpriteLinkPointPosX(constchar*szName,constintild);/*dGetSpriteLinkPointPosY:获取精灵链接点Y坐标。链接点是依附于精灵的一个坐标点,可以在编辑器里增加或者删除参数szName:精灵名字参数ild:链接点序号,第一个为1,后面依次递加*/externfloatdGetSpriteLinkPointPosY(constchar*szName,constintild);/*dDrawLine:在两点之间画一条线参数fStartX:起始坐标X参数fStartY:起始坐标Y参数fEndX:终点坐标X参数fEndY:终点坐标Y参数fLineWidth:线的粗细,大于等于1参数iLayer:该线所在的层,与编辑器里设置的精灵的层级是同一个概念。范围0-31。参数iRed,iGreen,iBIue:红绿蓝三原色的颜色值,范围0-255参数iAIpha:线的透明度,范围5255.0为全透明,255为不透明*/externvoiddDrawLine(constfloatfStartX,constfloatfStartY;constfloatfEndX,constfloatfEndYconstfloatfLineWidth,constintiLayer,constintiRed,constintiGreen,constintiBIue,constintiAIpha);Step3:思路阐述利用dSetSpriteLinearVelocityPolar即可实现钩子在某一角度放线,另外可以通过dAnimateSpritePlayAnimation来播放放线时矿工的动作,所以放线问题不大。但要注意三个问题:何时放线,放线的时候钩子停止旋转,在钩子和矿工之间画一条线表示绳索。下面来解决这三个问题:何时放线:我们不妨利用键盘上的方向键中的I来控制放线,在dOnKeyDown添加响应释放绳索的操作,这和海底世界中的WSAD控制鱼的方向原理类似;放线的时候钩子停止旋转:与海底世界中鼠标控制鱼游动一样,可以添加一个全局变量,当该变量为。时,钩子旋转当释放绳索时,置其为1,这样钩子就不会旋转了。绳索的展现:在step1中已经设置了链接点,其中矿工的。和钩子的0已经设置好,通过dGetSpriteLinkPointPosX和dGetSpriteLinkPointPosY获取这两个链接的位置,然后利用dDrawLine函数在两点之间画线即可。Step4:代码及注释首先定义钩子旋转的全局变量:intgiGameState=0;〃游戏状态,0表示钩子旋转,1表示释放绳索,后面还会定义其他状态在定义一个释放绳索速度的全局变量floatgfEmptyHookSpeed=15.f;在dOnKeyDown中添加响应I按键的代码:if(KEY_D0WN==iKey&&g_iGameState==0)〃按下I并且游戏状态为“1”giGameState=1; 「戊状态为1,1
//以当前朝向给钩子一个向前的速度dSetSpriteLinearVelocityPolar(*GoldHookz,,gfEmptyHookSpeed,gfHookRotation);//播放挖金者的动作(一个胳膊往下压的动作)dAnimateSpritePlayAnimation(*GoldMan^,*GolderManAnimationl*,0);//0表示播放一次,这里胳脚往下压就是一次在WinMain中,修改钩子摆动的代码,以控制摆动状态,即加入了if判断。gfHookRotationillookRotToLeftelsegfHookRotationfThisRotate;gfHookRotationfThisRotate;if(gfHookRotation<=0.f)g_fHookRotation0.g_fHookRotation0.f;iHookRotToLeft= 1;dSetSpriteRotationCyGoldllook'*,gfHookRotation);最后,还是在while循环中,添加画线连接的操作: //首先,从矿工精灵上获取一个缆绳链接点作为绳子的起始点(该链接点在编辑器里编辑好)floatfStartX=dGetSpriteLinkPointPosX("GoldMan”,I);floatfStartY=dGetSpriteLinkPointPosY(*GoldMan*,1);//绳子终点在钩子精灵上获取(该链接点在编辑器里编辑好)floatfEndX=dGetSpriteLinkPointPosXCGoldHook*,1);floatfEndY=dGetSpriteLinkPointPosY("GoldHook”,1);//在这两点之间划线.线的颜色红绿蓝值都为50,即灰色:255表示不透明,2.Of表示线的粗细,dDrawLine(fStartX,fStartY,fEndX,fEndY,2.f,0,50,50,50,255);编译运行,在适当的位置按I,可以发现钩子跟着绳索一起释放,如图:
练习:1.使钩子在抓到金块时以初始速度0.8倍的速度返回,碰到边界时则以两倍的速度返回。抓取金子学习目标学习应用dSetSpriteLinearVelocityPolar.dAnimateSpritePlayAnimation.dGetSpritePositionXdGetSpritePositionY函数学习strcpy函数有了前面的基础,我们可以顺利的释放绳索了,然而当钩子在碰到金块时会穿过去而不会将其抓住并拉回来。这节我们就来实现黄金矿工抓取金块并拖回的操作。Stepl:图片资源编辑点击地图上的钩子精灵,选择''编辑此精灵的链接点”,如图所示添加1链接点,保存即可。在WinMain的复制金子前给钩子加上发送碰撞属性:dSetSpriteCollisionSendCgoldHook'*,1);在WinMain的复制金子前给金块加上接受碰撞属性:dSetSpriteCollisionReceiveCgoldTemplate",1);注意:不要勾上接受物理碰撞与发送物理碰撞,否则funcode会自己处理碰撞Step2:Funcode接口介绍/*dOnSpriteColSprite:精灵与精灵碰撞后•将被调用的函数,可在此函数体里(Main.cpp)*增加自己的响应代码精灵之间要产生碰撞,必须在编辑器或者代码里设置精灵发送及接受碰撞参数szSrcName:发起碰撞的精灵名字参数szTarName:被碰撞的精灵名字7externvoiddOnSpriteColSprite(constchar*szSrcName,constchar*szTarName);/*dSpriteMountToSpriteLinkPoint:将一个精灵绑定到另一个精灵上,绑定位置为指定的链接点,暂时的成为另一个精灵的一部分,跟随其运动等参数szSrcName:要绑定的精灵名字参数szDstName:承载绑定的母体精灵名字参数iPointld:链接点序号返回值:返回一个绑定ID/externintdSpriteMountToSpriteLinkPoint(constchar*szSrcName,constchar*szDstName,constintiPointld);/*dGetSpritePositionX:获取精灵X坐标参数szName:精灵名字返回值:精灵的X坐标/externfloatdGetSpritePositionX(constchar*szName);/*dGetSpritePositionY:获取精灵Y坐标参数szName:精灵名字返回值:精灵的Y坐标7externfloat dGetSpritePositionY(constchar*szName);Step3:思路阐述钩子抓取金块实际上就是精灵与精灵碰撞的过程,所以应该在dOnSpriteColSprite中做文章。dOnSpriteColSprite中的szSrcName,szTarName可以判定碰撞的对象是否是金块和钩子。若是,则将金块绑定在钩子精灵上,利用dSpriteMountToSpriteLinkPoint函数,将金块锚定在前面设定的钩子精灵链接点“1”。继而就是把金块往回拉的过程,事先利用dGetSpritePositionX,dGetSpritePositionY获取钩子的起始位置并保存在全局变量中,之后利用dSpriteMoveTo移回初始位置。Step4:代码详解定义全局变量来存放钩子的初始位置floatgfHookStartPosX; .储钩子的初始\位'floatg_fHookstartPosY; 〃存储钩子的初始'charszGotGoldName[20]; ‘川『抓到金,在WinMain的初始化中,添加:gfHookStartPosX|dGetSpritePositionX(/zG()ldll()()k/,); 广的初始X坐标gfHookStartPosY=dGetSpritePositionY(*GoldHook^); )在dOnSpriteColSprite中添加处理金块与钩子碰撞的代码://发起者为GoldHook,接受者含有GoldBlock字段if(strcmp(szSrcName,*GoldHook*)==0&&strstr(szTarName,*GoldBlock*)!=NULL){dSpriteMountToSpriteLinkPoint(szTarName,"GoldHook”,2);dSpriteMoveTo(*GoldHook*,g_fHookStartPosX,g_fHookStartPosY,g_fEmptyHookSpeed,1);〃使钩子向初始位置移动,即会拉dAnimateSpritePlayAnimation(*GoldMan*,*GolderManAnimation3*,1); :U2.m strcpy(szGotGoldName,szTarName); h'h'i',;/ J,编译运行,在适当的位置按1,可以发现当钩子碰到金子后,可以拖着金子一起回拉,如图:
删除金子及边界处理学习目标学习应用dDeleteSprite,dSpriteDismount,dGetSpriteLinearVelocityX,dGetSpriteLinearVelocityY函数学会利用全局变量来分类控制游戏的运行状态学会判断精灵是否静止不动有了前面的基础,我们可以抓取金子并回拉到初始位置。然而当拉到初始处后金子依旧存在而且不能在继续抓取了,另外如果钩子没有碰到金块,那么钩子会不断往边界外面移动。这节我们就来实现抓取金子后删除,以及添加钩子的边界处理,来完成黄金矿工的最后一步。Stepls设置钩子与世界边界碰撞的模式为NULL在WinMain的初始化中初始化钩子与世界边界碰撞的模式为NULL,代码如下:dSetSpriteWorldLimitMode("goldHook",WORLD_LIMIT_NULL);Step2:Funcode接口介绍/*dDeleteSprite:在地图中删除一个精灵*参数szName:要删除的精灵名字*/externvoiddDeleteSprite(constchar*szName);/*dSpriteDismount:将已经绑定的精灵进行解绑参数szName:精灵名字1externvoiddSpriteDismount(constchar*szName);/*dGetSpriteLinearVelocityX:获取精灵X方向速度参数szName:精灵名字返回值:X方向速度/externfloatdGetSpriteLinearVelocityX(constchar*szName);/*dGetSpriteLinearVelocityY:获取精灵Y方向速度参数szName:精灵名字返回值:Y方向速度/externfloatdGetSpriteLinearVelocityY(constchar*szName);Step3:思路阐述同海底世界一样,我们在gJGameState中添加状态2,用于表示钩子的回拉状态。在回拉状态下,我们才会有删除金块的可能性。当金块拉回到初始位置时,我们删除金块,那么我们如何判断金块在初始位置呢?可以通过钩子的速度来实现。如果钩子的速度为0,说明钩子不再移动,即己经拉回到了初始位置,利用dGetSpriteLinearVelocityX,dGetSpriteLinearVelocityY来获取钩子速度进而进行判定。钩子的边界处理,我们让钩子在碰到世界边界时,向初始位置范围即可,只要在dOnSpriteColWorldLimit中利用dSpriteMoveTo即可。Step4:代码详解在dOnSpriteColSprite中处理金块与钩子碰撞的代码中添加:giGameState=2; 人,小即://发起者为GoldHook,接受者含有GoldBlock字段if(strcmp(szSrcName,*GoldHook*)==0&&strstr(szTarName,*GoldBlock*)!=NULL){〃将金块锚定在钩子上dSpriteMountToSpriteLinkPoint(szTarName,"GoldHook”,2);〃使钩子向初始位置移动,即回拉dSpriteMoveTo(*GoldHook*,gfHookStartPosX,gfHookStartPosY,gfEmptyHookSpeed,1);//播放拉金块的动作dAnimateSpriteP1ayAnimation(*GoldMan,*Go1derManAnimation3*,1);〃复制并保存当前抓取到金块的名称strcpy(szGotGoldName,szTarName);giGameState=2;在WinMain中添加的if(g_iGameState==0){floatfThisRotate=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(*Goldllook*,g_fHookRotation);)添加giGameState==2时的判定代码:elseif(g_iGameState=2)I float fSpeedX= dGetSpriteLinearVelocityX(*GoldHook*);〃获取钩子Y方向的速度float fSpeedY= dGetSpriteLinearVelocityY(*GoldHook*);〃当速度接近为。时,即可判定其已到达初始点if(fSpeedX<0.0000If&&fSpeedX>-0.00001f&&fSpeedY<0.0000If&&fSpeedY>-0.0000If)I〃解除金块与钩子的锚定dSpriteDismount(szGotGoldName);〃删除获取的金块dDeleteSprite(szGotGoldName);〃回拉结束,设定状态为0giGameState=0;〃播放矿工的动画,即准备拉金子的动画dAnimateSpritePlayAnimation("GoldMan","GolderManAnimation2”,0);最后我们添加边界处理的代码,在dOnSpriteColWorldLimit中:if(strcmp(szName,*GoldIlook*)==0)//碰到边界的为钩子时dSpriteMoveTo(szName,g_fHookStartPosX,gfHookStartPosY,gfEmptyHookSpeed,1);dAnimateSpritePlayAnimation(*GoldMan",*Go1derManAnimation3*,1);〃同样设置为回拉,只是没有碰到金子giGameState=2;编译运行,在适当的位置按I,可以发现当钩子碰到金子后,可以拖着金子一起回拉,来到初始点可以删除金块,另外碰到边界钩子会原速返回,部分效果如图:至此黄金矿工的任务完成,我们可以运行游戏,自己玩一遍黄金矿工了。实验:拍飞虫完成本实验后,可以实现拍打飞虫并计分的效果,如下所示:
移动拍子并拍打学习目标学习应用dShowCursor,dSetSpriteRotation,dOnMouseClick学会利用屏幕刷新时间EmeDelta实现拍打动作这节我们实现拍飞虫游戏的图片导入以及移动拍子的任务;Stepl:图片资源导入新建一个新的项目,取名为KilllnsectsDemo。添加资源到环境中,添加完成后的资源如图所示:V静态精灵(Sprites)►j《(Sprites)▼浪功图并按如卜.所示布置图片位置:
给拍子取名为paizi,并在拍子的基本属性中“朝向”属性设置为-40,效果如上图:将背景图片的层数设为10,如卜图:层QB0思考:层数有什么作用Step2:Funcode接口介绍本实验用到的API/*dSetSpriteRotation:设置精灵的旋转角度参数szName:精灵名字参数fRot:旋转角度,范围0-3607externvoiddSetSpriteRotation(constchar*szName,constfloatfRot);/*dShowCursor:隐藏/显示鼠标。此API只是隐藏本程序窗口内的鼠标,移动到窗口外的*时候,鼠标还是会显示参数iShow:1为显示,0为隐藏externvoiddShowCursor(constintiShow)/*dOnMouseClick:鼠标按下后将被调用的函数,可在此函数体里(Main.cpp)增加自一的响应代码参数iMouseType:鼠标按键值,见enumMouseTypes定义参数fMouseX,fMouseY:为鼠标当前坐标*/externvoiddOnMouseClick(constintiMouseType,constfloatfMouseX,constfloatfMouseY);//鼠标按键值定义enumMouseTypes(MOUSE_LEFT = 0, //左键MOUSE_RIGHT = 1, //右键MOUSE_MIDDLE = 2 〃中键};Step3:思路阐述拍子的移动应该同鼠标的移动一致,有了前面的基础,相信同学们应该很清楚了,应该在dOnMouseMove中做文章。在该函数中,我们利用dShowCursor来隐藏鼠标显示,然后通过dSetSpriteRotation来设置拍子的坐标即为鼠标坐标即可实现拍子跟着鼠标走。拍打动作是在点击鼠标左键时实现的,不难发现,funcode中的捕捉鼠标按键的接口是dOnMouseClicko在该函数中,我们使之在点击左键时给拍子一个旋转角度,然后经过一段小的时间后(比如0.2s)使拍子在恢复原先角度,这样即可实现拍子的拍打了,设置角度可以利用dSetSpriteRotation来实现。Step4:代码详解定义全局变量float gfRotateTime=0.f;//拍上拍F后距离复位还差多少时间float gf01dRotation =0.f; //拍子的初始角度首先实现,拍子随着鼠标的移动而移动;先隐藏鼠标,在WinMain的初始化部分,加入:dShowCursor(false); //在窗口内陷藏鼠标然后在dOnMouseMove添加dSetSpritePosition("paizi”,fMouseX,fMouseY); '使拍子的位置.和制标一致然后实现拍子的拍打动作,先在WinMain的初始化部分加入gfOldRotation=dGetSpriteRotation("paizi"); 「/获取拍子的初始旋转珀在dOnMouseClick中添加如下代码:if(iMouseType=MOUSE_LEFT)//鼠标左键按b'〃设置拍子的旋转角,为初始值TOdSetSpriteRotation(*paizigfOldRotation-10);〃拍打的时间间隔0.2s,即0.2s后恢复拍子初始角度gfRotateTime=0.2f;
因为拍子拍打在游戏过程中是一直重复执行的,所以在WinMain的while循环中加入:if(g_fRotateTime>0)〃每经过fTimeDelta,拍子旋转的时间也少ffTimeDeltagfRotateTime-=fTimeDelta;if(g_fRotateTime<=0)I 〃经过了0.2s以后,恢复拍子的初始旋转角dSetSpriteRotation(^paizi*,gfOldRotation);}I编译运行即可看到每点一下帕子就有一定角度的旋转。练习:.自定义拍子的拍打时间和拍打旋转角度空格开始与倒计时学习目标学习应用dSetTextValue.dSetSpriteVisible利用g_iGameState来控制复杂的游戏过程这节我们实现点击空格开始游戏以及开始游戏后5s的倒计时功能Stepl:图片资源导入将空格开始拖入屏幕中央,并取名为“kaishi”。点击 按钮,然后点击屏幕中央,输入5,接着可以在后期颜色处理中选择自己喜欢的颜色来显示文字,并将该精灵的名字设置为"countdown”如图:../11前色处,”(3开启源混自因子 SRC.ALPHA 二|小:"工「JrONE_MINUS_SRC_ALPHA*|后期颜色处理0118011831255GreenBlueAlpha
完成后的效果如图所示:Step2:Funcode接口介绍/*dSetTextValue:文字精灵显示某个数值参数szName:精灵名字参数iValue:要显示的数值VexternvoiddSetTextValue(constchar*szName,intiValue);/♦dSetSpriteVisible:设置精灵隐藏或者显示(可见不可见)参数szName:精灵名字参数iVisible:1可见0不可见VexternvoiddSetSpriteVisible(constchar*szName,constintiVisible);Step3:思路阐述实现的效果为:空格按下,游戏开始,跳出倒计时文字框,并进行倒计时(此时拍子无法移动),当倒计时为。时,倒计时文字框消失,拍子可以移动,且可以拍打。从上面的描述中,细心的同学已经发现,需要设置g_iGameState来控制游戏的状态,而且游戏的状态,应该有3个,不妨设:0表示按空格前,1表示按下空格的倒计时阶段,2表示倒计时结束可以移动拍子的阶段。0->1的切换:按下空格是0到1切换的标志。空格按钮可以利用dOnKeyDown来捕捉,此时置gJGameState为1,并且利用dSetSpriteVisible显示倒计时文字框,同时隐藏“空格开始”;1阶段:显示倒计时后,利用fTimeDelta来统计经过的时间,并且在倒计时框中实时显示,直到它为0;192切换:当倒计时为0后,隐藏倒计时文字框,并置gJGameState为2,表示拍子可以移动;增力口dOnMouseClick和dOnMouseMove的判定条件,使他们只在gJGameState为2的时候才可以工作;Step4:代码及注释定义全局变量intgiGameState=0;〃游戏状态,0表示未开始(此时拍子不随鼠标移动),1表〃示倒计时阶段,2表示开始拍子可以随鼠标移动并拍打因为在游戏开始时我们希望将拍子停放在屏幕中央,即下图中的位置:所以定义全局变量floatgfPosX=0.f;〃拍子初始X坐标floatg_fPosY=0.f;〃拍子初始Y坐标首先,在WinMain中继续添加初始化代码:〃获取拍子的初始位置坐标
gfPosX=dGetSpritePositionX(*paizi*);g_fPosY=dGetSpritePositionYCpaizi");入窗和1阚intcountdown=5;〃倒计时经过的时间floatcountPassedTime=0.f;〃设置倒计时不可见,该cutdown即为dSetSpriteVisible(*countdown*,false);初始化工作完成后,我们先来完成空格开始的操作,即0今1的切换:在dOnKeyDown中添加if(KEYSPACE=iKey&&0=giGameState)〃按下空格IL游戏状态为0时giGameState= 1;〃设置游戏状态,即0今1dSetSpriteVisible("countdown”,true);〃显示倒计时文本框dDeleteSprite("kaishi");//删除“空格开始”一拍「拍到开始键也会使分数增加,为编译运行,可以看•到,按下空格后,浮现倒计时文本框,此时文本框并不倒计时,而且拍子是可以移动和击打的;虽然还没有完全实现我们所要的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版酒店客房托管经营服务合同书3篇
- 二零二五年度房产买卖及配套设施改造服务合同3篇
- 二零二五年度建筑陶瓷材料采购与质量控制合同2篇
- 2025版高考政治二轮复习专题7民族和主权国家1热题快练含解析
- 《小儿川崎病》课件
- 思考照亮未来青春梦想起航
- 《公共部门的战略》课件
- 分级护理质量追踪与持续改进
- 二零二五年度教育培训机构销售代理合同范本6篇
- 2025年度网络安全培训与咨询服务合同书及责任声明
- 江西省2023-2024学年高二上学期期末教学检测数学试题 附答案
- 碳汇计量与监测技术智慧树知到期末考试答案章节答案2024年浙江农林大学
- 可用性控制程序
- GB/T 17554.1-2006识别卡测试方法第1部分:一般特性测试
- 消防安全风险辨识清单
- 无损检测-渗透检测(导学)
- 2022一、二级个人防护(穿脱防护服)操作评分表(精华版)
- 广东省中医院进修申请表
- 竣工之风量平衡测试报告air distribution balance report
- 贝利婴幼儿发展量表(BSID)
- 说明书hid500系列变频调速器使用说明书s1.1(1)
评论
0/150
提交评论