Chương 1: Xây dựng trò chơi Clicker

Đối với dự án này, chúng tôi sẽ cùng nhau xây dựng một trò chơi clicker, được tích hợp hoàn toàn với SoOn. Trong trò chơi này, mục tiêu là tích lũy số lượng lớn lượt nhấp chuột và tự động hóa hệ thống. Điều thú vị là chúng tôi sẽ sử dụng giao diện người dùng SoOn làm sân chơi của mình. Ví dụ: chúng tôi sẽ ẩn phần thưởng trong một số phần ngẫu nhiên của ứng dụng khách web.

Để bắt đầu, bạn cần có máy chủ SoOn đang chạy và môi trường phát triển. Trước khi bắt đầu bài tập, hãy đảm bảo bạn đã làm theo tất cả các bước được mô tả trong tutorial giới thiệu.

Mục tiêu

../../../_images/final.png

Giải pháp cho từng bài tập của chương được lưu trữ trên kho lưu trữ hướng dẫn chính thức của SoOn.

1. Tạo một mục systray

Để bắt đầu, chúng tôi muốn hiển thị một bộ đếm trong khay hệ thống.

  1. Tạo tệp clicker_systray_item.js (và xml) với thành phần hello world Owl.

  2. Đăng ký nó vào sổ đăng ký systray và đảm bảo rằng nó hiển thị.

  3. Cập nhật nội dung của mục để nó hiển thị chuỗi sau: Clicks: 0 và thêm nút ở bên phải để tăng giá trị.

../../../_images/systray.png

Và thì đấy, chúng ta có một trò chơi clicker hoàn toàn hoạt động!

2. Đếm số lần nhấp chuột bên ngoài

Chà, thành thật mà nói, nó vẫn chưa vui lắm. Vì vậy, hãy thêm một tính năng mới: chúng tôi muốn tất cả các lần nhấp chuột vào giao diện người dùng đều được tính, để người dùng được khuyến khích sử dụng SoOn nhiều nhất có thể! Nhưng rõ ràng, những cú click có chủ ý vào quầy chính vẫn nên được tính nhiều hơn.

  1. Sử dụng useExternalListener để nghe tất cả các lần nhấp vào document.body.

  2. Mỗi lần nhấp chuột này sẽ tăng giá trị bộ đếm lên 1.

  3. Sửa đổi mã để mỗi lần nhấp vào bộ đếm tăng giá trị lên 10

  4. Đảm bảo rằng một cú nhấp chuột vào bộ đếm không làm tăng giá trị lên 11!

  5. Ngoài ra còn có thách thức nữa: đảm bảo trình nghe bên ngoài nắm bắt được các sự kiện để chúng tôi không bỏ lỡ bất kỳ lượt nhấp nào.

3. Tạo hành động của khách hàng

Hiện tại, giao diện người dùng hiện tại khá nhỏ: nó chỉ là một mục systray. Chúng tôi chắc chắn cần nhiều chỗ hơn để hiển thị nhiều trò chơi của mình hơn. Để làm điều đó, chúng ta hãy tạo một hành động của khách hàng. Hành động của khách hàng là một hành động chính, được quản lý bởi máy khách web, hiển thị một thành phần.

  1. Tạo tệp client_action.js (và xml), với thành phần hello world.

  2. Đăng ký hành động của khách hàng đó trong sổ đăng ký hành động dưới tên awesome_clicker.client_action

  3. Thêm một nút trên mục systray với dòng chữ Open. Nhấp vào nó sẽ mở hành động của khách hàng awesome_clicker.client_action (sử dụng dịch vụ hành động để thực hiện điều đó).

  4. Để tránh làm gián đoạn quy trình làm việc của nhân viên, chúng tôi muốn thao tác của khách hàng mở trong cửa sổ bật lên thay vì ở chế độ toàn màn hình. Sửa đổi lệnh gọi doAction để mở nó trong cửa sổ bật lên.

    Mẹo

    Bạn có thể sử dụng target: "new" trong doAction để mở hành động trong cửa sổ bật lên:

    {
       type: "ir.actions.client",
       tag: "awesome_clicker.client_action",
       target: "new",
       name: "Clicker"
    }
    
../../../_images/client_action.png

4. Chuyển trạng thái sang một dịch vụ

Hiện tại, hành động của khách hàng của chúng tôi chỉ là một thành phần hello world. Chúng tôi muốn nó hiển thị trạng thái trò chơi của chúng tôi, nhưng trạng thái đó hiện chỉ có trong mục systray. Vì vậy, điều đó có nghĩa là chúng ta cần thay đổi vị trí của trạng thái để cung cấp trạng thái đó cho tất cả các thành phần của chúng ta. Đây là một trường hợp sử dụng hoàn hảo cho các dịch vụ.

  1. Tạo tệp clicker_service.js với dịch vụ tương ứng.

  2. Dịch vụ này sẽ xuất giá trị phản ứng (số lần nhấp chuột) và một số chức năng để cập nhật giá trị đó:

    const state = reactive({ clicks: 0 });
    ...
    return {
       state,
       increment(inc) {
          state.clicks += inc
       }
    };
    
  3. Truy cập trạng thái trong cả mục systray và hành động của máy khách (đừng quên useState nó). Sửa đổi mục systray để loại bỏ trạng thái cục bộ của chính nó và sử dụng nó. Ngoài ra, bạn có thể loại bỏ nút +10 lần nhấp.

  4. Hiển thị trạng thái trong hành động của máy khách và thêm nút nhấp chuột +10 trong đó.

../../../_images/increment_button.png

5. Sử dụng Hooks tùy chỉnh

Hiện tại, mọi phần mã cần sử dụng dịch vụ clicker của chúng tôi sẽ phải nhập useServiceuseState. Vì nó khá phổ biến nên chúng ta hãy sử dụng một hook tùy chỉnh. Cũng sẽ hữu ích nếu nhấn mạnh hơn vào phần clicker và ít nhấn mạnh hơn vào phần service.

  1. Xuất hook useClicker.

  2. Cập nhật tất cả các mục đích sử dụng hiện tại của dịch vụ clicker sang hook mới:

    this.clicker = useClicker();
    

6. Nhân hóa giá trị hiển thị

Trong tương lai chúng tôi sẽ hiển thị số lượng lớn, vì vậy chúng ta hãy sẵn sàng cho điều đó. Có một hàm humanNumber định dạng số theo cách dễ hiểu hơn: ví dụ: 1234 có thể được định dạng là 1,2k

  1. Sử dụng nó để hiển thị bộ đếm của chúng tôi (cả trong mục systray và hành động của máy khách).

  2. Tạo thành phần ClickValue hiển thị giá trị.

    Ghi chú

    Owl cho phép thành phần chỉ chứa các nút văn bản!

../../../_images/humanized_number.png

7. Thêm chú giải công cụ trong thành phần ClickValue

Với hàm humanNumber, chúng tôi thực sự đã mất đi một số độ chính xác trên giao diện của mình. Hãy để chúng tôi hiển thị số thực dưới dạng chú giải công cụ.

  1. Chú giải công cụ cần có phần tử html. Thay đổi ClickValue để bao bọc giá trị trong phần tử <span/>

  2. Thêm thuộc tính data-tooltip động để hiển thị giá trị chính xác.

../../../_images/humanized_tooltip.png

8. Mua ClickBot

Hãy để chúng tôi làm cho trò chơi của mình trở nên thú vị hơn nữa: khi người chơi đạt được 1000 lần nhấp chuột lần đầu tiên, trò chơi sẽ mở khóa một tính năng mới: người chơi có thể mua robot với 1000 lần nhấp chuột. Những robot này sẽ tạo ra 10 lần nhấp cứ sau 10 giây.

  1. Thêm số cấp vào trạng thái của chúng tôi. Đây là con số sẽ được tăng lên ở một số mốc quan trọng và mở ra những tính năng mới

  2. Thêm số clickBots vào trạng thái của chúng tôi. Nó đại diện cho số lượng robot đã được mua.

  3. Sửa đổi hành động của khách hàng để hiển thị số lượng bot nhấp chuột (chỉ khi level >= 1), với nút Mua được bật nếu lần nhấp >= 1000. Nút Mua sẽ tăng số lượng clickbot lên 1.

  4. Đặt khoảng thời gian 10 giây trong dịch vụ để tăng số lần nhấp lên 10*clickBots.

  5. Đảm bảo nút Mua bị tắt nếu người chơi không có đủ số lần nhấp.

../../../_images/clickbot.png

9. Tái cấu trúc mô hình lớp

Mã hiện tại được viết theo phong cách hơi chức năng. Nhưng để làm như vậy, chúng ta phải xuất trạng thái và tất cả các hàm cập nhật của nó trong đối tượng clicker. Khi dự án này phát triển, điều này có thể ngày càng trở nên phức tạp hơn. Để đơn giản hơn, chúng ta hãy tách logic nghiệp vụ ra khỏi dịch vụ của mình và thành một lớp.

  1. Tạo tệp clicker_model để xuất lớp phản ứng. Di chuyển tất cả các chức năng trạng thái và cập nhật từ dịch vụ vào mô hình.

    Mẹo

    Bạn có thể mở rộng ClickerModel với lớp Reactive từ @web/core/utils/reactive. Lớp Reactive bao bọc mô hình thành một proxy phản ứng.

  2. Viết lại dịch vụ clicker để khởi tạo và xuất lớp mô hình clicker.

10. Thông báo khi đạt được cột mốc

Không có nhiều phản hồi rằng có điều gì đó đã thay đổi khi chúng tôi đạt được 1 nghìn lượt nhấp. Chúng ta hãy sử dụng dịch vụ effect để truyền đạt thông tin đó một cách rõ ràng. Vấn đề là mô hình nhấp chuột của chúng tôi không có quyền truy cập vào các dịch vụ. Ngoài ra, chúng tôi muốn loại bỏ mối lo ngại về giao diện người dùng ra khỏi mô hình ở mức tối đa có thể. Vì vậy, chúng ta có thể khám phá một chiến lược truyền thông mới: xe buýt sự kiện.

  1. Cập nhật mô hình trình nhấp chuột để khởi tạo xe buýt và kích hoạt sự kiện MILESTONE_1k khi chúng tôi đạt được 1000 lần nhấp chuột lần đầu tiên.

  2. Thay đổi dịch vụ clicker để nghe cùng một sự kiện trên xe buýt mô hình.

  3. Khi điều đó xảy ra, hãy sử dụng dịch vụ effect để hiển thị người đàn ông cầu vồng.

  4. Thêm một số văn bản để giải thích rằng người dùng hiện có thể mua clickbots.

../../../_images/milestone1.png

11. Thêm BigBot

Rõ ràng, chúng ta cần một cách để cung cấp cho người chơi nhiều sự lựa chọn hơn. Hãy để chúng tôi thêm một loại clickbot mới: BigBots, loại này mạnh hơn: chúng cung cấp 100 lần nhấp chuột mỗi 10 giây, nhưng chúng có giá 5000 lần nhấp chuột

  1. tăng level khi đạt tới 5k (vì vậy nó phải là 2)

  2. Cập nhật trạng thái để theo dõi bigbots

  3. bigbots nên có sẵn ở level >=2

  4. Hiển thị thông tin tương ứng trong hành động của khách hàng

Mẹo

Nếu bạn cần sử dụng < hoặc > trong một mẫu dưới dạng biểu thức javascript, hãy cẩn thận vì nó có thể xếp lớp với trình phân tích cú pháp xml. Để giải quyết vấn đề đó, bạn có thể sử dụng một trong các bí danh đặc biệt: gt, gte, lt hoặc lte. Xem Trang tài liệu cú về các biểu thức mẫu.

../../../_images/bigbot.png

12. Thêm một loại tài nguyên mới: sức mạnh

Bây giờ, để thêm một điểm chia tỷ lệ khác, chúng ta hãy thêm một loại tài nguyên mới: hệ số nhân công suất. Đây là con số có thể tăng lên ở cấp >= 3 và nhân lên hành động của các bot (vì vậy, thay vì cung cấp một lần nhấp chuột, clickbots hiện cung cấp cho chúng ta số lần nhấp chuột số nhân).

  1. tăng level khi đạt tới 100k (vì vậy nó phải là 3).

  2. cập nhật trạng thái để theo dõi nguồn điện (giá trị ban đầu là 1).

  3. thay đổi bot để sử dụng số đó làm hệ số nhân.

  4. Cập nhật giao diện người dùng để hiển thị và cho phép người dùng mua mức năng lượng mới (chi phí: 50k).

../../../_images/bigbot.png

13. Xác định một số phần thưởng ngẫu nhiên

Chúng tôi muốn người dùng đôi khi nhận được tiền thưởng, phần thưởng bằng cách sử dụng SoOn.

  1. Xác định danh sách phần thưởng trong click_rewards.js. Phần thưởng là một đối tượng có: - một chuỗi tả. - một hàm apply lấy trạng thái trò chơi làm đối số và có thể sửa đổi nó. - số minLevel (tùy chọn) mô tả mức mở khóa mà phần thưởng có sẵn. - số maxLevel (tùy chọn) mô tả phần thưởng không còn có ở cấp độ mở khóa.

    Ví dụ:

    export const rewards = [
       {
          description: "Get 1 click bot",
          apply(clicker) {
                clicker.increment(1);
          },
          maxLevel: 3,
       },
       {
          description: "Get 10 click bot",
          apply(clicker) {
                clicker.increment(10);
          },
          minLevel: 3,
          maxLevel: 4,
       },
       {
          description: "Increase bot power!",
          apply(clicker) {
                clicker.multipler += 1;
          },
          minLevel: 3,
       },
    ];
    

    Bạn có thể thêm bất cứ điều gì bạn muốn vào danh sách đó!

  2. Xác định hàm getReward sẽ chọn phần thưởng ngẫu nhiên từ danh sách phần thưởng phù hợp với cấp độ mở khóa hiện tại.

  3. Trích xuất mã chọn ngẫu nhiên trong một mảng trong hàm select mà bạn có thể di chuyển sang tệp utils.js khác.

14. Cung cấp phần thưởng khi mở chế độ xem biểu mẫu

  1. Vá bộ điều khiển biểu mẫu. Mỗi lần bộ điều khiển biểu mẫu được tạo, nó sẽ quyết định ngẫu nhiên (1% cơ hội) xem có nên trao phần thưởng hay không.

  2. Nếu câu trả lời là có, hãy gọi phương thức getReward trên mô hình.

  3. Phương pháp đó sẽ chọn phần thưởng, gửi thông báo cố định, bằng nút Thu thập, sau đó sẽ áp dụng phần thưởng và cuối cùng, nó sẽ mở hành động của khách hàng clicker.

../../../_images/reward.png

15. Thêm lệnh trong bảng lệnh

  1. Thêm lệnh Mở trò chơi Clicker vào bảng lệnh.

  2. Thêm lệnh khác: Mua 1 click bot.

../../../_images/command_palette.png

16. Thêm một tài nguyên khác: cây cối

Bây giờ là lúc giới thiệu một loại tài nguyên hoàn toàn mới. Đây là một thứ không nên gây tranh cãi quá nhiều: cây cối. Bây giờ chúng tôi sẽ cho phép người dùng trồng (thu thập?) cây ăn quả. Một cái cây có giá 1 triệu cú nhấp chuột, nhưng nó sẽ cho chúng ta trái cây (lê hoặc anh đào).

  1. Cập nhật trạng thái để theo dõi các loại cây khác nhau: lê/anh đào và quả của chúng.

  2. Thêm hàm tính tổng số cây và quả.

  3. Xác định mức mở khóa mới ở lần nhấp >= 1 000 000.

  4. Cập nhật giao diện người dùng máy khách để hiển thị số lượng cây và trái cây cũng như để mua cây.

  5. Tăng số lượng quả lên 1 cho mỗi cây sau mỗi 30 giây.

../../../_images/trees.png

17. Sử dụng menu thả xuống cho mục systray

Trò chơi của chúng tôi bắt đầu trở nên thú vị. Nhưng hiện tại, khay hệ thống chỉ hiển thị tổng số lần nhấp chuột. Chúng tôi muốn xem thêm thông tin: tổng số cây và quả. Ngoài ra, sẽ rất hữu ích nếu có quyền truy cập nhanh vào một số lệnh và một số thông tin khác. Hãy để chúng tôi sử dụng một menu thả xuống!

  1. Thay thế mục systray bằng menu thả xuống.

  2. Nó sẽ hiển thị số lần nhấp, cây và trái cây, mỗi cái có một biểu tượng đẹp.

  3. Nhấp vào nó sẽ mở ra menu thả xuống hiển thị thông tin chi tiết hơn: từng loại cây và quả.

  4. Ngoài ra còn có một số mục thả xuống với một số lệnh: mở game clicker, mua clickbot, ...

../../../_images/dropdown.png

18. Sử dụng thành phần Notebook

Bây giờ chúng tôi theo dõi được nhiều thông tin hơn. Hãy để chúng tôi cải thiện giao diện máy khách của mình bằng cách sắp xếp thông tin và tính năng trong các tab khác nhau, với thành phần Notebook:

  1. Sử dụng thành phần Notebook.

  2. Tất cả nội dung click sẽ được hiển thị trong một tab.

  3. Tất cả nội dung cây/quả sẽ được hiển thị trong tab khác.

../../../_images/notebook1.png

19. Kiên trì trạng thái trò chơi

Bạn chắc chắn đã nhận thấy một lỗ hổng lớn trong trò chơi của chúng tôi: nó mang tính nhất thời. Trạng thái trò chơi bị mất mỗi khi người dùng đóng tab trình duyệt. Hãy để chúng tôi khắc phục điều đó. Chúng tôi sẽ sử dụng bộ nhớ cục bộ để duy trì trạng thái.

  1. Nhập browser từ @web/core/browser/browser để truy cập bộ nhớ cục bộ.

  2. Tuần tự hóa trạng thái cứ sau 10 giây (trong cùng một mã khoảng thời gian) và lưu trữ nó trên bộ nhớ cục bộ.

  3. Khi dịch vụ clicker được khởi động, nó sẽ tải trạng thái từ bộ nhớ cục bộ (nếu có) hoặc tự khởi tạo theo cách khác.

20. Giới thiệu hệ thống di cư của tiểu bang

Khi bạn duy trì trạng thái ở đâu đó, một vấn đề mới sẽ phát sinh: điều gì xảy ra khi bạn cập nhật mã của mình, do đó hình dạng của trạng thái thay đổi và người dùng mở trình duyệt của mình với trạng thái được tạo bằng phiên bản cũ? Chào mừng đến với thế giới của các vấn đề di cư!

Có lẽ là khôn ngoan nếu giải quyết vấn đề sớm. Những gì chúng tôi sẽ làm ở đây là thêm số phiên bản vào trạng thái và giới thiệu một hệ thống tự động cập nhật các trạng thái nếu nó chưa cập nhật.

  1. Thêm số phiên bản vào trạng thái.

  2. Xác định danh sách di chuyển (trống). Di chuyển là một đối tượng có số fromVersion, số toVersion và hàm apply.

  3. Bất cứ khi nào mã tải trạng thái từ bộ nhớ cục bộ, nó sẽ kiểm tra số phiên bản. Nếu trạng thái không được cập nhật, nó sẽ áp dụng tất cả các lần di chuyển cần thiết.

21. Thêm một loại cây khác

Để kiểm tra hệ thống di chuyển của chúng ta, chúng ta hãy thêm một loại cây mới: đào.

  1. Thêm cây 'đào`.

  2. Tăng số phiên bản trạng thái.

  3. Xác định một cuộc di cư.

../../../_images/peach_tree.png