原文地址:
咦,标题有点奇怪?别在意这些细节。
那么,基本的弹幕制作方法都已经明白了,我们试着做一些稍微复杂点的弹幕吧。
虽然这么说,但一下子就弄很难的弹幕会很难理解,还是从简单点的开始吧。
这回,首先看一下最终的执行效果。
运行结果:
严格的来说,这个和妖梦的弹幕稍微有点不一样。如果要弄的完全一样的话计算方式会变得很复杂,我们就简化一下吧。
要怎么样才能发射出这样的弹幕呢?
发射地点是绕着敌人为中心的圆形旋转移动的,是吧?
是从下往上的半圈呢。
这是从敌人开始的位置当做 PI/2 的位置的话,从 PI/2 + PI 和 PI/2 -PI的方向旋转的,是吧?
这次,在150帧里面发射15次弹幕来看看效果吧。
——————————————————————————————————————————————————————————————————
//---- shotH.cpp添加如下代码 ----
//凹梦的弹幕
void shot_bullet_H007(int n){
int t=shot[n].cnt;
int k;
if(t>=0 && t<=150 && t%10==0){
for(int i=0;i<20;i++){
if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
shot[n].bullet[k].knd =7;
shot[n].bullet[k].angle =PI2/20*i;
shot[n].bullet[k].flag =1;
shot[n].bullet[k].x =enemy[shot[n].num].x+cos(PI/2+PI/150*t)*100;
shot[n].bullet[k].y =enemy[shot[n].num].y+sin(PI/2+PI/150*t)*100;
shot[n].bullet[k].col =2;
shot[n].bullet[k].cnt =0;
shot[n].bullet[k].spd =1.2;
}
}
for(int i=0;i<20;i++){
if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
shot[n].bullet[k].knd =7;
shot[n].bullet[k].angle =PI2/20*i;
shot[n].bullet[k].flag =1;
shot[n].bullet[k].x =enemy[shot[n].num].x+cos(PI/2-PI/150*t)*100;
shot[n].bullet[k].y =enemy[shot[n].num].y+sin(PI/2-PI/150*t)*100;
shot[n].bullet[k].col =4;
shot[n].bullet[k].cnt =0;
shot[n].bullet[k].spd =1.2;
se_flag[0]=1;
}
}
}
}
——————————————————————————————————————————————————————————————————
cos(PI/2+PI/150*t)*100;
在这个表达式里,cos 是算出把x 方向的分量,转化为 0 到1 之间,然后乘以圆的半径100。
如果要调整圆的大小的话,修改这个100 就行了。
然后,后面每一章都要修改声明定义弹幕的函数的话很麻烦,我们预先声明18个弹幕模式好了。
——————————————————————————————————————————————————————————————
//---- shotH.cpp里添加如下代码 ----
void shot_bullet_H008(int n){}
void shot_bullet_H009(int n){}
void shot_bullet_H010(int n){}
void shot_bullet_H011(int n){}
void shot_bullet_H012(int n){}
void shot_bullet_H013(int n){}
void shot_bullet_H014(int n){}
void shot_bullet_H015(int n){}
void shot_bullet_H016(int n){}
void shot_bullet_H017(int n){}
//---- shot.cpp 里随便找个地方添加如下代码 ----
extern void shot_bullet_H000(int);extern void shot_bullet_H001(int);extern void shot_bullet_H002(int);
extern void shot_bullet_H003(int);extern void shot_bullet_H004(int);extern void shot_bullet_H005(int);
extern void shot_bullet_H006(int);extern void shot_bullet_H007(int);extern void shot_bullet_H008(int);
extern void shot_bullet_H009(int);extern void shot_bullet_H010(int);extern void shot_bullet_H011(int);
extern void shot_bullet_H012(int);extern void shot_bullet_H013(int);extern void shot_bullet_H014(int);
extern void shot_bullet_H015(int);extern void shot_bullet_H016(int);extern void shot_bullet_H017(int);
void (*shot_bullet[SHOT_KND_MAX])(int) ={
shot_bullet_H000,shot_bullet_H001,shot_bullet_H002,shot_bullet_H003,shot_bullet_H004,
shot_bullet_H005,shot_bullet_H006,shot_bullet_H007,shot_bullet_H008,shot_bullet_H009,
shot_bullet_H010,shot_bullet_H011,shot_bullet_H012,shot_bullet_H013,shot_bullet_H014,
shot_bullet_H015,shot_bullet_H016,shot_bullet_H017,
};
//---- define.h 的定义改成这样 ----
#define SHOT_KND_MAX 18
——————————————————————————————————————————————————————————————
下面是Excel 文档的改动。
以后弹幕的编号改动了的话,只需要改【弹幕种类】,一点一点增加就行了。
/帧数 | 移动模式 | 敌人种类 | x坐标 | y坐标 | 速度 | 发射时间 | 弹幕种类 | 弹幕颜色 | 体力 | 子弹种类 | 待机时间 | 道具1 | 2 | 3 | 4 | 5 | 6 |
/cnt | pattern | knd | x | y | sp | bltime | blknd | col | hp | blknd2 | wait | item_n | |||||
60 | 9 | 0 | 200 | 150 | 0 | 60 | 7 | 0 | 100 | 0 | 200 | 0 | -1 | -1 | -1 | -1 | -1 |
Excel文档下载 |
(PS: 2014年3月7日笔记:
昨晚写完后,本来想给弹幕写个人的注释,发现到后面还是没理解,于是作罢。睡觉前终于想清楚了.
enemy[shot[n].num].x+cos(PI/2-PI/150*t)*100;
enemy[shot[n].num].y+sin(PI/2-PI/150*t)*100;
这两句,是根据 t 的变化,让发射的起始点顺着以敌机为圆心,100为半径的圆周移动的。
当 t =0 的时候,很容易分析出,x 不变,y +100 。 可是实际调试的时候发现,t 改为0,发射点就在敌机下方。y 不是加100么,怎么在下方的呢?
然后突然想到了,恍然大悟,在这里窗口的y 轴是向下的,这也就很好的解释了里面说的 从 PI/2 到 PI/2 +PI 和 从PI/2 到 PI/2-PI 这两个方向了。
PI/2 就是向下的方向,因为y轴向下,x轴向右,这里算角度是从x轴往下,顺时针计算的。
其他就没什么了,每次发射的,不过是20颗等分圆的圆形弹幕而已)
本人CSDN博客目录: