Làm thế nào để lưu trữ và hiển thị hiệu quả bản đồ ô vuông trên web?


9

Trong khoảng

Đây thực sự là hai câu hỏi trong một. Trước hết tôi đang tìm cách lưu trữ hiệu quả một lượng lớn dữ liệu gạch. Các khía cạnh khác liên quan đến truy vấn tập dữ liệu và hiển thị gạch. Hãy để tôi cung cấp cho bạn một số nền tảng đầu tiên.

Chúng tôi đang tạo một trò chơi ông trùm nhiều người chơi dựa trên trình duyệt bằng thư viện CraftyJS để kết xuất nó thành Canvas. Trong nền tảng của GUI, chúng tôi đang chạy Yii Framework trên PHP và tất cả đều kết nối với trình tạo bản đồ ngẫu nhiên và công cụ trò chơi Python.

Đây là cách hiển thị bản đồ thô đầu tiên: http://i.imgur.com/khAXtl.png

Lưu trữ dữ liệu bản đồ

Thế giới trò chơi được tạo ngẫu nhiên mỗi khi trò chơi bắt đầu. Kích thước là gạch hình lục giác 100x100 cho mỗi người chơi. Điều đó có nghĩa là đối với một trò chơi ba người chơi, có 90.000 ô được tạo. Hiện tại tôi chỉ tạo một mảng JavaScript từ đó tôi kết xuất bản đồ.

Điều này hoạt động tốt để kết xuất, nhưng đối với bất kỳ loại tương tác nào với bản đồ, chúng tôi cần lưu trữ người chơi nào sở hữu ô đó, loại cấu trúc nào được xây dựng trên nó, giá hiện tại là gì, v.v. Lúc đầu, ít nhất là đối với nguyên mẫu, chúng tôi muốn sử dụng MySQL, nhưng sau một số thử nghiệm, nó không chính xác nhanh như tôi muốn. Có lẽ một kho lưu trữ đối tượng như MongoDB sẽ phù hợp hơn để lưu trữ dữ liệu ô thay vì bảng SQL. Hoặc có thể một cái gì đó khác?

Hiển thị bản đồ

Một vấn đề khác tôi thấy là di chuyển xung quanh bản đồ. Hiện tại tôi đang tạo các thực thể Crafty cho mỗi ô ngay cả khi nó không nằm trong chế độ xem. Điều này là chậm, bởi vì mặc dù Crafty chỉ hiển thị những cái trong chế độ xem, nó lưu trữ và có thể lặp lại qua tất cả các ô trên mỗi sự kiện kết xuất. Những gì tôi hiện đang có là một bản đồ được tạo ra rất chậm để tải và lắp đặt khi bạn di chuyển xung quanh, bây giờ tôi muốn làm cho nó có thể chơi được.

Ý tưởng đầu tiên của tôi là tải tập hợp con được hiển thị của các ô nằm trong khung nhìn. Nhưng khi người chơi sẽ di chuyển khung nhìn sang một khu vực trống, tôi cần truy vấn máy chủ và đợi phản hồi trở lại, chỉ sau đó bản đồ mới có thể được hiển thị. Điều này sẽ ổn trong một ứng dụng gốc, nhưng nó bị lag trong một trò chơi web.

Cách để có được hiệu suất mượt mà từ bản đồ có thể là tải trước một tập hợp con lớn hơn vào một mảng javascript và sử dụng nó làm bộ đệm. Người chơi sẽ có một vài màn hình "được lưu trong bộ nhớ cache" và khi anh ta di chuyển khung nhìn, tôi sẽ tải thêm các ô vào "bộ đệm" của JS.

Tôi đang đi đúng hướng? Tôi rất thích nhận thêm một số thông tin từ một người đã làm điều gì đó tương tự. Tôi mới bắt đầu phát triển trò chơi, nhưng đã trải qua rất nhiều nguồn trong vài tuần qua.


1
Tôi ngạc nhiên khi bạn xác định MySQL là một nút cổ chai. Bạn đã kiểm tra những gì để đi đến kết luận rằng nó làm mọi thứ chậm lại?
bummzack

@bummzack Nếu anh ta có một hàng trên mỗi ô, tôi khó có thể thấy mọi thứ không thể chậm như thế nào.
aaaaaaaaaaaa

1
@eBusiness Truy vấn vài nghìn hàng từ DB không phải là vấn đề thực sự. Điều này vẫn nên nằm trong phạm vi của một vài phần nghìn giây. Ngoài ra, nó sẽ không phải là 90'000 hàng, mà là 30'000 hàng cho 3 người chơi (100x100 mỗi người chơi).
bummzack

Xin lỗi vì toán khó hiểu, cũng có hai lần khoảng trống giữa các người chơi ngoài khu vực người chơi để họ có khoảng cách bằng nhau, khiến cho 90k. Truy vấn không phải là một vấn đề. Chọn gạch 90k và xây dựng bản đồ là. Nhưng nó không phải là một cách tốt để làm điều đó. Tôi sẽ tuần tự hóa dữ liệu bản đồ và sử dụng truy vấn các ô trong db khi thông tin chi tiết được yêu cầu.
phần tử

Câu trả lời:


2

Trò chơi
Trước hết tôi muốn hỏi bạn, bạn có thực sự cần 10000 gạch cho mỗi người chơi không? Mặc dù tôi không biết bạn đang làm loại trò chơi nào nhưng nói chung là bản đồ lớn tạo ra các trò chơi dài. Bản đồ lớn nhất trong Civilization 5 là 10240 ô và nó chỉ hoạt động vì bạn không cần phải chơi nhiều hơn một phần của nó.

Cơ sở dữ liệu
Bạn không nên cố gắng chạy một trò chơi như thế này khỏi cơ sở dữ liệu, bạn cần giữ dữ liệu trong bộ nhớ ứng dụng. Bạn có thể sử dụng cơ sở dữ liệu để sao lưu trò chơi. Để sao lưu hoàn toàn, hãy lưu tuần tự hóa dữ liệu trò chơi, và sau đó bạn có thể tăng nó bằng cách lưu các đơn đặt hàng đã cho và sau đó chạy lại chúng nếu cần sử dụng bản sao lưu.

Lưu trữ JavaScript
Đối với máy khách, tôi muốn nói rằng tốt hơn hết là bạn nên tải toàn bộ bản đồ, ít nhất là nếu bạn dính vào các viên gạch có tất cả trong một cây đối tượng đẹp có thể hơi quá, vì vậy bạn có thể nên giữ dữ liệu trong một định dạng được mã hóa "bán nhị phân". Các chuỗi hoạt động tuyệt vời cho loại công cụ này, thay vào đó, bạn có thể lưu trữ một cách an toàn các số nguyên không dấu lên đến 53 bit trong một float 64 bit, nhét rất nhiều thứ trong một mảng và tôi nghĩ bạn sẽ thấy dấu chân bộ nhớ khá khiêm tốn.

Trực quan hóa JavaScript
Mặc dù tôi sẽ không nói rằng bạn nhất thiết không nên sử dụng canvas, nhưng thực sự bạn không cần nó cho những thứ như thế này. Thiết lập tất cả thành một nhóm các phần tử img và thay đổi thuộc tính src để hiển thị các phần khác nhau của bản đồ.

Nhân tiện
, đôi khi việc chia sẻ hạt giống được sử dụng để tạo ra nó dễ dàng hơn so với việc chia sẻ toàn bộ bản đồ.


+1, nhưng thật đáng buồn, một ứng dụng web được viết bằng PHP thường không có nghĩa là giữ trạng thái trò chơi trong bộ nhớ.
bummzack

@bummzack, Ahh, phải, tôi nghĩ rằng bằng cách nào đó tôi đã bỏ qua từ PHP và chỉ đọc Python. Sau đó, một sự thay đổi của khung phụ trợ có thể theo thứ tự. Node.js có thể là một tùy chọn.
aaaaaaaaaaaa

Tôi đang xây dựng một ông trùm vận tải cạnh tranh, hãy nghĩ đến OpenTTD, một bản đồ có kích thước 512x512 (262k) không phải là quá lớn đối với một vài người chơi. Tôi nhận ra rằng đó là tham vọng, nhưng nếu bản đồ không lớn, trò chơi sẽ kết thúc quá sớm. Vì đây là trò chơi nhiều người chơi nên tôi cần đồng bộ hóa các thay đổi với bản đồ giữa những người chơi. Bản năng đầu tiên của tôi là chỉ sử dụng các khái niệm tôi biết từ phát triển web và đi với một cơ sở dữ liệu. Nó không cần phải là siêu thời gian. Tôi đang đi với trực quan hóa JS, vì tôi muốn có những thứ năng động trên bản đồ.
phần tử

Hãy xem câu trả lời của tôi là một số gợi ý, cuối cùng, bạn sẽ phải tự mình thực hiện hiệu suất, đó là một vấn đề nghiêm trọng và bạn có thể phải thực hiện một số thỏa hiệp.
aaaaaaaaaaaa

Tôi đồng ý, câu trả lời của bạn đã cho tôi rất nhiều thức ăn để suy nghĩ. Tôi sẽ cố gắng tìm cách giữ dữ liệu bản đồ nối tiếp trong bộ nhớ và giữ cơ sở dữ liệu như một bản sao lưu. Nhưng sau đó tôi phải tìm ra cách chia sẻ những thay đổi giữa những người chơi. Tôi sẽ trở lại với những gì tôi nghĩ ra sau khi tôi làm thêm một số thử nghiệm.
phần tử

1

MySQL không chậm. Nhiều khả năng bạn đang thực hiện các truy vấn ngây thơ hoặc có các chỉ mục dưới tối ưu. Các cách tiếp cận NoQuery như MongoDB có thể nhanh hơn, có thể không. Mẫu truy cập và lựa chọn truy vấn của bạn là những gì thực sự quan trọng ở đây. Có thể đưa ra lời khuyên về cách cải thiện hiệu suất, nhưng không phải là không nhìn thấy những gì bạn đang làm.

Cách để có được hiệu suất mượt mà từ bản đồ có thể là tải trước một tập hợp con lớn hơn vào một mảng javascript và sử dụng nó làm bộ đệm.

Phải, tất nhiên. Không có nhiều thứ để thêm ở đây - khách hàng yêu cầu gạch từ máy chủ, vì vậy bạn chỉ cần đảm bảo rằng những cái bạn yêu cầu bao phủ một khu vực lớn hơn màn hình.

Phụ lục:

chúng tôi đang chạy Yii Framework trên PHP và tất cả đều kết nối với trình tạo bản đồ ngẫu nhiên và công cụ trò chơi Python.

Nếu bạn thành thạo với Python thì tôi khuyên bạn nên bỏ qua người trung gian PHP. Nếu bạn chạy trò chơi của mình dưới dạng quy trình Python thì bạn có thể giữ dữ liệu ô của mình trong bộ nhớ dễ dàng hơn nhiều và giảm đáng kể truy cập MySQL. Nó cũng giúp Python là một ngôn ngữ lành mạnh hơn PHP.

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.