Does anybody have some ideas on how I could create some sort of algorithm that can draw a lightning type effect between one point and another?
Printable View
Does anybody have some ideas on how I could create some sort of algorithm that can draw a lightning type effect between one point and another?
I am not sure if Grant gives any source for his lightning effect, but you may be able to look around on his blog for tips on it.
http://www.gskinner.com/blog/archive...incompl_1.html
Yea that is an interesting effect but he doesn't have source code on his site.
That lightning in the screenshot looks like it's generated with perlin noise. You could also generate a similar effect with a fractal algorithm in which you choose two end points, pick a random offset from the midpoint to make two new segments, then repeat with each segment. 3 or 4 iterations should do the trick for each bolt. If you want to branch, then that'll make it a little more complex.
The actual drawing looks like a simple lineto with a glow filter.
Okay I have been working on this a bit but haven't completely pinned it down. I suppose I am going for more of an electricity effect than lightning actually...sorry to confuse.
In any case this is what I have so far:
http://www.cheezeworld.com/files/tests/electricity.swf
The problem is that on the horizontals and verticals it becomes a straight line. Any advice? I'll keep working on it...hopefully someone else can use this too once we get it looking good. Maybe I'll add some bitmap effects to it or something.
Here is the code I am currently using:
Code:private function drawLightning( p1:Vector2D, p2:Vector2D, color:uint ) : void
{
var maxDistance:Number = MathUtils.rand( 3, 20 );
var ratio:Number = Math.abs( ( p1.x - p2.x ) ) / Math.abs( ( p1.y - p2.y ) );
var x:Number = p1.x;
var y:Number = p1.y;
g.lineStyle( 1, color );
g.moveTo( x, y );
while( true )
{
maxDistance = MathUtils.rand( 3, 30 );
if( p1.x < p2.x )
{
x += ( Math.random() * maxDistance ) * ratio;
if( x > p2.x )
{
x = p2.x;
}
}
else
{
x -= ( Math.random() * maxDistance ) * ratio;
if( x < p2.x )
{
x = p2.x;
}
}
if( p1.y < p2.y )
{
y += Math.random() * maxDistance;
if( y > p2.y )
{
y = p2.y;
}
}
else
{
y -= Math.random() * maxDistance;
if( y < p2.y )
{
y = p2.y;
}
}
g.lineTo( x, y );
if( x == p2.x && y == p2.y )
{
break;
}
}
}
That looks pretty good. The straight line problems come in because of your use of ratio, which is not altogether a bad approach, but obviously goes to 0 or NaN in those cases. You could just put in special case logic for those two cases to come up with a random small ratio (for the 0 case) and a random large ratio (for the NaN case).
The iterative approach you've taken here is a pretty good compromise between complexity and end effect. For comparison, here's pseudocode to do the recursive approach I outlined before.
This code is completely untested and therefore probably has fatal flaws.Code:private function drawLightning( p1:Vector2D, p2:Vector2D, color:uint ) : void
{
g.lineStyle( 1, color );
drawLightningRecursive(p1, p2, 3);
}
private function drawLightningRecursive(p1:Vector2D, p2:Vector2D, depth:int):void{
if (depth == 0){ //draw rather than recurse here
g.moveTo(p1.x, p1.y);
g.lineTo(p2.x, p2.y);
return;
}
//calculate midpoint
var midp:Vector2D = new Vector2D((p1.x+p2.x)/2, (p1.y+p2.y)/2);
//offset midpoint by a bit.
var dist:Number = Math.sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
var offsetDist:Number = dist/5; //arbitrary divisor.
midp.x += (Math.random()*offsetDist)-offsetDist;
midp.y += (Math.random()*offsetDist)-offsetDist;
drawLightningRecursive(p1, midp, depth-1);
drawLightningRecursive(midp, p2, depth-1);
}
make it angle depending (random angles instead of random x/y positions)- its to much angled within 45° snaps
Alright I've finished up the lightning bomb. I gave it a glow and a blur filter, which doesn't seem to be effecting game speed at all.
To fix the straight line stuff I added some special cases for when the ratio is above 4 and below .4 and just gave some quick not-so-well thought out code which seems to do its job just fine for this case.
I could have probably done a lot better but since I'm trying to get this all done as quick as possible I am happy with the final result.
Check it out here: http://cheezeworld.com/under-development/
Upgrade your missiles all the way up and shoot the bomb with 'F'
It's a lot cooler if you let a lot of enemies spawn first then shoot it.
controls didn´t work for me,- also after 2-5 seconds the main menu pops up again (game over?)- very odd
same here it doesnt respond and goes to main menu
Sorry it's just kind of an alpha version...I think you have to click on the screen after you hit play for the controls to work (something to do with focus)
If you die it goes back to the main screen. I'll get it all straightened up for the final version of course, but right now its all just testing and what not :P
It worked for me. The effect was certainly passable.
Worked here. I personally would go for bright blue for the lightning but the effect worked for me. I can understand you would need a lot of linetos to draw the lightning effect smoother but great work getting it to render each bolt as fast as you have. I have done a lightning gun effect recently for next game episode and it takes a moment for the lightning to draw before I can even render it.
Doesn't load for me. Just a black screen, but right-click menu works, so it's not the wrong version of fplayer.