Railway Track

Show off your games, demos and other (playable) creations.
Post Reply
User avatar
darkfrei
Party member
Posts: 1168
Joined: Sat Feb 08, 2020 11:09 pm

Railway Track

Post by darkfrei »

Hi all!

There is my try to make railway track, where it's path is defined as love.graphics's line.

Used functions:
Get offset polyline - the right and left rails are just the same line as defined, but with offset :)
Get Points Along Line - every tie must be on the same distance, but the defined polyline can have long or short segments.

Code: Select all

 -- gives points on the line every gap; also returns tangents in this points
function get_points_along_line (line, gap)
	local points = {}
	local tangents = {}
	local rest = gap/2 -- rest is gap to start point on this section
	local x1, y1, x2, y2, dx, dy = line[1],line[2]
	for i=3, #line-1, 2 do
		x2, y2 = line[i],line[i+1]
		dx, dy = x2-x1, y2-y1
		local sector_length = (dx*dx+dy*dy)^0.5
		if sector_length > rest then
			-- rest is always shorter than gap; sector is shorter than rest (or gap)
			dx, dy = dx/sector_length, dy/sector_length
			while sector_length > rest do
				local x, y = x1+rest*dx, y1+rest*dy
				table.insert (points, x)
				table.insert (points, y)
				table.insert (tangents, dx)
				table.insert (tangents, dy)
				rest = rest + gap
			end
		else -- no point in this distance
		end
		-- the tail for the next 
		rest = rest-sector_length
		x1, y1 = x2, y2
	end
	return points, tangents
end

Code: Select all

-- Offsets the given polyline (line) by offset (offset)
function get_offset_polyline (line, offset, reversed)
	local offset_polyline = {}
	local loop = is_loop (line)
	if reversed then
		line = reverse_line (line)
	end
	if #line == 4 then
		local x1, y1 = line[1], line[2]
		local x2, y2 = line[3], line[4]
		local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
		offset_polyline = {px1, py1, px2, py2}
	elseif not loop then
		local x1, y1, x2, y2 = line[1], line[2], line[3], line[4]
		local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
		table.insert (offset_polyline, px1)
		table.insert (offset_polyline, py1)
		for i = 5, #line-1, 2 do
			local x3, y3 = line[i], line[i+1]
			local px3, py3, px4, py4 = get_parallel_segment (x2, y2, x3, y3, offset)
			local x, y = get_intersection (px1, py1, px2, py2, px3, py3, px4, py4, false, 4)
			table.insert (offset_polyline, x)
			table.insert (offset_polyline, y)
			x1, y1, x2, y2 = x2, y2, x3, y3
			px1, py1, px2, py2 = px3, py3, px4, py4
		end
		table.insert (offset_polyline, px2)
		table.insert (offset_polyline, py2)
	else -- loop
		local x1, y1, x2, y2 = line[#line-5], line[#line-4], line[#line-3], line[#line-2]
		local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
--		for i = 1, #line-1, 2 do
		for i = 1, #line-1, 2 do
			local x3, y3 = line[i], line[i+1]
			local px3, py3, px4, py4 = get_parallel_segment (x2, y2, x3, y3, offset)
			local x, y = get_intersection (px1, py1, px2, py2, px3, py3, px4, py4, false, 4)
			table.insert (offset_polyline, x)
			table.insert (offset_polyline, y)
			x1, y1, x2, y2 = x2, y2, x3, y3
			px1, py1, px2, py2 = px3, py3, px4, py4
		end
	end
	if #offset_polyline > 3 then
		return offset_polyline
	end
end
Attachments
2021-09-18T19_52_49-Untitled.png
2021-09-18T19_52_49-Untitled.png (24.15 KiB) Viewed 10010 times
2021-09-18T22_50_34.png
2021-09-18T22_50_34.png (129.88 KiB) Viewed 10010 times
railway-track-01.love
(2.59 KiB) Downloaded 232 times
Last edited by darkfrei on Sun Sep 19, 2021 10:23 am, edited 1 time in total.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
togFox
Party member
Posts: 764
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: Railway Track

Post by togFox »

Nice. I'll not sure where I would start with such a problem!
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

Is it necessary to get this offset?
You could just draw two lines of different width on top of each other i would say.

For the ties it is also possible to draw them short and thick, may be faster.
This would have been a use case for stipple lines, but that setting was removed.
obey
User avatar
darkfrei
Party member
Posts: 1168
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:21 am Is it necessary to get this offset?
You could just draw two lines of different width on top of each other i would say.

For the ties it is also possible to draw them short and thick, may be faster.
This would have been a use case for stipple lines, but that setting was removed.
But rails must be above the ties and in the middle between rails must be transparent area, not black thick line.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
(1.85 KiB) Downloaded 233 times
obey
User avatar
darkfrei
Party member
Posts: 1168
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:15 pm You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
Nice! Didn't know that you can erase by writing with the color {0,0,0,0} with color replacing.

Code: Select all

-- new canvas
tmp = love.graphics.newCanvas()
	love.graphics.setCanvas(tmp)
	love.graphics.setColor({0.6,0.8,0.8}) -- rail color
	love.graphics.setLineWidth (rail_width+3) -- three pixels more
	love.graphics.line(line)
	love.graphics.setBlendMode("replace")
	love.graphics.setColor(0,0,0,0) -- black transparent color
	love.graphics.setLineWidth (rail_width-3) -- three pixels less
	love.graphics.line(line) -- each rail is 3 pixels wide now
-- disabling canvas
love.graphics.newCanvas()
love.graphics.setBlendMode("alpha")
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
darkfrei
Party member
Posts: 1168
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:15 pm You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
The problem:
Attachments
2021-10-06T16_41_52.png
2021-10-06T16_41_52.png (86.34 KiB) Viewed 8432 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

I dont think trains work like that dude.
Anyway, how do you even want it to look in the end? If you want to get rid of the rail gap you can simply add another canvas and render the rails step by step.
obey
Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests