Like the zap zap kind. Not a misspelling.
The closest thing I've found is this and I'm not really sire how it applies to love2d.
I'm guessing a crude way be to get 2 points (start and destination) and then create a bunch of lines (that fit into the width of end minus start) of different lengths and offsets to each other. But that's crude I think.
Any known nice way of implementing it. (Examples Nuclear throne, MDickie games (Extra Lives, BackWars))
Not that sporadic but this is the gif I could find
How to do lightning
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to do lightning
While not at destination
Determine random segment length
Determine random angle
Draw segment
End
There is probably some recursion in there somewhere.
Determine random segment length
Determine random angle
Draw segment
End
There is probably some recursion in there somewhere.
Last project:
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/idle-gridiron
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/idle-gridiron
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to do lightning
So I tried with the posts I got + some ideas and now I have this...
It's a little fast but I think it's pretty good. Not fancy but could work.
Though problems that I couldn't seem to fix:
1) As I see it I can only go one axis/direction at a time. Either a vertical path or a horizontal one whereas I'd like there to also be diagonal.
2) The last segment doesn't end at the intended destination.
Code: Select all
local function distance(x,y,xx,yy)
return math.sqrt(((x-xx)^2)+(y-yy)^2)
end
rand = function(x)
return math.random(-x, x)
end
ldraw = function(x,y,xx,yy)
local drawLine = love.graphics.line
local len = distance(x,y,xx,yy)
local nlen = len
local lines = {}
local nn = 15
local ox, oy = x, y
local min, max = 3,13
local mx = math.random(min,max)
while nlen>0 do
local t = len/(math.random(min,max))
if t > nlen then
t = nlen
end
nlen = nlen - t
local done = nlen<=0
local line = {
x = ox,
y = oy,
x2 = ox+(done and 0 or rand(nn)),
y2 = oy+t,0+(done and 0 or rand(nn))
}
ox,oy=line.x2, line.y2
lines[#lines+1] = line
end
for xi = 1, #lines do
local l = lines[xi]
drawLine(l.x, l.y, l.x2, l.y2)
end
end
love.draw = function()
ldraw(100,10,100,300)--startx, starty, endx, endy
--love.graphics.line(200,10,200,300)
end
Though problems that I couldn't seem to fix:
1) As I see it I can only go one axis/direction at a time. Either a vertical path or a horizontal one whereas I'd like there to also be diagonal.
2) The last segment doesn't end at the intended destination.
- Attachments
-
- zap.love
- (548 Bytes) Downloaded 141 times
Re: How to do lightning
This.Gunroar:Cannon() wrote: ↑Wed Jul 13, 2022 10:27 am 2) The last segment doesn't end at the intended destination.
Make the line between start and end points.
Take a point between them and move it slightly. So you have two lines now, that are not on the straight line between start and end points.
For each line take any point plus/minus near the middle and move it slightly.
Ignore too short lines and repeat until result.
The animation is just random moving this all new middle points, respecting the sequence of it creation.
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to do lightning
Is that possible in love2d. Won't I need a mesh or something similar for that? My implementation consists of multiple lines starting at the end of the line that came before them(or the starting point if the line is the first one).
Re: How to do lightning
A table. Think of lines in abstract, not as in love.graphics.line(). You'll get to the rendering part later.Gunroar:Cannon() wrote: ↑Wed Jul 13, 2022 11:09 am Is that possible in love2d. Won't I need a mesh or something similar for that?
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to do lightning
Ahhh, yes! I'll try this.pgimeno wrote: ↑Wed Jul 13, 2022 12:02 pmA table. Think of lines in abstract, not as in love.graphics.line().Gunroar:Cannon() wrote: ↑Wed Jul 13, 2022 11:09 am Is that possible in love2d. Won't I need a mesh or something similar for that?
Re: How to do lightning
(not tested)
Code: Select all
local source ={x=0, y=0}
local target ={x=800, y=600}
local lightning= {
source=source,
target=target,
mainLine={source, target},
}
function addPoint (lightning, index) -- index = math.random(#lightning.mainLine -1)
local x1=lightning.mainLine[index].x
local y1=lightning.mainLine[index].y
local x2=lightning.mainLine[index+1].x
local y2=lightning.mainLine[index+1].y
local t = 0.25 + 0.5*math.random()
local x = x1+ t*(x2 - x1)
local y = y1+ t*(y2 - y1)
x = x + 0.25*(y2 - y1)* (math.random()-1)
y = y + 0.25*(x2 - x1)* (math.random()-1)
table.insert (lightning.mainLine, index+1, {x=x,y=y})
end
- Gunroar:Cannon()
- Party member
- Posts: 1143
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to do lightning
A little too fast (no delay implemented) but here's what I scrounged up (still haven't tested darkfrei's one yet, just wanted to see if this idea worked first).
But it works, can even branch
Code: Select all
local function choose(t)
return t[math.random(#t)]
end
local function point_distance(x,y,xx,yy)
return math.sqrt(((x-xx)^2)+(y-yy)^2)
end
local function point_direction(x,y,xx,yy)
return -math.atan2(yy-y, xx-x)
end
random_range = function(x,y)
return math.random((y and x or -x), y or x)
end
array_length = function(t)
return #t
end
function lengthdir_x(spd, ang)
return spd*math.cos(ang)
end
function lengthdir_y(spd, ang)
return spd*-math.sin(ang)
end
function draw_set_alpha(a)
local r,g,b = love.graphics.getColor()
love.graphics.setColor(r,g,b,a)
end
function set_color(rr,gg,bb,aa)
local r,g,b,a = love.graphics.getColor()
if not rr then
return r, g, b, a
end
love.graphics.setColor(rr,gg,bb,aa)
return r,g,b,a
end
function draw_line_width_colour(x1, y1, x2, y2,size,color1,color2)
local r,g,b,a = set_color(color1)
local p = love.graphics.getLineWidth()
love.graphics.setLineWidth(sizge or p)
love.graphics.line(x1,y1,x2,y2)
set_color(r,g,b,a)
love.graphics.setLineWidth(p)
end
function draw_circle_colour(x,y,r,c1,c2)
local r,g,b,a = set_color(c1)
love.graphics.circle("fill",x,y,r)
set_color(r,g,b,a)
end
local c_white = {1,1,1}
function draw_lightning(x1, y1, x2, y2, branches, size, color)
--draw_lightning(x, y, x2, y2, branches, size, colour)
--
--draws a lightning bolt from the given starting location to the given end location
--
--x = x of the bolt's start
--y = y of the bolt's start
--x2 = x of the bolt's end
--y2 = y of the bolt's end
--branches = true or false, if the lightning bolt branches into multiple smaller ones
--size = pixel width of the lightning
--colour = colour of the glow
--
--amusudan 23/5/2016
--
--feel free to use this in your project!
--
local dir = point_direction(x1,y1,x2,y2)
local length = point_distance(x1,y1,x2,y2) --error(length)
local colour = color;
local _size = size;
--make different segments
local point = {};
point[1] = 0;
local i2 = 2;
for i = 1, length do
if (math.random() < .06) then
point[i2] = i;
i2 = i2+1;
end
end
point[i2] = length;-- error(point[#point-0])
local points = array_length(point);
--draw segments
local i2 = 2
local difx = 0;
local difx2 = 0;
local dify = 0;
local ii =0
local dify2 = 0; --error(points)
local dis = 7
for i2 = 2, points do
local i2 = i2+ii
difx = random_range(dis)
dify = random_range(dis)
local xx = x1 + lengthdir_x(point[i2 - 1],dir);
local yy = y1 + lengthdir_y(point[i2 - 1],dir);
local xx2 = x1 + lengthdir_x(point[i2],dir);
local yy2 = y1 + lengthdir_y(point[i2],dir); --error(xx2..","..x1..",y2:"..yy2..","..y1..","..dir..","..point[i2])
--create a branch
if (math.random() < .15 and branches) then
local bdir = dir + choose({random_range(-45,-25),random_range(45,25)});
local blength = random_range(5,30);
draw_lightning(xx + difx2, yy + dify2, xx + difx2 + lengthdir_x(blength,bdir), yy + dify2 + lengthdir_y(blength,bdir), false, _size, colour)
end
--draw the glow of the lightning
set_color(1,1,1,.1)
draw_line_width_colour(xx + difx2,yy + dify2,xx2 + difx,yy2 + dify, size + 5,colour,colour);
draw_line_width_colour(xx + difx2,yy + dify2,xx2 + difx,yy2 + dify, size + 3,c_white,c_white);
draw_line_width_colour(xx + difx2,yy + dify2,xx2 + difx,yy2 + dify, size + 1,c_white,c_white);
draw_set_alpha(1)
--draw the white center of the lightning
draw_line_width_colour(xx + difx2,yy + dify2,xx2 + difx,yy2 + dify, size,c_white,c_white);
--ii = ii+1;
difx2 = difx;
dify2 = dify;
end
--draw a glowing circle
if (branches) then
draw_set_alpha(.91);
draw_circle_colour(x1,y1,size + 2.5,colour,colour,false);
draw_circle_colour(x1,y1,size + 1.5,colour,colour,false);
draw_circle_colour(x1,y1,size + .5,colour,colour,false);
draw_set_alpha(1);
draw_circle_colour(x1,y1,size,c_white,c_white,false);
end
end
love.draw = function()
love.graphics.scale(.5)
--love.graphics.translate(0,500)
local x = 100
local y = 100
local xx = 150
local yy = 300
--draw_line_width_colour(x,y,xx,yy,1,{0,1,0})
draw_lightning(x,y,xx,yy,true,10)
end
Who is online
Users browsing this forum: No registered users and 5 guests