Đang tạo Roll It

Justin Gitlin
Justin Gitlin

Roll It là một Thử nghiệm trên Chrome tái hiện trò chơi kinh điển trên bờ biển chỉ bằng trình duyệt trên điện thoại và máy tính. Trình duyệt trên điện thoại cho phép bạn nhắm và lăn bi bằng một cú hất cổ tay, trong khi trình duyệt trên máy tính hiển thị đồ hoạ theo thời gian thực của đường hầm Roll It bằng WebGL và Canvas. Hai thiết bị này giao tiếp qua Websockets. Không có ứng dụng nào. Không có bản tải xuống nào. Không có mã thông báo. Bạn chỉ cần một trình duyệt hiện đại.

Theo hướng dẫn của Google Creative Lab, Legwork đã phát triển trải nghiệm người dùng, giao diện và môi trường trò chơi, sau đó hợp tác với đối tác phát triển Mode Set để xây dựng Roll It. Trong suốt thời gian thực hiện dự án, chúng tôi đã gặp phải một số thách thức riêng. Bài viết này trình bày một số kỹ thuật chúng tôi đã sử dụng, các thủ thuật chúng tôi đã khám phá và bài học chúng tôi đã rút ra trong quá trình phát triển Roll It.

Quy trình công việc 3D

Một trong những khó khăn ban đầu là tìm ra cách tốt nhất để chuyển mô hình 3D từ phần mềm của chúng tôi sang định dạng tệp sẵn sàng cho web. Sau khi tạo các thành phần bên trong Cinema 4D, các mô hình đã được đơn giản hoá và chuyển đổi thành lưới đa giác thấp. Mỗi lưới được cung cấp một số thẻ lựa chọn đa giác nhất định để phân biệt các phần của đối tượng để tô màu và tạo hoạ tiết. Sau đó, chúng tôi có thể xuất dưới dạng tệp Collada 1.5 (.dae) và nhập vào Blender, một chương trình 3D nguồn mở, để tạo các tệp tương thích cho three.js. Sau khi đảm bảo các mô hình được nhập chính xác, chúng tôi đã xuất lưới dưới dạng tệp JSON và áp dụng ánh sáng bằng mã. Sau đây là thông tin chi tiết hơn về các bước chúng tôi đã thực hiện:

Mô hình hoá đối tượng bên trong C4D. Đảm bảo pháp tuyến của lưới hướng ra ngoài.
Tạo mô hình đối tượng bên trong C4D. Đảm bảo pháp tuyến của lưới hướng ra ngoài.
Sử dụng công cụ chọn đa giác, hãy tạo thẻ lựa chọn của các khu vực cụ thể mà bạn muốn tạo hoạ tiết. Áp dụng chất liệu cho từng thẻ lựa chọn.
Sử dụng công cụ chọn đa giác, hãy tạo thẻ lựa chọn của các khu vực cụ thể mà bạn muốn tạo hoạ tiết. Áp dụng chất liệu cho từng thẻ lựa chọn.
Xuất lưới dưới dạng tệp.dae COLLADA 1 .5.
Xuất lưới dưới dạng tệp.dae COLLADA 1 .5.
Đảm bảo bạn đã chọn "xuất hình học 2D". Việc xuất tam giác thường được hỗ trợ rộng rãi hơn trên các môi trường 3D ở phía mã, nhưng có nhược điểm là làm tăng gấp đôi số lượng đa giác. Số lượng đa giác càng cao thì mô hình càng gây áp lực cho bộ xử lý của máy tính. Vì vậy, hãy chọn tính năng này nếu bạn thấy hiệu suất chậm.
Đảm bảo bạn đã chọn "xuất hình học 2D". Việc xuất tam giác thường được hỗ trợ rộng rãi hơn trên các môi trường 3D ở phía mã, nhưng có nhược điểm là làm tăng gấp đôi số lượng đa giác. Số lượng đa giác càng cao thì mô hình càng gây áp lực cho bộ xử lý của máy tính. Vì vậy, hãy bỏ chọn tuỳ chọn này nếu bạn thấy hiệu suất bị chậm.
Nhập tệp Collada vào Blender.
Nhập tệp Collada vào Blender.
Sau khi nhập vào Blender, bạn sẽ thấy các chất liệu và thẻ lựa chọn cũng được chuyển sang.
Sau khi nhập vào Blender, bạn sẽ thấy rằng các chất liệu và thẻ lựa chọn cũng được chuyển sang.
Chọn đối tượng và điều chỉnh chất liệu của đối tượng theo ý bạn.
Chọn đối tượng và điều chỉnh chất liệu của đối tượng theo ý bạn.
Xuất tệp dưới dạng tệp three.js
Xuất tệp dưới dạng tệp three.js để tương thích với webGL.

Viết mã

Roll It được phát triển bằng các thư viện nguồn mở và chạy nguyên gốc trong các trình duyệt hiện đại. Với các công nghệ như WebGL và WebSocket, web đang dần bắt kịp trải nghiệm đa phương tiện và trò chơi chất lượng cao trên máy chơi trò chơi. Nhà phát triển có thể dễ dàng và thoải mái xây dựng những trải nghiệm này nhờ có nhiều công cụ hiện đại hơn để phát triển HTML.

Môi trường phát triển

Hầu hết mã gốc của Roll It được viết bằng CoffeeScript – một ngôn ngữ rõ ràng và súc tích, biên dịch sang JavaScript đã được tìm lỗi mã nguồn và có định dạng hợp lệ. CoffeeScript tỏa sáng trong quá trình phát triển OOP nhờ mô hình kế thừa tuyệt vời và khả năng xử lý phạm vi rõ ràng hơn. CSS được viết bằng khung SASS, cung cấp cho nhà phát triển một số công cụ tuyệt vời để nâng cao và quản lý các tệp kiểu của dự án. Việc thêm các hệ thống này vào quy trình xây dựng sẽ mất một chút thời gian để thiết lập, nhưng lợi ích thu được chắc chắn là xứng đáng, đặc biệt là đối với một dự án lớn hơn như Roll It. Chúng tôi thiết lập một máy chủ Ruby on Rails để tự động biên dịch các thành phần trong quá trình phát triển, nhờ đó, tất cả các bước biên dịch này đều trở nên minh bạch.

Ngoài việc tạo môi trường lập trình đơn giản và thoải mái, chúng tôi đã tối ưu hoá các thành phần theo cách thủ công để giảm thiểu các yêu cầu nhằm tải trang web nhanh hơn. Chúng tôi đã chạy mọi hình ảnh thông qua một số chương trình nén – ImageOptimImageAlpha. Mỗi chương trình tối ưu hoá hình ảnh theo cách riêng, tương ứng là không suy hao và suy hao. Với cách kết hợp chế độ cài đặt phù hợp, bạn có thể giảm đáng kể kích thước tệp của hình ảnh. Việc này không chỉ giúp tiết kiệm băng thông khi tải hình ảnh bên ngoài, mà sau khi được tối ưu hoá, hình ảnh của bạn sẽ được chuyển đổi thành chuỗi được mã hoá base64 nhỏ hơn nhiều để nhúng cùng dòng trong HTML, CSS và JavaScript. Trong chủ đề về mã hoá base64, chúng tôi cũng nhúng trực tiếp các tệp phông chữ WOFF và SVG Open Sans vào CSS bằng kỹ thuật này, nhờ đó tổng số yêu cầu còn giảm hơn nữa.

Cảnh 3D có hỗ trợ vật lý

THREE.js là thư viện JavaScript 3D phổ biến cho web. Thư viện này gói toán học 3D cấp thấp và các tính năng tối ưu hoá WebGL dựa trên phần cứng, cho phép người dùng dễ dàng tạo cảnh 3D tương tác đẹp mắt và được chiếu sáng tốt mà không cần phải viết chương trình đổ bóng tuỳ chỉnh hoặc thực hiện phép biến đổi ma trận theo cách thủ công. Physijs là một trình bao bọc dành riêng cho THREE.js cho một thư viện vật lý C++ phổ biến đã được dịch sang JavaScript. Chúng tôi đã tận dụng thư viện này để mô phỏng quả bóng lăn, nhảy và nảy về đích trong không gian 3D.

Ngay từ đầu, chúng tôi đã đặt ra mục tiêu không chỉ tạo ra trải nghiệm thực tế khi lăn bóng mà còn đảm bảo rằng các đối tượng trong trò chơi đều chân thực. Điều này đòi hỏi nhiều lần lặp lại để điều chỉnh trọng lực tổng thể của cảnh Physijs, tốc độ của quả bóng khi lăn từ cú ném của người chơi, độ dốc của bước nhảy của làn đường và các thuộc tính ma sát và trả lại (độ nảy) của quả bóng và vật liệu của làn đường. Sự kết hợp giữa trọng lực và tốc độ cao hơn đã mang đến trải nghiệm chơi trò chơi chân thực hơn.

Làm mượt

Hầu hết các tổ hợp trình duyệt và thẻ video hiện đại đều tận dụng tính năng khử răng cưa dựa trên phần cứng gốc trong môi trường WebGL, nhưng một số tổ hợp sẽ không hoạt động tốt. Trong trường hợp tính năng khử răng cưa không hoạt động theo cách gốc, mọi cạnh cứng và tương phản trong cảnh THREE.js sẽ bị răng cưa và xấu xí (ít nhất là đối với mắt tinh tường của chúng ta).

May mắn là có một cách khắc phục: thông qua một đoạn mã, chúng ta có thể phát hiện xem nền tảng có hỗ trợ tính năng khử răng cưa gốc hay không. Nếu có, chúng ta có thể tiếp tục. Nếu không, có một loạt chương trình đổ bóng xử lý hậu kỳ đi kèm với THREE.js có thể giúp chúng ta. Cụ thể là bộ lọc khử răng cưa FXAA. Bằng cách vẽ lại cảnh kết xuất mỗi khung hình bằng chương trình đổ bóng này, chúng ta thường có được đường nét và cạnh mượt mà hơn nhiều. Hãy xem bản minh hoạ bên dưới:

// Check for native platform antialias support via the THREE renderer
// from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing
var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;

Điều khiển trò chơi dựa trên gia tốc kế

Phần lớn sự thú vị của Roll It đến từ cử chỉ lăn bóng mà người chơi thực hiện bằng điện thoại. Các thiết bị di động đã có quyền truy cập vào gia tốc kế trong trình duyệt được một thời gian, nhưng với tư cách là một ngành, chúng ta mới chỉ bắt đầu khám phá tính năng nhận dạng cử chỉ dựa trên chuyển động trên web. Chúng ta bị hạn chế một chút về dữ liệu mà gia tốc kế của điện thoại cung cấp, nhưng chỉ cần một chút sáng tạo, chúng ta có thể tạo ra một số trải nghiệm mới tuyệt vời.

Phát hiện thao tác xoay Thao tác "xoay" chính của ứng dụng bắt đầu bằng cách theo dõi 10 bản cập nhật gia tốc kế gần đây nhất đến từ sự kiện deviceorientation của cửa sổ. Bằng cách trừ giá trị độ nghiêng trước đó khỏi giá trị độ nghiêng hiện tại, chúng ta sẽ lưu trữ delta góc giữa các sự kiện. Sau đó, bằng cách liên tục cộng 10 delta góc gần nhất, chúng ta có thể phát hiện chuyển động xoay liên tục khi điện thoại di chuyển trong không gian. Khi điện thoại vượt qua ngưỡng thay đổi góc quét, chúng ta sẽ kích hoạt một lần xoay. Sau đó, bằng cách tìm delta độ nghiêng lớn nhất trong lần quét đó, chúng ta có thể ước tính tốc độ của quả bóng. Trong Roll It, tốc độ này được chuẩn hoá bằng cách sử dụng dấu thời gian mà chúng ta đính kèm vào mỗi lần cập nhật gia tốc kế. Điều này giúp làm mượt tốc độ biến thiên mà các bản cập nhật gia tốc kế truyền vào trình duyệt trên nhiều thiết bị.

Giao tiếp WebSocket

Sau khi người chơi lăn quả bóng bằng điện thoại, một thông báo sẽ được gửi từ điện thoại đến máy tính xách tay để yêu cầu máy tính xách tay khởi chạy quả bóng. Thông báo "đổ xúc xắc" này được gửi qua đối tượng dữ liệu JSON thông qua kết nối WebSocket giữa hai máy. Dữ liệu JSON có kích thước nhỏ, chủ yếu bao gồm loại thông báo, tốc độ ném và hướng nhắm.

{
  "type": "device:ball-thrown",
  "speed": 0.5,
  "aim": 0.1
}

Tất cả hoạt động giao tiếp giữa máy tính xách tay và điện thoại đều diễn ra thông qua các thông báo JSON nhỏ như thế này. Mỗi khi trò chơi cập nhật trạng thái trên máy tính hoặc người dùng nghiêng hoặc nhấn vào một nút trên điện thoại, một thông báo WebSocket sẽ được truyền giữa các máy. Để giữ cho hoạt động giao tiếp này đơn giản và dễ quản lý, các thông điệp WebSockets được truyền bằng một điểm thoát duy nhất từ một trong hai trình duyệt. Ngược lại, có một điểm truy cập duy nhất trên trình duyệt nhận, với một đối tượng WebSocket xử lý tất cả thông báo đến và đi ở cả hai đầu. Khi nhận được thông báo WebSocket, dữ liệu JSON sẽ được phát lại trong ứng dụng JavaScript bằng phương thức trigger() của jQuery. Tại thời điểm này, dữ liệu đến hoạt động giống như mọi sự kiện DOM tuỳ chỉnh khác và có thể được bất kỳ đối tượng nào khác trong ứng dụng thu thập và xử lý.

var websocket = new WebSocket(serverIPAddress);

// rebroadcast incoming WebSocket messages with a global event via jQuery
websocket.onmessage = function(e) {
  if (e.data) {
    var obj = JSON.parse(e.data);
    $(document).trigger(data.type, obj);
  }
};

// broadcast outgoing WebSocket messages by passing in a native .js object
var broadcast = function(obj) {
  websocket.send(JSON.stringify(obj));
};

Máy chủ WebSocket của Roll It được tạo ngay khi hai thiết bị đồng bộ hoá với mã trò chơi. Phần phụ trợ của Roll It được xây dựng trên nền tảng Google Compute EngineApp Engine bằng cách sử dụng Go.

Nghiêng màn hình trình đơn

Ngoài các thông báo WebSocket do sự kiện điều khiển được dùng trong khi chơi, các trình đơn trong Roll It được điều khiển bằng cách nghiêng điện thoại và nhấn vào một nút để xác nhận lựa chọn. Điều này đòi hỏi luồng dữ liệu nghiêng nhất quán hơn truyền từ điện thoại sang máy tính xách tay. Để giảm băng thông và tránh gửi thông tin cập nhật không cần thiết, các thông báo này chỉ được gửi nếu độ nghiêng của thiết bị thay đổi nhiều hơn vài độ. Không cần gửi luồng dữ liệu độ nghiêng nếu điện thoại nằm phẳng trên mặt bàn! Tốc độ truyền cũng bị điều tiết – không quá 15 thông báo WebSockets được gửi mỗi giây trong Roll It, ngay cả khi thiết bị đang được nghiêng.

Sau khi các giá trị độ nghiêng được thu thập trên máy tính, chúng sẽ được nội suy theo thời gian bằng cách sử dụng requestAnimationFrame để duy trì cảm giác mượt mà. Kết quả cuối cùng là một trình đơn xoay và một quả bóng lăn để cho biết lựa chọn của người dùng. Khi điện thoại gửi dữ liệu độ nghiêng, các phần tử DOM này được cập nhật theo thời gian thực bằng cách tính toán lại phép biến đổi CSS bên trong vòng lặp requestAnimationFrame. Vùng chứa của trình đơn chỉ xoay, nhưng quả bóng có vẻ như lăn trên sàn. Để đạt được hiệu ứng này, chúng ta triển khai một số phép tính lượng giác cơ bản để liên kết toạ độ x của quả bóng với độ xoay của quả bóng. Phương trình đơn giản là: số vòng quay = x / (đường kính * π)

Tóm tắt

Roll It là một dấu hiệu của thời đại. Giữa các dự án nguồn mở hỗ trợ sự phát triển của web, sức mạnh xử lý của các thiết bị trên bàn và trong túi của chúng ta, cũng như trạng thái của web dưới dạng một nền tảng, đây là thời điểm thực sự thú vị và mang tính chuyển đổi để kết nối trên web mở. Chỉ vài năm trước, phần lớn công nghệ này chỉ tồn tại trong các hệ thống độc quyền, không thể tự do sử dụng và phân phối. Ngày nay, chúng ta có thể tạo ra những trải nghiệm phức tạp với ít công sức hơn và nhiều trí tưởng tượng hơn khi tạo và chia sẻ các mảnh ghép mới của câu đố mỗi ngày. Vậy bạn còn chần chừ gì nữa? Hãy tạo ra những sản phẩm tuyệt vời và chia sẻ với mọi người!

Biểu trưng Roll it