Any way to make the slopes system more efficient?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
oscaradalid
Prole
Posts: 16
Joined: Wed May 09, 2018 11:48 am

Any way to make the slopes system more efficient?

Post by oscaradalid »

Code: Select all

-- Variables para los polígonos
local polygons = {
    -- Primer polígono
    {
        {200, 400},
        {200, 250},
        {560, 250},
        {650, 400}
    },
    -- Segundo polígono (un triángulo)
    {
        {0, 400},
        {200, 250},
        {400, 500}
    }
}

local playerDirection = 1  -- Inicialmente se mueve hacia la derecha
local playerVerticalDirection = 0  -- Inicialmente sin movimiento vertical
local lastRectY = 0  -- Para almacenar la última posición vertical del rectángulo

-- Variables para el rectángulo
local rectX, rectY = 260, 0  -- Empieza fuera de la pantalla
local rectW, rectH = 40, 60
local rectVelocityY = 0
local gravity = 500  -- Aceleración debida a la gravedad
local jumpForce = -600  -- Fuerza del salto
local moveSpeed = 200 -- Velocidad de movimiento horizontal
local collisionTolerance = 0 -- Tolerancia de colisión en píxeles
local isColliding = false -- Variable para controlar si hay colisión
local anclar = false
local saltando = false

-- Colores
local polygonColor = {0, 1, 0}  -- Verde
local rectColor = {1, 0, 0}  -- Rojo
local collisionColor = {1, 1, 0}  -- Amarillo

-- Estado de las teclas
local keysPressed = {
    left = false,
    right = false,
    jump = false
}

-- Inicializa LÖVE
function love.load()
    -- Define el rectángulo y la gravedad
    rectY = 0  -- Empieza desde arriba
    rectVelocityY = 0
    lastRectY = rectY  -- Guarda la posición inicial
end

-- Actualiza la lógica del juego
function love.update(dt)
    -- Verifica si se está presionando alguna tecla de movimiento
    keysPressed.left = love.keyboard.isDown("left")
    keysPressed.right = love.keyboard.isDown("right")
    keysPressed.jump = love.keyboard.isDown("space")

    if anclar then
        moveSpeed = 250
    end

    if playerVerticalDirection == 0 then
        gravity = 1500
    end

    -- Determina la dirección horizontal
    if keysPressed.right then
        playerDirection = 1
    elseif keysPressed.left then
        playerDirection = -1
    else
        playerDirection = 0
    end

    if anclar and playerDirection == 0 then
        -- gravity = 0
    end

    -- Aplica la gravedad
    rectVelocityY = rectVelocityY + gravity * dt
    rectY = rectY + rectVelocityY * dt

    -- Verifica colisión con todos los polígonos
    local collides = false
    for _, polygon in ipairs(polygons) do
        local currentCollision, _ = rectCollidesWithPolygon(rectX, rectY, rectW, rectH, polygon)
        if currentCollision then
            collides = true
            -- Ajusta la posición del rectángulo para evitar la colisión y posicionarlo en la arista con tolerancia
            rectX, rectY = adjustPositionToEdge(rectX, rectY, rectW, rectH, polygon)
            rectVelocityY = 0  -- Detener la velocidad vertical
            isOnGround = true -- El rectángulo está en el suelo
            playerVerticalDirection = 0  -- No se mueve verticalmente
            anclar = true
            break
        end
    end

    if not collides then
        isOnGround = false -- El rectángulo no está en el suelo
        -- Determina la dirección vertical comparando la posición actual con la anterior
        if rectY > lastRectY then
            playerVerticalDirection = 1  -- Está cayendo
        elseif rectY < lastRectY then
            playerVerticalDirection = -1  -- Está subiendo
        end

        -- Nuevo bloque: Bajar 1 píxel hasta colisionar
        if not keysPressed.jump and anclar then
            -- gravity = 10000
            moveSpeed = 0
            for i = 1, 4 do  
                rectY = rectY + 1  -- Baja 1 píxel en cada iteración
                collides = false
                for _, polygon in ipairs(polygons) do
                    local currentCollision, _ = rectCollidesWithPolygon(rectX, rectY, rectW, rectH, polygon)
                    if currentCollision then
                        collides = true
                        rectX, rectY = adjustPositionToEdge(rectX, rectY, rectW, rectH, polygon)
                        rectVelocityY = 0
                        isOnGround = true
                        playerVerticalDirection = 0
                        break
                    end
                end
                if collides then
                    break
                end
            end
            anclar = false
        end
    end

    -- Mueve el rectángulo con las teclas de flecha si se está presionando alguna tecla
    if playerDirection == 1 then
        rectX = rectX + moveSpeed * dt
    elseif playerDirection == -1 then
        rectX = rectX - moveSpeed * dt
    end

    -- Realiza el salto si la barra espaciadora está presionada y el rectángulo está en el suelo
    if keysPressed.jump and isOnGround then
        rectVelocityY = jumpForce
        isOnGround = false -- Después de saltar, el rectángulo ya no está en el suelo
        playerVerticalDirection = -1  -- Empezar a subir
        anclar = false
    end

    -- Actualiza la posición vertical anterior
    lastRectY = rectY
end

-- Dibuja los objetos en la pantalla
function love.draw()
    -- Dibuja todos los polígonos
    love.graphics.setColor(polygonColor)
    for _, polygon in ipairs(polygons) do
        love.graphics.polygon("line", getPolygonVertices(polygon))
    end

    -- Dibuja el rectángulo
    love.graphics.setColor(rectColor)
    love.graphics.rectangle("line", rectX, rectY, rectW, rectH)

    -- Si hay colisión, cambia el color del polígono y el rectángulo
    if isColliding then
        love.graphics.setColor(collisionColor)
        for _, polygon in ipairs(polygons) do
            love.graphics.polygon("line", getPolygonVertices(polygon))
        end
        love.graphics.rectangle("line", rectX, rectY, rectW, rectH)
    end

    -- Imprime las variables en pantalla
    love.graphics.setColor(1, 1, 1)  -- Cambia el color del texto a blanco
    love.graphics.print("Player Direction: " .. playerDirection, 10, 10)
    love.graphics.print("Player Vertical Direction: " .. playerVerticalDirection, 10, 30)
    love.graphics.print("Anclado: " .. tostring(anclar), 10, 60)
end

-- Funciones auxiliares
function getPolygonVertices(polygon)
    local vertices = {}
    for _, v in ipairs(polygon) do
        table.insert(vertices, v[1])
        table.insert(vertices, v[2])
    end
    return vertices
end

function getRectangleVertices(rx, ry, rw, rh)
    return {
        {rx, ry},
        {rx + rw, ry},
        {rx + rw, ry + rh},
        {rx, ry + rh}
    }
end

function pointInPolygon(px, py, polygon)
    local c = false
    local j = #polygon
    for i = 1, #polygon do
        local vi = polygon[i]
        local vj = polygon[j]
        if ((vi[2] > py) ~= (vj[2] > py)) and (px < (vj[1] - vi[1]) * (py - vi[2]) / (vj[2] - vi[2]) + vi[1]) then
            c = not c
        end
        j = i
    end
    return c
end

function rectCollidesWithPolygon(rx, ry, rw, rh, polygon)
    local rectVertices = getRectangleVertices(rx, ry, rw, rh)
    for _, vertex in ipairs(rectVertices) do
        local px, py = vertex[1], vertex[2]
        if pointInPolygon(px, py, polygon) then
            return true, nil
        end
    end

    for i = 1, #polygon do
        local nextIndex = (i % #polygon) + 1
        local x1, y1 = polygon[i][1], polygon[i][2]
        local x2, y2 = polygon[nextIndex][1], polygon[nextIndex][2]

        if rectEdgesIntersectPolygon(x1, y1, x2, y2, rx, ry, rw, rh, polygon) then
            local normal = lineNormal(x1, y1, x2, y2)
            return true, normal
        end
    end

    return false, nil
end

function rectEdgesIntersectPolygon(x1, y1, x2, y2, rx, ry, rw, rh, polygon)
    local rectEdges = {
        {rx, ry, rx + rw, ry},
        {rx + rw, ry, rx + rw, ry + rh},
        {rx + rw, ry + rh, rx, ry + rh},
        {rx, ry + rh, rx, ry}
    }

    for _, edge in ipairs(rectEdges) do
        local ex1, ey1, ex2, ey2 = edge[1], edge[2], edge[3], edge[4]

        for i = 1, #polygon do
            local nextIndex = (i % #polygon) + 1
            local px1, py1 = polygon[i][1], polygon[i][2]
            local px2, py2 = polygon[nextIndex][1], polygon[nextIndex][2]

            if linesIntersect(ex1, ey1, ex2, ey2, px1, py1, px2, py2) then
                return true
            end
        end
    end

    return false
end

function linesIntersect(x1, y1, x2, y2, x3, y3, x4, y4)
    local function ccw(Ax, Ay, Bx, By, Cx, Cy)
        return (Cy - Ay) * (Bx - Ax) > (By - Ay) * (Cx - Ax)
    end

    return ccw(x1, y1, x3, y3, x4, y4) ~= ccw(x2, y2, x3, y3, x4, y4) and
           ccw(x1, y1, x2, y2, x3, y3) ~= ccw(x1, y1, x2, y2, x4, y4)
end

-- Ajusta la posición del rectángulo sobre la arista del polígono con tolerancia
function adjustPositionToEdge(rectX, rectY, rectW, rectH, polygon)
    local minDist = math.huge
    local edgeX1, edgeY1, edgeX2, edgeY2
    local closestVertex

    -- Revisar cada arista del polígono
    for i = 1, #polygon do
        local nextIndex = (i % #polygon) + 1
        local x1, y1 = polygon[i][1], polygon[i][2]
        local x2, y2 = polygon[nextIndex][1], polygon[nextIndex][2]

        -- Revisar cada vértice del rectángulo
        for _, vertex in ipairs(getRectangleVertices(rectX, rectY, rectW, rectH)) do
            local dist = pointToLineDistance(vertex[1], vertex[2], x1, y1, x2, y2)
            if dist < minDist then
                minDist = dist
                edgeX1, edgeY1, edgeX2, edgeY2 = x1, y1, x2, y2
                closestVertex = vertex
            end
        end
    end

    -- Calcular el punto de intersección en la arista con tolerancia
    local normalX, normalY = lineNormal(edgeX1, edgeY1, edgeX2, edgeY2)
    local overlap = minDist - collisionTolerance

    -- Ajustar el rectángulo para que quede justo en la arista, con la tolerancia aplicada
    return rectX - normalX * overlap, rectY - normalY * overlap
end

-- Calcula la distancia desde un punto a una línea
function pointToLineDistance(px, py, x1, y1, x2, y2)
    local A = px - x1
    local B = py - y1
    local C = x2 - x1
    local D = y2 - y1
    local dot = A * C + B * D
    local len_sq = C * C + D * D
    local param = -1
    if len_sq ~= 0 then
        param = dot / len_sq
    end
    local xx, yy
    if param < 0 then
        xx, yy = x1, y1
    elseif param > 1 then
        xx, yy = x2, y2
    else
        xx = x1 + param * C
        yy = y1 + param * D
    end
    local dx = px - xx
    local dy = py - yy
    return math.sqrt(dx * dx + dy * dy)
end

-- Calcula la normal de una línea y la longitud
function lineNormal(x1, y1, x2, y2)
    local dx = x2 - x1
    local dy = y2 - y1
    local length = math.sqrt(dx * dx + dy * dy)
    return -dy / length, dx / length
end


User avatar
darkfrei
Party member
Posts: 1197
Joined: Sat Feb 08, 2020 11:09 pm

Re: Any way to make the slopes system more efficient?

Post by darkfrei »

oscaradalid wrote: Mon Aug 26, 2024 7:00 pm Any way to make the slopes system more efficient?

The main idea is to check if the moving point has collision with the slope / line:
viewtopic.php?p=255011#p255011

For the character rectangle here must be 4 moving points, each must be checked and the dx, dy must be shortened accordingly.
2024-08-27Code Doodles - Page 17 - LÖVE.png
2024-08-27Code Doodles - Page 17 - LÖVE.png (5.37 KiB) Viewed 11541 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
RNavega
Party member
Posts: 355
Joined: Sun Aug 16, 2020 1:28 pm

Re: Any way to make the slopes system more efficient?

Post by RNavega »

You could use LÖVE's physics module for collision against shapes, if it has the features you need.

Also, you didn't give any info on the game you're trying to make, and it's important to know bc if you're just going for a Metal Slug type of platforming, you can greatly simplify things by just using a vertical raycast and a polyline (a sequence of connected lines) as the imaginary collision shape. Getting the slope position from that vertical raycast is very simple, you do it against the segment of the polyline that the character is above. In your demo, that'd be the top edges of those polygons.

These are from the Metal Slug debug mode, showing the imaginary ground lines:

ms01.jpg
ms01.jpg (849.76 KiB) Viewed 11475 times
ms02.jpg
ms02.jpg (492.58 KiB) Viewed 11475 times
oscaradalid
Prole
Posts: 16
Joined: Wed May 09, 2018 11:48 am

Re: Any way to make the slopes system more efficient?

Post by oscaradalid »

Thank you for the answers, I am trying to apply a simple and efficient system. I am now attempting to implement what darkfrei has suggested. If I find the solution I publish it to share it.
oscaradalid
Prole
Posts: 16
Joined: Wed May 09, 2018 11:48 am

Re: Any way to make the slopes system more efficient?

Post by oscaradalid »

Gracias!!! ya he programado lo que pretendia,ahora a pulir codigo,hacerlo mas reducido y evitar unos pequeños problemas ,pero la parte complicada ya la tengo ..una forma de hacer un juego de plataformas facil XD.
teclas : left
right
space

Code: Select all

-- Inicialización de variables
point = {x = 300, y = 100, speed = 200, vy = 0, gravity = 1000, ancla = false, normal_x = 0, normal_y = 0, colision = false,pMovil = 0}
-- Variables para ajustar el offset de la cruz
local crossOffsetX = 0
local crossOffsetY = 0
-- Variables para guardar el tipo de segmento actual, anterior, colisión real y sentido del jugador
current_segment_type = "Ninguno"
previous_segment_type = "Ninguno"
colision_real = false
sentido_x = 0 -- Variable para el sentido del jugador en el eje X
en_superficie_recta = false -- Variable para verificar si estamos en una superficie recta

-- Variables para ajustar la longitud de las rectas perpendiculares
local crossLengthHorizontal = 12
local crossLengthVertical =  28 

-- Agrupación de segmentos según su tipo
segments = {
	rampas_ascendentes = {
		{340, 230, 500, 100},
		--  {300, 400, 400, 300}
	},
	rampas_descendentes = {
		{200, 100, 300, 480}, --azul
		--   {200, 200, 300, 300}
	},
	superficies_rectas = {
		{0, 100, 100, 100},
		{100, 100, 200, 100},
		{200, 200, 400, 200},
		{500, 100, 600, 100},
		{250, 150, 300, 150}



	},

	rampas_moviles = {
		{200, 500, 600, 500} --azul

	},

}





local function updateRampasMoviles(dt)
	local amplitude = -0.1 -- Amplitud del movimiento
	local frequency = 0.5 -- Frecuencia del movimiento
	local offset_y = amplitude * math.sin(frequency * love.timer.getTime())

	for _, segment in ipairs(segments.rampas_moviles) do
		segment[2] = segment[2] + offset_y
		segment[4] = segment[4] + offset_y
	end
end








-- Función para ajustar la dirección del movimiento del punto para que se deslice a lo largo del segmento
local function sliding(segmentDX, segmentDY, dx, dy)
	local dotProduct = dx * segmentDX + dy * segmentDY
	local segmentLength = math.sqrt(segmentDX * segmentDX + segmentDY * segmentDY)
	segmentDX = segmentDX / segmentLength
	segmentDY = segmentDY / segmentLength
	dx = segmentDX * dotProduct
	dy = segmentDY * dotProduct 
	return dx, dy
end








local function checkCollisionWithCross(px, py)
	local check_positions = {}
	-- Definir las dos rectas perpendiculares
	local horizontal_x1 = px - crossLengthHorizontal+ crossOffsetX
	local horizontal_y1 = py+ crossOffsetY
	local horizontal_x2 = px + crossLengthHorizontal+ crossOffsetX
	local horizontal_y2 = py+ crossOffsetY

	local vertical_x1 = px+ crossOffsetX
	local vertical_y1 = py - crossLengthVertical+ crossOffsetY
	local vertical_x2 = px+ crossOffsetX
	local vertical_y2 = py + crossLengthVertical+ crossOffsetY



	-- Comprobar intersección con los segmentos de rampas ascendentes
	for _, segment in ipairs(segments.rampas_ascendentes) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		if segmentsIntersect(horizontal_x1, horizontal_y1, horizontal_x2, horizontal_y2, x1, y1, x2, y2) or
		segmentsIntersect(vertical_x1, vertical_y1, vertical_x2, vertical_y2, x1, y1, x2, y2) then
			return "Rampa Ascendente"
		end
	end

	-- Comprobar intersección con los segmentos de rampas descendentes
	for _, segment in ipairs(segments.rampas_descendentes) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		if segmentsIntersect(horizontal_x1, horizontal_y1, horizontal_x2, horizontal_y2, x1, y1, x2, y2) or
		segmentsIntersect(vertical_x1, vertical_y1, vertical_x2, vertical_y2, x1, y1, x2, y2) then
			return "Rampa Descendente"
		end
	end

	-- Comprobar intersección con los segmentos de superficies rectas
	for _, segment in ipairs(segments.superficies_rectas) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		if segmentsIntersect(horizontal_x1, horizontal_y1, horizontal_x2, horizontal_y2, x1, y1, x2, y2) or
		segmentsIntersect(vertical_x1, vertical_y1, vertical_x2, vertical_y2, x1, y1, x2, y2) then
			return "Superficie Recta"
		end
	end

	-- Comprobar intersección con los segmentos de superficies rectas
	for _, segment in ipairs(segments.rampas_moviles) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		if segmentsIntersect(horizontal_x1, horizontal_y1, horizontal_x2, horizontal_y2, x1, y1, x2, y2) or
		segmentsIntersect(vertical_x1, vertical_y1, vertical_x2, vertical_y2, x1, y1, x2, y2) then
			return "PMovil"
		end
	end

	return "Ninguno"


end




-- Función para manejar la colisión entre el punto y un segmento
local function handlePointCollision(px, py, x1, y1, x2, y2, dx, dy, segment_type)
	local segmentDX = x2 - x1
	local segmentDY = y2 - y1
	local segmentLength = math.sqrt(segmentDX * segmentDX + segmentDY * segmentDY)
	segmentDX = segmentDX / segmentLength
	segmentDY = segmentDY / segmentLength

	local dotProduct = (px - x1) * segmentDY - (py - y1) * segmentDX
	local dotProduct2 = (px + dx - x1) * segmentDY - (py + dy - y1) * segmentDX

	if not (dotProduct > -1/256 and dotProduct2 < 0) then
		-- No hay cruce del segmento desde el lado positivo al negativo
		return dx, dy
	end

	local segmentDot = (px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)
	local t = segmentDot / (segmentLength * segmentLength)

	if t >= 0 and t <= 1 then
	
		-- Colisión con el segmento
		point.colision = true
		point.normal_x = -segmentDY
		point.normal_y = segmentDX

		-- Si el tipo de segmento cambia, actualizar previous_segment_type
		if current_segment_type ~= segment_type then
			previous_segment_type = current_segment_type
			current_segment_type = segment_type
		end
		-- Actualizar la variable de colisión con la plataforma móvil
		if segment_type == "Rampa Móvil" then
           point.pMovil = 1
		end

		colision_real = true  -- Indicar que hay una colisión real
		return sliding(segmentDX, segmentDY, dx, dy)
	else
		-- No hay colisión con el segmento
		return dx, dy
	end
end

-- Función auxiliar para verificar si un punto está en un segmento
local function pointOnSegment(px, py, x1, y1, x2, y2)
	local crossProduct = (py - y1) * (x2 - x1) - (px - x1) * (y2 - y1)
	if math.abs(crossProduct) > 1e-10 then
		return false
	end
	local dotProduct = (px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)
	if dotProduct < 0 then
		return false
	end
	local squaredLength = (x2 - x1)^2 + (y2 - y1)^2
	return dotProduct <= squaredLength
end


----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------

function love.update(dt)
	local px, py = point.x, point.y
	local speed = point.speed
	local dx, dy = 0, point.vy * dt
	local saltando = false
crossOffsetY = 0

	updateRampasMoviles(dt)

	-- Verifica si el punto está en colisión y permite el salto
	if love.keyboard.isDown("space") and point.colision then
		if point.pMovil == 1 then
		   point.pMovil = 0
		end
		
		point.vy = -400  -- Velocidad del salto
		saltando = true
		point.colision = false  -- Evita múltiples saltos sin colisión
	end


   -- Aplicar la gravedad si no está anclado o en colisión
   
       -- Aplicar la gravedad si no está anclado o en colisión
    if not point.colision or current_segment_type == "Ninguno" and point.pMovil == 0 then
        point.vy = point.vy + point.gravity * dt
			crossOffsetY = -28
			
    else
		if current_segment_type == "Ninguno" then
		point.vy = 0
        dy = 0
		point.pMovil = 0
		end
		
        point.vy = 0
        dy = 0
		--if point.pMovil == 1 then
	
		--end
		
    end

     





	-- Movimiento basado en las teclas presionadas
	if love.keyboard.isDown("right") then
		if current_segment_type == "Rampa Descendente" then
			dy = speed * dt
		else
			dx = speed * dt
		end
		sentido_x = 1
	elseif love.keyboard.isDown("left") then
		if current_segment_type == "Rampa Ascendente" then
			dy = speed * dt
		else
			dx = -speed * dt
		end
		sentido_x = -1
	else
		sentido_x = 0
	end

	if love.keyboard.isDown("down") then
		dy = speed * dt
	elseif love.keyboard.isDown("up") then
		dy = -speed * dt
	end


	if saltando then

		if current_segment_type =="Rampa Ascendente"  and sentido_x ~= 0 then
			dx = -4
			dy =  -1


		end

		if current_segment_type =="Rampa Descendente" and sentido_x ~= 0 then


			dx = 6 
			dy = 1
		end


	end 



-- Determinar el tipo de segmento
	current_segment_type = checkCollisionWithCross(px, py)






-- Colisión con rampas ascendentes
	local new_dx, new_dy = dx, dy
	point.ancla = false  -- Reiniciar la variable de ancla
	for _, segment in ipairs(segments.rampas_ascendentes) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		new_dx, new_dy = handlePointCollision(px, py, x1, y1, x2, y2, new_dx, new_dy, "Rampa Ascendente")
	end

-- Colisión con rampas descendentes
	for _, segment in ipairs(segments.rampas_descendentes) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		new_dx, new_dy = handlePointCollision(px, py, x1, y1, x2, y2, new_dx, new_dy, "Rampa Descendente")
	end

-- Colisión con superficies rectas
	for _, segment in ipairs(segments.superficies_rectas) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		new_dx, new_dy = handlePointCollision(px, py, x1, y1, x2, y2, new_dx, new_dy, "Superficie Recta")
	end

	for _, segment in ipairs(segments.rampas_moviles) do
		local x1, y1 = segment[1], segment[2]
		local x2, y2 = segment[3], segment[4]
		new_dx, new_dy = handlePointCollision(px, py, x1, y1, x2, y2, new_dx, new_dy, "Rampa Móvil")

		-- Si el punto está en la plataforma móvil, hacer que siga la plataforma
	-- Si el punto está en la plataforma móvil, hacer que siga la plataforma
		if point.pMovil == 1 then
		 py= y1  -- Mantener la 'y' del punto igual a la 'y' de la plataforma móvil
		end 
	end
	


-- Actualizar la posición del punto
	point.x = px + new_dx
	point.y = py + new_dy
end




















-- Función para dibujar en pantalla
function love.draw()
	-- Dibujar las rampas ascendentes
	love.graphics.setColor(0, 1, 0) -- Verde para rampas ascendentes
	for _, segment in ipairs(segments.rampas_ascendentes) do
		love.graphics.line(segment)
	end

	-- Dibujar las rampas descendentes
	love.graphics.setColor(0, 0, 1) -- Azul para rampas descendentes
	for _, segment in ipairs(segments.rampas_descendentes) do
		love.graphics.line(segment)
	end

	-- Dibujar las superficies rectas
	love.graphics.setColor(1, 0, 0) -- Rojo para superficies rectas
	for _, segment in ipairs(segments.superficies_rectas) do
		love.graphics.line(segment)
	end


	-- Dibujar las rampas moviles
	love.graphics.setColor(1, 1, 1) -- Rojo para superficies rectas
	for _, segment in ipairs(segments.rampas_moviles) do
		love.graphics.line(segment)
	end



	-- Dibujar el punto
	love.graphics.setColor(1, 1, 0) -- Amarillo para el punto
	love.graphics.circle("fill", point.x, point.y, 5)

	-- Dibujar la cruz alrededor del punto con offset independiente
	love.graphics.setColor(1, 1, 1) -- Blanco para la cruz
	love.graphics.line(point.x - crossLengthHorizontal + crossOffsetX, point.y + crossOffsetY,
		point.x + crossLengthHorizontal + crossOffsetX, point.y + crossOffsetY)
	love.graphics.line(point.x + crossOffsetX, point.y - crossLengthVertical + crossOffsetY,
		point.x + crossOffsetX, point.y + crossLengthVertical + crossOffsetY)

	-- Imprimir el estado de colisión y tipo de rampa en pantalla
	love.graphics.setColor(1, 1, 1) -- Blanco para el texto
	love.graphics.print("Colisión: " .. tostring(point.colision), 10, 10)
	love.graphics.print("Tipo de segmento actual: " .. current_segment_type, 10, 30)
	love.graphics.print("Tipo de segmento anterior: " .. previous_segment_type, 10, 50)
	love.graphics.print("Colisión real: " .. tostring(colision_real), 10, 70)
	love.graphics.print("Sentido X: " .. sentido_x, 10, 90)
	-- Dibuja el valor de colision_con_plataforma_movil en pantalla
	love.graphics.setColor(1, 1, 1)
	love.graphics.print("Colisión con plataforma móvil: " .. tostring(point.pMovil), 10, 120)

end


-- Función para comprobar la intersección de dos segmentos
function segmentsIntersect(x1, y1, x2, y2, x3, y3, x4, y4)
	local function orientation(px, py, qx, qy, rx, ry)
		local val = (qy - py) * (rx - qx) - (qx - px) * (ry - qy)
		if val == 0 then return 0 end
		return (val > 0) and 1 or 2
	end

	local o1 = orientation(x1, y1, x2, y2, x3, y3)
	local o2 = orientation(x1, y1, x2, y2, x4, y4)
	local o3 = orientation(x3, y3, x4, y4, x1, y1)
	local o4 = orientation(x3, y3, x4, y4, x2, y2)

	if o1 ~= o2 and o3 ~= o4 then
		return true
	end

	return false
end

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 4 guests