2011-01-20 12 views
0

제스처를 시도 할 때 내보기를 스크롤하는 방법 (또는 모든 개체를 오프셋하는 방법)에 대한 수학을 이해할 수 없습니다. . 나는 스크롤이 어떤 종류의 편이성을 가지길 원한다.XNA의 스크롤 화면

public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) 
    { 
     float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; 

     //Some math to change 'matrixOffsetY' 
     //I use 'matrixOffsetY' to offset my objects in Draw() 

     base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); 
    } 

여기 어려운해서는 안됩니다 제스처 이벤트

public override void HandleInput(InputState input) 
    { 
     if (input == null) 
      throw new ArgumentNullException("input"); 

     while (TouchPanel.IsGestureAvailable) 
     { 
      GestureSample gesture = TouchPanel.ReadGesture(); 

      switch (gesture.GestureType) 
      { 
       case GestureType.Flick: 
        { 
         //Set a variable with some math? Using: 
         //gesture.Delta 

         //gesture.Delta gives us pixels/sec 
         break; 
        } 
       default: return; 
      } 
     } 
    } 

이에게, 그러나 나는 뇌 동결이 :) 저를 도와주세요!

답변

3

두 값 사이를 "lerp"(선형 보간)하여 서서히 가까워 질 수 있습니다 (빠르기 시작, 천천히 끝남).

2D로 스크롤한다고 가정합니다. 그래서 위치는 Vector2입니다. 이 XNA의 경우, 숀은 아마 이미 문제를 해결했다, 평소처럼

position; //current position of the object. 
targetPosition; //set by scrolling, position should gradually come close to this 
float weigth; //how much the weight is of the targetPosition compared to the position 
//practically this means how fast position approaches targetPosition. 
//First try values between 0 and 1, for example 0.8f for starters. 
public void Scroll(Vector2 ammount) 
{ 
    //We assume scrolling the scrollbar 1 pixel down, means the object should go 1 pixel up. 
    //So the targetPosition should move the same ammount opposite. 
    //If you don't want scrolling to correspond 1:1, you can multiply ammount by a float. 
    targetPosition -= ammount; 
} 

public void Update(GameTime gameTime) 
{ 
    //.. 
    //Executed every update, position closes in on targetPosition pretty fast.  
    position = Vector2.Lerp(position, targetPosition, weigth); 

    //Because we Lerp position will only get extremely close to targetPosition. Never exactly at it. 
    //most of the time this is good enough, if this isnt use the following code 

    float omega = 0.05f; // the minimum dinstance between position and targetPosition before we clamp 
    if(Vector2.Distance(position, targetPosition) < omega) 
    { 
     position = targetPosition; 
    } 
    //.. 
} 

public void Draw(GameTime gameTime) 
{ 
    //.. 
    spriteBatch.Begin(); 
    spriteBatch.Draw(texture, position, Color.White); 
    spriteBatch.End(); 
    //.. 
} 
+0

와우. 내가 예상했던 것보다 완벽하고 훌륭하게 작동합니다! 감사. – Frexuz

+0

안녕하세요, Frexuz, 다행입니다. –

3

나는 당신이 점차적으로 나는 터치 패널 및 제스처)에 대해 잘 모르는 (에 아주 명확하지 않다하는 (이 어떻게 생각 무엇을한다는 것을 "밖으로 완화"을 의미하는 가정합니다.

있습니다 당신은 물리적 인 접근법을 취하고 뉴턴의 법칙을 사용하여 간단히 미분 방정식을 풀 수 있습니다.

저는 일반적으로 마우스로 창을 스크롤 할 때 점진적으로 멈추는 등의 방식으로이 작업을 수행합니다. 원하는 감각을 얻기 위해 수정할 수있는 매개 변수가있는 일부 기능을 사용하여 점차적으로 속도를 줄이는 것입니다.

당신의 경우에는, 나는 당신이하려는 것을 얻었고, 당신은 단지 속도에 기초하여 위치를 업데이트하기를 원할뿐입니다. 당신은 (일반적으로는 2D 위해 그것을 할 수 있습니다에서) 수평으로 그 일을 가정

,

X_new = X_old + 속도 * 속도 DT = 최대 (0, 속도 * 0.95-0.2)

무엇 이것은 점차적으로 x 좌표를 움직입니다 (X_old는 X_new가 루프를 통해 매번 (일반적으로 스레드에서 수행)). 그래서 완전히 멈추지 않고 속도가 0에 도달 할 때까지 계속 이동합니다. 나는 간단한 pow 함수를 사용하여 그것을 점차적으로 줄이지 만, 어떤 유형의 함수를 생각해 낼 수있다.

실제로 포인터의 가장자리까지의 거리를 고려할 수도 있습니다. 나는 내 프로그램 중 하나에서 이렇게 마우스 커서가 가장자리에서 이동할 때 스크롤하는 속도는 얼마나 멀리 (그래서 당신이 약간 스크롤하려는 경우 조금 움직이고 많은 많이 이동).

스레드에서이 문제를 계속 처리해야한다는 것을 알고 있어야합니다. 또한 가속도를 계산하고 간단한 물리학을 사용하여 가속도를 기반으로 위치를 계산할 수 있습니다. x = x0 + x '* t + 1/2 * x' '* t^2 타입의 물건.

0

:

는 다음과 같이하십시오. 두 게시물에서 그는 Lerp, SmoothStep and other math operationsphysics based approach을 사용하여 전환을 설명합니다. 예제에서는 Game State Management 프로젝트를 사용하지만 아이디어는 어디에서나 사용할 수 있습니다.

그런데 카메라를 기준으로 모든 물체를 움직이지 않는 것이 좋습니다.어딘가에 vector2 또는 vector3 cameraOffset을 저장하고 SpriteBatch.Begin에서 transformMatrix를 사용할 수 있습니다. 물론 이것은 하나 또는 두 개의 스프라이트 묶음주기를 사용하여 모든 세계 객체를 칠하는 경우에 가장 유용합니다.

+0

사실 저는 전에 이것을 했었지만 동시에 많은 물체를 그렸습니다. 제 "캔버스"가 5000px로 높았 기 때문에 약 3fps를주었습니다. 객체의 Y가 바뀌지 않기 때문에 보이는 객체 만 그리는 방법을 알 수 없습니다. – Frexuz

+0

카메라가 고정 된 경우 페인트 할 대상을 선택하는 것과 같은 방법입니다. 사각형 (0, 0, screenWidth, screenHeight)과 안쪽 여백을 칠하는 대신 사각형은 (cameraPos.X - halfScreenWidth, cameraPos.Y - halfScreenHeight, screenWidth, screenHeight) 및 패딩을 더한 것입니다. 카메라에 붙은 직사각형을 유지하고 교차점을 확인할 수도 있습니다. Z에서 viewRect와 교차하는 모든 것이 그려집니다. 게임 영역에 파티션을 추가하면 더 빨리 게임을 진행할 수 있습니다. – Elideb