플랫 포머 게임에서 스윙을 쉽게 구현하려면 어떻게해야합니까?


9

스파이더 맨이나 바이오닉 코만도 처럼 로프를 사용하여 스윙 할 수있는 게임을 개발 중이며이 동작을 구현하는 데 문제가 있습니다. 누구 든지이 작업을 수행하는 방법을 도울 수 있습니까? 물리학 수식 등을 의미합니다. 지금까지 3 가지 아이디어를 생각해 냈습니다. 하나는 봄을 사용하지만 많은 시간을 소비하며 때로는 삐걱 거리는 경우가 있습니다. 다른 두 개는 다음 단계를 계산하려고 시도하고 (하나는 전위 에너지를 계산하고 다른 하나는 토크를 계산하여) 배우가 스윙하려고 할 때마다 둘 다 거의 충돌합니다.

토크를 계산하기 위해 작성한 코드는 다음과 같습니다.

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

관련 (로프를 만들 때) : 2D 로프 충돌 감지
doppelgreener

@JonathanHobbs 그 질문에 대한 대답은 정확히 한 가지 예외로 로프를 구현하려고하는 방법입니다. 충돌이 필 요하지 않기 때문에 모든 로프 부분을 센서로 설정하여 서로 붙어 있지 않고 자유롭게 움직일 수 있습니다.
Ali1S232

로프 용 간단한 진자 + 로프 피한 애니메이션은 어떻습니까? Bionic Commando와 같은 오래된 게임에는 진자가 아닌 다른 것이 있다고 생각하지 않습니다.
user712092

@ 사용자 진자 아이디어가 잘 작동해야합니다. 그러나 제 경우에는 플레이어의 빠른 움직임이나 나쁜 구현으로 인해 좋은 결과를 얻지 못했습니다.
Ali1S232

@Gajet은 제대로 될 때까지 디버그 드로잉을 시도합니까? 이 진자 라인은 Box2D에서 충분히 얇은 상자로 수행되어 충돌을 일으킬 수 있습니다 (물리에서 제외하고 손으로 움직일 수 있습니까?).
user712092

답변:


6

강성 스윙을 원하면 회전 점까지의 거리가 일정하므로 문자를 회전 점 중심의 원점으로 취급하면됩니다. 그에게 1 차원 (원을 따라) 각속도를 줘. 각가속도 accelerationDueToGravity * cos(angleOfPlayerOnCircle)가 0 이어야하는 각 프레임은 오른쪽으로 향해야합니다.

로프의 길이를 늘리거나 줄이려면 위의 구성표를 사용하고 각 프레임의 반경을 변경할 수 있습니다.


당신은 내 두 번째 시도했지만 대답은 내 질문을 편집하고 내 코드를 추가해야 할 정도로 훨씬 더 빠른 속도로 움직입니다. 어쩌면 문제가 있는지 알 수 있습니다.
Ali1S232

3

많은 시도 후에 나는 box2d와 함께 갔다.

이 시뮬레이션에 대해 일반적으로 두 가지 접근 방식이 있거나 적어도 2를 찾았습니다.

  1. 하나는 원 모양을 사용하고 먼 조인트를 사용하여 연결하는 것입니다.
  2. 다른 하나는 체인 자체의 사각형에 대한 것이고 회전 조인트를 사용하여 부착하는 것입니다.

각 시나리오에서 당신은 ancher (내 경우에는 정적 박스)를 가져야합니다. 예를 들어보다 사실적인 물리를 얻기 위해 로프 부품의 무게를 낮추면 (원형 또는 직사각형 모양을 사용하는 것이) 좋습니다. 밀도를 0.1로 설정하고 로프 끝에 연결된 상자에 밀도 10을 사용했습니다.

로프 세그먼트가 서로 반응하는 방식에 대해 걱정해야 할 또 다른 사항입니다. 방금 로프가 장면에서 자유롭게 움직이기를 원했기 때문에 모든 로프 고정구를 센서로 표시했습니다. 다른 접근 방식이 필요할 수 있습니다.

다음으로 걱정해야 할 것은 월드 업데이트에 페이징하는 반복 횟수입니다. 로프의 낮은 세그먼트 (최대 8)는 높은 반복 값을 사용할 필요가 없습니다 .10 / 2는 box2d 자체 제안 충분하지만 세그먼트의 수를 늘리면 예를 들어 30 개의 세그먼트를 시도했지만 반복 횟수가 적 으면 로프가 길이를 더 길게 늘리는 것처럼 보이므로 해당 상황을 해결하기 위해 40/40 반복이 필요할 수 있습니다.

일부 테스트 후 box 2d는 0.1m ~ 10m의 객체 크기를 가진 장면을 위해 설계된 것으로 보이며 큰 장면에 제안 된 최대 크기는 약 50mx50m입니다. 따라서 기본적으로 이러한 매개 변수와 일치하도록 객체를 축소해야합니다. 필자의 경우 먼저 픽셀 위치를 box2d로 직접 전달하려고 시도했지만 세계가 빨리 움직여야하는 속도 제한이있는 것처럼 보였으므로 최상의 결과를 얻으려면 장면을 64 배 정도 조정해야했습니다. 내가 직접 테스트하지는 않았지만 box2d에는 더 큰 장면을 사용하지 못하게하는 몇 가지 제한이 있습니다. 예를 들어 box2d 설정을 변경할 수 있는 b2Setting.h파일에 정의 된 값이 #define b2_maxTranslation 2.0f있지만 권장되지 않는 것 같습니다.


box2d가 왜 다운 보트를 얻었 을까요?
Ali1S232

이것은 질문에 대답하지 않습니다. 적어도 Box2D를 사용하여 어떻게 작동하게 했는지 기록하십시오 .
bummzack 2016 년

@bummzack : 알았어. 내 대답에 추가하겠습니다.
Ali1S232

이것을 답변으로 받아들이면 결함이있는 경우 질문이됩니다. 세그먼트 화 된 로프 물리학은 설명한 것과 크게 다릅니다.
AttackingHobo

@attackingHobo : 당시 쿼리는 정확했지만 코드를 box2d로 변환 할 때 많은 노력없이 세그먼트 로프 물리를 구현할 수 있다는 것을 알았습니다. 그리고 그것은별로 다르지 않습니다. 제 질문은 세그먼트 로프의 한 세그먼트라고 생각하십시오. 거의 모든 솔루션은 box2d없이 원형 ​​스타일 로프를 구현하는 방법이었습니다.
Ali1S232 2016

2

로프가 연직선 (중앙)에서 얼마나 떨어져 있는지에 따라 스윙 운동 속도를 늦추는 것을 고려 했습니까?


로프의 길이는 3 개의 모든 접근에서 스윙 속도를 계산하는 데 사용 된 매개 변수 중 하나입니다. 그러나 나는 그것을 올바르게 사용했다고 보증 할 수 없습니다. 방금 실제 계산을 수행하고 해결 된 버전을 게임에 적용했습니다.
Ali1S232

중앙에서 멀어 질수록 로프 스윙의 다음 움직임 전에 지연 시간이 길어집니다. 지연의 ABSolute 값에 0.28과 같은 값을 곱할 수도 있습니다 (이를 실험해야 함).
랜돌프 리차드슨

다음 단계를 계산할 때 delta_time에 대한 상수 값이 있고 내가 가지고있는 모든 매개 변수 (예 : 이전 속도, 이전 위치, 로프 길이 등)를 사용하여 계산하려고하는 것을 얻을 수 없습니다. 새 속도를 지정한 다음이 속도에 delta_time을 곱한 값을 마지막 위치에 더하여 새 위치를 생성하십시오. 다른 의미가 있으면 답변에 자세한 내용을 입력하십시오.
Ali1S232

1

플레이어가 로프의 길이보다 길면 플레이어는 지나간 거리와 같은 힘으로 즉시 뒤로 밀려납니다. 탄력이 없어야하며 플레이어에게 직관적으로 느껴 져야합니다. 게임에서 최상의 결과를 얻으려면 물리를 조정해야 할 수도 있습니다.

로프가 부착 된 경우. 저장maxLength값을 .

각 업데이트는 확인 distance사이를player , 그리고attachPoint

는 경우 distance댄 적은maxLength 일반적으로 업데이트 로프에서 효과없이.

거리가 ~보다 큰 경우 에서 ~까지 플레이어를 maxLength찾으십시오 . 사이의 차이를 가져 와 . 받는 사람 추가 ,normalattachPointdistancemaxLengthplayerVelocitynormal 차이를 곱한.

의사 코드 :

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

그래서 내가 당신의 대답으로 편집 한 코드 (미안하지만 추가 할 곳을 찾지 못했습니다)는 당신이 제안하는 코드입니까?
Ali1S232

나는 편집을 승인했고, 그래야한다고 생각합니다. 이전에는 로프 물리학을 사용하고 훨씬 더 복잡한 방법으로 동일한 작업을 수행했지만이 코드가 제대로 작동하는지 확실하지는 않지만 코드가 제대로 작동해야한다고 생각합니다. 거기에 방법의 %.
AttackingHobo

일부 시도 후 나는이 문제에 대한 당신은 당신이 너무 그 코드를 변경해야하는 방식으로 Box2D의 노력 갈거야 생각 dx = player.x - attachpoint.x하고 dy = player.y - attachpoint.y.
Ali1S232

1

http://www.cocos2d-iphone.org/archives/1112 를 보면 로프 끝에 단단한 몸체가 부착 된 로프가 구현되어 있습니다. 물리 엔진에 Box2D를 사용합니다. 소스 코드를 보면 원하는 언어로 구현할 수 있다고 확신합니다.

또한 로프 질문에 대한 위의 링크는 내 것이고 위의 데모 (제공된 링크)가 실제로 도움이되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.