Chuyển từ A (x, y) sang B (x1, y1) với tốc độ không đổi?


21

Tôi hiện đang có một cái gì đó như:

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

Và cứ sau 0,01 giây tôi làm mới vị trí đối tượng của mình như thế này:

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

Vì vậy, điều này di chuyển đối tượng của tôi từ point0 đến point1 trong 1 giây. Điều tôi cần là có 2 điểm, để có thể di chuyển đối tượng từ điểm 0, đối mặt (theo hướng) điểm1 với tốc độ không đổi. Do đó, khi tôi có một điểm gần với điểm ban đầu của mình, vật thể sẽ di chuyển về phía nó với cùng tốc độ nếu tôi có một điểm xa hơn. Bất kỳ đề xuất đều được đánh giá cao. Cảm ơn.


Có thể trùng lặp: gamedev.stackexchange.com/questions/23430/ Nhật Tôi sẽ đăng cùng một câu trả lời mà tôi đã đưa ra cho câu hỏi khác. Nhưng điều này sẽ không biết xấu hổ về phần của tôi.
Gustavo Maciel

Câu trả lời:


26

Tôi sẽ sử dụng một số cấu trúc đại số tuyến tính vì việc mô tả các hoạt động theo cách đó dễ dàng hơn. Trong trường hợp bạn không biết cách thực hiện các thao tác vectơ này, tôi sẽ giải thích nhanh vào cuối.

Vì vậy, giả sử bạn bắt đầu với các giá trị này: startendđánh dấu điểm kết thúc của chuyển động, speedlà nó sẽ di chuyển bao nhiêu pixel trong giây và elapsedlà tốc độ bạn sẽ cập nhật vị trí đối tượng của mình (một số công cụ đã cung cấp giá trị đó cho bạn ):

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

Điều đầu tiên bạn sẽ muốn tính toán là khoảng cách giữa cả hai điểm và một vectơ chuẩn hóa chứa hướng từ đầu đến cuối. Ngoài ra, bạn nên "chụp" vị trí đối tượng vào startđiểm. Bước này chỉ được thực hiện một lần, khi bắt đầu:

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

Sau đó, trên phương pháp cập nhật của bạn, bạn di chuyển các đối tượng bằng cách thêm một phép nhân của direction, speedelapsedvị trí của nó. Sau đó, để kiểm tra xem chuyển động đã kết thúc chưa, bạn xem khoảng cách giữa điểm bắt đầu và vị trí hiện tại của đối tượng có lớn hơn khoảng cách ban đầu bạn đã tính không. Nếu đó là sự thật, chúng tôi sẽ đưa vị trí của đối tượng đến điểm cuối và ngừng di chuyển đối tượng:

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

Tham khảo hoạt động Vector nhanh

Đại diện

Vector2 A = float aX, aY;

Tổng / trừ

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

Nhân với vô hướng (float)

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

Chiều dài / khoảng cách

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

Bình thường hóa

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

Điều đó là đủ để chuyển đổi mã trên thành các hoạt động thông thường nếu bạn không có Vectorsẵn một lớp học.


Ví dụ về chuyển đổi

// 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 Đó là lý do tại sao tôi đã đưa ra lời giải thích về vectơ ở cuối. Câu trả lời được cho là chung chung. Nếu bạn không có lớp Vector, thì hãy sử dụng hai phao riêng biệt. Ví dụ Vector2 start;trở thành float startX, startY;. Và bạn có thể dễ dàng tính toán khoảng cách bằng tay, như tôi giải thích ở cuối. Tức float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);.
David Gouveia

@Fafole Kiểm tra chỉnh sửa, tôi đã thêm một ví dụ. Không chắc chắn nếu tôi bỏ lỡ một cái gì đó mặc dù.
David Gouveia

3 năm sau và bạn chỉ khiến tôi hiểu cách di chuyển các vật thể bằng vectơ. Chúc mừng!
Oliver Schöning


2

Sao chép và dán từ câu trả lời của tôi vào: Nhận điểm trên một đường thẳng giữa hai điểm

Trong mã giả:

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
}

Câu trả lời này hoạt động tốt nhất cho trường hợp sử dụng của tôi.
vỏ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.