How to make a convincing laser beam?

Does anyone have any advice on how to generate a convincing laser beam animation? I've been using a basic gradient line as a placeholder but it's not really very compelling visually.

An image-based beam seems like it wouldn't work due to the need to draw it at varying lengths.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function drawBeam (distance, angle)
        
        local h = graphics.newGradient({ 220, 0, 0 },{ 0, 30, 0 },"down" )
 
        beamImage = display.newRect(shipX,shipY,distance, 3)
        beamImage:setReferencePoint( display.TopLeftReferencePoint )
        beamImage:setFillColor( h )
        beamImage:rotate(angle)
        beamImage.xScale = .2
 
end
--
function doTurn()
        if (beamImage) then
                if (beamImage.xScale < 1) then
                beamImage.xScale = beamImage.xScale + .2
                end
        frame = frame + 5
        local red = 220 - frame
        local blue = math.random (0,frame/2)
        local green = math.random(0,frame/2)
        
        local h = graphics.newGradient({ red, green, blue },{ red/4, 0, 0 },"down" )
        beamImage:setFillColor( h )
        
        if (red <= 0) then
        beamImage:removeSelf()  
        beamImage = nil
 
        frame = 0
        a = nil
        d = nil
        end
end
 
Runtime:addEventListener( "enterFrame", doTurn )

I was just thinking about this the other day.

You could use images depending on the look. Use a spritesheet and create lengths like 1, 2, 4, 8, 16, 32, 64, etc.

Then you can calculate the length of the beam. Say it's 345 pixels. Divide that by your largest length. Say it's 256 that gives 345/256 = (256 + 89) / 256 then find the next largest, then the next until you get down to 1 pixel.

Then you should have the counts for your lengths, create the images out of a pool and then line them up.

I think that'll work.

That probably would, thanks. I may end up heading in that direction. I guess I was just hoping there might be a more out-of-the-box solution.

Why not just draw you graphic beam at X length. If you need it different lengths, just change the xScale up or down.

I had just assumed that would look bad.

Well you wouldn't want to stretch a 10px image to 200px but 50% up and down should be okay assuming you're doing something thin.

Are you looking at thin beams or fatter more detailed beams? On my space shooter my retina blaster beams are 6px wide for the beam and 18px counting the glow so there isn't a whole lot of detail in a thin beam.

Unfortunately, I'm looking at something on the thin side, because the ship icons are small (< 20x20) -- it's a strategic space game rather than action game. The beam code included above uses a 3px wide Corona rect. I may try 5 to see if I can get more of a glow effect -- I'd like something neon-like, that pops visually, but I'm guessing that's difficult with so few pixels to work with.

I made something a little while back and got a nice "so bright and fast the eyes need to catch up" effect by transitioning a second level of "glow" down to alpha 0 in the lasers path. Just fyi, hope you get a good one!

I ran a quick test using my blaster graphic from Omniblaster:

Which you are free to use if you like. I think I drew this from scratch.

Any way, in my game its a short "pulse" type laser blast, so I was okay with the shorter image. It's 9x32 and I also included the Retina version which is 18x64.

I went into Corona and wrote a quick test using .yScale to scale up the app. The leftmost is the natural image. The middle one is scaled at 2.0 (200%) and the right most is scaled at 4.0 (400%). I took screen shots based on what an iPhone is about sized to and the zoomed in retina graphics:

To me, scaling a graphic up like this seems to work really well.

Oh I think in my game I was using the additive blend mode on this graphic, I did not do that with this test.

Rob

try making the image 1px wide and however tall you want then stretch it.
or in the orientation @ robmiracle did, it would be 1px tall and 32 wide.

Thanks, I'll test that out & let you know how it goes.

views:1981 update:2012/2/8 8:46:10
corona forums © 2003-2011