ทำไมวัตถุของฉันเคลื่อนที่เร็วกว่า 45 องศามากกว่า 90 องศา


32

ฉันมีวัตถุในเกมของฉันที่เคลื่อนที่เร็วขึ้นที่ 45 องศาจากนั้นที่ 90 องศา

แต่ละวัตถุมี

  • ตำแหน่งจุด (x, y)
  • ทิศทาง Vector2D (x, y)
  • ความเร็วสูง

และสิ่งที่ฉันทำในระหว่างการอัพเดทคือตำแหน่งใหม่จะถูกคำนวณดังนี้:

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

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร ฉันต้องการให้มันเคลื่อนที่ด้วยความเร็วเท่ากันทุกมุม


8
ปรับเวกเตอร์ทิศทางของคุณให้เป็นปกติก่อนใช้งาน แก้ไขปัญหา.
decaviatedcaviar

1
Had to google normalizing :) พบเว็บไซต์นี้มีประโยชน์fundza.com/vectors/normalize/index.html
Jason94

และถ้าคุณกำลังใช้การป้อนข้อมูลของผู้ใช้ในการควบคุมวัตถุนี้ให้ตระหนักถึงการล็อคไป 12,3,6,9 ทิศทางตามที่อธิบายไว้ที่นี่สำหรับ devs XNA: xona.com/2010/05/03.html อาจเป็นสิ่งที่คุณต้องการ (เช่นในเกม RPG) หรือไม่ (เช่นในเกมสไตล์ Geometry Wars)
Xonatron

ในเกมเก่าโคตรนี้เป็นคุณลักษณะ
J. Holmes

@ 32bitkid ใช่ดูDoom straferunning ด้วย
bobobobo

คำตอบ:


55

สิ่งนี้สามารถอธิบายได้ด้วยทฤษฎีบทพีทาโกรัสซึ่งเป็นสูตรต่อไปนี้:

a² + b² = c²

ในกรณีของคุณเมื่อเคลื่อนที่ไปทางขวาคุณกำลังใช้ (x: 1, y: 0) ซึ่งให้เรา

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

เมื่อเลื่อนขึ้นและลงคุณใช้ (x: 1, y: 1) ซึ่งให้เรา

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

อย่างที่คุณเห็นความยาวแนวทแยงมุมยาวกว่าความยาวของแกนแกน

ตามที่คนอื่นพูดถึงคุณควรปรับเวกเตอร์ทิศทางของคุณให้เป็นมาตรฐาน หากคุณใช้ XNA จะทำเช่นนี้:

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

ฉันให้ +1 คุณเพื่อช่วยคุณ คำถามของฉัน :)
มาร์ติน

12

ปรับเวกเตอร์ทิศทางของคุณให้เป็นปกติก่อนใช้งาน

ดังที่อธิบายไว้โดย MindWorX สิ่งนี้สามารถเข้าใจได้ง่ายหากคุณกังวลเกี่ยวกับทิศทางเวกเตอร์ของคุณที่อาจทำให้คุณเศร้าโศก

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

หากเป็นมาตรฐาน:

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

14
ไม่ใช่คำตอบที่เป็นประโยชน์ หากผู้ถามทราบว่า "การทำให้เวกเตอร์ทิศทางของคุณเป็นจริง" หมายถึงอะไรเขาจะไม่ถามคำถามนั้น
Kristopher Johnson

@ KristopherJohnson ไม่ชัดเจนผู้ถามไม่ทราบวิธีการทำให้เวกเตอร์เป็นปกติ แม้ว่าผู้ถามจะดูเหมือนว่ามีความรู้มากพอที่จะไม่สำคัญก็ตาม
ชะลอตัวลงขณะที่

2
@KristopherJohnson: ถ้าผู้ถามไม่ทราบว่า "normalize your direction vector" หมายถึงอะไรเขาเพียงแค่พิมพ์ลงใน google ต่อท้ายชื่อภาษาของเขาและรับรหัสพร้อมคำอธิบาย
Lie Ryan

6

คุณคำนวณทิศทางของคุณอย่างไร ถ้า 45 องศาเท่ากับ(1,1), มันจะเร็วกว่า 90 องศา(1,0)แน่นอน

ฉันขอแนะนำให้คุณใช้สิ่งนี้:

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

เพื่อให้ได้มุมเรเดียนที่คุณจะต้องคูณองศาของคุณด้วยหรือดียิ่งขึ้นใช้PI / 180 MathHelperเช่น.

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

6

เจสัน

แทนที่จะมีสามคุณลักษณะของวัตถุ

  • ตำแหน่งจุด (x, y)
  • ทิศทาง Vector2D (x, y)
  • ความเร็วสูง

มันง่ายกว่ามากในการรวมทิศทางและความเร็วเข้ากับเวกเตอร์ความเร็ว จากนั้นคุณมีเพียงสองคุณสมบัติ

  • ตำแหน่งจุด (x, y)
  • ความเร็ว Vector2D (x, y)

กำลังอัปเดตตำแหน่ง

เมื่อคุณต้องการอัปเดตตำแหน่งของวัตถุมันง่ายเหมือน:

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

Δtเดลต้าเวลาของคุณอยู่ที่ไหน- หรือเวลาต่างกัน - หรือขั้นตอนเวลา

การอัปเดตตำแหน่งและความเร็ว

นอกจากนี้ยังเป็นวิธีที่ง่ายมากในการจัดการกับการเร่งความเร็ว (เช่นจากแรงโน้มถ่วง) หากคุณมีเวกเตอร์ความเร่งคุณสามารถอัปเดตความเร็วและตำแหน่งพร้อมกันดังนี้:

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;

(นี่คือสูตร s = vt + ½at²จาก Physics 101)

ใช้ความเร็ว

หากคุณต้องการใช้ความเร็วที่กำหนดในทิศทางปกติคุณสามารถตั้งค่าความเร็วดังนี้:

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

ได้รับความเร็ว

และถ้าคุณต้องการทำสิ่งตรงกันข้าม - ได้มาซึ่งความเร็วและทิศทางจากเวกเตอร์ความเร็วที่กำหนด - คุณสามารถใช้ทฤษฎีบทพีทาโกรัสหรือ.Length()วิธีการ:

speed = velocity.Length();

และเมื่อความเร็วเป็นที่รู้จักทิศทางปกติสามารถคำนวณได้โดยการหารความเร็วด้วยความเร็ว (ระมัดระวังเพื่อหลีกเลี่ยงการหารด้วยศูนย์):

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.