Làm thế nào để xử lý vật lý của các nền tảng di chuyển trong một platformer?


8

Vì vậy, sau vài giờ tìm kiếm trên internet, tôi vẫn chưa tìm thấy câu trả lời thú vị về cách xử lý các nền tảng di chuyển trong trò chơi nền tảng 2d. Vì vậy, tôi quyết định tạo ra một nguyên mẫu đơn giản trong đó bạn tương tác với 2 nền tảng khác nhau, một nền tảng di chuyển theo chiều dọc và một nền tảng theo chiều ngang. Tôi rất thích một số trợ giúp để mổ xẻ và xem những gì không hoạt động, và cách khắc phục chúng. Tôi đã gửi tệp .fla + .as bên dưới, kèm theo một liên kết đến .swf có thể phát.

Mục tiêu là làm cho Hero tương tác với các nền tảng như thể chúng là những vật thể rắn mà anh ta có thể đứng, đẩy cùng với, nhảy lên / xuống, v.v.

Các vấn đề với nguyên mẫu của tôi là:

  • Khi bạn đứng trên nền tảng di chuyển theo chiều ngang, không di chuyển (không chạm vào bất kỳ phím nào), Hero di chuyển cùng với nền tảng, nhưng với một chút chậm trễ khiến anh hùng trượt trở lại một chút.

  • Khi bạn đứng trên nền tảng di chuyển theo chiều ngang và nhảy, bạn di chuyển cùng với tầng trên của nền tảng (một số trò chơi thích có nó như thế này, nhưng nó không cảm thấy tự nhiên và không muốn ở đây). Điều này có thể do Hero giữ lại vận tốc trên trục X từ nền tảng.

  • Khi bạn nhảy lên phía dưới cùng trên nền tảng di chuyển theo chiều dọc, trong khi nền tảng đang di chuyển xuống dưới, bạn chìm trong đó trong một giây ngắn ngủi. Anh hùng xuyên qua như thể vụ va chạm không tồn tại trong giây lát.

  • Khi bạn nhảy trên nền tảng di chuyển theo chiều dọc, veloctiy trên trục Y được giữ lại, vì vậy khi bạn rời khỏi nền tảng, bạn rơi xuống với tốc độ cao hơn. Với tốc độ của vận tốc được giữ lại, + trọng lực được thêm vào (điều này chủ yếu là do tôi không thể tìm ra cách đặt lại vận tốc trên trục Y về 0 khi bạn hạ cánh trên nền tảng, mà không có người chơi đóng băng giữa không trung).

Tôi là một lập trình viên mới làm quen nên tôi chắc chắn có nhiều cách TỐT HƠN để làm điều này và tôi rất thích nghe tất cả. Mọi ý tưởng về cách cải thiện mã hoặc các phương pháp khác mà bạn có thể triển khai các nền tảng di chuyển thành trò chơi Tilebasing đều được hoan nghênh. Cuối cùng, tôi đang cố gắng tìm một cách vững chắc để xử lý các nền tảng di chuyển trong các nền tảng 2d.

SWF có thể phát: http://dl.dropbox.com/u/28271061/Pl platformerhowtoFLA.html (Di chuyển bằng phím mũi tên, Nhảy bằng phím X, Chạy bằng phím Z)

Sourcecode AS-file: http://dl.dropbox.com/u/28271061/Pl platformerhowto.as

SourcefileFLA: http://dl.dropbox.com/u/28271061/Pl PlatformerhowtoFLA.fla

Nếu bạn chỉ muốn đọc mã qua Pastie trực tuyến: http://pastie.org/2266764



Tôi đã đọc chủ đề đó, nhưng vì tôi không sử dụng các nút theo bất kỳ cách nào, nên có cảm giác như nó không giải quyết được vấn đề. Trò chơi mà tôi đang xây dựng dựa trên gạch, nhưng các nền tảng di chuyển sẽ được triển khai như trên (di chuyển tự do). Sử dụng các nút sẽ yêu cầu viết lại toàn bộ công cụ của tôi, điều mà tôi đã mất một thời gian dài. Tôi đoán rằng tôi đã hy vọng ai đó sẽ xem mã và đưa ra một giải pháp tương tự như những gì được đề xuất hoặc tìm thấy một cải tiến cho mã.
Kid

Bạn sẽ sử dụng các nút một khi bạn triển khai giải pháp đó cho các nền tảng di chuyển, ngay cả khi đó là nơi duy nhất bạn sử dụng chúng. Nó sẽ giải quyết vấn đề trượt của bạn.
doppelgreener

2
"(Một số trò chơi thích có nó như thế này, nhưng nó không cảm thấy tự nhiên và không muốn ở đây)" Làm thế nào mà nó không "cảm thấy tự nhiên"? Quán tính và động lượng của Google ...
Riki

1
@Fel lov, Tự nhiên về mặt chơi game, không phải thế giới thực. Nếu bạn chơi Super Mario Bros hoặc bất kỳ nền tảng cổ điển nào, bạn sẽ nhận thấy rằng họ KHÔNG bảo toàn động lực trong khi nhảy trên nền tảng di chuyển. Nó phá vỡ cảm giác đứng và tương tác với một nền tảng di chuyển.
Kid

Câu trả lời:


17

Hãy tách vấn đề của bạn thành các vấn đề khác biệt ...

Một từ về chất lượng mã

Mã của bạn hiện có các nền tảng của bạn trực tiếp kiểm soát vận tốc của người chơi và thậm chí cả hằng số trọng lực của thế giới . Đó là hacky, và nó là thủ tục khi nó nên được hướng đối tượng. Một khi bạn bắt đầu mở rộng trò chơi này, mọi thứ sẽ trở nên xấu xí nhanh chóng .

Bạn cần cấu trúc lại mã của bạn. Thực hiện một lớp người chơi, một lớp nền tảng và một lớp sàn. Tách biệt mối quan tâm của họ: yêu cầu người chơi diễn giải các điều khiển bàn phím và kiểm soát cách anh ta chạy và nhảy, và để các nền tảng thay đổi động lượng của anh ta khi cần thiết (bằng cách thêm tốc độ của riêng họ vào tốc độ đã được xác định của người chơi, khi cần thiết).

Yêu cầu người chơi của bạn xác định vị trí của nó đối với vật thể loại sàn (cả nền và sàn sẽ có một BodyType = BodyTypes.Floorhoặc một thứ gì đó) và tự xác định vị trí của nó đối với vật thể đó, cách nó phản ứng và liệu nó rơi xuống hay trên mặt đất.

Điều này có thể xứng đáng là một chủ đề riêng biệt vì đây là một vấn đề hoàn toàn riêng biệt với mọi thứ bạn đã đưa ra. Tuy nhiên, bạn sẽ phải làm điều đó vào một lúc nào đó.

Quán tính ngang / dọc khi rời bục

Để giải quyết vấn đề vận tốc dọc và ngang của bạn, hãy lưu ý hai điều:

  • Về tốc độ ngang: Mã của bạn chỉ đặt tốc độ ngang thành 0 khi người chơi chạm đất (trên dòng Pastie 200) hoặc một nền tảng.
  • Về tốc độ dọc: Người chơi của bạn có gia tốc rơi liên tục. Khi anh ta bước ra khỏi bục thẳng đứng, gia tốc rơi này cứ tiếp tục được thêm vào chuyển động đã đi xuống của anh ta.

Người chơi của bạn chỉ đơn giản là chịu đựng quán tính : động lượng của anh ta được duy trì cho đến khi một cái gì đó ngăn chặn nó.

Giải pháp: Cả hai vấn đề sẽ được giải quyết bằng giải pháp của jSepia về Làm cách nào để xử lý các nền tảng di chuyển trong trò chơi nền tảng? vì nó sẽ tách biệt hoàn toàn quá trình di chuyển của người chơi với cách các nền tảng di chuyển anh ta. Bạn chỉ đơn giản là không rơi nhanh hơn khi bước ra khỏi một nền tảng thẳng đứng và sẽ không bảo toàn động lượng ngang của bạn nhảy ra khỏi một nền ngang, bởi vì các nền tảng sẽ không còn ảnh hưởng đến vxvy của người chơi của bạn .

Lưu ý: Bạn có thể gặp một số khó khăn khi triển khai giải pháp của jSepia trước khi mã của bạn được cấu trúc lại.

Trượt từ bên này sang bên kia trên nền tảng ngang

Trình phát của bạn không thực sự di chuyển theo chiều ngang khá nhanh như nền tảng di chuyển. Nó không rõ ràng với tôi tại sao. Vấn đề này cũng có thể được giải quyết bằng cách triển khai giải pháp của jSepia và tái cấu trúc đúng mã của bạn (điều sau chỉ đơn giản là làm cho nguyên nhân rõ ràng).

Phát hiện va chạm: chồng chéo với nền tảng dọc

Xem dòng Pastie 381: mỗi bước nó đặt lại vy của người chơi về 0 miễn là người chơi va chạm với mặt dưới của nền tảng dọc. Trong bước tiếp theo, vy được tăng lên nhờ gia tốc trọng lực và sau đó người chơi di chuyển (và sau đó nó được đặt lại về 0).

Điều này có nghĩa là miễn là người chơi của bạn va chạm với đáy của nền tảng, anh ta sẽ di chuyển xuống với tốc độ không đổi (hằng số trọng lực). Nền tảng dọc nhanh hơn thế nên nó chồng lên anh ta. Nếu nền tảng dọc di chuyển trên một khoảng cách dài hơn, nó sẽ trượt qua anh ta cho đến khi người chơi được đăng ký là đứng trên nền tảng.

Giải pháp: Không đặt lại vy của người chơi về 0. Chỉ cần đặt vy của người chơi theo tốc độ dọc của nền tảng ( nếu nền tảng đang di chuyển xuống dưới ). Người chơi của bạn sau đó sẽ di chuyển ra khỏi nền tảng dọc ít nhất là nhanh như nền tảng và tăng tốc ra khỏi nó.


Thông minh! Đầu tiên cảm ơn giải pháp cho việc nhảy và thâm nhập vào nền tảng thẳng đứng (hoạt động!). Và thứ hai, bạn đã đúng, mã là khủng khiếp trong trạng thái này. Mặc dù bản thân đây không phải là trò chơi, nhưng đây là một nguyên mẫu nhanh được thực hiện để thử nghiệm và hiểu rõ hơn về các nền tảng di chuyển. Tuy nhiên, nếu tôi dịch nó sang mã trò chơi thực tế, tôi nên giữ một mã có cấu trúc và hướng đối tượng hơn. Nó sẽ làm trơn tru việc chuyển tiền. Bây giờ, liên quan đến giải pháp jSpeias, tôi nghĩ rằng tôi có khái niệm cây nút, chỉ là tôi không biết cách triển khai nó đúng cách.
Kid

Suy nghĩ đầu tiên của tôi là tạo ra các giá trị Boolean mô tả trạng thái của người chơi, chẳng hạn như: "onFloor", "onPl platform", "onGround", "fall", "jump", v.v. sự kiện enterFrame kiểm tra trạng thái hiện tại và thay đổi thuộc tính Người chơi tương ứng (?) Ví dụ: if (Hero.onPl platform == true) {Player.x = platform.x (liên quan đến người chơi toàn cầu x);}. Một cái gì đó theo cách đó.
Kid

Tôi đang làm việc với nó khi chúng ta nói, nhưng đồng thời tôi đang tách mã thành các lớp khác nhau như bạn đề xuất, điều này cũng hơi khó hiểu (giao tiếp giữa các lớp nền tảng / va chạm / người chơi bị uốn cong).
Kid

@Kid: Playercó một phương thức GetPositionvà các biến nội bộ parent(cho nút cha của nó) và position(cho vị trí của nó so với cha mẹ của nó). Player.GetPosition()trả lại position + parent.GetPosition(). Cha mẹ của nó làm điều tương tự cho đến khi bạn đạt đến gốc của cây - nút thế giới. Khi người chơi của bạn di chuyển, bạn chỉ đối phó với positionbiến riêng . Người chơi của bạn được vẽ trên màn hình trò chơi theo GetPosition()giá trị của. Tôi sẽ cho bạn biết làm thế nào chuyển đổi giữa các nút. ;)
doppelgreener

Có một lớp người chơi biết cách sửa đổi vận tốc của chính mình, tất nhiên không phải là sự tách biệt các mối quan tâm
Andy Ray
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.