일정한 속도로 A (x, y)에서 B (x1, y1)로 이동합니까?


21

나는 현재 다음과 같은 것을 가지고있다 :

float deltaX = point0.getX() - point1.getX();
float deltaY = point0.getY() - point1.getY();

그리고 0.01 초마다 다음과 같이 객체 위치를 새로 고칩니다.

object.setPosition(object.getX()-deltaX/100,object.getY()-deltaY/100);

따라서 이것은 객체를 1 초 안에 point0에서 point1로 이동시킵니다. 내가 필요로하는 것은 2 점을 가지고있어 point0에서 객체를 이동하고 point1 방향으로 일정한 속도로 향하게 할 수 있습니다. 따라서 초기 지점에 더 가까운 지점이 있으면 객체가 더 멀리있을 경우와 동일한 속도로 객체를 향해 이동합니다. 모든 제안을 부탁드립니다. 감사.


가능한 중복 : gamedev.stackexchange.com/questions/23430/… 나는 다른 질문에했던 것과 같은 답변을 게시 할 것입니다. 그러나 이것은 내 몫이 될 것입니다.
구스타보 메이 엘

답변:


26

그런 식으로 연산을 설명하는 것이 더 쉽기 때문에 선형 대수 구조를 사용하겠습니다. 이 벡터 연산을 구현하는 방법을 모른다면 마지막에 간단한 설명을 드리겠습니다.

그럼이 값으로 시작 가정 해 봅시다 : startend운동의 끝 지점을 표시, speed이 두 번째로 이동해야합니다 얼마나 많은 픽셀이며, elapsed당신이 당신의 객체의 위치 (일부 엔진이 이미 당신을 위해 가치를 제공을 업데이 트됩니다되는 속도입니다 ) :

Vector2 start = new Vector2(x1, y2);
Vector2 end = new Vector2(x2, y2);
float speed = 100;
float elapsed = 0.01f;

가장 먼저 계산하고자하는 것은 두 점 사이의 거리와 시작부터 끝까지의 방향을 포함하는 정규화 된 벡터입니다. 또한 객체 위치를 start점에 "스냅"해야 합니다. 이 단계는 처음에 한 번만 수행됩니다.

float distance = Vector2.Distance(start, end);
Vector2 direction = Vector2.Normalize(end - start);
object.Position = start;
moving = true;

그런 다음 업데이트 방법에, 당신의 곱셈을 추가하여 개체를 이동 direction, speed그리고 elapsed그 위치로. 그런 다음 이동이 끝났는지 확인하기 위해 시작점과 객체의 현재 위치 사이의 거리가 계산 한 초기 거리 보다 큰지 확인합니다. 그것이 사실이라면, 우리는 객체의 위치를 ​​끝점으로 스냅하고 객체 이동을 중단합니다 :

if(moving == true)
{
    object.Position += direction * speed * elapsed;
    if(Vector2.Distance(start, object.Position) >= distance)
    {
        object.Position = end;
        moving = false;
    }
}

빠른 벡터 연산 참조

대표

Vector2 A = float aX, aY;

합계 / 빼기

A+B = a.x + b.x; a.y + b.y;
A-B = a.x - b.x; a.y - b.y;

스칼라 곱하기 (float)

A*float = a.x*float; a.y*float;

길이 / 거리

length(A) = sqrt(a.x*a.x + a.y*a.y)
distance(A,B) = length(B-A)

정규화

normalize(A) = a.X/length(A); a.Y/length(A);

Vector사용 가능한 클래스 가 없으면 위의 코드를 일반 작업으로 변환하기에 충분해야 합니다.


변환의 예

// Your Variables
float startX, startY, endX, endY;
float speed = 100;
float elapsed = 0.01f;

// On starting movement
float distance = Math.sqrt(Math.pow(endX-startX,2)+Math.pow(endY-startY,2));
float directionX = (endX-startX) / distance;
float directionY = (endY-startY) / distance;
object.X = startX;
object.Y = startY;
moving = true;

// On update
if(moving == true)
{
    object.X += directionX * speed * elapsed;
    object.Y += directionY * speed * elapsed;
    if(Math.sqrt(Math.pow(object.X-startX,2)+Math.pow(object.Y-startY,2)) >= distance)
    {
        object.X = endX;
        object.Y = endY;
        moving = false;
    }
}

1
@Fofole 그렇기 때문에 마지막에 벡터에 대해 설명했습니다. 대답은 일반적인 것으로 생각되었습니다. Vector 클래스가없는 경우 별도의 두 부동 소수점을 사용하십시오. 예를 들어 Vector2 start;이된다 float startX, startY;. 마지막에 설명 하듯이 거리를 수동으로 쉽게 계산할 수 있습니다. 즉 float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);.
David Gouveia

@Fafole 편집을 확인하고 예제를 추가했습니다. 그래도 뭔가를 놓쳤다면 확실하지 않습니다.
David Gouveia

3 년 후 방금 벡터로 객체를 이동하는 방법을 이해하게 만들었습니다. 건배!
Oliver Schöning 2016 년


2

내 대답에서 복사하여 붙여 넣기 : 두 점 사이의 선에 점을 가져옵니다.

의사 코드에서 :

speed_per_tick = 0.05 //constant speed you want the object to move at
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}

이 대답은 내 유스 케이스에 가장 효과적이었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.