Di chuyển một sprite trong XNA / C #, sử dụng vectơ


9

Tôi hiện đang xem xét phát triển trò chơi XNA với ngôn ngữ C #.

Tôi có hai lớp: trình xử lý trò chơi chính và lớp "sprite". Sau đây là một số mã giả cơ bản mà tôi hy vọng mô tả đầy đủ vấn đề.

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
    }
  }
}

Về cơ bản: khi người dùng nhấp vào đâu đó trong cửa sổ trò chơi, tọa độ x và y của chuột sẽ được lấy và đối tượng trò chơi sẽ di chuyển về phía vị trí đó trong một khoảng thời gian.

Chà ... mã hoạt động, nhưng nó xấu, và các đối tượng không di chuyển trực tiếp về phía đối tượng (thay vào đó, đó là chuyển động chéo, tiếp theo là chuyển động một trục). Tôi đoán có một số hàm toán học tôi có thể sử dụng, nhưng thật lòng tôi không biết phải bắt đầu từ đâu. Bất kỳ đề xuất?


3
Xin chào Khách. Những gì bạn đang tìm kiếm là bình thường hóa. Vui lòng đọc câu trả lời cho câu hỏi này: gamedev.stackexchange.com/questions/7540/ . Một cung cấp mã mà bạn cần, thứ hai giải thích cách nó hoạt động rất độc đáo.
Notabene

Xin chào, tôi đã xem liên kết và đó chính xác là những gì tôi cần. Cảm ơn bạn!
Matt

Câu trả lời:


12

Nếu tôi hiểu đúng vấn đề của bạn, bạn chỉ nên có một hướng Vector2 đại diện cho hướng bạn muốn di chuyển bên trong lớp sprite của mình. Như thế này:

public Vector2 Direction { get; set; }

Đây là vectơ chuẩn hóa (có nghĩa là nó có độ dài 1) hiển thị nơi bạn muốn đi.

Sau đó, thêm thuộc tính Tốc độ nổi, cho biết tốc độ của sprite sẽ đi nhanh như thế nào.

public float Speed { get; set; }

Bạn cũng cần thêm một hàm UpdateSprite, vậy tại sao không đặt nó bên trong lớp Sprite của bạn?

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

Điều này sẽ cập nhật vị trí của sprite để làm cho nó di chuyển (bạn nhân với số giây delta để sprite di chuyển đúng trên các máy tính chậm).

Cuối cùng, bạn chỉ cần đặt thuộc tính hướng của mình như thế này:

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

Cũng lưu ý rằng nếu độ dài của sprite.Direction (trước khi chuẩn hóa) nhỏ hơn một số ngưỡng, sprite của bạn đã đến.
TreDubZedd

Chính xác, tôi đã định chỉnh sửa bài viết của mình, nhưng tôi đoán tôi sẽ không làm thế. Nếu bạn không muốn sprite của mình liên tục tìm kiếm mục tiêu, chỉ cần đặt Hướng thành Vector2.Zero khi nó đủ gần mục tiêu.
Jesse Emond

Câu trả lời rất hay ... và bạn cũng dạy tôi về việc sử dụng gameTime (để di chuyển các sprite ở tốc độ phù hợp trên các máy tính chậm hơn), vì vậy hai con chim với một hòn đá. Tôi sẽ đánh dấu câu trả lời này là được chấp nhận.
Matt

:) Nhân tiện, cá nhân tôi thích đặt chuẩn hóa bên trong lớp sprite của mình (bên trong chức năng cập nhật của tôi), để tránh phải liên tục bình thường hóa nó bên ngoài lớp. Bạn cũng nên đảm bảo rằng độ dài của vectơ không bằng 0, nếu không, bạn sẽ được chia cho 0 ngoại lệ. Chỉ cần kiểm tra xem Direction.LdropsSquared ()> 0 trước khi bình thường hóa nó có an toàn không (độ dài bình phương để bạn không phải tính hàm vuông đắt tiền đó;)).
Jesse Emond

Hãy nói rằng chúng ta đang sử dụng một IDE khác không có chức năng chuẩn hóa, phương trình Chuẩn hóa sẽ là gì?
Spooks

1

Google bình thường hóa ... tôi cũng hơi mất mát về điều này, nhưng tôi khá chắc chắn rằng điều này sẽ giúp giải quyết vấn đề của bạn. Một số người khác có thể giải thích hoặc từ chối câu trả lời của tôi, tôi chắc chắn

Chỉnh sửa: Tôi có thể trả lời điều này tốt hơn, xin lỗi

Cá nhân tôi luôn tìm đến bài đăng trên blog này để giúp giải quyết các loại vấn đề này: http://blog.wolfire.com/2009/07/linear-acheebra-for-game-developers-part-1/

Nó bắt đầu từ đầu và có liên quan đến phát triển trò chơi.


3
Bạn nói đúng, đó là bình thường hóa. Nhưng nó luôn luôn tốt hơn để cố gắng tìm câu trả lời tốt trong các câu hỏi trước. Và nếu bạn đang trả lời, tốt hơn hết là giải thích hoặc chia sẻ mã hoặc bất cứ điều gì bạn nghĩ có thể hữu ích, không chỉ vào google.
Notabene

Tôi nên có ý kiến, bạn đúng.
Douglas Rae
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.