Làm thế nào để thực hiện các khu vực cạnh mềm với các hạt


13

Trò chơi của tôi được tạo bằng Phaser, nhưng câu hỏi đặt ra là không tin tưởng vào động cơ.

Trong trò chơi của tôi, tôi có một số môi trường, về cơ bản là các khu vực đa giác mà nhân vật người chơi có thể di chuyển vào và bị ảnh hưởng. Ví dụ: băng, lửa, chất độc, v.v ... Yếu tố đồ họa của các khu vực này là chính khu vực đa giác đầy màu sắc và các hạt thuộc loại phù hợp (trong ví dụ này là các mảnh băng). Đây là cách tôi hiện đang thực hiện điều này - với mặt nạ đa giác bao phủ một lát gạch với mẫu hạt:

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

Các cạnh cứng trông xấu. Tôi muốn cải thiện bằng cách thực hiện hai điều: 1. Tạo vùng điền đa giác để có cạnh mềm mại và hòa trộn vào nền. 2. Có một số mảnh vỡ đi ra khỏi khu vực đa giác, để chúng không bị cắt ở giữa và khu vực không có một đường thẳng

ví dụ (mockup):

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

Tôi nghĩ rằng 1 có thể đạt được bằng cách làm mờ đa giác, nhưng tôi không chắc chắn cách thực hiện với 2.

Làm thế nào bạn sẽ đi về thực hiện điều này?


2
Trông tuyệt vời. Tôi có thể có một liên kết đến trò chơi của bạn xin vui lòng? :)
tro999

@GameAlchemist Đây là hình ảnh gạch i.imgur.com/y54CeQ9.png
OpherV

@ tro999 Đây vẫn là một công việc đang tiến triển. Tôi chắc chắn sẽ đăng một liên kết ở đây khi tôi có nó :)
OpherV

Lưu ý rằng đó là một PNG trong suốt với các đối tượng màu trắng. Nếu bạn xem nó trên nền trắng (như thường lệ khi mở ảnh trong trình duyệt), bạn sẽ không thấy gì cả
OpherV

@OpherV đó sẽ là tuyệt vời. Vui lòng chỉ chỉnh sửa câu hỏi của bạn và đăng một liên kết - đó có lẽ là cách chủ đề nhất để tiếp thị nó trên trang web này :)
tro999

Câu trả lời:


2

1.Nếu bạn muốn thứ gì đó gần với mockup của mình, tôi sẽ sử dụng các hạt (Nó không phải là một hệ thống hạt được thổi hoàn toàn).

Kết xuất các hạt của bạn dưới dạng đa giác trên RenderTexture. Hãy chắc chắn để sử dụng hỗn hợp phụ gia trên các hạt. Các hạt bên trong đa giác sẽ hòa trộn với nhau một cách trơn tru trong khi các hạt ở bên ngoài sẽ tạo ra cạnh mềm mại mà bạn muốn. (Một ví dụ về hiệu ứng có thể được xem trong video youtube này: Video Hạt phụ Bây giờ kết xuất RenderTexture trên màn hình chính của bạn và bạn đã hoàn tất.

Bạn có thể thử đặt các hình tam giác trực tiếp lên kết cấu hạt và xem cách thức hoạt động của nó. Nếu không, hãy đặt chúng lên trên "súp hạt" của bạn dưới dạng một lớp riêng biệt.

Tạo một mockup nhanh trong một jsfiddle được cập nhật trông như thế này Bản giới thiệu Bạn có thể tìm thấy bản demo được cập nhật ở đây

2.Mỗi hạt có vận tốc và nguồn gốc. Khi người chơi của bạn chạm vào đa giác, bạn thay đổi từng hạt vận tốc tỷ lệ với vận tốc của người chơi. Một hạt càng xa người chơi của bạn, nó càng ít bị ảnh hưởng bởi vận tốc của người chơi.

Công thức tính vận tốc của các hạt sẽ giống như thế này:

//player.velocity and particle.velocity are vectors 
//k is a factor to enhance or weaken the influence of players velocity
var distanceToPlayer = (player.position - particle.position).length();
particle.velocity = particle.velocity + ((k * player.velocity) + particle.velocity) * (1/distanceToPlayer);

Để tính toán vị trí của hạt bạn đặt điều này trong phương pháp cập nhật của bạn:

var speedY = -(springConstant * (particle.position.y - particle.origin.y)) - (dampingFactor * particle.velocity.y);
var speedX = -(springConstant * (particle.position.x - particle.origin.x)) - (dampingFactor * particle.velocity.x);

particle.position.y = particle.position.y + speedY;
particle.position.x = particle.position.x + speedX;

particle.velocity.x = particle.velocity.x + speedX;
particle.velocity.y = particle.velocity.y + speedY;

Điều này sẽ cung cấp cho bạn một "chất lỏng" trong đó mỗi hạt dao động xung quanh nguồn gốc của nó khi người chơi khuấy chất lỏng. SpringConstant thay đổi số lượng hạt bay ra khỏi nguồn gốc của nó và dampingFactor tốc độ của hạt đến mức nào. Bạn có thể phải điều chỉnh mã vì đây là phiên bản sửa đổi của mô phỏng 1d tôi sử dụng trong trò chơi của mình.

Bây giờ với bản demo: Bản trình diễn Chỉ cần tinh chỉnh 3 hằng số ở trên cùng cho đến khi chất lỏng hoạt động như bạn muốn.


Đó là một ý tưởng thực sự thú vị để giải quyết # 1! Tôi thích nó. Làm thế nào bạn có thể đề nghị thực hiện chuyển động tam giác \ khoảng cách?
OpherV

1
Tôi đã chỉnh sửa bài gốc để trả lời câu hỏi số 2.
zilluss

thêm một bản demo nhỏ của hiệu ứng hạt. Tôi nghĩ rằng bạn có thể có được hiệu ứng mong muốn của bạn với một chút điều chỉnh.
zilluss

Tôi đã kết thúc bằng cách sử dụng giải pháp của bạn, đó là cách gần nhất với hiệu quả mà tôi đang mong muốn đạt được. Cảm ơn! Mặc dù vậy, có một câu hỏi - làm thế nào tôi có thể giữ được độ lò xo trong các ví dụ của bạn, để những chuyển động thực sự nhẹ sẽ không khiến các hạt nhảy xa như vậy?
OpherV

Bạn có thể chơi xung quanh với dampingFactor và springConstant. Một giảm xóc cao sẽ mang lại cho các hạt nhanh hơn để nghỉ ngơi. Một hằng số lò xo thấp hơn làm giảm tốc độ của các hạt. Thật không may, cả hai giá trị cho phép súp hạt cảm thấy nhớt hơn. Vì vậy, thay vào đó, khi người chơi của bạn chạm vào hạt, bạn có thể kẹp tốc độ tối đa mà người chơi thêm vào hạt, như thế này: partic.velocity.x = Kẹp (maxVelocity, -maxVelocity, partic.velocity.x + ((playerInfluenceFactor * deltaVelocityX ) + partic.velocity.x) * (1 / distanceToPlayer)); cho kẹp xem: stackoverflow.com/a/11409944
zilluss

4

Suy nghĩ của tôi về hai điểm này:

  1. Bạn có thể sử dụng shader Blur, nhưng điều đó sẽ rất tốn kém. Thay vào đó, tôi sẽ vẽ thêm một đường viền hình tam giác mờ dần từ mờ ở trung tâm thành trong suốt ở các cạnh, để mô phỏng "mờ". Tôi đã làm điều đó trong một trò chơi của tôi và nó hoạt động khá tốt. Đây là hai ảnh chụp màn hình của một trợ thủ cầu vồng trong trò chơi của tôi.

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

    Đường viền bên ngoài có độ dốc. Trong tình huống của tôi, đường viền không bắt đầu ở cùng độ mờ như phần bên trong, nhưng nếu bạn đặt các độ mờ đó bằng nhau, bạn sẽ có một độ mờ đẹp.

  2. Tôi sẽ lập trình một hệ thống hạt và làm cho các hạt theo đa giác. Bằng cách làm như vậy, bạn không phải lo lắng về những gì sẽ xảy ra ở các cạnh. Động lực học của hệ thống hạt của bạn sẽ đảm bảo rằng các hạt nằm bên trong đa giác và phân bố đều. Bạn có thể cố gắng làm cho các hạt gần nhất đẩy nhau ra xa, nhưng làm cho nó có nhiều "khối lượng" để bạn có quán tính và nó trông trơn tru. Để làm cho điều này nhanh chóng, có một số khả năng, nhưng vấn đề lớn sẽ là sự phức tạp thời gian của cơ chế đẩy nhau. Nếu bạn tạo từng hạt đẩy từng hạt khác, bạn sẽ có O (n ^ 2), điều này không tốt, nếu bạn có ví dụ 100 hạt trong hệ thống của mình. Đọc tốt về cách bạn có thể tối ưu hóa đây là bản trình bày này của PixelJunk:http://fumufumu.q-games.com/gdc2010/shooterGDC.pdf

    Một cách tiếp cận đơn giản hơn là kết nối mỗi hạt với ba hoặc bốn hạt khác khi xây dựng hệ thống hạt. Bây giờ mọi hạt sẽ chỉ phải đẩy bốn hạt khác mà nó được kết nối. Tuy nhiên, cách tiếp cận này làm cho nhiễu loạn trong hệ thống hạt của bạn là không thể. Nhưng điều này dường như không phải là một vấn đề, vì tình huống hiện tại của bạn sử dụng kết cấu tĩnh. Cách tiếp cận này sẽ là O (n) rất tuyệt vời.


Cảm ơn! 1. Tôi đang gặp khó khăn khi hình dung điều này. Bạn có thể vui lòng đăng một mockup về cách nó trông \ hoạt động trong trò chơi của bạn không? 2. Thú vị! sẽ đọc về điều đó
OpherV

Cảm ơn những hình ảnh. Tôi có thể thấy nó sẽ hoạt động như thế nào trong một hình dạng dựa trên ống hoặc đường ống, nhưng nó sẽ hoạt động như thế nào với đa giác? Không phải độ dốc của các hình tam giác được chiếu từ mỗi bên sẽ không thẳng hàng ...?
OpherV

Làm cho chúng phù hợp độc đáo. Đó là ý tưởng. Điều này liên quan đến một số điểm toán học và tính toán của giao lộ, v.v. Bạn cũng có thể chia nhỏ đường viền và làm phẳng nó. Tấn khả năng.
Martijn Courteaux

3

Ý tưởng tôi có khi đọc bài viết của bạn là ý tưởng này:
• xây dựng một bộ gạch mà bạn sẽ sử dụng cho các khu vực của mình.
• hiển thị đa giác khu vực trên một khung vẽ tạm thời nhỏ ở độ phân giải lát (ví dụ: nếu các ô có kích thước 16X16, hiển thị ở độ phân giải thấp hơn (16X, 16X)).
• sử dụng khung vẽ tạm thời đó để quyết định thời tiết để kết xuất các ô hoặc không trên khung chính:
nếu một điểm được đặt trên khung có độ phân giải thấp, hãy vẽ một ô 'ngẫu nhiên' trên khung chính. nếu một điểm chỉ là lân cận của điểm đã đặt, hãy vẽ ô 'ngẫu nhiên' ở độ mờ thấp hơn (để thực hiện chuyển đổi) trên khung chính.

Tôi sợ rằng việc giảm độ phân giải sẽ tạo ra hiệu ứng khối, nhưng ngay cả với gạch 20X20, nó trông vẫn khá tốt:

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

Các bước cho việc này là: lấy đa giác của bạn:
nhập mô tả hình ảnh ở đây

Vẽ đa giác ở độ phân giải gạch của bạn: nhập mô tả hình ảnh ở đây (!! vâng, đó là thứ màu đỏ trung tâm).

Sau đó, sử dụng imageData của khung vẽ có độ phân giải thấp để quyết định thời tiết để vẽ một ô hoặc ghi chú.
Nếu một pixel được đặt trên khung vẽ có độ phân giải thấp, điều đó có nghĩa là chúng ta nên vẽ ô: chọn chỉ số ô 'ngẫu nhiên' để chọn ô nào sẽ vẽ. Chỉ số ngẫu nhiên đó phải luôn giống nhau cho một khu vực / ô nhất định.
Nếu một điểm trống nhưng bên cạnh một điểm được lấp đầy, cũng vẽ một ô, nhưng với độ mờ một nửa.

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

Vì vậy, hãy vẽ gạch:

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

Đối với đa giác, tôi chỉ cần vẽ nhiều lần cho đa giác, thu nhỏ nó xuống và tăng độ mờ cho mỗi lần vẽ (người ta có thể sử dụng 'bật lửa' globalCompổngOperation ').

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

Khi bạn thêm mọi thứ, nó sẽ cung cấp:

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

Fiddle ở đây:

http://jsfiddle.net/gamealchemist/T7b4Y/

Hãy cho tôi biết nếu điều này sẽ giúp.


Cảm ơn bạn đã xây dựng giải pháp của bạn và cung cấp mã! Ý bạn là gì khi "Sau đó sử dụng imageData của khung vẽ có độ phân giải thấp để quyết định thời tiết để vẽ một ô hoặc ghi chú". Làm thế nào để bạn sử dụng dữ liệu hình ảnh nhỏ để quyết định nơi \ làm thế nào để vẽ trên hình ảnh lớn? Và sử dụng phương pháp này làm thế nào tôi có thể tránh được sự chồng chéo của các hình tam giác để đạt được khoảng cách tương tự như mockup của tôi?
OpherV

Ý tôi là đó là một bài kiểm tra boolean hoàn chỉnh: Tôi có cần điền vào ô này không? , đúng hay sai, được đưa ra bằng thử nghiệm của thử nghiệm độ phân giải thấp trên imageData [(x + y * width) * 4]! = 0, nghĩa là == 'tôi đã vẽ một cái gì đó trên khung hình độ phân giải thấp hơn tại chỗ gạch đó? '. Sau đó, nếu có, tôi sử dụng một số công thức được điền đầy đủ số nguyên tố (getRandomNumber) để đi từ (x, y) đến chỉ số ô 'ngẫu nhiên' sẽ luôn cung cấp cùng một số cho một khu vực nhất định + (x, y). Tôi không thấy mọi thứ có thể trùng lặp như thế nào nếu bạn xác định đúng đa giác của mình để tôi không nhận được câu hỏi thứ hai.
GameAlchemist

1

Chỉ là một ý tưởng:

Trong ô của bạn, "các mảnh" rộng nhất khoảng 80px. Tôi sẽ đề nghị, làm 2 khu vực. Bạn vẽ đa giác ban đầu của mình và bạn tạo ra một mô hình của nó khoảng 80 pixel từ mỗi cạnh. Sau đó, bạn vẽ gạch của bạn vào đa giác lớn hơn.

Sau đó, Tất cả các "mảnh" có pixel bên ngoài đa giác bên trong và không có giao điểm với đa giác bên trong, bạn có thể lấp đầy chúng với độ trong suốt.

Đây là cấp độ rất cao, nhưng tôi đoán tôi sẽ chia sẻ nó với bạn. Có rất nhiều chi tiết được xác định ở đây.

Một hình ảnh thô để chứng minh:

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

Nếu đa giác màu đen bên trong là bản gốc, bạn sẽ xóa tất cả các đa giác bằng dấu chấm màu đỏ.


Làm thế nào bạn sẽ kiểm tra giao điểm cho các mảnh được nhúng trong hình ảnh gạch với đa giác bên trong?
OpherV

@OpherV Uhmm, Bạn có thể xác định xem điểm X có nằm trong đa giác không? Bạn có thể lặp qua tất cả các pixel trong đa giác bên ngoài và với mỗi pixel trắng, kiểm tra lũ tất cả các pixel và xem liệu có bất kỳ lời nói dối nào trong bên trong / bên ngoài. Điều này không có vẻ đặc biệt hiệu quả, nhưng một khi bạn có một cái gì đó bạn có thể nghĩ cách để tối ưu hóa?
dùng46560

Đó là xử lý hậu kỳ được thực hiện trên CPU. Khó có thể tối ưu hóa trên chính nó. Ý tưởng của bạn có thể hoạt động tốt nếu đa giác bên trong và bên ngoài được kết nối bởi một dải tam giác. OP có thể thêm thông tin thuộc tính đỉnh và gắn thẻ cho mỗi đỉnh như bên trong hoặc bên ngoài. Sau đó, trong shader đỉnh, opacity / alpha có thể được nội suy tuyến tính từ một giá trị kém trong suốt hơn đến một mờ hoàn toàn.
teodron

@teodron Đây là điểm tôi đã cố gắng đưa ra trong câu trả lời. Đó là một ý tưởng cấp cao và tôi không thực sự là một nhà phát triển trò chơi. Tôi mới có một ý tưởng.
dùng46560

@ user46560 yeah, nhưng theo cách này, bạn không cần phải tính toán các pixel nào trong dải đa giác đó .. không phải trên GPU, cũng như trên CPU. Vì bạn không quen với những cách phát triển trò chơi như bạn nói, bạn xứng đáng được +1 cho ý tưởng của mình :).
teodron
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.