การย้ายเทพดาใน XNA / C # โดยใช้เวกเตอร์


9

ฉันกำลังดูการพัฒนาเกม XNA ด้วยภาษา C #

ฉันมีสองคลาส: ตัวจัดการเกมหลักและคลาส "สไปรต์" ต่อไปนี้เป็นรหัสหลอกพื้นฐานที่ฉันหวังว่าจะอธิบายปัญหาได้อย่างเพียงพอ

Game.cs

class game {
  sprite the_sprite;
  void update(time) {
    var mouse = mouse.state
    if(mouse.clicked) { this.the_sprite.moveTo(mouse.x, mouse.y) }
    this.the_sprite.update(time)
    base.update(time)
  }
}

Sprite.cs

class sprite {
  vector2 location;
  vector2 move_to;
  void moveTo(x, y) { this.move_to = new vector2(x, y) }
  void update(time) {
    if(this.location.x > this.move_to.x /* (or less than) */) {
      // adjust location.x
    }
    if(this.location.y > this.move_to.y /* (or greater than) */) {
      // adjust location.y
    }
  }
}

โดยพื้นฐาน: เมื่อผู้ใช้คลิกที่ไหนสักแห่งในหน้าต่างเกมพิกัด x และ y ของเมาส์จะถูกนำมาและวัตถุของเกมจะย้ายไปยังตำแหน่งนั้นในช่วงระยะเวลาหนึ่ง

ดี ... รหัสใช้งานได้ แต่มันน่าเกลียดและวัตถุไม่ได้เคลื่อนไปที่วัตถุโดยตรง (แทนมันคือการเคลื่อนไหวในแนวทแยงมุมตามด้วยการเคลื่อนที่แบบแกนเดียว) ฉันเดาว่ามีฟังก์ชั่นทางคณิตศาสตร์บางอย่างที่ฉันสามารถใช้ได้ แต่ฉันก็ยังไม่รู้เลยว่าจะเริ่มต้นอย่างไร ข้อเสนอแนะใด ๆ


3
สวัสดีแขก คุณกำลังมองหาสิ่งที่เป็นมาตรฐาน โปรดอ่านคำตอบของคำถามนี้: gamedev.stackexchange.com/questions/7540/... หนึ่งข้อเสนอรหัสที่คุณต้องการที่สองอธิบายว่ามันทำงานได้ดีมาก
Notabene

สวัสดีฉันได้ดูลิงก์และเป็นสิ่งที่ฉันต้องการ ขอบคุณ!
Matt

คำตอบ:


12

หากฉันเข้าใจปัญหาของคุณอย่างถูกต้องคุณควรมีทิศทาง Vector2 ที่แสดงถึงทิศทางที่คุณต้องการย้ายเข้าไปในชั้นเรียนสไปรต์ แบบนี้:

public Vector2 Direction { get; set; }

นี่คือเวกเตอร์ที่ทำให้เป็นมาตรฐาน (ซึ่งหมายความว่ามันมีความยาว 1) แสดงตำแหน่งที่คุณต้องการไป

จากนั้นเพิ่มคุณสมบัติ Speed ​​float ซึ่งระบุว่าสไปรต์ควรไปเร็วแค่ไหน

public float Speed { get; set; }

คุณต้องเพิ่มฟังก์ชั่น UpdateSprite แล้วทำไมไม่ลองใส่ฟังก์ชั่น Sprite ในคลาส?

public Update(GameTime gameTime)
{
   Position += Direction * Speed * gameTime.ElapsedGameTime.TotalSeconds;
}

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

ในที่สุดคุณเพิ่งตั้งค่าคุณสมบัติทิศทางของคุณดังนี้:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();

โปรดทราบด้วยว่าถ้าความยาวของสไปรท์ทิศทาง (ก่อนการปรับสภาพ) น้อยกว่าขีด จำกัด บางสไปรต์ของคุณมาถึงแล้ว
TreDubZedd

ฉันกำลังจะแก้ไขโพสต์ของฉัน แต่ฉันเดาว่าจะไม่ทำ หากคุณไม่ต้องการให้ผีสางของคุณค้นหาเป้าหมายอย่างต่อเนื่องเพียงแค่ตั้งค่าทิศทางเป็น Vector2.Zero เมื่อมันอยู่ใกล้กับเป้าหมายมากพอ
Jesse Emond

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

:) โดยส่วนตัวแล้วฉันชอบที่จะวางมาตรฐานในคลาสสไปรต์ของฉัน (ในฟังก์ชั่นอัปเดตของฉัน) เพื่อป้องกันไม่ให้มีการทำให้ปกติอยู่นอกคลาส คุณควรตรวจสอบให้แน่ใจว่าความยาวของเวกเตอร์ไม่เท่ากับ 0 มิฉะนั้นคุณจะได้หารด้วย 0 ยกเว้น เพียงตรวจสอบว่า Direction.LengthSquared ()> 0 ก่อนที่จะทำให้เป็นมาตรฐานปลอดภัยหรือไม่ (ความยาวยกกำลังสองเพื่อให้คุณไม่ต้องคำนวณฟังก์ชันสแควร์ที่มีราคาแพง;))
Jesse Emond

ให้บอกว่าเราใช้ IDE ที่แตกต่างกันซึ่งไม่มีฟังก์ชั่นการทำให้เป็นปกติอะไรคือสมการ Normalize?
Spooks

2

การทำให้เป็นมาตรฐานของ Google ... ฉันก็หลงทางอยู่เหมือนกัน แต่ฉันค่อนข้างมั่นใจว่าสิ่งนี้จะช่วยแก้ปัญหาของคุณได้ คนอื่นสามารถทำอย่างละเอียดหรือหักล้างคำตอบของฉันฉันแน่ใจ

แก้ไข: ฉันสามารถตอบได้ดีกว่านี้ขอโทษ

ฉันมักจะมองไปที่โพสต์บล็อกนี้เพื่อช่วยแก้ไขปัญหาเหล่านี้: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

มันเริ่มต้นจากศูนย์และเกี่ยวข้องกับการพัฒนาเกม


3
คุณพูดถูกมันเป็นมาตรฐาน แต่จะเป็นการดีกว่าเสมอหากพยายามค้นหาคำตอบที่ดีในคำถามก่อนหน้า และหากคุณตอบคำถามจะเป็นการดีกว่าที่จะอธิบายหรือแบ่งปันรหัสหรือสิ่งที่คุณคิดว่ามีประโยชน์เสมอไม่ใช่แค่ชี้ไปที่ google
Notabene

ฉันควรจะแสดงความคิดเห็นคุณถูกต้อง
Douglas Rae
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.