Làm thế nào chính xác làm dốc và cạnh làm việc trong kịch bản này?


7

Vì vậy, loại hành vi này có thể tồn tại trong các trò chơi khác, nhưng các trò chơi Kirby cũ - Kirby's Adventure và Kirby's Dreamland 2 - là nơi tôi nhận thấy điều đó.

Vì vậy, khi giao dịch với các nền tảng khối thông thường, hitbox của Kirby hoạt động như một hình chữ nhật đơn giản, như bạn mong đợi, bằng chứng là bạn có thể đứng như vậy:

Kirby đứng trên một cạnh, chỉ được hỗ trợ bởi một hoặc hai pixel.

Mặt khác, khi xử lý các loại dốc , đứng trên chúng trông như thế này:

Kirby đứng trên dốc, với một chân nhúng vào dốc.

Như bạn có thể thấy, nếu chúng ta vẫn đang sử dụng hộp đựng hình chữ nhật, nó sẽ nằm ở giữa mặt đất. Tuy nhiên, loại hành vi này dễ dàng được giải thích, tuy nhiên, hãy mua một hộp hitbox có hình dạng 'kim cương' hoặc 'cộng'. (Điều này có lẽ là do nó không giống như Kirby đang lơ lửng giữa không trung khi đi trên sườn núi)

Các nền tảng như thế này thể hiện tính nhất quán hoàn hảo với mô hình hitbox 'diamond':

Kirby lơ lửng ngoài rìa của một nền tảng dốc.Kirby đứng trên đỉnh giữa hai con dốc.

Tuy nhiên, tất nhiên, ảnh chụp màn hình đầu tiên cho thấy không thể sử dụng hitbox hình kim cương mọi lúc, hoặc bạn có thể 'trượt' khỏi bất kỳ góc nào như thể có độ dốc ở đó.

Kirby đứng trên môi giữa một bề mặt phẳng và dốc.

Trên thực tế, các thành tạo như điều này cho thấy rằng nó thậm chí không thể dựa trên các ô cụ thể, ít nhất là không phải là 'toàn bộ'. (16x16, kích thước của Kirby) (Nếu không, bạn không thể đi bộ lên dốc đó)

Một mô hình khác mà tôi nghĩ ra là hitbox luôn có hình chữ nhật, nhưng tất cả các sườn dốc trong trò chơi thực sự 'chìm sâu' hơn những viên gạch mà bạn tin tưởng. Tuy nhiên, các nền tảng hình cọc trong ảnh chụp màn hình thứ ba và thứ tư làm mất hiệu lực mô hình này, kể từ đó bạn sẽ không thể đứng ở giữa trên cùng như bạn thấy ở đó.

Nhân tiện, các sườn dốc trên trần nhà hoạt động đối xứng, như có thể nhìn thấy trong các giai đoạn nước.

Trong khi nó có vẻ trực quan với người chơi, làm thế nào chúng ta có thể lập trình một hệ thống va chạm tương tự ?

Lưu ý Tôi không yêu cầu suy đoán về hoạt động nội bộ của Kirby (trừ khi có người ở đây thực sự phát triển hệ thống va chạm cho những trò chơi đó - không thể xảy ra). Chỉ là một cách tiếp cận chung.


6
Chúng tôi thường không trả lời các câu hỏi về sự tò mò lịch sử trên trang web Hỏi & Đáp này. Tài nguyên này được dành riêng để giúp các nhà phát triển ngày nay giải quyết các vấn đề trong các trò chơi mà họ hiện đang phát triển - vì vậy nếu câu hỏi của bạn là "Làm cách nào tôi có thể xử lý các va chạm của nền tảng 2D" thì bạn sẽ tìm thấy nhiều câu trả lời giải quyết chủ đề này. Làm thế nào Kirby đã làm nó có thể hoặc không phải là một giải pháp phù hợp cho trò chơi bạn đang thực hiện, vì vậy tốt hơn là hỏi về vấn đề hơn là một giải pháp cụ thể trong quá khứ. Nếu bạn quan tâm đến cơ chế lịch sử của Kirby, một diễn đàn hack ROM có thể là một nơi tốt hơn để hỏi.
DMGregory

2
Tôi đã điều chỉnh câu hỏi để tránh khía cạnh "suy đoán lịch sử" giả định được ghi nhận bởi @DMGregory.
Kỹ sư

Câu trả lời:


1

Một cách khác mà điều này có thể được xử lý là bằng cách kiểm tra va chạm ở trung tâm của căn cứ của nhân vật trước và rơi trở lại lớp gạch chồng lên nhau nếu không tìm thấy va chạm ở đó.

Bất kể gạch nào cuối cùng chúng ta tìm thấy va chạm, chúng tôi luôn tính chiều cao sàn bằng cách sử dụng cùng một điểm ở giữa cơ sở của nhân vật, ở đây tôi đang gọi characterFootXYtương ứng

Giả sử tọa độ pixel nguyên trên lưới ô vuông 16x16, nó có thể trông như thế này:

// Round the character's foot position into its corresponding tile indices.
int tileX = characterFootX >> 4;
int tileY = characterFootY >> 4;

// Fall back on an adjacent tile if this tile has no collision.
if(tiles[tileX, tileY] == EMPTY_TILE) {

    // Round the character's tile up or down to the closest neighbouring tile horizontally.
    // (+1 if we're in the right half of the tile, -1 in the left half)
    tileX += (characterFootX & 0x8) >> 2 - 1;

    // Check tile above, to handle cases where we're 
    // just off the bottom edge of a slope above us.
    if(tiles[tileX, tileY + 1] != EMPTY_TILE)
        tileY++;
}

int floorY = -1;
Tile tile = tiles[tileX, tileY];

if(tile == EMPTY_TILE) {
    // Falling
} else {
    // Get pixel offset from the center of the tile.
    int deltaX = characterFootX - 16 * tileX + 8;

    // Get base height of the tile.
    floorY = tileY * 16 + tile.baseHeight;

    // Adjust height based on slope.
    floorY += tile.slope * deltaX;
}

Tôi nghĩ rằng chính sách này luôn luôn sử dụng trung tâm của căn cứ của nhân vật để va chạm và chỉ nhìn vào ô va chạm hợp lệ duy nhất gần trung tâm đó, có thể giải thích cho tất cả các trường hợp được hiển thị trong ảnh chụp màn hình.


1

Đối với các trò chơi 2D cũ, các va chạm vector đầy đủ quá nặng CPU và các phím tắt đã được thực hiện. Nếu bạn muốn tạo lại cảm giác tương tự và sự cố va chạm liên quan, bạn sẽ phải sử dụng các thủ thuật tương tự.

Có hai loại va chạm riêng biệt: va chạm khối đầy đủ đơn giản và nhanh chóng (màu xanh lam) và các trường hợp đặc biệt (dốc màu vàng).

Vòng tròn màu vàng là va chạm 1 pixel.

Sự va chạm hoàn toàn (màu xanh lam) chỉ kiểm tra các khối đầy đủ hoàn toàn bỏ qua gạch đặc biệt (màu vàng).

Điều này cho phép đi vào ranh giới tế bào của độ dốc.

Khi kiểm tra điểm ảnh chân (màu vàng) phát hiện ở bên trong dốc, nó sẽ đẩy nhân vật lên khi cần thiết và vô hiệu hóa kiểm tra va chạm đầy đủ để cho phép đi bộ hết đường lên dốc. Nếu va chạm hoàn toàn (màu xanh) không bị vô hiệu hóa khi ở trong một ô dốc, bạn sẽ bị kẹt ở giữa dốc do va vào một bên của ô đầy đủ trên cùng.

nhập mô tả hình ảnh ở đây

Tùy chọn, có một va chạm 1 pixel tương tự cho bên trái và bên phải ở trung tâm để xử lý trường hợp tường lên dốc (màu xanh lá cây).

Điều này có thể tránh được nếu không bao giờ có một bức tường lên dốc và một số trò chơi đã làm điều này. Khi bạn chỉ có từ 1 đến 8 MHz, bạn đã lưu ở nơi bạn có thể.

Và một kiểm tra thứ 4 trên đỉnh đầu cho độ dốc trần.

nhập mô tả hình ảnh ở đây

Để tiết kiệm cho việc xử lý các va chạm trong trường hợp đặc biệt không phải là một viên kim cương thật mà là các séc có kích thước pixel đơn. Điều này hoạt động tốt với các hình dạng dốc giới hạn và đảm bảo chỉnh sửa bản đồ phù hợp để tránh khả năng nêm nhân vật.

Trừ khi bạn nhắm mục tiêu một bộ điều khiển vi mô ~ 8Mhz hoặc muốn tái tạo các vấn đề cụ thể, mánh khóe này có thể gây ra một vụ va chạm hình kim cương thực sự có thể được sử dụng trên các máy tính hiện đại.


0

Bạn có thể đạt được điều này bằng cách sử dụng các điều kiện va chạm khác nhau cho:

  1. điều chỉnh vị trí y của nhân vật trong khi ở trạng thái "nối đất" để có độ dốc theo hành vi
  2. chuyển từ trạng thái "nối đất" sang trạng thái "rơi"

Bất cứ khi nào nhân vật-người chơi ở trạng thái "có căn cứ", bạn thực hiện một tia sáng từ một điểm giữa hai chân của nhân vật thẳng xuống và thẳng lên. Xem nơi bạn chạm vào bề mặt nền tảng và thay đổi tọa độ y của trình phát sprite để nó nằm trên nền tảng đó. Giới hạn độ dài của raycast xuống dưới 1 ô ở cả hai hướng và không làm gì khi không có cú đánh. Điều này là để không can thiệp vào hành vi đứng trên vách đá được nhìn thấy trong ảnh chụp màn hình thứ 1 và thứ 3 khi có mặt đất bên dưới vách đá.

Sau đó, kiểm tra xem nhân vật vẫn còn căn cứ. Sử dụng một đường truyền từ góc dưới bên trái đến góc dưới bên phải của trình phát sprite để kiểm tra xem nó có còn tiếp xúc với nền tảng hay không. Khi không, thay đổi trạng thái của người chơi từ "căn cứ" thành "rơi".


Lưu ý rằng đây là những gì bạn sẽ làm trong một trò chơi "hiện đại", nơi bạn có sự thuận tiện để sử dụng có chủ ý các số liệu va chạm số học và hình học phức tạp. Trò chơi từ ví dụ là từ thời gian đơn giản hơn nhiều. CPU MOS 6502 của NES thậm chí không có đơn vị dấu phẩy động, vì vậy chúng phải làm mọi thứ với toán học số nguyên. Điều này có nghĩa là mã của họ có khả năng rất nhiều. Tôi sẽ cho rằng họ có mã hóa đặc biệt để xử lý việc đi bộ trên các đường chéo. Cái gì đó như:

walkRight:
    x++;
    if (tile[x>>4, y>>4 + 1] == UP_SLOPE)
        y--;
    if (tile[x>>4, y>>4 + 1] == DOWN_SLOPE)
        y++;

0

Có nhiều cách để thực hiện các hệ thống va chạm trong các trò chơi 2D. Tôi thấy không chắc rằng trò chơi đặc biệt này đã không sử dụng một hệ thống dựa trên gạch nào đó, các sprite lớn hơn hitbox của họ là một tính năng phổ biến cho các nền tảng dựa trên gạch và hệ thống gạch hoàn hảo pixel vẫn cực kỳ hữu ích cho các trò chơi hiện đại. . Phần khó khăn duy nhất về nó là xử lý các sườn dốc và các chướng ngại vật cạnh khác như nền tảng một chiều. Bài viết này cung cấp một lời giải thích hợp lý cho một số hệ thống va chạm, mặc dù nó không phải là phương pháp duy nhất.

Tôi sẽ mô tả thuật toán cơ bản mà bài viết cung cấp, nhưng tôi khuyến khích bạn đọc toàn bộ để có giải thích / hiểu biết toàn diện hơn về các hệ thống này. Ngày nay chắc chắn có nhiều cách hiệu quả hơn, trực quan hơn để thực hiện các hệ thống va chạm 2D, nhưng đây là những gì tôi có thể thu thập từ câu hỏi cụ thể của bạn.


Toàn bộ cấp độ được xây dựng dưới dạng bản đồ với tất cả các thông tin có liên quan được lưu trữ trên các ô (loại địa hình, hiệu ứng người chơi, v.v.) và các nhân vật có hộp va chạm / va chạm thông thường. Phần lớn các hệ thống va chạm 2D, đặc biệt là cho các trò chơi cũ hơn, liên quan đến toán học hoàn hảo pixel và tương tự.

Mỗi khung hình chúng tôi xác định chuyển động theo hướng X và Y. Nếu di chuyển sang trái, chúng ta sẽ lấy cạnh ngoài cùng bên trái của hộp điều khiển (tương tự để di chuyển sang phải, lên và xuống) và xác định gạch nào cạnh đó đang giao nhau. Đi qua các ô này để phát hiện bất kỳ chướng ngại vật nào có thể ngăn cản chuyển động và di chuyển nhân vật khoảng cách tối thiểu mà nó có thể di chuyển. Lặp lại cho đến khi bạn tính toán tất cả các chuyển động cho khung.

Đó là đối với các bản đồ không có độ dốc và việc thêm chúng có thể trở nên khó khăn. Trừ khi bạn muốn thực hiện một số tính toán kỳ quặc hơn, tốt nhất là giữ cho các sườn được sử dụng một kích thước phù hợp. Vì vậy, ví dụ, một đoạn đường nối dài 4 gạch và đi lên 1 gạch không bao giờ được đặt với các khoảng trống hoặc kết thúc sớm.

Trước tiên chúng ta cần kiểm tra hướng X của chuyển động, và trước khi kiểm tra va chạm, trước tiên chúng ta kiểm tra xem gạch chúng ta đang ở có dốc không và chỉ đăng ký gạch là va chạm nếu chúng ta đi lên dốc (trong này trường hợp di chuyển sang trái). Nếu chúng ta có va chạm dốc, chúng ta sẽ phải di chuyển người chơi lên theo hướng Y.

Ví dụ bản đồ gạch Mega Man

Một trường hợp khác chúng ta cần xem xét là đỉnh và đáy của toàn bộ độ dốc (gạch có chấm màu xanh được đánh dấu trên đó). Để ngăn nhân vật bị mắc kẹt, chúng ta nên bỏ qua chướng ngại vật đầy đủ ngay trước và sau khi độ dốc hoàn thành. Bài viết thực hiện điều này bằng cách kiểm tra xem độ dốc được lấp đầy ở các cạnh trái hay phải, có nghĩa là chúng ta đang ở cuối các lát dốc.

Đối với chuyển động thẳng đứng, thông thường chúng ta có lực hấp dẫn được áp dụng cho nhân vật, vì vậy một lần nữa chúng ta kiểm tra va chạm trong các ô dốc và di chuyển người chơi xuống tương ứng.

Rất nhiều trong số này là toán học và va chạm hoàn hảo pixel phụ thuộc nhiều vào hệ tọa độ bạn đang sử dụng cho tilemap của mình.


0

Đối với những hình ảnh mà bạn đăng lên, có vẻ như Kirby bị va chạm điểm ở giữa hai chân và khung cảnh có các hộp va chạm được mở rộng ra ngoài các cạnh vách đá để va chạm điểm không cho phép Kirby rơi xuống cho đến khi anh ta hoàn toàn vượt ra ngoài cạnh của vách đá.


0

Vâng, bạn đã tự trả lời nó. Khi Kirby đang đứng trên một viên gạch "bình thường", hộp giới hạn là hình chữ nhật và khi anh ta chạm vào một con dốc, nó biến thành một viên kim cương.


Việc triển khai thực tế có khả năng là những gì DMG đề xuất. Mô hình khôn ngoan, hộp giới hạn "thay đổi hình dạng".
AturSams
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.