【四圣龙神录的编程教室】第18章、给自机的子弹加上碰撞检测吧
2014-03-15 14:17
316 查看
原文地址:
http://dixq.net/rp/18.html
这次的内容是碰撞检测相关的方面。
做过STG的人的话,可能会说“用勾股定理就轻松搞定了啦”这样的观点。
但当子弹的射速比较快的时候,只用那个就可能不行了。
如果对和碰撞检测相关的用勾股定理判定的方法不太清楚的话,
到游戏编程馆里的第s11章去看一下先吧。 看这里
假设碰撞检测的有效范围是10,子弹的速度是100的话,会怎么样呢?
子弹每次会移动100的距离,但碰撞检测只能对那10 的范围进行检测,
也就是说,子弹在高速移动的话,会有检测不到的地方。
因此,有可能发生敌人直接穿过自机的子弹的情况。
为了避免这样的情况,要对自机子弹通过的地方,一点一点的进行检查,必须要保证没有遗漏的地方。
那么,啰嗦了这么多,我们就按如下步骤进行实现吧。
在out_judge_cshot 函数里,把传进来的 i 号的自机子弹, 和 s 号的敌机进行碰撞检测,
>if(cshot[i].cnt>0){
也就是说,一旦计算了子弹的轨道,要回到一帧以前的位置开始,
一点一点的让子弹飞向现在的位置,同时判断子弹和敌机是否发生碰撞,这样对每一部都进行检测才行。
实现过程如下。(睡觉先,2:39了)
————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————
在out_main 函数里,对所有的自机子弹,和所有的敌机判断是否发生碰撞。
相应的,还要做以下的改动。
——————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————
最后加上去的 music_play 函数的
if(i==8)continue;
这么写是不是有什么原因呢,敌人被击中时发出的8号音效,
如果他已经在播放的话,就停止让他从头播放,就能听到扑扑扑的声音。
也就是说,一定要让他放完之后,重头再开始播放。
这次,因为只有8号音效需要这样,所以我们就先改成这样。
Excel 文件作适当的变更。
执行结果
http://dixq.net/rp/swf/18.swf
原文地址:
http://dixq.net/rp/18.html
这次的内容是碰撞检测相关的方面。
做过STG的人的话,可能会说“用勾股定理就轻松搞定了啦”这样的观点。
但当子弹的射速比较快的时候,只用那个就可能不行了。
如果对和碰撞检测相关的用勾股定理判定的方法不太清楚的话,
到游戏编程馆里的第s11章去看一下先吧。 看这里
假设碰撞检测的有效范围是10,子弹的速度是100的话,会怎么样呢?
子弹每次会移动100的距离,但碰撞检测只能对那10 的范围进行检测,
也就是说,子弹在高速移动的话,会有检测不到的地方。
因此,有可能发生敌人直接穿过自机的子弹的情况。
为了避免这样的情况,要对自机子弹通过的地方,一点一点的进行检查,必须要保证没有遗漏的地方。
那么,啰嗦了这么多,我们就按如下步骤进行实现吧。
在out_judge_cshot 函数里,把传进来的 i 号的自机子弹, 和 s 号的敌机进行碰撞检测,
>if(cshot[i].cnt>0){
也就是说,一旦计算了子弹的轨道,要回到一帧以前的位置开始,
一点一点的让子弹飞向现在的位置,同时判断子弹和敌机是否发生碰撞,这样对每一部都进行检测才行。
实现过程如下。(睡觉先,2:39了)
————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————
在out_main 函数里,对所有的自机子弹,和所有的敌机判断是否发生碰撞。
相应的,还要做以下的改动。
——————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————
最后加上去的 music_play 函数的
if(i==8)continue;
这么写是不是有什么原因呢,敌人被击中时发出的8号音效,
如果他已经在播放的话,就停止让他从头播放,就能听到扑扑扑的声音。
也就是说,一定要让他放完之后,重头再开始播放。
这次,因为只有8号音效需要这样,所以我们就先改成这样。
Excel 文件作适当的变更。
执行结果
http://dixq.net/rp/swf/18.swf
本人CSDN博客目录:
http://blog.csdn.net/tidus5
擦,你妹的CSDN,要我输验证码,我输半天,半个字都没错,就是不让我过。就让我输一些很2 的算式,
你这验证码系统有问题是吧!!!
打了一局游戏,本来想发到其他坛子,对CSDN太失望了。回来一想,这是要我输个数字?
然后输入了个数字,竟然行了。。。
你妹的这验证码
http://dixq.net/rp/18.html
这次的内容是碰撞检测相关的方面。
做过STG的人的话,可能会说“用勾股定理就轻松搞定了啦”这样的观点。
但当子弹的射速比较快的时候,只用那个就可能不行了。
如果对和碰撞检测相关的用勾股定理判定的方法不太清楚的话,
到游戏编程馆里的第s11章去看一下先吧。 看这里
假设碰撞检测的有效范围是10,子弹的速度是100的话,会怎么样呢?
子弹每次会移动100的距离,但碰撞检测只能对那10 的范围进行检测,
也就是说,子弹在高速移动的话,会有检测不到的地方。
因此,有可能发生敌人直接穿过自机的子弹的情况。
为了避免这样的情况,要对自机子弹通过的地方,一点一点的进行检查,必须要保证没有遗漏的地方。
那么,啰嗦了这么多,我们就按如下步骤进行实现吧。
在out_judge_cshot 函数里,把传进来的 i 号的自机子弹, 和 s 号的敌机进行碰撞检测,
>if(cshot[i].cnt>0){
也就是说,一旦计算了子弹的轨道,要回到一帧以前的位置开始,
一点一点的让子弹飞向现在的位置,同时判断子弹和敌机是否发生碰撞,这样对每一部都进行检测才行。
实现过程如下。(睡觉先,2:39了)
————————————————————————————————————————————————————————————————————————
---- out.cpp を変更 ---- #include "../include/GV.h" #define ENEMY_RANGE_MAX 4 #define CSHOT_RANGE_MAX 2 //敌机的碰撞检测范围 int enemy_range[ENEMY_RANGE_MAX]={16,30,16,50}; //自机的子弹的碰撞检测范围 int cshot_range[CSHOT_RANGE_MAX]={6,}; //判断是否发生碰撞 int out_judge_cshot(int i,int s){ int j; if(cshot[i].cnt>0){//每一帧都对子弹的轨道进行计算 double x=cshot[i].x-enemy[s].x;//敌机和自机子弹的距离 double y=cshot[i].y-enemy[s].y; //超界的判断 if(cshot[i].knd>=CSHOT_RANGE_MAX || enemy[s].knd>=ENEMY_RANGE_MAX) printfDx("out_judge_cshot内オーバーフロー"); //敌机的判定和自己子弹判定的加起来的范围 double r=cshot_range[cshot[i].knd]+enemy_range[enemy[s].knd]; //如果需要中间计算 if(cshot[i].spd>r){ //保存下前一帧所在的位置 double pre_x=cshot[i].x+cos(cshot[i].angle+PI)*cshot[i].spd; double pre_y=cshot[i].y+sin(cshot[i].angle+PI)*cshot[i].spd; double px,py; for(j=0;j<cshot[i].spd/r;j++){//前进的部分除以碰撞判定的部分,循环这么多次 px=pre_x-enemy[s].x; py=pre_y-enemy[s].y; if(px*px+py*py<r*r) return 1; pre_x+=cos(cshot[i].angle)*r; pre_y+=sin(cshot[i].angle)*r; } } if(x*x+y*y<r*r)//检测在碰撞内的话 return 1;//碰撞 } return 0; } //判断敌机是否死亡 void enemy_death_judge(int s){ int i; se_flag[8]=1;//敌机被打中的音效 if(enemy[s].hp<0){//敌机的血量小于0的话 enemy[s].flag=0;//让敌机消失 se_flag[1]=1;//敌机的 BIU 的音效 for(i=0;i<SHOT_MAX;i++){//遍历所有的弹幕 if(shot[i].flag!=0){//如果有注册了的弹幕数据 if(s==shot[i].num){//如果这个弹幕是这个敌机发出来的 shot[i].flag=2;//设置标记,让这个弹幕不再持续了 break; } } } } } //碰撞检测,主函数 void out_main(){ int i,s; for(i=0;i<CSHOT_MAX;i++){//自机的子弹总数 if(cshot[i].flag>0){ for(s=0;s<ENEMY_MAX;s++){//敌机总数 if(enemy[s].flag>0){ if(out_judge_cshot(i,s)){//自机子弹和敌机碰撞的话 cshot[i].flag=0;//让那个自机的子弹消失 enemy[s].hp-=cshot[i].power;//根据子弹的威力,减去对应的敌机HP enemy_death_judge(s);//判断敌机是否死亡 } } } } } }
——————————————————————————————————————————————————————————————————————————
在out_main 函数里,对所有的自机子弹,和所有的敌机判断是否发生碰撞。
相应的,还要做以下的改动。
——————————————————————————————————————————————————————————————————————————
---- main.cpp 做如下改动 ---- case 100://通常处理 calc_ch(); //自机的处理 ch_move(); //自机的移动操作 cshot_main();//自机的射击主函数 enemy_main();//敌机的处理的主函数 shot_main(); //射击的主函数 out_main(); //碰撞检测 graph_main();//绘画的主函数 stage_count++; break; ---- function.h 里做如下改动 ---- //out.cpp GLOBAL void out_main(); ---- load.cpp 的 load函数加上下面这些 ---- sound_se[1]=LoadSoundMem("dat/se/enemy_death.wav"); sound_se[2]=LoadSoundMem("dat/se/cshot.wav"); sound_se[8]=LoadSoundMem("dat/se/hit.wav"); ChangeVolumeSoundMem( 50, sound_se[0] ) ;//设定各个素材的回放音量 ChangeVolumeSoundMem(128, sound_se[1] ) ; ChangeVolumeSoundMem(128, sound_se[2] ) ; ChangeVolumeSoundMem( 80, sound_se[8] ) ; ---- music.cpp 的 music_play改成如下这样 ---- void music_play(){ int i; for(i=0;i<SE_MAX;i++){ if(se_flag[i]==1){ if(CheckSoundMem(sound_se[i])!=0){ if(i==8)continue; StopSoundMem(sound_se[i]); } PlaySoundMem(sound_se[i],DX_PLAYTYPE_BACK); } } }
——————————————————————————————————————————————————————————————————————————
最后加上去的 music_play 函数的
if(i==8)continue;
这么写是不是有什么原因呢,敌人被击中时发出的8号音效,
如果他已经在播放的话,就停止让他从头播放,就能听到扑扑扑的声音。
也就是说,一定要让他放完之后,重头再开始播放。
这次,因为只有8号音效需要这样,所以我们就先改成这样。
Excel 文件作适当的变更。
执行结果
http://dixq.net/rp/swf/18.swf
原文地址:
http://dixq.net/rp/18.html
这次的内容是碰撞检测相关的方面。
做过STG的人的话,可能会说“用勾股定理就轻松搞定了啦”这样的观点。
但当子弹的射速比较快的时候,只用那个就可能不行了。
如果对和碰撞检测相关的用勾股定理判定的方法不太清楚的话,
到游戏编程馆里的第s11章去看一下先吧。 看这里
假设碰撞检测的有效范围是10,子弹的速度是100的话,会怎么样呢?
子弹每次会移动100的距离,但碰撞检测只能对那10 的范围进行检测,
也就是说,子弹在高速移动的话,会有检测不到的地方。
因此,有可能发生敌人直接穿过自机的子弹的情况。
为了避免这样的情况,要对自机子弹通过的地方,一点一点的进行检查,必须要保证没有遗漏的地方。
那么,啰嗦了这么多,我们就按如下步骤进行实现吧。
在out_judge_cshot 函数里,把传进来的 i 号的自机子弹, 和 s 号的敌机进行碰撞检测,
>if(cshot[i].cnt>0){
也就是说,一旦计算了子弹的轨道,要回到一帧以前的位置开始,
一点一点的让子弹飞向现在的位置,同时判断子弹和敌机是否发生碰撞,这样对每一部都进行检测才行。
实现过程如下。(睡觉先,2:39了)
————————————————————————————————————————————————————————————————————————
---- out.cpp を変更 ---- #include "../include/GV.h" #define ENEMY_RANGE_MAX 4 #define CSHOT_RANGE_MAX 2 //敌机的碰撞检测范围 int enemy_range[ENEMY_RANGE_MAX]={16,30,16,50}; //自机的子弹的碰撞检测范围 int cshot_range[CSHOT_RANGE_MAX]={6,}; //判断是否发生碰撞 int out_judge_cshot(int i,int s){ int j; if(cshot[i].cnt>0){//每一帧都对子弹的轨道进行计算 double x=cshot[i].x-enemy[s].x;//敌机和自机子弹的距离 double y=cshot[i].y-enemy[s].y; //超界的判断 if(cshot[i].knd>=CSHOT_RANGE_MAX || enemy[s].knd>=ENEMY_RANGE_MAX) printfDx("out_judge_cshot内オーバーフロー"); //敌机的判定和自己子弹判定的加起来的范围 double r=cshot_range[cshot[i].knd]+enemy_range[enemy[s].knd]; //如果需要中间计算 if(cshot[i].spd>r){ //保存下前一帧所在的位置 double pre_x=cshot[i].x+cos(cshot[i].angle+PI)*cshot[i].spd; double pre_y=cshot[i].y+sin(cshot[i].angle+PI)*cshot[i].spd; double px,py; for(j=0;j<cshot[i].spd/r;j++){//前进的部分除以碰撞判定的部分,循环这么多次 px=pre_x-enemy[s].x; py=pre_y-enemy[s].y; if(px*px+py*py<r*r) return 1; pre_x+=cos(cshot[i].angle)*r; pre_y+=sin(cshot[i].angle)*r; } } if(x*x+y*y<r*r)//检测在碰撞内的话 return 1;//碰撞 } return 0; } //判断敌机是否死亡 void enemy_death_judge(int s){ int i; se_flag[8]=1;//敌机被打中的音效 if(enemy[s].hp<0){//敌机的血量小于0的话 enemy[s].flag=0;//让敌机消失 se_flag[1]=1;//敌机的 BIU 的音效 for(i=0;i<SHOT_MAX;i++){//遍历所有的弹幕 if(shot[i].flag!=0){//如果有注册了的弹幕数据 if(s==shot[i].num){//如果这个弹幕是这个敌机发出来的 shot[i].flag=2;//设置标记,让这个弹幕不再持续了 break; } } } } } //碰撞检测,主函数 void out_main(){ int i,s; for(i=0;i<CSHOT_MAX;i++){//自机的子弹总数 if(cshot[i].flag>0){ for(s=0;s<ENEMY_MAX;s++){//敌机总数 if(enemy[s].flag>0){ if(out_judge_cshot(i,s)){//自机子弹和敌机碰撞的话 cshot[i].flag=0;//让那个自机的子弹消失 enemy[s].hp-=cshot[i].power;//根据子弹的威力,减去对应的敌机HP enemy_death_judge(s);//判断敌机是否死亡 } } } } } }
——————————————————————————————————————————————————————————————————————————
在out_main 函数里,对所有的自机子弹,和所有的敌机判断是否发生碰撞。
相应的,还要做以下的改动。
——————————————————————————————————————————————————————————————————————————
---- main.cpp 做如下改动 ---- case 100://通常处理 calc_ch(); //自机的处理 ch_move(); //自机的移动操作 cshot_main();//自机的射击主函数 enemy_main();//敌机的处理的主函数 shot_main(); //射击的主函数 out_main(); //碰撞检测 graph_main();//绘画的主函数 stage_count++; break; ---- function.h 里做如下改动 ---- //out.cpp GLOBAL void out_main(); ---- load.cpp 的 load函数加上下面这些 ---- sound_se[1]=LoadSoundMem("dat/se/enemy_death.wav"); sound_se[2]=LoadSoundMem("dat/se/cshot.wav"); sound_se[8]=LoadSoundMem("dat/se/hit.wav"); ChangeVolumeSoundMem( 50, sound_se[0] ) ;//设定各个素材的回放音量 ChangeVolumeSoundMem(128, sound_se[1] ) ; ChangeVolumeSoundMem(128, sound_se[2] ) ; ChangeVolumeSoundMem( 80, sound_se[8] ) ; ---- music.cpp 的 music_play改成如下这样 ---- void music_play(){ int i; for(i=0;i<SE_MAX;i++){ if(se_flag[i]==1){ if(CheckSoundMem(sound_se[i])!=0){ if(i==8)continue; StopSoundMem(sound_se[i]); } PlaySoundMem(sound_se[i],DX_PLAYTYPE_BACK); } } }
——————————————————————————————————————————————————————————————————————————
最后加上去的 music_play 函数的
if(i==8)continue;
这么写是不是有什么原因呢,敌人被击中时发出的8号音效,
如果他已经在播放的话,就停止让他从头播放,就能听到扑扑扑的声音。
也就是说,一定要让他放完之后,重头再开始播放。
这次,因为只有8号音效需要这样,所以我们就先改成这样。
Excel 文件作适当的变更。
执行结果
http://dixq.net/rp/swf/18.swf
本人CSDN博客目录:
http://blog.csdn.net/tidus5
擦,你妹的CSDN,要我输验证码,我输半天,半个字都没错,就是不让我过。就让我输一些很2 的算式,
你这验证码系统有问题是吧!!!
打了一局游戏,本来想发到其他坛子,对CSDN太失望了。回来一想,这是要我输个数字?
然后输入了个数字,竟然行了。。。
你妹的这验证码
相关文章推荐
- 【四圣龙神录的编程教室】第21章、给自机加上碰撞检测和无敌效果吧
- 【四圣龙神录的编程教室】第13章、给敌人加上射击功能吧
- 【四圣龙神录的编程教室】第4章、画个自机形象看看吧
- 【四圣龙神录的编程教室】第17章、让自机可以发射子弹吧
- 【四圣龙神录的编程教室】第19章、给敌机加上消灭特效吧
- 【四圣龙神录的编程教室】第3章、使用全局变量看看吧
- 【四圣龙神录的编程教室】第5章、研究下声明的方法吧
- 【四圣龙神录的编程教室】第0章 开始
- 【四圣龙神录的编程教室】第8章、把按键的对应设置一下吧
- 【四圣龙神录的编程教室】第23章、来制作决死炸弹吧
- 【四圣龙神录的编程教室】——使用规则
- 【四圣龙神录的编程教室】第9章、试试操作人物的移动吧
- 【四圣龙神录的编程教室】第10章、把敌人表示出来看看吧
- 【四圣龙神录的编程教室】第15章、来制作凹梦的弹幕吧
- 【四圣龙神录的编程教室】第1章、准备项目的素材
- 【四圣龙神录的编程教室】第24章、来制作boss吧
- 【四圣龙神录的编程教室】第20章、我们来绘制背景吧
- 【四圣龙神录的编程教室】第7章、把面板表示出来吧
- 【四圣龙神录的编程教室】第2章、首先运行下看看吧
- 【四圣龙神录的编程教室】第11章、用Excel制作敌人的登场数据吧