2009-07-10 2 views
2

iPhone에서 Cocos2d를 사용하여 2D 자동차를 그리며 자연스럽게 왼쪽에서 오른쪽으로 조정합니다. 여기자동차가 원을 그리며 스프라이트를 움직이는 경우

내가 뭘하려 :

  1. 는 바퀴의 각도를 계산하고 단지 바퀴가 가리키는 대상 지점으로 이동합니다. 그러나 이것은 매우 부 자연스러운 느낌을줍니다. 자동차가 시간의 절반을 드리프트한다

  2. 나는 차에서 회전 원을 얻는 방법에 대한 연구를 시작했는데, 이는 휠베이스와 자동차 너비와 같은 몇 가지 상수가 필요하다는 것을 의미했다.

    float steerAngle = 30; // in degrees 
    float speed = 20; 
    float carWidth = 1.8f; // as in 1.8 meters 
    float wheelBase = 3.5f; // as in 3.5 meters 
    
    float x = (wheelBase/abs(tan(steerAngle)) + carWidth/ 2); 
    float wheelBaseHalf = wheelBase/2; 
    float r = (float) sqrt(x * x + wheelBaseHalf * wheelBaseHalf); 
    
    float theta = speed * 1/r; 
    if (steerAngle < 0.0f) 
        theta = theta * -1; 
    
    drawCircle(CGPointMake(carPosition.x - r, carPosition.y), 
          r, CC_DEGREES_TO_RADIANS(180), 50, NO); 
    

    라인의 처음 몇 내 상수 :

많은 조사 후, 나는 다음과 같은 코드를 만들었습니다. carPosition의 유형은 CGPoint입니다. 그 후에 나는 내 자동차의 회전 원을 보여주는 원을 그리려고하지만 그 원이 그리는 원은 너무 작습니다. 원을 더 크게 만들기 위해 상수를 더 크게 만들 수는 있습니다.하지만이 원에 스프라이트를 이동하는 방법을 알아야합니다.

나는이 주제에서 발견 된 .NET tutorial 다음을 시도했지만 실제로 코코아에서 지원하지 않는 Matrixes를 사용하기 때문에 변환 할 수 없다.

누군가 내게 이것을 시작하는 방법에 대한 몇 가지 지침을 줄 수 있습니까? 예제 코드를 찾고 있었지만 찾을 수 없습니다. 내 상수를 수정 아래의 댓글 후

편집, 내 휠베이스, 내 carWidth은 (스프라이트는 폭 30 픽셀입니다) 30 (스프라이트가 높은 50 픽셀입니다) 지금 50입니다.

하지만 지금 내 차가 처음 '틱'할 때 회전이 정확하고 배치 후에도 문제가 발생하지만 계산이 잘못되었다고 생각합니다.

터닝 원의 가운데가 원래 위치로 유지되는 대신 이동됩니다. 내가 필요로하는 것은 (내가 생각하기에) 차의 각 각도에서 회전 중심의 원래 중심을 다시 계산해야한다는 것입니다. 나는 이것이 반경과 회전 각을 가지고 있기 때문에 이것이 쉽다라고 생각할 것이다. 그러나 나는 멋진 원안에서 차를 계속 움직이는 방법을 알아낼 수 없다.

더 이상 포인터가 있습니까?

+0

매트릭스는 다차원 배열 일뿐입니다. 참조 코드를 수정하거나 작업 할 수 있어야합니다. – EightyEight

답변

1

당신은 맞는 생각이 있습니다. 이 경우 상수가 문제입니다. 보기 크기와 일치하는 단위로 wheelBasecarWidth을 지정해야합니다. 예를 들어 화면의 차 이미지의 휠 기준이 30 픽셀이면 WheelBase 변수에 30을 사용합니다.

화면상의 원이 너무 작은 이유를 설명합니다. 코코아는 너비가 1.8 픽셀 밖에 안되는 작은 차를 위해 서클을 그리려하고 있습니다!

이제 원을 따라 차를 이동하는 문제에 관해서는 :

위의 코드를 계산 theta 변수가 당신의 중심점 주위에 차를 이동하는 데 사용할 것 인 것이다 회전 속도입니다 해당 동그라미 :

변수는 초당 픽셀 단위로 계산되어 더 쉽게 계산할 수 있습니다. 내가 올바른 방법은 자동차의 이미지를 회전 무엇인지 확실하지 않다, 그래서 난 그냥 얻을 rotateByAngle:을 사용 :

// calculate the new position of the car 
newCarPosition.x = (carPosition.x - r) + r*cos(theta); 
newCarPosition.y = carPosition.y + r*sin(theta); 

// rotate the car appropriately (pseudo-code) 
[car rotateByAngle:theta]; 

참고 : 위의 해당 가정으로, 당신은 단순히 한 번 매 초마다 다음과 같은 코드를 실행하는 것입니다 가리킨다. 도움이되기를 바랍니다! (주석 후)

업데이트는 :

나는 차로 이동 회전 원의 중심에 대해 생각하지 않았다. 원래 코드는 자동차가 이미 회전 한 각도를 고려하지 않습니다. 나는 다음과 같이 그것을 바꿀 것이다 :

... 
if (steerAngle < 0.0f) 
    theta = theta * -1; 

// calculate the center of the turning circle, 
// taking int account the rotation of the car 
circleCenter.x = carPosition.x - r*cos(carAngle); 
circleCenter.y = carPosition.y + r*sin(carAngle); 

// draw the turning circle 
drawCircle(circleCenter, r, CC_DEGREES_TO_RADIANS(180), 50, NO); 

// calculate the new position of the car 
newCarPosition.x = circleCenter.x + r*cos(theta); 
newCarPosition.y = circleCenter.y + r*sin(theta); 

// rotate the car appropriately (pseudo-code) 
[car rotateByAngle:theta]; 
carAngle = carAngle + theta; 

이것은 자동차를 돌렸을지라도 터닝 원의 중심을 적절한 지점에 유지해야한다.

+0

귀하의 의견을 통합하려했지만 여전히 작동하지 않습니다. 나는 이것을 원래의 게시물에서 설명하려고 노력했다. 희망을 좀 더 줄 수 있길 바래요? –

+0

원 중심을 따라 움직이는 문제를 해결할 수있는 코드를 추가했습니다. 한번 해봐! –

+0

고마워, 아직 약간의 조정이 필요하지만, 이것은 아주 좋은 시작처럼 보입니다. 제 시작 게시물을 업데이트 할 것입니다. –