2014-12-28 3 views
0

나는 html5 게임 프레임 워크를 작성하고 2d 플랫폼 작성자를 만들려고했습니다. 하지만 게임의 충돌 감지 부분에 붙어있어서 프레임 워크에 "intersects"메서드가있는 rect 개체가 포함되어 있습니다. 그래서 rect rect rectex 다른 rect 함께 체크 잘 수 있지만이 방법에 반응하는 방법을 잘 모르겠다. 나는 마지막으로 "비 충돌"위치로 플레이어 위치를 설정하려고 시도했으나 그 문제는 플레이어 속도 오프셋과 함께 플레이어 속도와의 간격이있을 때마다 ...2d 플랫폼에서 충돌 감지에 대응하는 방법

더 이상 생각하지 않아.

+0

저는 이것이 게임 디자인 질문이며 일반적으로 HTML5 나 JS와 관련이 없다고 생각합니다. 질문의 태그를 업데이트해야합니다. – Rapti

+0

감사합니다. 나는 당신에게 상세한 답변을 곧 줄 것이다. – Rapti

+0

단서가 없지만 충돌시 선수 위치를 업데이트하지 않습니까? – ManyQuestions

답변

1

저는 이것이 HTML5/JS 게임뿐만 아니라 일반적인 게임 메 커닉 질문이라고 생각합니다. HTML5 구문에 익숙하지 않아서 코드 예제의 일부 내용을 다시 작성해야 할 수도 있습니다. 또한, 나는 당신이 코드를 얼마나 정확하게 구조화했는지 모른다. 플레이어와 블록 모두 getX(), getXSpeed(), setX() 등과 같은 몇 가지 기능을 가지고 있다고 가정합니다.

플레이어 (또는 이동할 수있는 다른 개체)와 환경 블록 사이의 충돌을 감지하면 플레이어의 위치를 ​​업데이트하여 차단하지 않고 블록을 만지기를 원할 것입니다. 이 작업을 수행하기 전에 이 블록과 충돌하는 방법을 알아야합니다. 플레이어가 위, 왼쪽, 오른쪽 또는 아래쪽에서 블록을 입력 했습니까?

먼저 플레이어의 위치가 필요합니다.

playerX = player.getX(); 
playerY = player.getY(); 

플레이어가 이동하는 방향에 따라 플레이어가 이동하는 방향을 가리키는 코너의 좌표를 얻기 위해 플레이어의 폭과 높이를 추가 할 수 있습니다.

if(player.getXSpeed() > 0) { 
    playerX += player.getWidth(); 
} 
if(player.getYSpeed() > 0) { 
    playerY += player.getHeight(); 
} 

다음으로 플레이어의 이전 위치에 가장 근접한 블록면을 얻는 것이 좋습니다. 플레이어의 속도가 긍정적인지 또는 부정적인지 여부를 확인하여 그가 어느 쪽에서오고 있는지 확인할 수 있습니다. 함께, 플레이어가 오는 방향을 가리키는 코너의 좌표를 나타냅니다.

blockX = player.getXSpeed() > 0? block.getX() : block.getX() + block.getWidth(); 
blockY = player.getYSpeed() > 0? block.getY() : block.getY() + block.getHeight(); 

이제 우리는 Y 수직 측의 좌표와 X 플레이어가 통과 블록의 가로 측의 좌표 및 총 우리가 양측의 모서리의 좌표를 갖고있다.

Collision Diagram

블랙 박스는 환경 블록을 나타냅니다

나는 우리가이 일을하는 이유를 이해하지 못하는 경우 작은 다이어그램을 만들었습니다. 주황색 프레임은 플레이어의 이전 및 현재 위치를 나타냅니다. 파란색 선은 플레이어가 이동 한 경로를 나타냅니다. 이제 블록의 모서리를 나타내는 파란색 점이 해당 선의 위 또는 아래에 있는지 확인해야합니다. 이것은 플레이어가 블록의 수평 또는 수직 측면에 부딪쳤는 지 여부를 알려줍니다.

플레이어가 수직면에 닿는 경우 파란색 선의 경사는 플레이어 모서리에서 블록 모퉁이까지의 기울기보다 작습니다.수학의 관점에서이 수단이 적용되지 않는 경우

(currentPlayerY - previousPlayerY)/(currentPlayerX - previousPlayerX) 

보다 작은

(currentPlayerY - blockY)/(currentPlayerX - blockX) 

이며, 플레이어는 블록의 수평 측 안타. 코드는 다음과 같이 다소 보일 것이다 : 우리는 중력을 무시 할 수 있기 때문에, 우리는 플레이어의 움직임이 선형 척 할 수

bool verticalSide = abs(player.getYSpeed()/player.getXSpeed()) < abs((playerY/blockY)/(playerX - blockX)); 

. 플레이어가 어느 방향에서 오는지 알려면이 줄에 한 지점 만 있으면됩니다. 즉, 플레이어가 이전 게임 사이클에서 얼마나 멀리 있었는지 상관없이 (currentPlayerY - previousPlayerY)/(currentPlayerX - previousPlayerX)은 항상 player.getYSpeed()/player.getXSpeed()과 같습니다. 플레이어가 반드시 왼쪽 상단에서 오는 것은 아니므로 계산 된 기울기가 음수가 될 수 있습니다. 우리는 프로그래밍 언어가 보통 절대 값을 얻기 위해 제공하는 수학 클래스 'abs() 함수를 사용합니다. 즉, 모든 음수 값을 양수로 설정합니다.

이제 우리는 우리가 수평 또는 수직 충돌 처리 여부를 알고, 우리는 그에 따라 플레이어의 위치를 ​​업데이트 할 수 있습니다 사실입니다

if(verticalSide) { 
    player.setX(player.getXSpeed() > 0? blockX - player.getWidth(): blockX); 
    player.setXSpeed(0); 
} else { 
    player.setY(player.getYSpeed() > 0? blockY - player.getHeight(): blockY); 
    player.setYSpeed(0); 
} 

verticalSide 경우, 플레이어가 블록의 측면에 부딪된다. 이제 우리는 플레이어의 x 속도가 그가 왼쪽에서 오는 것인지 또는 오른쪽에서 오는 것인지를 알아 내고 자신의 위치를 ​​업데이트하여 블록에 닿아 있는지 여부를 확인합니다. 또한 수평 속도를 0으로 설정합니다. 그러나 verticalSide이 참이 아닌 경우 플레이어가 블록의 상단 또는 하단에 부딪혀서 y 축에 대해 동일한 작업을 수행합니다. 이것은 필요한 모든 것이어야합니다.

하지만 추가 팁이 있습니다. 플레이어가 현재 스페이스 바 또는 키를 눌렀을 때 점프 할 수 있는지 여부를 결정하기 위해 플레이어가 현재지면에 접촉하고 있는지 여부에 대한 정보가 필요합니다. 이렇게하려면 플레이어 클래스에서 플레이어가 이동할 때마다 false로 설정된 부울 필드 grounded을 만들어야합니다. 충돌 검사 중에 플레이어가 블록의 상단을 치는 경우 즉, 이 false이고 player.getYSpeed() > 0true 인 경우 다시 true로 설정하십시오. 점프 키를 누르면 점프를 트리거하기 전에 groundedtrue인지 확인하십시오.

재미있는 점은 제가 어제 정확하게 똑같은 문제가 있었지만이 해결책을 찾아 냈지만 단지 몇 줄의 코드로 압축했기 때문에 정확히 여기서 내가 한 것을 기억하기 위해 거꾸로 작업해야했습니다. 추후에 내 코드에 주석을 달아야합니다.

+0

오, 세상에, 너는 sooooo sooooo :)). 내가 자바 스크립트/자바 등으로 게임을 만들기 시작한 이래로이 문제가 있었고 결코 해결하지 못했습니다. 나는 충돌 탐지를위한 해결책을 찾았지 만 그것에 반응하는 방법은 찾지 못했습니다. 너는 내 하루를 resp했다. 나의 휴일. 독일에서 감사합니다. 그리고 행복한 새해 (때가되면) :) 다시 thx sooo. – Nimmi

+0

뒤셀도르프 (Düsseldorf) 근처에있는 독일 도시 라팅 겐 (Ratingen)에서 문제가없는 루틴 (Ruten)을 다시 방문하십시오. – Rapti

+0

오, 문제가 생겨 났을 때 문제가 생겼다. 블록과 손목 또는 블록이 다른 블록으로 이동했을 때 손목 시계가 다른 사람의 손목에 닿지 않았습니까? – Nimmi