Build Mintegral

Bước cơ bản: Sửa file .adapterrc

Bước 1 – Bật cờ mindworks xử lý khi nhấn nút Download

  • Script SimpleDownloadOverlay (thường là SimpleDownloadOverlay.ts) dùng để xử lý khi nhấn nút Download do tự mình thiết kế, và khi nhấn nút đó thì với Mintegral sẽ dùng link download từ campaign do người tạo quảng cáo thiết lập.

  • Thêm/đặt biến cờ: mindworks = true.

  • Sửa lại link download cho đúng với store

// SimpleDownloadOverlay.ts
export default class SimpleDownloadOverlay {
  public mindworks: boolean = true;      // BẬT CỜ MINDWORKS
    // --- URL theo nền tảng ---
  downloadUrl: string = 'https://play.google.com/store/apps/details?id=com.cscmobi.cookingmarina';

  androidUrl: string = 'https://play.google.com/store/apps/details?id=com.cscmobi.cookingmarina';

  iosUrl: string = 'https://apps.apple.com/us/app/cooking-marina-cooking-games/id1488429989';
  private doDownload() {
    const w: any = globalThis as any;
    const myWindow = window as any
    if (this.mindworks) {
      myWindow?.install && myWindow.install();
      myWindow?.gameEnd && myWindow.gameEnd();
      return;
    }

    if (w?.dapi?.openStoreUrl) {
      // ironSource: theo mẫu của bạn, không truyền URL
      w.dapi.openStoreUrl();
      return;
    }

    // Unity/Applovin/khác → dùng onDownloadAction
    this.onDownloadAction();
  }


}

Code mẫu:

// assets/scripts/SimpleDownloadOverlay.ts
import {
  _decorator,
  Component,
  Node,
  Button,
  Sprite,
  Color,
  Widget,
  UIOpacity,
  BlockInputEvents,
  UITransform,
  Canvas,
  sys,
} from 'cc';
const { ccclass, property } = _decorator;

// Khai báo MRAID theo mẫu
declare const mraid: {
  open: (url: string) => void;
  close?: () => void;
  expand?: () => void;
  resize?: () => void;
  getState?: () => string;
  isViewable?: () => boolean;
  addEventListener?: (event: string, listener: () => void) => void;
  removeEventListener?: (event: string, listener: () => void) => void;
} | undefined;

@ccclass('SimpleDownloadOverlay')
export class SimpleDownloadOverlay extends Component {
  @property({ type: Node, tooltip: 'Nền xám mờ full màn (Node có Sprite + Widget)' })
  dim: Node | null = null;

  @property({ type: Button, tooltip: 'Nút Download ở giữa' })
  downloadBtn: Button | null = null;

  // --- URL theo nền tảng ---
  downloadUrl: string = 'https://play.google.com/store/apps/details?id=com.cscmobi.cookingmarina';

  androidUrl: string = 'https://play.google.com/store/apps/details?id=com.cscmobi.cookingmarina';

  iosUrl: string = 'https://apps.apple.com/us/app/cooking-marina-cooking-games/id1488429989';

  // --- Cờ theo SDK/quảng cáo ---
  mindworks = true;

  @property({ tooltip: 'Bấm Download xong thì ẩn overlay' })
  autoHideOnClick: boolean = true;

  onLoad() {
    // Chặn click xuyên
    this.node.getComponent(BlockInputEvents) || this.node.addComponent(BlockInputEvents);
    this.dim?.getComponent(BlockInputEvents) || this.dim?.addComponent(BlockInputEvents);

    // Gắn handler cho nút
    this.downloadBtn?.node.off(Button.EventType.CLICK, this.onClickDownload, this);
    this.downloadBtn?.node.on(Button.EventType.CLICK, this.onClickDownload, this);

    // Ép full màn
    this.fitToCanvas();
    this.scheduleOnce(() => this.fitToCanvas(), 0);

    // Ẩn mặc định
    // this.node.active = false;
  }

  onEnable() { this.fitToCanvas(); }

  /** Hiện overlay (có thể truyền fallback URL mới) */
  show(url?: string) {
    if (url) this.downloadUrl = url;
    this.node.active = true;

    // Đưa lên trên cùng
    const p = this.node.parent;
    if (p) this.node.setSiblingIndex(p.children.length - 1);

    this.fitToCanvas();
  }

  /** Ẩn overlay */
  hide() { this.node.active = false; }

  // ===== helpers UI =====
  private fitToCanvas() {
    const canvas = this.node.scene?.getComponentInChildren(Canvas);
    const canvasUT = canvas?.node.getComponent(UITransform)
                   ?? this.node.parent?.getComponent(UITransform);
    if (!canvasUT) return;

    // Overlay full Canvas
    const overlayUT = this.node.getComponent(UITransform) ?? this.node.addComponent(UITransform);
    overlayUT.setContentSize(canvasUT.contentSize);
    const overlayW = this.node.getComponent(Widget) ?? this.node.addComponent(Widget);
    overlayW.isAlignTop = overlayW.isAlignBottom = overlayW.isAlignLeft = overlayW.isAlignRight = true;
    overlayW.top = overlayW.bottom = overlayW.left = overlayW.right = 0;
    overlayW.updateAlignment();

    // Dim full Canvas
    if (this.dim) {
      const dimUT = this.dim.getComponent(UITransform) ?? this.dim.addComponent(UITransform);
      dimUT.setContentSize(canvasUT.contentSize);
      this.dim.setPosition(0, 0, 0);

      const dimW = this.dim.getComponent(Widget) ?? this.dim.addComponent(Widget);
      dimW.isAlignTop = dimW.isAlignBottom = dimW.isAlignLeft = dimW.isAlignRight = true;
      dimW.top = dimW.bottom = dimW.left = dimW.right = 0;
      dimW.updateAlignment();

      const sp = this.dim.getComponent(Sprite) ?? this.dim.addComponent(Sprite);
      if (!sp.spriteFrame) {
        console.warn('[SimpleDownloadOverlay] Dim chưa có SpriteFrame. Hãy gán 1 sprite trắng 1×1.');
      }
      sp.color = new Color(0, 0, 0, 180); // xám mờ nhìn xuyên
      this.dim.getComponent(UIOpacity) ?? this.dim.addComponent(UIOpacity);
    }

    // Đặt nút giữa màn
    // if (this.downloadBtn) this.downloadBtn.node.setPosition(0, 0, 0);
  }

  // ====== LOGIC DOWNLOAD (áp dụng đúng mẫu của bạn) ======
  /** Chọn link theo nền tảng, có fallback. */
  private resolveLink(): string {
    if (sys.os === sys.OS.ANDROID && this.androidUrl) return this.androidUrl;
    if (sys.os === sys.OS.IOS && this.iosUrl) return this.iosUrl;
    return this.downloadUrl || this.androidUrl || this.iosUrl || '';
  }

  /** onDownloadAction theo mẫu của bạn (mặc định MRAID → window.open). */
  private onDownloadAction() {
    const link = this.resolveLink();
    console.log({link})
    if (!link) return;

    if (typeof mraid !== 'undefined' && mraid && typeof mraid.open === 'function') {
      mraid.open(link);
    } else {
      (globalThis as any).open ? (globalThis as any).open(link) : sys.openURL(link);
    }
  }

  /** onDownload theo mẫu của bạn: Mindworks → dapi (ironSource) → mặc định. */
  private doDownload() {
    const w: any = globalThis as any;
    const myWindow = window as any
    if (this.mindworks) {
      myWindow?.install && myWindow.install();
      myWindow?.gameEnd && myWindow.gameEnd();
      return;
    }

    if (w?.dapi?.openStoreUrl) {
      // ironSource: theo mẫu của bạn, không truyền URL
      w.dapi.openStoreUrl();
      return;
    }

    // Unity/Applovin/khác → dùng onDownloadAction
    this.onDownloadAction();
  }

  private onClickDownload = () => {
    console.log("download")
    this.doDownload();
    if (this.autoHideOnClick) this.hide();
    this.node.emit('overlay:download_clicked', this.resolveLink());
  };
}

Bước 2 – Tạo file MintegralBuild.ts

  • Tạo file MintegralBuild.ts trong thư mục scripts

  • Add Script vào Component trong Canvas Main Scene

import { _decorator, Component } from 'cc';
const { ccclass } = _decorator;

@ccclass('MintegralBuild')
export class MintegralBuild extends Component {
    public mindworks: boolean = true;  // đảm bảo có cờ
    public vungle?: boolean;

    start() {
        // Ở ĐẦU start(): thông báo game đã sẵn sàng
        if (this.mindworks) {
            (window as any)?.gameReady && (window as any)?.gameReady();
        }

        // ... phần logic khởi tạo còn lại
    }

    // Method sự kiện theo yêu cầu
    EventNetWork() {
        if (this.mindworks) {
            (window as any)?.gameEnd && (window as any)?.gameEnd();
        }
        if (this.vungle) {
            (parent as any).postMessage('complete', '*');
        }
    }
}

Gợi ý: nếu EventNetWork() được gọi ở cuối màn chơi/hoàn thành level, hãy đảm bảo các nơi đó đã gọi sang method này.


Bước 3 – Sửa file index.html

  • Mở build\Mintegral\index.html.

  • Thêm nút CTA (chỉ dùng cho Mintegral):

<!-- CTA DOM: chỉ Mintegral -->
<button
  id="download-btn"
  aria-label="Download"
  onclick="(function(){window.install&&window.install();window.gameEnd&&window.gameEnd();})();"
  style="
    position: fixed;
    right: 8px;
    bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    width: 60px;
    height: 20px;
    z-index: 99999;
    cursor: pointer;

    background: #00b847;
    color: #fff;
    border: 0;
    border-radius: 6px;
    padding: 0;
    font: 700 10px/20px system-ui, -apple-system, Segoe UI, Arial, sans-serif;
    letter-spacing: 0.3px;
    text-align: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
  "
>
  Download
</button>

Lưu ý: Nút gọi window.install()window.gameEnd()—hãy chắc 2 hàm này có tồn tại trong runtime Mintegral của bạn (hoặc được SDK thiết lập).


Bước 4 - Xóa Splash Cocos

  • Thường ban đầu có splash logo của Cocos nên mình cần loại bỏ

  • Trong thư mục Mintegral\js, tìm xem file .js chứa "splash"

  • Sửa totalTime: 3000 =⇒ totalTime:0 (Mục đích để không cho chạy Splash vì time=0)

"splashScreen\":{\"displayRatio\":0.4,\"totalTime\":0

Bước 5 – Đóng gói

  • Nén (ZIP) thư mục Mintegral vừa build được để bàn giao.


Bước 6 – Test

  • Chờ test và ở màn hình demo, nhấn vào Download và tiếp tục kiểm tra kết quả

  • Mọi thứ tích xanh hết có nghĩa là đã thành công


Ghi chú nhanh (khuyến nghị)

  • TypeScript: dùng (window as any)/(parent as any) để tránh lỗi type khi gọi hàm do SDK gắn lên window/parent.

  • Gọi EventNetWork() tại điểm kết thúc game/quảng cáo để phát tín hiệu gameEnd và (nếu có vungle) postMessage 'complete'.

  • Nếu bạn sửa trong nhiều lớp, đảm bảo chỉ 1 nơi gọi gameReady() lúc bắt đầu để tránh bắn nhiều lần.

Last updated