先前在网上看了一个老外用递归的方式实现一个非常棒的闪电路径模拟算法,就直接拿来用到游戏中
有位网友也进行了分析,并在cocos2d-x上进行了模拟,链接如下
http://cocos2d.9tech.cn/news/2014/0210/39791.html
在原文中,闪电是有两点进行中点位移的,这样产生的闪电的所有起点和终点都是固定,显然不符合现实的,所以改成每次绘制时都是随机产生两点,再进行中点位移
void Lightning::drawLightning(float x1, float y1, float x2, float y2, float displace) {
_curDetail = CCRANDOM_0_1() * 5;
if (displace < _curDetail) {//当位移值小于预定义的一个值时画出,递归结束,出栈画线。可以看到这里的_curDetail与displace越接近,递归的次数越少,画出的先越直
ccDrawLine(ccp(x1, y1), ccp(x2, y2));
}else {
//两点之间的中点
float mid_x = (x2 + x1) / 2;
float mid_y = (y2 + y1) / 2;
//用一个随机值代替中点,产生一个不规则线段碎形
mid_x += (CCRANDOM_0_1() - 0.5) * displace;
mid_y += (CCRANDOM_0_1() - 0.5) * displace;
//位移值不断减少一半
drawLightning(x1, y1, mid_x, mid_y, displace / 2);
drawLightning(x2, y2, mid_x, mid_y, displace / 2);
}
}
void Lightning::draw() {
ccDrawColor4B(200, 200, 200, 255);//线的颜色
glLineWidth(1);//线的宽度(粗度)
//确定一个产生闪电的矩形
_x1 = CCRANDOM_0_1() * (_width * 0.6);
_y1 = CCRANDOM_0_1() * (_height * 0.6);
_x2 = CCRANDOM_0_1() * (_width * 0.8);
_y2 = CCRANDOM_0_1() * (_height * 0.8);
//随机获取一个位移量
float d = CCRANDOM_0_1() * 50;
d = d < 30 ? 30 : d;
//开始递归
drawLightning(_x1, _y1, _x2, _y2, d);
}