Game không tự nhúng mạng quảng cáo nào. Bạn chỉ gọi WSG.ads.interstitial() hoặc WSG.ads.rewarded(); portal quyết định có hiện quảng cáo không, hiện gì, và trả kết quả về cho game.
Hai loại quảng cáo
| Interstitial | Rewarded | |
|---|---|---|
| Là gì | Quảng cáo toàn màn hình ở điểm nghỉ tự nhiên | Quảng cáo người chơi chủ động chọn xem để nhận thưởng |
| Người chơi chọn? | Không | Có, bằng một nút rõ ràng |
| Giới hạn tần suất | Portal ép tối thiểu 60 giây giữa hai lần hiện | Không có |
| Kết quả cần đọc | Không cần làm gì thêm | Chỉ thưởng khi rewarded === true |
Hiện portal dùng quảng cáo giả lập: interstitial hiện 3 giây rồi mới có nút Đóng; rewarded chạy 5 giây và tự kết thúc, người chơi bấm Esc để bỏ ngang. Khi portal chuyển sang mạng quảng cáo thật, API giữ nguyên nên game không phải sửa.
Khi nào nên gọi
Nên:
- Gọi interstitial ở điểm nghỉ: sau màn game over, trước khi chơi lượt mới, khi chuyển màn.
- Giãn tần suất, ví dụ một interstitial sau mỗi hai lần game over như template Phaser.
- Nộp điểm trước, rồi mới gọi quảng cáo.
- Chỉ gọi rewarded khi người chơi bấm nút, và nói rõ họ nhận được gì ("Xem quảng cáo để hồi sinh").
Không nên:
- Gọi quảng cáo giữa lúc đang chơi, hay ngay khi game vừa tải xong lần đầu.
- Gọi chồng lên một quảng cáo đang hiện (bạn sẽ nhận
not_available). - Đếm trên cooldown của portal để quyết định nhịp quảng cáo; cooldown chỉ là ngưỡng tối thiểu.
Interstitial giữa các lượt
let gameOvers = 0;
async function onGameOver(score) {
WSG.gameplayStop();
await WSG.leaderboard.submit(score); // nộp điểm trước
gameOvers += 1;
if (gameOvers % 2 === 0) {
await WSG.ads.interstitial({ placement: 'between_rounds' });
// shown hay không (cooldown, unfilled...) thì cũng chơi tiếp bình thường
}
showGameOverButtons();
}Kết quả của interstitial chỉ để thống kê; game không cần rẽ nhánh theo nó.
Rewarded và cấp thưởng
function canOfferRevive(run) {
return !run.revived && WSG.isAvailable('ads.rewarded') && !WSG.ads.isBlocked();
}
async function onReviveButton(run) {
reviveButton.disabled = true;
const result = await WSG.ads.rewarded({ placement: 'revive' });
if (result.rewarded !== true) {
// dismissed, unfilled, lỗi hệ thống... đều không có thưởng
reviveButton.disabled = false;
showToast('Chưa xem hết quảng cáo, chưa hồi sinh được');
return;
}
run.revived = true; // một lần mỗi lượt
WSG.track('revive_used', { score: run.score });
resumeRun(run);
WSG.gameplayStart(); // SDK đã gọi gameplayStop() trước quảng cáo
}- Chỉ tin
rewarded.shown: truekhông có nghĩa là người chơi đã xem hết: rewarded bị đóng sớm trả{ shown: true, rewarded: false, reason: 'dismissed' }. - Gọi lại
gameplayStart()sau khi hồi sinh, vì SDK đã dừng gameplay khi quảng cáo bắt đầu. - Hồi sinh làm mốc tính thời gian chơi của server bị đặt lại; nộp điểm ở lần chết trước khi mời hồi sinh để kỷ lục chắc chắn được ghi. Chi tiết ở Điểm và bảng xếp hạng.
Tạm dừng và âm thanh quanh quảng cáo
Khi bạn gọi quảng cáo, SDK tự lo trình tự:
- Nếu gameplay đang chạy:
gameplayStop(). - Phát
pausevàaudio(false). - Portal hiện quảng cáo phủ lên game.
- Quảng cáo đóng: phát
audio(true)vàresume. - Promise resolve với
AdResult.
Game chỉ cần nghe sự kiện, như khi tab bị ẩn:
WSG.on('pause', () => {
loop.stop();
sound.suspend();
});
WSG.on('resume', () => {
loop.start();
if (!settings.muted) sound.resume();
});
WSG.on('audio', (enabled) => {
sound.setMasterVolume(enabled && !settings.muted ? 1 : 0);
});Đừng chỉ dựa vào await của quảng cáo để tạm dừng: game cũng phải dừng khi tab bị ẩn, và portal phát cùng các sự kiện đó.
Xử lý reason
reason | Interstitial | Rewarded |
|---|---|---|
| (không có) | Chơi tiếp | Thưởng nếu rewarded === true |
cooldown | Chơi tiếp | Không xảy ra với rewarded |
dismissed | — | Không thưởng; cho bấm lại nếu muốn |
unfilled | Chơi tiếp | Không thưởng; có thể ẩn nút một lúc |
adblock | Chơi tiếp | Không thưởng; isBlocked() thành true, ẩn nút |
not_available | Đang có quảng cáo khác; bỏ qua | Như bên trái |
disabled, error | Chơi tiếp | Không thưởng |
Bảng đầy đủ nằm ở Tham chiếu SDK. Quảng cáo không bao giờ làm Promise reject vì sự cố, trừ khi gọi trước init().
Kiểm thử quảng cáo
- Standalone: mọi quảng cáo chờ 1 giây rồi trả
shown: true(rewarded có thêmrewarded: true), không có cooldown. Dùng để kiểm luồngpause/resumevà tắt tiếng. - Trong portal: gọi interstitial hai lần liên tiếp sẽ thấy lần hai trả
reason: 'cooldown'; bấm Esc trong lúc rewarded chạy sẽ thấydismissed. Game_conformancelàm sẵn cả hai bước này.