Tại sao đối tượng của tôi di chuyển nhanh hơn ở 45 độ so với 90 độ?


32

Tôi có các đối tượng trong trò chơi của mình di chuyển nhanh hơn ở 45 độ sau đó ở 90 độ.

Mỗi đối tượng có

  • Vị trí điểm (x, y)
  • Hướng Vector2D (x, y)
  • Tốc độ nội bộ

Và những gì tôi làm trong một bản cập nhật là vị trí mới được tính như sau:

position.x += direction.x * speed
position.y += direction.y * speed

Làm thế nào để tôi sửa điều này? Tôi muốn nó di chuyển với cùng tốc độ ở mọi góc độ.


8
Bình thường hóa vector hướng của bạn trước khi sử dụng; Vấn đề được giải quyết.
giảm tốc

1
Phải google bình thường hóa :) tìm thấy trang web hữu ích này fundza.com/vector/n normalize / index.html
Jason94

Và nếu bạn đang sử dụng đầu vào của người dùng để kiểm soát đối tượng này, hãy lưu ý khóa các hướng 12,3,6,9 như được giải thích ở đây cho XNA devs: xona.com/2010/05/03.html . Nó có thể là thứ bạn muốn (chẳng hạn như trong trò chơi RPG) hoặc không (chẳng hạn như trong trò chơi theo phong cách Geometry Wars).
Xonatron

Trong trò chơi cũ Descent , đây là một tính năng .
J. Holmes

@ 32bitkid Có, xem thêm Doom căng thẳng
bobobobo

Câu trả lời:


55

Điều này có thể được giải thích với Định lý Pythagore , đây là công thức sau:

a² + b² = c²

Trong trường hợp của bạn, khi di chuyển sang phải, bạn đang sử dụng (x: 1, y: 0) mang lại cho chúng tôi

c² = 1 + 0 = 1
c = sqrt(1) = 1.00

Khi di chuyển lên và sang phải, bạn đang sử dụng (x: 1, y: 1) mang lại cho chúng tôi

c² = 1 + 1 = 2
c = sqrt(2) = 1.41

Vì vậy, như bạn có thể thấy, chiều dài theo đường chéo dài hơn chiều dài trên các trục chính.

Như những người khác đã đề cập, bạn chỉ cần bình thường hóa vector hướng của bạn. Nếu bạn sử dụng XNA, nó được thực hiện như thế này:

var normalizedDirection = direction;
normalizedDirection.Normalize();
position += normalizedDirection * speed

Tôi sẽ cho bạn +1 để được giúp đỡ trong câu hỏi của tôi :)
Martin.

12

Bình thường hóa vector hướng của bạn trước khi sử dụng.

Theo giải thích của MindWorX, điều này có thể hiểu đơn giản, nếu bạn lo lắng về các vectơ chỉ đường của bạn có thể khiến bạn đau buồn, hãy chắc chắn rằng chúng là các vectơ đơn vị (cường độ / chiều dài 1).

Length(Vector2(1, 1)) == 1.4142135623730951 // first hint of grief
Length(Vector2(1, 0)) == 1

Vector2(1, 1) * 2 == Vector2(2, 2)
Vector2(1, 0) * 2 == Vector2(2, 0)

Length(Vector2(2, 2)) = 2.8284271247461903 // second hint
Length(Vector2(2, 0)) = 2

Nếu bình thường hóa:

normal(Vector2(1, 1)) == Vector2(0.707107, 0.707107)
Length(Vector2(0.707107, 0.707107)) == 1 // perfect

14
Không phải là một câu trả lời hữu ích. Nếu người hỏi biết "bình thường hóa vectơ chỉ đường của bạn" nghĩa là gì, anh ta sẽ không hỏi câu hỏi đó.
Kristopher Johnson

@KristopherJohnson không rõ người hỏi không biết làm thế nào để bình thường hóa một vectơ. Mặc dù người hỏi có vẻ tháo vát đến mức dù sao nó cũng không thành vấn đề.
giảm tốc

2
@KristopherJohnson: nếu người hỏi không biết "bình thường hóa vectơ chỉ đường của bạn" nghĩa là gì, anh ta chỉ cần gõ nó vào google, nối tên ngôn ngữ của mình và nhận mã với lời giải thích.
Lie Ryan

6

Làm thế nào bạn đang tính toán hướng của bạn? Nếu 45 độ là (1,1), thì chắc chắn nó sẽ nhanh hơn 90 độ (1,0).

Tôi đề nghị bạn sử dụng một cái gì đó như thế này:

direction.x = Math.Cos(angleInRadians);
direction.y = Math.Sin(angleInRadians);

Để có được góc theo radian, bạn sẽ phải nhân mức độ của mình với PI / 180hoặc thậm chí tốt hơn, sử dụng MathHelper. Ví dụ.

angleInRadians = 45.0 * Math.PI / 180.0; // first method
angleInRadians = MathHelper.ToRadians(45f); //second method

6

Jason,

Thay vì có ba thuộc tính đối tượng,

  • Vị trí điểm (x, y)
  • Hướng Vector2D (x, y)
  • Tốc độ nội bộ

thường dễ dàng hơn nhiều để kết hợp hướng và tốc độ thành một vectơ vận tốc. Sau đó, bạn chỉ có hai thuộc tính,

  • Vị trí điểm (x, y)
  • Vận tốc của Vector2D (x, y)

Cập nhật vị trí

Khi bạn cần cập nhật vị trí của đối tượng, nó đơn giản như:

position.x += velocity.x * Δt;
position.y += velocity.y * Δt;

nơi Δtđồng bằng thời gian của bạn - hoặc chênh lệch thời gian - hoặc bước thời gian.

Cập nhật vị trí và vận tốc

Cách này cũng rất dễ dàng để xử lý gia tốc (chẳng hạn như từ trọng lực). Nếu bạn có một vectơ gia tốc, bạn có thể cập nhật vận tốc và vị trí cùng nhau như thế này:

position.x += (velocity.x * Δt) + (0.5 * acceleration.x * Δt * Δt);
position.y += (velocity.y * Δt) + (0.5 * acceleration.y * Δt * Δt);

velocity.x += acceleration.x * Δt;
velocity.y += acceleration.y * Δt;

(Về cơ bản, đây là công thức s = vt + at² từ Vật lý 101.)

Áp dụng tốc độ

Nếu bạn muốn áp dụng một tốc độ nhất định theo một số hướng chuẩn hóa, bạn có thể đặt vận tốc như thế này:

velocity.x = normalizedDirection.x * speed;
velocity.y = normalizedDirection.y * speed;

Tăng tốc

Và nếu bạn cần thực hiện ngược lại - lấy tốc độ và hướng từ một vectơ vận tốc nhất định - bạn có thể chỉ cần sử dụng định lý Pythagore hoặc .Length()phương pháp:

speed = velocity.Length();

Và một khi tốc độ đã biết, hướng chuẩn hóa có thể được tính bằng cách chia vận tốc cho tốc độ (cẩn thận để tránh chia cho 0):

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
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.