update to convert poly to mesh

This commit is contained in:
2021-12-23 15:05:00 +01:00
parent 7c62363827
commit 963b3ac174
4 changed files with 273 additions and 212 deletions

View File

@@ -28,11 +28,6 @@
]] ]]
-- require('mobdebug').start() -- require('mobdebug').start()
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
require("lldebugger").start()
end
require 'src/Dependencies' require 'src/Dependencies'
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then

View File

@@ -1,17 +1,23 @@
-- require('mobdebug').start() -- require('mobdebug').start()
Level = Class {}
Level = Class{}
function Level:init() function Level:init()
self.segments = self:createLevel() self.segments = self:createLevel()
self.polygon = self:createPolygon() self.polygon = self:createPolygon()
self.player = {} self.player = {}
self.mesh = {}
end end
function Level:update(dt) function Level:update(dt)
self:createPolygon()
if #self.polygonPoints < 3 then
self.mesh = {}
else
print_r(self.polygonPoints)
self.mesh = poly2mesh(self.polygonPoints)
end
end end
function Level:render() function Level:render()
@@ -20,21 +26,32 @@ function Level:render()
end end
function Level:renderOuterSegments() function Level:renderOuterSegments()
for k,segment in pairs(self.segments) do for k, segment in pairs(self.segments) do segment:render() end
segment:render()
end
end end
function Level:renderBackground() function Level:renderBackground()
love.graphics.draw(gImages["img1"],LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP) love.graphics.draw(gImages["img1"], LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP)
love.graphics.draw(self.mesh, 0, 0)
end end
function Level:createLevel() function Level:createLevel()
local level = { local level = {
[1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5,'down'), [1] = Segment({LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP}, {
[2] = Segment({VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},.5,'left'), VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP
[3] = Segment({VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},{LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},.5,'up'), }, .5, 'down'),
[4] = Segment({LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},{LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},.5,'right') [2] = Segment({
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP
}, {
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET,
VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, .5, 'left'),
[3] = Segment({
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET,
VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, {LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET}, .5, 'up'),
[4] = Segment({
LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, {LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP}, .5, 'right')
} }
-- local level = { -- local level = {
-- [1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5), -- [1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5),
@@ -47,168 +64,171 @@ function Level:createLevel()
return level return level
end end
function Level:insideBounds2(x,y) function Level:insideBounds2(x, y)
local shape = love.physics.newPolygonShape(self.polygonPoints) local shape = love.physics.newPolygonShape(self.polygonPoints)
return shape:testPoint(x,y) return shape:testPoint(x, y)
end end
function Level:insideBounds(x,y, segments) function Level:insideBounds(x, y, segments)
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local up,down,left,right = false local up, down, left, right = false
local upSeg, downSeg, leftSeg, rightSeg = nil local upSeg, downSeg, leftSeg, rightSeg = nil
-- find closest segments -- find closest segments
for i, segment in pairs(segments) do for i, segment in pairs(segments) do
-- check raycast on y axis -- check raycast on y axis
if segment.vertical then if segment.vertical then
if y <= math.max(segment.firstPointY, segment.secondPointY) and if y <= math.max(segment.firstPointY, segment.secondPointY) and y >=
y >= math.min(segment.firstPointY, segment.secondPointY) then math.min(segment.firstPointY, segment.secondPointY) then
if x <= segment.firstPointX then if x <= segment.firstPointX then
if not rightSeg then if not rightSeg then
rightSeg = segment rightSeg = segment
elseif math.abs(segment.firstPointX - x) < math.abs(rightSeg.firstPointX - x) then elseif math.abs(segment.firstPointX - x) <
rightSeg = segment math.abs(rightSeg.firstPointX - x) then
end rightSeg = segment
else
if not leftSeg then
leftSeg = segment
elseif math.abs(segment.firstPointX - x) < math.abs(leftSeg.firstPointX - x) then
leftSeg = segment
end
end end
else
if not leftSeg then
leftSeg = segment
elseif math.abs(segment.firstPointX - x) <
math.abs(leftSeg.firstPointX - x) then
leftSeg = segment
end
end
end end
end end
if segment.horizontal then if segment.horizontal then
if x <= math.max(segment.firstPointX, segment.secondPointX) and if x <= math.max(segment.firstPointX, segment.secondPointX) and x >=
x >= math.min(segment.firstPointX, segment.secondPointX) then math.min(segment.firstPointX, segment.secondPointX) then
if y <= segment.firstPointY then if y <= segment.firstPointY then
if not downSeg then if not downSeg then
downSeg = segment downSeg = segment
elseif math.abs(segment.firstPointY - y) < math.abs(downSeg.firstPointY - y) then elseif math.abs(segment.firstPointY - y) <
downSeg = segment math.abs(downSeg.firstPointY - y) then
end downSeg = segment
else
if not upSeg then
upSeg = segment
elseif math.abs(segment.firstPointY - y) < math.abs(upSeg.firstPointY - y) then
upSeg = segment
end
end end
else
if not upSeg then
upSeg = segment
elseif math.abs(segment.firstPointY - y) <
math.abs(upSeg.firstPointY - y) then
upSeg = segment
end
end
end end
end end
end end
if not rightSeg or not leftSeg or not upSeg or not downSeg then if not rightSeg or not leftSeg or not upSeg or not downSeg then
return false return false
end end
if rightSeg.face ~= 'left' or leftSeg.face ~= 'right' or upSeg.face ~= 'down' or downSeg.face ~= 'up' then if rightSeg.face ~= 'left' or leftSeg.face ~= 'right' or upSeg.face ~=
return false 'down' or downSeg.face ~= 'up' then return false end
end
return true return true
end end
function Level:insideBounds3(x,y) function Level:insideBounds3(x, y)
x = math.floor(x) x = math.floor(x)
y = math.floor(y) y = math.floor(y)
local oddNodes = false local oddNodes = false
local j = #self.polygon local j = #self.polygon
local polygon = self.polygon local polygon = self.polygon
for i = 1, #polygon do for i = 1, #polygon do
if (polygon[i].y < y and polygon[j].y >= y or polygon[j].y < y and polygon[i].y >= y) then if (polygon[i].y < y and polygon[j].y >= y or polygon[j].y < y and
if (polygon[i].x + ( y - polygon[i].y ) / (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) < x) then polygon[i].y >= y) then
oddNodes = not oddNodes if (polygon[i].x + (y - polygon[i].y) /
end (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) <
x) then oddNodes = not oddNodes end
end end
j = i j = i
end end
return oddNodes return oddNodes
end end
function Level:createPolygon() function Level:createPolygon()
local polygon = {} local polygon = {}
local polygonPoints = {} local polygonPoints = {}
local j = 1 local j = 1
for i,segment in ipairs(self.segments) do for i, segment in ipairs(self.segments) do
polygon[i] = {} polygon[i] = {}
polygon[i+1] = {} polygon[i + 1] = {}
polygon[i].x, polygon[i].y, polygon[i+1].x, polygon[i+1].y = segment:segmentToPoints() polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y =
segment:segmentToPoints()
polygonPoints[j] = polygon[i].x polygonPoints[j] = polygon[i].x
polygonPoints[j+1] = polygon[i].y polygonPoints[j + 1] = polygon[i].y
polygonPoints[j+2] = polygon[i+1].x polygonPoints[j + 2] = polygon[i + 1].x
polygonPoints[j+3] = polygon[i+1].y polygonPoints[j + 3] = polygon[i + 1].y
j = j + 4 j = j + 4
i = i + 1 i = i + 1
end end
self.polygonPoints = polygonPoints self.polygonPoints = polygonPoints
return polygon return polygon
end end
function Level:pointOnEdge(x,y,segments) function Level:pointOnEdge(x, y, segments)
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local margin = 2 local margin = 2
for i,segment in pairs(segments) do for i, segment in pairs(segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return true return true
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return true return true
end end
end end
end end
return false return false
end end
function Level:getTouchingSegment(x,y) function Level:getTouchingSegment(x, y)
local margin = 2 local margin = 2
for i,segment in pairs(self.segments) do for i, segment in pairs(self.segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return i, segment return i, segment
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return i, segment return i, segment
end end
end end
end end
return nil return nil
end end
function Level:cutLevel() function Level:cutLevel()
local newSegs = self.player.trailSegments local newSegs = self.player.trailSegments
local startSegi, startSeg = self.player.trailStartSegment[1],self.player.trailStartSegment[2] local startSegi, startSeg = self.player.trailStartSegment[1],
local endSegi, endSeg = self.player.trailFinishSegment[1],self.player.trailFinishSegment[2] self.player.trailStartSegment[2]
local endSegi, endSeg = self.player.trailFinishSegment[1],
self.player.trailFinishSegment[2]
local first = 0 local first = 0
local last = 0 local last = 0
local firstFace = '' local firstFace = ''
--check if it is same start and finish segment -- check if it is same start and finish segment
if startSegi == endSegi then if startSegi == endSegi then
-- print("cutlevel same start and end segment: "..tostring(startSegi)..' - '..tostring(endSegi)) -- print("cutlevel same start and end segment: "..tostring(startSegi)..' - '..tostring(endSegi))
local s = {} local s = {}
-- split the start/end segment -- split the start/end segment
local new = {} local new = {}
local split = self.segments[startSegi]:copy() local split = self.segments[startSegi]:copy()
newSegs[1]:joinPerpendicular(split) newSegs[1]:joinPerpendicular(split)
newSegs[#newSegs]:joinPerpendicular(split) newSegs[#newSegs]:joinPerpendicular(split)
@@ -221,7 +241,7 @@ function Level:cutLevel()
end end
local part1, part2, temp = {} local part1, part2, temp = {}
local inOrder = false local inOrder = false
local j,k = 1,1 local j, k = 1, 1
local insertedNewSegs = false local insertedNewSegs = false
-- print("-- Create new segments table") -- print("-- Create new segments table")
-- create the new set of segments -- create the new set of segments
@@ -231,7 +251,8 @@ function Level:cutLevel()
-- print("Reached the segment being cut") -- print("Reached the segment being cut")
-- print_r(self.segments[k]) -- print_r(self.segments[k])
-- print("split the segment") -- print("split the segment")
part1, temp, part2 = self.segments[k]:splitInThreeWithSegments(newSegs[1],newSegs[#newSegs]) part1, temp, part2 = self.segments[k]:splitInThreeWithSegments(
newSegs[1], newSegs[#newSegs])
-- print("part1") -- print("part1")
part1:debug() part1:debug()
-- print("part2") -- print("part2")
@@ -244,12 +265,12 @@ function Level:cutLevel()
-- insert new segs -- insert new segs
-- print("-- insert new segments into new set") -- print("-- insert new segments into new set")
for i, segment in pairs(newSegs) do for i, segment in pairs(newSegs) do
if i + 1 < #newSegs then if i + 1 < #newSegs then
newSegs[i+1]:joinPerpendicular(segment) newSegs[i + 1]:joinPerpendicular(segment)
end end
new[j] = segment:copy() new[j] = segment:copy()
j = j + 1 j = j + 1
end end
insertedNewSegments = true insertedNewSegments = true
new[j] = part2 new[j] = part2
j = j + 1 j = j + 1
@@ -266,9 +287,9 @@ function Level:cutLevel()
new = self:orderSegments(new) new = self:orderSegments(new)
-- print_r(new) -- print_r(new)
-- print("calculate faces") -- print("calculate faces")
self:calculateSegmentFaces(new,new[1].face) self:calculateSegmentFaces(new, new[1].face)
-- print_r(new) -- print_r(new)
self.segments = new self.segments = new
else else
-- create two set of segments, one to one side of the cut, one to the other -- create two set of segments, one to one side of the cut, one to the other
local board1 = {} local board1 = {}
@@ -279,12 +300,12 @@ function Level:cutLevel()
local j = 1 local j = 1
local last = #self.segments local last = #self.segments
local insertedNewSegments = false local insertedNewSegments = false
local savedStart,savedEnd = {} local savedStart, savedEnd = {}
local board2StartSegi,board2EndSegi = 0 local board2StartSegi, board2EndSegi = 0
-- create first board -- create first board
while k <= #self.segments do while k <= #self.segments do
-- print("-----start Loop for "..tostring(k).."-----") -- print("-----start Loop for "..tostring(k).."-----")
if k == startSegi and not insertedNewSegments then if k == startSegi and not insertedNewSegments then
board2StartSegi = k board2StartSegi = k
-- print("-- this segment is the start segment and not inserted new segments yet") -- print("-- this segment is the start segment and not inserted new segments yet")
-- print("newsegs[1] is joined perpendicular to k segment:") -- print("newsegs[1] is joined perpendicular to k segment:")
@@ -292,14 +313,15 @@ function Level:cutLevel()
newSegs[1]:joinPerpendicular(self.segments[k]) newSegs[1]:joinPerpendicular(self.segments[k])
newSegs[1]:debug() newSegs[1]:debug()
-- print("newSegs[1] is joined -- finished") -- print("newSegs[1] is joined -- finished")
local startPart1, startPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[1]) local startPart1, startPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[1])
-- print("-- Segment k split into 2 segments by newsegs[1]: ") -- print("-- Segment k split into 2 segments by newsegs[1]: ")
startPart1:debug() startPart1:debug()
startPart2:debug() startPart2:debug()
if self.segments[last]:endEqualsStartOf(self.segments[k]) or if self.segments[last]:endEqualsStartOf(self.segments[k]) or
self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one
--keep first part of segment -- keep first part of segment
-- print("-- keep first part of the k segment") -- print("-- keep first part of the k segment")
self.segments[k] = startPart1 self.segments[k] = startPart1
savedStart = startPart2 savedStart = startPart2
@@ -308,7 +330,7 @@ function Level:cutLevel()
self.segments[k] = startPart2 self.segments[k] = startPart2
savedStart = startPart1 savedStart = startPart1
end end
board1[j] = self.segments[k] board1[j] = self.segments[k]
j = j + 1 j = j + 1
@@ -326,11 +348,12 @@ function Level:cutLevel()
j = j + 1 j = j + 1
end end
-- print_r(board1) -- print_r(board1)
local endPart1, endPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs]) local endPart1, endPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs])
-- print("-- proceed to insert the second split segment") -- print("-- proceed to insert the second split segment")
if self.segments[last]:endEqualsEndOf(self.segments[k]) or if self.segments[last]:endEqualsEndOf(self.segments[k]) or
self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one
self.segments[k] = endPart1 self.segments[k] = endPart1
savedEnd = endPart2 savedEnd = endPart2
-- print("-- keep first part of the k segment") -- print("-- keep first part of the k segment")
@@ -353,12 +376,13 @@ function Level:cutLevel()
newSegs[#newSegs]:joinPerpendicular(self.segments[k]) newSegs[#newSegs]:joinPerpendicular(self.segments[k])
newSegs[#newSegs]:debug() newSegs[#newSegs]:debug()
-- print("newSegs[#newSegs] is joined -- finished") -- print("newSegs[#newSegs] is joined -- finished")
local endPart1, endPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs]) local endPart1, endPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs])
-- print("-- Segment k split into 2 segments by newsegs[#newSegs]: ") -- print("-- Segment k split into 2 segments by newsegs[#newSegs]: ")
endPart1:debug() endPart1:debug()
endPart2:debug() endPart2:debug()
if self.segments[last]:endEqualsStartOf(self.segments[k]) or if self.segments[last]:endEqualsStartOf(self.segments[k]) or
self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one
-- keep first part of segment -- keep first part of segment
self.segments[k] = endPart1 self.segments[k] = endPart1
@@ -387,28 +411,29 @@ function Level:cutLevel()
end end
-- print_r(board1) -- print_r(board1)
local startPart1, startPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[1]) local startPart1, startPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[1])
-- print("-- Segment k split into 2 segments by newsegs[1]: ") -- print("-- Segment k split into 2 segments by newsegs[1]: ")
startPart1:debug() startPart1:debug()
startPart2:debug() startPart2:debug()
if self.segments[last]:endEqualsEndOf(self.segments[k]) or if self.segments[last]:endEqualsEndOf(self.segments[k]) or
self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one
self.segments[k] = startPart1 self.segments[k] = startPart1
savedstart = startPart2 savedstart = startPart2
else else
self.segments[k] = startPart2 self.segments[k] = startPart2
savedStart= startPart1 savedStart = startPart1
end end
board1[j] = self.segments[k]:copy() board1[j] = self.segments[k]:copy()
j = j + 1 j = j + 1
-- print_r(board1) -- print_r(board1)
insertedNewSegments = true insertedNewSegments = true
end end
elseif k ~= startSegi and k ~= endSegi then elseif k ~= startSegi and k ~= endSegi then
board1[j] = self.segments[k]:copy() board1[j] = self.segments[k]:copy()
j = j + 1 j = j + 1
end end
@@ -417,7 +442,7 @@ function Level:cutLevel()
end end
-- print("order segments in cutlevel board1") -- print("order segments in cutlevel board1")
board1 = self:orderSegments(board1) board1 = self:orderSegments(board1)
self:calculateSegmentFaces(board1,board1[1].face) self:calculateSegmentFaces(board1, board1[1].face)
-- print("PREPARE BOARD 1 -- FINAL") -- print("PREPARE BOARD 1 -- FINAL")
-- print_r(board1) -- print_r(board1)
@@ -468,7 +493,7 @@ function Level:cutLevel()
-- print_r(board2) -- print_r(board2)
-- print('insert the saved start segment') -- print('insert the saved start segment')
-- insert new segments reverse order -- insert new segments reverse order
board2[j] = savedStart board2[j] = savedStart
j = j + 1 j = j + 1
-- print_r(board2) -- print_r(board2)
-- print('-- insert the new segments in reverse order') -- print('-- insert the new segments in reverse order')
@@ -478,14 +503,14 @@ function Level:cutLevel()
board2[j]:switchDirection() board2[j]:switchDirection()
j = j + 1 j = j + 1
i = i - 1 i = i - 1
end end
-- print('-- inserted new segments, final board2 before ordering') -- print('-- inserted new segments, final board2 before ordering')
-- print_r(board2) -- print_r(board2)
end end
-- print("order segments in cutlevel board2") -- print("order segments in cutlevel board2")
board2 = self:orderSegments(board2) board2 = self:orderSegments(board2)
self:calculateSegmentFaces(board2,board2[1].face) self:calculateSegmentFaces(board2, board2[1].face)
-- print("PREPARE BOARD 2 -- FINAL") -- print("PREPARE BOARD 2 -- FINAL")
-- print_r(board2) -- print_r(board2)
@@ -494,20 +519,21 @@ function Level:cutLevel()
elseif self:containsBalls(board2) == 0 then elseif self:containsBalls(board2) == 0 then
self.segments = board1 self.segments = board1
else else
self.segments = self:getPerimeter(board1) > self:getPerimeter(board2) and board1 or board2 self.segments = self:getPerimeter(board1) >
self:getPerimeter(board2) and board1 or board2
end end
end end
end end
function Level:orderSegments(segs) function Level:orderSegments(segs)
--returns the list of segments in the level linked to each other in order and perpendicular to each other -- returns the list of segments in the level linked to each other in order and perpendicular to each other
local new = {} local new = {}
-- -- print('----- order Segments : ') -- -- print('----- order Segments : ')
-- print_s(segs) -- print_s(segs)
new[1] = segs[1] new[1] = segs[1]
table.remove(segs,1) table.remove(segs, 1)
local found = false local found = false
local k = #segs local k = #segs
@@ -517,60 +543,66 @@ function Level:orderSegments(segs)
-- print_s(new) -- print_s(new)
-- -- print(' --new search') -- -- print(' --new search')
-- print_s(segs) -- print_s(segs)
for j, s in ipairs(segs) do for j, s in ipairs(segs) do
-- -- print("test if j is next segment to i, j = "..tostring(j)) -- -- print("test if j is next segment to i, j = "..tostring(j))
if new[i]:endEqualsStartOf(s) then if new[i]:endEqualsStartOf(s) then
found = true found = true
-- -- print("new[i] end equals start of ") -- -- print("new[i] end equals start of ")
-- s:debug() -- s:debug()
if new[i].vertical == s.vertical and new[i].horizontal == s.horizontal then if new[i].vertical == s.vertical and new[i].horizontal ==
s.horizontal then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(j)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(j))
new[i]:joinContiguous(s) new[i]:joinContiguous(s)
table.remove(segs,j) table.remove(segs, j)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
break break
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j))
s:joinPerpendicular(new[i]) s:joinPerpendicular(new[i])
new[i+1] = s new[i + 1] = s
table.remove(segs,j) table.remove(segs, j)
break break
end end
elseif new[i]:endEqualsEndOf(s) then elseif new[i]:endEqualsEndOf(s) then
found = true found = true
-- -- print("new[i] end equals end of ") -- -- print("new[i] end equals end of ")
-- s:debug() -- s:debug()
s:switchDirection() s:switchDirection()
if new[i].vertical == s.vertical and new[i].horizontal == s.horizontal then if new[i].vertical == s.vertical and new[i].horizontal ==
s.horizontal then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(j)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(j))
new[i]:joinContiguous(s) new[i]:joinContiguous(s)
table.remove(segs,j) table.remove(segs, j)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
break break
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j))
s:joinPerpendicular(new[i]) s:joinPerpendicular(new[i])
new[i+1] = s new[i + 1] = s
table.remove(segs,j) table.remove(segs, j)
break break
end end
end end
end end
local fi, fs = 0,{} local fi, fs = 0, {}
if not found then if not found then
-- -- print("search didnt yield any segment") -- -- print("search didnt yield any segment")
local margin = 2 local margin = 2
while not found and margin < 5 do while not found and margin < 5 do
fi, fs = self:findNearestSegment(new[i].secondPointX,new[i].secondPointY,segs,margin) fi, fs = self:findNearestSegment(new[i].secondPointX,
new[i].secondPointY, segs,
margin)
if not fs then if not fs then
fi, fs = self:findNearestSegment(new[i].firstPointX,new[i].firstPointY,segs,margin) fi, fs = self:findNearestSegment(new[i].firstPointX,
new[i].firstPointY, segs,
margin)
if not fs then if not fs then
margin = margin + 1 margin = margin + 1
@@ -586,20 +618,20 @@ function Level:orderSegments(segs)
if new[i].vertical == fs.vertical then if new[i].vertical == fs.vertical then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(fi)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(fi))
new[i]:joinContiguous(fs) new[i]:joinContiguous(fs)
table.remove(segs,fi) table.remove(segs, fi)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(fi)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(fi))
fs:joinPerpendicular(new[i]) fs:joinPerpendicular(new[i])
new[i+1] = fs new[i + 1] = fs
table.remove(segs,fi) table.remove(segs, fi)
end end
end end
end end
if not found then if not found then
-- print("ERROR -- order segments does not find next segment to ") -- print("ERROR -- order segments does not find next segment to ")
new[i]:debug("number: " ..tostring(i)) new[i]:debug("number: " .. tostring(i))
break break
else else
found = false found = false
@@ -616,16 +648,16 @@ function Level:calculateSegmentFaces(segments, firstFace)
local face = firstFace local face = firstFace
for k, s in ipairs(segments) do for k, s in ipairs(segments) do
s.face = face s.face = face
if k + 1 <= #segments then if k + 1 <= #segments then
if face == 'up' then if face == 'up' then
if s.direction == 'right' then if s.direction == 'right' then
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'left' face = 'left'
else else
face = 'right' face = 'right'
end end
else else
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'right' face = 'right'
else else
face = 'left' face = 'left'
@@ -633,13 +665,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'down' then elseif face == 'down' then
if s.direction == 'right' then if s.direction == 'right' then
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'right' face = 'right'
else else
face = 'left' face = 'left'
end end
else else
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'left' face = 'left'
else else
face = 'right' face = 'right'
@@ -647,13 +679,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'right' then elseif face == 'right' then
if s.direction == 'up' then if s.direction == 'up' then
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'down' face = 'down'
else else
face = 'up' face = 'up'
end end
else else
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'up' face = 'up'
else else
face = 'down' face = 'down'
@@ -661,13 +693,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'left' then elseif face == 'left' then
if s.direction == 'up' then if s.direction == 'up' then
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'up' face = 'up'
else else
face = 'down' face = 'down'
end end
else else
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'down' face = 'down'
else else
face = 'up' face = 'up'
@@ -680,54 +712,45 @@ end
function Level:getPerimeter(segments) function Level:getPerimeter(segments)
local p = 0 local p = 0
if not segments then if not segments then segments = self.segments end
segments = self.segments for k, s in pairs(segments) do p = p + s:length() end
end
for k, s in pairs(segments) do
p = p + s:length()
end
return p return p
end end
function Level:findNearestSegment(x,y,segments,margin) function Level:findNearestSegment(x, y, segments, margin)
if not segments then if not segments then segments = self.segments end
segments = self.segments if not margin then margin = 2 end
end
if not margin then
margin = 2
end
-- find a touching segment within margins -- find a touching segment within margins
for i,segment in pairs(segments) do for i, segment in pairs(segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return i, segment return i, segment
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return i, segment return i, segment
end end
end end
end end
return nil, nil return nil, nil
end end
function Level:containsBalls(segments) function Level:containsBalls(segments)
-- returns numbere of balls inside the bounds passed in or self.segments -- returns numbere of balls inside the bounds passed in or self.segments
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local counter = 0 local counter = 0
for k,b in pairs(self.balls) do for k, b in pairs(self.balls) do
if self:insideBounds(b.x + 4, b.y + 4,segments) or self:pointOnEdge(b.x+4, b.y+4, seegments) then if self:insideBounds(b.x + 4, b.y + 4, segments) or
self:pointOnEdge(b.x + 4, b.y + 4, seegments) then
counter = counter + 1 counter = counter + 1
end end
end end
return counter return counter
end end

View File

@@ -70,4 +70,47 @@ function print_s(segments)
for k, s in ipairs(segments) do for k, s in ipairs(segments) do
s:debug(tostring(k)) s:debug(tostring(k))
end end
end end
-- convert a list of points forming a polygon {x1, y1, x2, y2, ...} into a mesh
function poly2mesh(points)
-- remove duplicates???
local polypts = love.math.triangulate(points)
local tlist
local vnums = {}
local vcoords = {}
do
local verthash = {}
local n = 0
local v
-- use unique vertices by using a coordinate hash table
for i = 1, #polypts do
for j = 1, 3 do
local px = polypts[i][j * 2 - 1]
local py = polypts[i][j * 2]
if not verthash[px] then verthash[px] = {} end
if not verthash[px][py] then
n = n + 1
verthash[px][py] = n
vcoords[n * 2 - 1] = px
vcoords[n * 2] = py
v = n
else
v = verthash[px][py]
end
vnums[(i - 1) * 3 + j] = v
end
end
end
local mesh = love.graphics.newMesh(#vcoords, "triangles", "static")
for i = 1, #vcoords / 2 do
local x, y = vcoords[i * 2 - 1], vcoords[i * 2]
-- Here's where the UVs are assigned
mesh:setVertex(i, x, y, x / 50, y / 50, .5, .5, .9, 1)
end
mesh:setVertexMap(vnums)
return mesh
end

View File

@@ -21,7 +21,7 @@ function PlayState:enter()
end end
function PlayState:update(dt) function PlayState:update(dt)
-- self.level:update(dt) self.level:update(dt)
self.player:update(dt) self.player:update(dt)
self:updateBalls(dt, self.level) self:updateBalls(dt, self.level)
end end