Author Topic: Lightning class [CAUTION!]  (Read 5478 times)

xhunterko

  • Contributor
  • ****
  • Posts: 449
  • Karma: +0/-0
    • View Profile
Lightning class [CAUTION!]
« on: Wed, May 9, 2012 »
So I was looking to post cool effects into my game, and I found an old one that was built for 2.35. The result in the old version, is if you click the mouse, a constrant stream of varied lightning bolts flicker from the center of the screen to the mouse button. It looked really cool, and with the help of wg/funstorm I was able to get it to work. Sort of. The 2.55 version only streams a single lightning bolt fromt he screen center to the mouse, and to get it to stream again you have to click again. It'd be cool if someone would try and tweak it to the original specs, that'd be awesome, but anyways, enough ramble.

Here's the Lightning Class. Put it in your game folder (src, com, whatever your style is):
Code: [Select]
package com
{
import flash.display.BitmapData;
import flash.geom.Matrix;
import org.flixel.*;
import org.flixel.plugin.photonstorm.*;
import flash.display.Shape;
import flash.filters.GlowFilter;


public class Lightning extends FlxSprite
{
private var radius:Number = 1;
private var visibleDuration:Number = .25;
private var visibleTimer:Number;
private var targetX:int;
private var targetY:int;

public function Lightning():void
{
super();
solid = false;
this.kill();
}

public function SetTarget(Target:FlxPoint):void
{
targetX = Target.x;
targetY = Target.y;

}

override public function update():void
{
visibleTimer -= FlxG.elapsed;

if (visibleTimer <= 0)
this.kill();
super.update();
}

override public function draw():void
{
var canvas:Shape = new Shape();
var scrollX:int = FlxG.camera.scroll.x;
var scrollY:int = FlxG.camera.scroll.y;
if (Math.random() < .8)
{
var boltOrigin:FlxPoint = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY)
var dx:int = boltOrigin.x - (targetX+scrollX);
var dy:int = boltOrigin.y - (targetY+scrollY);
var dist:int = int(Math.sqrt (dx * dx + dy * dy));
var radians:Number = Math.atan2 (dy, dx);
var theAngle:Number = radians * 180 / Math.PI;
//canvas.graphics.clear();
canvas.graphics.lineStyle(2, 0xffffff);
canvas.graphics.moveTo (boltOrigin.x, boltOrigin.y);

var traveled:Number = 0;
var linethickness:Number = 3;
var alpha:Number = 0;
var timer:Number = 20;
while (traveled < dist - 10)
{
var speed:Number = Math.random()*2 + 30;
var tmpAngle:Number = theAngle * Math.PI / 180;
var bx:int = traveled * Math.cos (tmpAngle);
var by:int = traveled * Math.sin (tmpAngle);
traveled += speed;
var theX:Number = (boltOrigin.x - bx) + Math.random () * 25 - 13;
var theY:Number = (boltOrigin.y - by) + Math.random () * 25 - 13;

canvas.graphics.lineStyle (linethickness, 0xFFFFFF, 1);
canvas.graphics.lineTo (theX, theY);
linethickness -= 1;
alpha += .25;
}
canvas.graphics.lineTo (targetX+scrollX, targetY+scrollY);
canvas.graphics.endFill();
var glow:GlowFilter = new GlowFilter;
glow.color = 0x3333FF;
glow.strength = 6;
glow.blurX = 24;
glow.blurY = 24;
canvas.filters = [glow];
        FlxG.camera.buffer.draw(canvas, null, null, "screen");


}

}

public function strike(X:int, Y:int):void
{
this.x = X;
this.y = Y;
this.exists = true;
this.alive = false;
visibleTimer = visibleDuration;
}
}
}

Playstate use example:
Code: [Select]
package com
{
import org.flixel.*;
import org.flixel.plugin.photonstorm.*;

public class Tribute extends FlxState
{


[Embed(source = '../../data/crosshairs.png')]private var ImgCursor:Class;
public var bolt:Lightning;


override public function create():void
{
FlxG.mouse.show(ImgCursor);

}

override public function update():void
{


//The pause menu is popped up here


super.update();

if (FlxG.mouse.justPressed())
{
bolt = add(new Lightning()) as Lightning;
var target:FlxPoint = new FlxPoint(FlxG.width / 2, FlxG.height / 2);
bolt.SetTarget(target);
bolt.strike(target.x, target.y);

}


}



}
}


That should work straight out of the box. Also, I'm not the original author of the 2.35 version. I just needed help porting it over. So if you are the original author and you do read this then THANK YOU!

All righty.

Enjoy!
« Last Edit: Fri, May 11, 2012 by xhunterko »
Now on twitter: http://twitter.com/xhunterko I made a game that's in alpha you can buy here: http://xhunterko.itch.io/wave-miner-alpha

LegacyCrono

  • New Member
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Lightning class
« Reply #1 on: Wed, May 9, 2012 »
Sort of. The 2.55 version only streams a single lightning bolt fromt he screen center to the mouse, and to get it to stream again you have to click again.
Well, you're using FlxG.mouse.justPressed(), you can change it to FlxG.mouse.pressed() and it constantly streams lightning bolts.  :P
Pretty nice by the way! Thanks for sharing!

xhunterko

  • Contributor
  • ****
  • Posts: 449
  • Karma: +0/-0
    • View Profile
Re: Lightning class
« Reply #2 on: Wed, May 9, 2012 »
I have now added the ability to input the origin point as well. Instead of it just being the mouse cursor. Now you can have lightning doors and the like.

Code: [Select]
package com
{
import flash.display.BitmapData;
import flash.geom.Matrix;
import org.flixel.*;
import org.flixel.plugin.photonstorm.*;
import flash.display.Shape;
import flash.filters.GlowFilter;


public class Lightning extends FlxSprite
{
private var radius:Number = 1;
private var visibleDuration:Number = .25;
private var visibleTimer:Number;
private var targetX:int;
private var targetY:int;
private var orginX:int;
private var orginY:int;

public function Lightning():void
{
super();
solid = false;
this.kill();
}

public function SetTarget(Target:FlxPoint):void
{
targetX = Target.x;
targetY = Target.y;

}

public function SetOrigin(Origin:FlxPoint):void
{
orginX = Origin.x;
orginY = Origin.y;

}

override public function update():void
{
//visibleTimer -= FlxG.elapsed;

if (visibleTimer <= 0)
this.kill();

super.update();
}

override public function draw():void
{
var canvas:Shape = new Shape();
var scrollX:int = FlxG.camera.scroll.x;
var scrollY:int = FlxG.camera.scroll.y;
if (Math.random() < .8)
{
var boltOrigin:FlxPoint = new FlxPoint(orginX, orginY)
var dx:int = boltOrigin.x - (targetX+scrollX);
var dy:int = boltOrigin.y - (targetY+scrollY);
var dist:int = int(Math.sqrt (dx * dx + dy * dy));
var radians:Number = Math.atan2 (dy, dx);
var theAngle:Number = radians * 180 / Math.PI;
//canvas.graphics.clear();
canvas.graphics.lineStyle(2, 0xffffff);
canvas.graphics.moveTo (boltOrigin.x, boltOrigin.y);

var traveled:Number = 0;
var linethickness:Number = 3;
var alpha:Number = 0;
var timer:Number = 20;
while (traveled < dist - 10)
{
var speed:Number = Math.random()*2 + 30;
var tmpAngle:Number = theAngle * Math.PI / 180;
var bx:int = traveled * Math.cos (tmpAngle);
var by:int = traveled * Math.sin (tmpAngle);
traveled += speed;
var theX:Number = (boltOrigin.x - bx) + Math.random () * 25 - 13;
var theY:Number = (boltOrigin.y - by) + Math.random () * 25 - 13;

canvas.graphics.lineStyle (linethickness, 0xFFFFFF, 1);
canvas.graphics.lineTo (theX, theY);
linethickness -= 1;
alpha += .25;
}
canvas.graphics.lineTo (targetX+scrollX, targetY+scrollY);
canvas.graphics.endFill();
var glow:GlowFilter = new GlowFilter;
glow.color = 0x3333FF;
glow.strength = 6;
glow.blurX = 24;
glow.blurY = 24;
canvas.filters = [glow];
//FlxG.buffer.draw(canvas, null, null, "screen");
FlxG.camera.buffer.draw(canvas, null, null, "screen");


}

}

public function strike(X:int, Y:int):void
{
                        //These should just be made to the origin x and y. Cause that's all it is really.
this.x = X;
this.y = Y;
this.exists = true;
this.alive = false;
visibleTimer = visibleDuration;
}
}
}

Playstate use:
Code: [Select]
if (FlxG.mouse.justPressed())
{
bolt = add(new Lightning()) as Lightning;
var origin:FlxPoint = new FlxPoint(_bx.x, _bx.y);
var target:FlxPoint = new FlxPoint(_w.x, _w.y);
bolt.SetOrigin(origin);
bolt.SetTarget(target);
bolt.strike(_bx.x, _bx.y);

}


/*
* WARNING: You can call it like this. However, it creates a new bolt
* constantly. Greatly reducing the frame rate. Use with caution!!!
                         *There's probably a better way to add it. If you figure it out please post it here! Thanks!
bolt = add(new Lightning()) as Lightning;
var origin:FlxPoint = new FlxPoint(_bx.x, _bx.y);
var target:FlxPoint = new FlxPoint(_w.x, _w.y);
bolt.SetOrigin(origin);
bolt.SetTarget(target);
bolt.strike(_bx.x, _bx.y);
*/

Enjoy!

EDIT: It still scrolls uncontrollably though. When I find it I'll post a fix here.
« Last Edit: Wed, May 9, 2012 by xhunterko »
Now on twitter: http://twitter.com/xhunterko I made a game that's in alpha you can buy here: http://xhunterko.itch.io/wave-miner-alpha

xhunterko

  • Contributor
  • ****
  • Posts: 449
  • Karma: +0/-0
    • View Profile
Re: Lightning class
« Reply #3 on: Thu, May 10, 2012 »
Found him!

Link: http://forums.flixel.org/index.php/topic,1596.msg10337.html#msg10337

Rybar is responsible for the initial lightning class. Again. Thank you sir!
Now on twitter: http://twitter.com/xhunterko I made a game that's in alpha you can buy here: http://xhunterko.itch.io/wave-miner-alpha

xhunterko

  • Contributor
  • ****
  • Posts: 449
  • Karma: +0/-0
    • View Profile
Re: Lightning class [CAUTION!]
« Reply #4 on: Fri, May 11, 2012 »
Hey guys!

So I've done some testing and this is what I've found out.

When you have the lightning bolt run constantly, it creates a new bolt every second or so.

This is very, very, very memory conusming! Unless you really know what your doing, I'd use this class with caution. If your confident, then by all means, use it, and share what your doing to optimize it! I'll try a few tweaks later on, but I'm not going to use it as is. You also might be able to do it in pure flixel, since flixel has a line method and you can swap a bitmap glow over it according to the method shown to me by photonstorm. So, yeah.

USE THIS CLASS WITH CAUTION!

That is all.

Note: It might be okay to set it to a moust click, but I'd be careful doing that too. It also doesn't collide with anything, so you might want to do something about that as well. Maybe make a straight line or have a flixel sprite at an angle.
Now on twitter: http://twitter.com/xhunterko I made a game that's in alpha you can buy here: http://xhunterko.itch.io/wave-miner-alpha

Raf

  • Contributor
  • ****
  • Posts: 268
  • Karma: +0/-0
    • View Profile
Re: Lightning class [CAUTION!]
« Reply #5 on: Wed, Dec 5, 2012 »
I'm trying to apply this class on a FlxGroup, so a lightning bolt gets shot at a certain, programmatically decided moment (so not upon user input). It gets to the code (the trace is logged), and if I'm not careful, it lags the whole thing down, yet I can't see the bolt.

This is my code:
Code: [Select]
package objects.obstacles.lightning
{
    import org.flixel.*;
    import org.flixel.plugin.photonstorm.*;

   
    /**
     * ...
     * @author Raf
     */
    public class LightningGroup extends FlxGroup
    {
        private var lightningCloud:LightningCloud;
        public var bolt:Lightning;
       
        public function LightningGroup() {
            lightningCloud = new LightningCloud();           
            add(lightningCloud);       
        }
       
        public function go():void {
            exists = true;
            lightningCloud.go();
        }

       
        public override function update():void {
            super.update();
           
            if (lightningCloud.lightningStarted == true && lightningCloud.lightningDone == false) {
                trace('LIGHTNING');
                bolt = add(new Lightning()) as Lightning;
                var origin:FlxPoint = new FlxPoint(lightningCloud.x+32, lightningCloud.y+32);
                var target:FlxPoint = new FlxPoint(FlxG.width/2, FlxG.height);               
                bolt.SetOrigin(origin);
                bolt.SetTarget(target);
                bolt.strike(target.x, target.y);
                lightningCloud.lightningDone = true;
            }
        }
       
    }

}

Any ideas why it's executing but not showing? I'm using Flixel v2.55

Edit: Also tried in a playstate (my main menu), exactly as the examples in this topic described. Still no lightning :-\
« Last Edit: Wed, Dec 5, 2012 by Raf »

grisevg

  • Member
  • **
  • Posts: 47
  • Karma: +0/-0
    • View Profile
    • Dubit Limited
Re: Lightning class [CAUTION!]
« Reply #6 on: Thu, Dec 6, 2012 »
I used this thingie for the prototype I making at work right now:
http://blog.oaxoa.com/2009/07/27/actionscript-3-as3-lightning-thunderbolt-electric-discharge-class/
Here's how it looks:

And here's my current implementation(fast'n'dirty): http://pastie.org/private/unpuajwt4xjv2eg720rqg

Can lag as hell if used a lot, but I think it's because original source code is not very well optimized. Will try to clean it up when I have some free time.
There's no memory leaks from what I've seen. If you succeed in speeding it up, please let me know.
« Last Edit: Thu, Dec 6, 2012 by grisevg »

Raf

  • Contributor
  • ****
  • Posts: 268
  • Karma: +0/-0
    • View Profile
Re: Lightning class [CAUTION!]
« Reply #7 on: Wed, Dec 12, 2012 »
Hmm, just added everything, but it doesn't show. I got to do an "add()" of it, I guess, but since it's not derived from FlxBasic, I can't use that. Can't find anything on how to do that from the demo codes either, so... time to learn a bit of Actionscript away from Flixel!

Raf

  • Contributor
  • ****
  • Posts: 268
  • Karma: +0/-0
    • View Profile
Re: Lightning class [CAUTION!]
« Reply #8 on: Wed, Dec 12, 2012 »
Alright, finally got it to work! Now I just got to figure out how to make it "fork out" a bit (so it's more spikey than stringy), as the lightning has to serve as... well... lightning, bursting down from a cloud, and not as an electrical discharge from point A to point B :P

xhunterko

  • Contributor
  • ****
  • Posts: 449
  • Karma: +0/-0
    • View Profile
Re: Lightning class [CAUTION!]
« Reply #9 on: Sat, Dec 29, 2012 »
This is cool! I was hoping some other people would find a use for this too!
Now on twitter: http://twitter.com/xhunterko I made a game that's in alpha you can buy here: http://xhunterko.itch.io/wave-miner-alpha