# Full Implementation (Code)

```typescript
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;

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.reneverse.io/publisher-flow/sdk-integration/phaser-3/full-implementation-code.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
