직사각형 블록으로 곡면을 만들려면 어떻게해야합니까?


12

A에 대한 Peggle의 -like 게임,이 같은 곡선을 따라 블록을 만들고 싶어 :

커브를 따라 블록

그러면 공이 맞으면 블록이 사라집니다.

가로로 그릴 수는 있지만 경로를 따라가는 데 문제가 있습니다.

경로 추적 블록에 대한 나의 시도

어떻게해야합니까? 사용자 정점으로 Box2D 객체 를 만들어야 합니까?


상자가 단순히 겹치지 않게 하시겠습니까, 아니면 어디에도 틈이 없도록 하시겠습니까? ( "객체 각도에 따라 객체 Y 축을 오프셋"한다는 것은 무슨 의미인지 잘 모르겠습니다).
Roy T.

1
당신은 겹치지과 곡선을 채울 수없는 사각형 이거야, 그래서 해야 더 격차를 원하지 않을 경우 일부 사용자 지정 geomety을 만들 수 있습니다.
Anko

@RoyT. 그 차이는 중요하지 않습니다. 내 진짜 문제는 서로 다른 각도로 서로 따르는 블록의 위치를 ​​계산하는 것입니다.
Moerin

내가 접근하는 방법은 각 상자 사이의 공통 모서리로 작동하는 일련의 정점을 정의하는 것입니다. 경로를 사용하여 경로를 정의하더라도 정점 사이의 거리와 각 상자의 길이를 정의하려면 추가 매개 변수가 필요합니다.

4
첫 번째 이미지의 "상자"는 상자가 아니며 삼각형 쌍입니다. i.stack.imgur.com/Tzuql.png
egarcia

답변:


14

"루트"곡선이 주어지면 블록 정점을 생성하는 방법은 다음과 같습니다.

블록 베 지어

루트 곡선은 가운데에 검은 색입니다. 제어점은 빨간색으로 표시됩니다 X.

한마디로 : 나는 베 지어를 만들고 (구성 가능한 속도로) 샘플링했습니다. I는 발견 직교 벡터 , 다음에 각 샘플로부터의 벡터를 정규화 하여, 그리고 스케일링 오른쪽에 반비례 한 다음, 제 왼쪽으로하는 (구성) 절반 폭에. 그런 다음 그것을 그렸습니다.

이것에 추가 할 수있는 것들 :


여기 내 코드가 있습니다. 그것은로 작성 루아 합니다 (대한 사랑 게임 프레임 워크), 그러나 나는 누군가를 위해 읽을 생각합니다.

local v = require "vector"

-- A function that makes bezier functions
-- Beziers have start point     p0
--              control point   p1
--              end point       p2
local function makeBezierFunction(p0,p1,p2)
    return function (t)
        local pow = math.pow
        return pow( (1-t),2 ) * p0
               + 2 * (1-t) * t * p1
               + pow(t,2) * p2
    end
end

love.graphics.setBackgroundColor(255, 255, 255)
function love.draw()
    local line = love.graphics.line
    local colour = love.graphics.setColor

    -- Bezier sampling parameters
    local nSegments = 10
    local segIncr = 1/nSegments

    -- Bezier definition: Start (`p0`), control (`p1`) and end `p2`) point
    local p0 = v(100,100)
    local p1 = v( love.mouse.getX(), love.mouse.getY() )
    local p2 = v(500,100)
    local controlPoints = {p0,p1,p2}
    local bez = makeBezierFunction(p0,p1,p2)

    -- Sample the bezier
    for i=0,1-segIncr,segIncr do
        colour(0, 0, 0)
        local x1,y1 = bez(i        ):unpack()
        local x2,y2 = bez(i+segIncr):unpack()
        line(x1,y1,x2,y2)

        -- Find left and right points.
        local center = v(x1, y1)
        local forward = v(x2, y2) - center
        local left = center + forward:perpendicular():normalize_inplace() * 10
        local right = center - forward:perpendicular():normalize_inplace() * 10

        -- Draw a line between them.
        line(left.x, left.y, right.x, right.y)

        -- Find *next* left and right points, if we're not beyond the end of
        -- the curve.
        if i + segIncr <= 1 then
            local x3, y3 = bez(i+segIncr*2):unpack()
            local center2 = v(x2, y2)
            local forward2 = v(x3, y3) - center2
            local left2 = center2 + forward2:perpendicular():normalize_inplace() * 10
            local right2 = center2 - forward2:perpendicular():normalize_inplace() * 10

            -- Connect the left and right of the current to the next point,
            -- forming the top and bottom surface of the blocks.
            colour(0, 0xff, 0)
            line(left.x, left.y, left2.x, left2.y)
            colour(0, 0, 0xff)
            line(right.x, right.y, right2.x, right2.y)
        end
    end

    -- Draw an X at the control points
    for _,p in ipairs(controlPoints) do
        local x,y = p:unpack()
        colour(0xff,0x00,0x00)
        line(x-5,y-5, x+5,y+5)
        line(x-5,y+5, x+5,y-5)
    end
    -- Draw lines between control points
    for i=1,#controlPoints do
        colour(0xff,0x00,0x00, 100)
        local cp1 = controlPoints[i]
        local cp2 = controlPoints[i+1]
        if cp1 and cp2 then
            line(cp1.x, cp1.y
                ,cp2.x, cp2.y)
        end
    end
end

당신이 그것을 가지고 놀고 싶다면 : LÖVE를 얻고 위의 코드를 main.lua자체 디렉토리에 넣으 십시오 . 넣어 vector.lua으로부터 HUMP같은 디렉토리에 라이브러리입니다. love <that-directory>명령 행에서 와 같이 실행하십시오 .

마우스를 움직여 라! 중간 제어점은 마우스 위치로 설정됩니다.

마우스로 제어점 설정


Anko는 LibGdx를 사용해 보셨습니까? 그렇다면 Löve를 선호합니까? 현재 게임 후 표준 안드로이드 API를 사용하지 않고 LibGdx와 Löve를 결정하려고합니다. 위의 btw처럼 흥미로운 답변
Green_qaue

@Anko 감사합니다. 예상보다 많이 들었습니다. 더 많이 LUA와 비슷한 내 게임에 MonkeyX를 사용하기 때문에 코드를 쉽게 이해할 수 있다고 생각합니다.
Moerin

1
@iQ Libgdx를 사용하지는 않았지만 그것에 대해 많이 읽었으며 Java를 잘 알고 있습니다. Libgdx는 크다 . (이것은 가속도계 지원, 커브 생성기 및 모든 것에 내장되어 있음) Love2D는 매우 작습니다 (아무 것도없고 쉐이더 지원이 없습니다). 그럼에도 불구하고 Love2D는 단순성 덕분에 빠른 프로토 타입과 작은 게임에는 훌륭했지만 일부 프로젝트에는 너무 미니멀 할 수 있습니다. 누가 알아. (당신이 해보십시오 ! 보십시오 : D)
Anko

훌륭한 답변, 그리고 그 GIF는 정말 좋은 보너스입니다!
Roy T.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.