Full Implementaion (Code)

import { useRef } from "react";
import { IRefPhaserGame, PhaserGame } from "./game/PhaserGame";
import { useState } from "react";
import { PhaserHooks } from "@reneverse/rene-sdk-phaser";

function App() {
  //  References to the PhaserGame component (game and scene are exposed)
  const phaserRef = useRef<IRefPhaserGame | null>(null);

  // Initialize PhaserHooks with API Key and Private Key for ReneVerse
  const phaserHooks = new PhaserHooks({
    apiKey: process.env.NEXT_PUBLIC_API_KEY as string,
    privateKey: process.env.NEXT_PUBLIC_PRIVATE_KEY as string,
  });

  // Array to store adsf
  const [ads, setAds] = useState<any[]>([]);

  // Map to store ad impressions
  const [adImpressions, setAdImpressions] = useState<
    Map<
      string,
      {
        adCoverage: number;
        impressions: number;
      }
    >
  >(new Map());

  const serveAd = async () => {
    if (phaserRef.current) {
      const scene = phaserRef.current.scene;

      if (scene) {
        // Fetch Ad surfaces
        const adSurfaces = await phaserHooks.useReneVerse().getAdSurfaces();

        if (!adSurfaces.items.length) {
          console.log("No ad surfaces found");
          return;
        }

        // Fetch Ad from ReneVerse
        const ad = await phaserHooks
          .useReneVerse()
          .getAd(adSurfaces.items[0].adSurfaceId);

        console.log("Ad served", ad);

        // Load Ad image
        if (ad.adId) {
          // Add ad to the list
          setAds((prevAds) => [...prevAds, ad]);

          // Add ad to the impressions map
          setAdImpressions((prevImpressions) => {
            const newImpressions = new Map(prevImpressions);
            newImpressions.set(ad.adId!, {
              adCoverage: 0, // Initial coverage
              impressions: 0, // Initial impressions
            });
            return newImpressions;
          });

          scene.load.image("dynamicAd", ad.url as string);

          scene.load.once("complete", () => {
            // Add more stars
            const x = Phaser.Math.Between(100, 900);
            const y = Phaser.Math.Between(100, 600);

            //  `add.sprite` is a Phaser GameObjectFactory method and it returns a Sprite Game Object instance
            const adSurface = scene.add.sprite(x, y, "dynamicAd");

            // Set display size
            adSurface.setDisplaySize(300, 200);

            // Check visibility of the ad
            const trackAdVisibility = async () => {
              // Check if Ad is fully visible
              const visibilityCheck = phaserHooks
                .useTracking()
                .checkAdFullVisibility(adSurface, scene);

              if (visibilityCheck.isFullyVisible) {
                console.log(`Ad ${ad.adId} is fully visible`);

                // if Fully visible, calculate ad coverage
                const adCoverage = phaserHooks
                  .useTracking()
                  .calculateAdCoverage(adSurface, scene.cameras.main);

                console.log(adCoverage);

                // Track Ad
                const trackAds = await phaserHooks
                  .useReneVerse()
                  .trackAdSingle(
                    ad,
                    adCoverage.screenCoveragePercentage,
                    1000,
                    0
                  );

                if (trackAds) {
                  // If tracking is successful, update ad impressions
                  setAdImpressions((prevImpressions) => {
                    const newImpressions = new Map(prevImpressions);
                    const currentImpressionData = newImpressions.get(
                      ad.adId!
                    ) || {
                      adCoverage: 0,
                      impressions: 0,
                    };

                    newImpressions.set(ad.adId!, {
                      adCoverage: adCoverage.screenCoveragePercentage,
                      impressions: currentImpressionData.impressions + 1,
                    });

                    return newImpressions;
                  });
                } else {
                  console.log(`Failed to track ad ${ad.adId}`);
                }
              } else {
                // Ad is partially or fully blocked
                console.log(
                  `Ad ${ad.adId} is blocked by ${visibilityCheck.blockingSprites.length} sprites`,
                  {
                    blockingSprites: visibilityCheck.blockingSprites.map(
                      (sprite: any) => sprite.name || "Unnamed Sprite"
                    ),
                  }
                );
              }
            };

            // Track visibility every second
            const visibilityInterval = scene.time.addEvent({
              delay: 1000, // Check every second
              callback: trackAdVisibility,
              loop: true,
            });

            // Stop tracking after 5 minutes
            scene.time.delayedCall(5 * 60 * 1000, () => {
              visibilityInterval.remove();
              console.log(`Stopped tracking ad ${ad.adId}`);
            });
          });
        }
        scene.load.start();
      }
    }
  };

  return (
    <div className="parent">
      <PhaserGame ref={phaserRef} />

      <div className="stats">
        <button className="button" onClick={serveAd}>
          Serve Ad
        </button>

        <div>
          Total Ads: {ads.length} <br />
          Total Coverage:{" "}
          {Array.from(adImpressions.values())
            .reduce((acc, curr) => acc + curr.adCoverage, 0)
            .toFixed(2)}{" "}
          <br />
          Total Impressions:{" "}
          {Array.from(adImpressions.values()).reduce(
            (acc, curr) => acc + curr.impressions,
            0
          )}
        </div>
      </div>
    </div>
  );
}

export default App;

Last updated