2011-11-01 25 views
8

trình đọc thời gian dài đầu tiên. Làm ơn dịu dàng.Các lớp 'Tự nhận thức'?

Tôi khao khát tạo trò chơi trong VB.net. Là một lập trình viên sở thích, tôi cho miễn phí trò chơi của mình. Vì tôi là một Hobbiest mà không được đào tạo chính quy, tôi cố gắng và tự học về các nguyên tắc lập trình thích hợp và tuân theo chúng khi lập trình như OOP. Tuy nhiên, có một số điều tôi rõ ràng đã bỏ lỡ là tự học mà có lẽ tôi sẽ biết nếu tôi được giáo dục chính thức.

Một khi vấn đề đó thực sự là lệnh cấm của tôi là các lớp khác nhau (từ bây giờ được gọi là đối tượng) 'biết' về nhau KHÔNG tương tác với chương trình cụ thể (ở lại với tôi ở đây ... vui lòng ...)

rồi tưởng tượng này, bạn có một trò chơi không gian và các đối tượng sau đây

  • clsShip
  • clsMissile
  • clsAsteroid
  • clsSpaceJunk

Bây giờ, mỗi đối tượng trong số này có một thành viên riêng tư Y tế, X, Y và Z, tất cả đều được kế thừa từ clsSpaceEntity vì lợi ích đối số. Bây giờ một cách để va chạm lập trình giữa chúng sẽ được mã hóa ra logic sau đây trong vòng lặp trò chơi chính

cho mỗi tàu trong một danh sách các tàu
kiểm tra mỗi clsMissile trong một danh sách để xem nếu nó va chạm với nó và nếu như vậy, làm giảm sức khỏe
kiểm tra mỗi clsAsteroidin một danh sách để xem nếu nó va chạm với nó và nếu như vậy, làm giảm sức khỏe
kiểm tra mỗi danh sách clsSpaceJunka để xem nếu nó va chạm với nó và nếu như vậy, làm giảm sức khỏe
... và vv cứ tiếp tục như vậy cho mọi đối tượng tiếp theo

ect ect ...

Bây giờ điều này có thể đường may nếu bạn nói về ví dụ đơn giản ở trên nhưng một số trò chơi của tôi có hàng chục hoặc thậm chí hàng trăm đối tượng tương tác theo cách cơ bản này.

Bây giờ câu hỏi của tôi dành cho những người lập trình có kinh nghiệm ở đó.

Có cách nào trong OOP phải làm như sau ...

cho mỗi điều được thừa kế từ clsSpaceEntity
kiểm tra đối với tất cả các đối tượng khác mà được thừa hưởng kiểu này (ngoại trừ chính nó) và nếu họ va chạm sau đó giảm sức khỏe
next

?

Loại khả năng này cho một loại đối tượng/lớp hoặc bất kỳ thứ gì để 'nhận thức' của người khác và cách chúng giống nhau/khác nhau và tương tác sẽ tiết kiệm cho tôi tấn và tấn và TONNES của mã hóa.

Mọi hỗ trợ/trợ giúp hoặc phản hồi về điều này sẽ rất được đánh giá cao. Cảm ơn bạn đã dành thời gian, xin lỗi vì đã đọc lâu.

+7

Không sử dụng ký hiệu Hungary ('clsWhatever'). – SLaks

+1

Dường như bạn đang cố gắng để đạt được sự tách biệt mối quan tâm. Sử dụng một số khái niệm OOP khác, bạn có thể tạo ra logic tách biệt đẹp mắt mà không có các phương thức khổng lồ xử lý mọi loại đối tượng. Chúc may mắn! – SLaks

+1

Tắt chủ đề, nhưng bạn có vẻ hơi bối rối về các lớp và đối tượng. Trong khi chúng có liên quan, chúng không giống nhau. Hộp bình luận này là một chút nhỏ cho một lời giải thích đầy đủ, nhưng đọc lên trên sự khác biệt sẽ làm cho cuộc sống dễ dàng hơn cho bạn. –

Trả lời

7

Thay vì có một riêng biệt List(Of T) cho mỗi đối tượng có nguồn gốc, bạn nên tạo một đơn List(Of SpaceEntity) chứa tất cả các thực thể của bạn.

Sau đó, bạn có thể tạo vòng lặp For Each lồng nhau qua từng cặp đối tượng và kiểm tra va chạm. (sau khi kiểm tra If x <> y)

Bạn có thể nâng cao hơn nữa thiết kế của mình bằng cách cung cấp chức năng SpaceEntity để xử lý va chạm với các đối tượng khác mà không gây ô nhiễm vòng lặp va chạm với logic riêng biệt cho từng thực thể.
Có lẽ bạn nên sử dụng visitor pattern để cho phép các thực thể phản ứng khác nhau với các va chạm với các loại thực thể khác nhau.

Lưu ý rằng mỗi va chạm sẽ được gửi đến cả hai đối tượng va chạm riêng; bạn cần phải xử lý điều đó trong logic của bạn.

2

Nếu tôi viết logic xử lý một tàu đơn, hoặc tên lửa đơn, tiểu hành tinh, v.v. Sau đó, logic đó rõ ràng nên thuộc về lớp tương ứng.

Nếu tôi viết logic giao dịch với nhiều đối tượng hoặc thậm chí tệ hơn, nhiều đối tượng thuộc nhiều loại khác nhau, tôi có xu hướng đặt logic đó vào một lớp đại diện cho khái niệm cấp cao hơn.

Ví dụ: bạn có thể có một lớp Vũ trụ có chứa bộ sưu tập của SpaceEntity. Và có một Universe.FindCollisions() trả về một tập hợp các đối tượng Collision.

public class Universe { 
    private IEnumerable<SpaceEntity> _entities; 

    public IEnumerable<Collision> FindCollisions() { 
     foreach(var e1 in _entities) { 
      foreach(var e2 in _entities) { 
       if (e1.CollidesWith(e2)) { 
        yield return new Collision(e1, e2); 
       } 
      } 
     } 
    } 
} 

Một cách khác để giải quyết nó có thể là để có một lớp CollisionCalculator chấp nhận một bộ sưu tập của SpaceEntity trong constructor của nó và là nơi mà cuộc sống logic cụ thể.

public class CollisionCalculator { 
    public IEnumerable<Collision> Collisions {get; set;} 

    public CollisionCalculator(IEnumerable<SpaceEntity> entities) { 
     // logic to build the Collisions collection goes here 
    } 
} 
+0

Vòng lặp foreach lồng nhau đó sẽ trả về hai va chạm cho mỗi cặp chồng chéo của các thực thể. Một cho tên lửa va chạm với tảng đá và một cho tảng đá va chạm với cây tên lửa. Bạn có thể cần phải lọc chúng ra, tùy thuộc vào độ phân giải va chạm của bạn được xử lý như thế nào. – tcarvin

+0

Có thể cần lưu ý rằng vòng lặp lồng nhau kép sẽ trở thành không thực tế khi số lượng đối tượng lớn (trên vài trăm). Nếu có khoảng cách giữa các đối tượng sẽ đảm bảo rằng chúng không thể va chạm, có thể hữu ích khi chia nhỏ vũ trụ thành các khối lớn hơn và giữ một danh sách các đối tượng ít nhất một phần trong mỗi khối. Sử dụng phân vùng đơn giản trong không gian 3d, một số đối tượng có thể phải xuất hiện trong tối đa tám danh sách, nhưng thử nghiệm 100 nhóm mười đối tượng cho các va chạm sẽ nhanh hơn thử nghiệm một nhóm 1.000. – supercat

+0

Ngẫu nhiên, có thể và không quá khó để chia nhỏ không gian 3 chiều thành các khu vực sao cho không đối tượng nào rơi vào nhiều hơn bốn khu vực (thay vì tám). Nếu làm tròn Y thành số nguyên gần nhất sẽ sinh số lẻ, cộng 0,5 vào X. Nếu làm tròn Z đến số nguyên gần nhất sẽ cho số lẻ, cộng 0,5 vào cả X và Y. Sau đó làm tròn cả ba tọa độ thành số nguyên. Một ánh xạ giữa các tọa độ không gian và các giá trị XY sẽ cho thấy không gian được chia thành các khối đơn vị được đặt sao cho không quá bốn sẽ nằm trong một đơn vị quý của bất kỳ điểm nào. – supercat

Các vấn đề liên quan