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

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.
Tạo tệp
clicker_systray_item.js
(vàxml
) với thành phần hello world Owl.Đăng ký nó vào sổ đăng ký systray và đảm bảo rằng nó hiển thị.
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ị.

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.
Sử dụng
useExternalListener
để nghe tất cả các lần nhấp vàodocument.body
.Mỗi lần nhấp chuột này sẽ tăng giá trị bộ đếm lên 1.
Sửa đổi mã để mỗi lần nhấp vào bộ đếm tăng giá trị lên 10
Đả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!
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.
Tạo tệp
client_action.js
(vàxml
), với thành phần hello world.Đă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
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àngawesome_clicker.client_action
(sử dụng dịch vụ hành động để thực hiện điều đó).Để 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"
trongdoAction
để 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" }

Xem thêm
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ụ.
Tạo tệp
clicker_service.js
với dịch vụ tương ứng.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 } };
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
.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 đó.

Xem thêm
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 useService
và useState
. 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
.
Xuất hook
useClicker
.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();
Xem thêm
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
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).
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!

Xem thêm
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ụ.
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/>
Thêm thuộc tính
data-tooltip
động để hiển thị giá trị chính xác.

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.
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ớiThê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.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útMua
được bật nếulần nhấp >= 1000
. NútMua
sẽ tăng số lượng clickbot lên 1.Đặt khoảng thời gian 10 giây trong dịch vụ để tăng số lần nhấp lên
10*clickBots
.Đảm bảo nút Mua bị tắt nếu người chơi không có đủ số lần nhấp.

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.
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ớpReactive
bao bọc mô hình thành một proxy phản ứng.Viết lại dịch vụ clicker để khởi tạo và xuất lớp mô hình clicker.
Xem thêm
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.
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.Thay đổi dịch vụ clicker để nghe cùng một sự kiện trên xe buýt mô hình.
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.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.

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
tăng
level
khi đạt tới 5k (vì vậy nó phải là 2)Cập nhật trạng thái để theo dõi bigbots
bigbots nên có sẵn ở
level >=2
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.

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
).
tăng
level
khi đạt tới 100k (vì vậy nó phải là 3).cập nhật trạng thái để theo dõi nguồn điện (giá trị ban đầu là 1).
thay đổi bot để sử dụng số đó làm hệ số nhân.
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).

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.
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ỗimô tả
. - một hàmapply
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 đó!
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.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ệputils.js
khác.
14. Cung cấp phần thưởng khi mở chế độ xem biểu mẫu¶
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.
Nếu câu trả lời là có, hãy gọi phương thức
getReward
trên mô hình.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àngclicker
.

15. Thêm lệnh trong bảng lệnh¶
Thêm lệnh
Mở trò chơi Clicker
vào bảng lệnh.Thêm lệnh khác:
Mua 1 click bot
.

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).
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.
Thêm hàm tính tổng số cây và quả.
Xác định mức mở khóa mới ở
lần nhấp >= 1 000 000
.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.
Tăng số lượng quả lên 1 cho mỗi cây sau mỗi 30 giây.

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
:
Sử dụng thành phần
Notebook
.Tất cả nội dung
click
sẽ được hiển thị trong một tab.Tất cả nội dung
cây/quả
sẽ được hiển thị trong tab khác.

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.
Nhập
browser
từ@web/core/browser/browser
để truy cập bộ nhớ cục bộ.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ộ.
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.
Thêm số phiên bản vào trạng thái.
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àmapply
.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.
Thêm cây 'đào`.
Tăng số phiên bản trạng thái.
Xác định một cuộc di cư.
