Tutorial: Cloud Application Rendering web demo

Cloud Application Rendering web demo

Basic Content

For more information, see the GitHub repository.

To add the queue feature, use the queue demo.

In theory, this demo is compatible with both PC and mobile clients (touch events on the mobile client have been processed in onTouchEvent).

For backend implementation, see the backend demo solution.

Below is the sample code:

<!doctype html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" />
  <title>Tencent Cloud - Real-Time Cloud Rendering - CAR - demo</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    html,
    body {
      width: 100%;
      height: 100%;
      overflow: hidden;
      font-family: 'SimHei', 'Microsoft YaHei', 'Arial', 'sans-serif';
    }

    #demo-container {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <div id="demo-container">
    <div id="mount-point"></div>
  </div>
  <script type="text/javascript" src="path/to/tcg-sdk"></script>
  <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>
  <script>
    // For CAR, the backend service API `StartProject` is actually a serial call of `ApplyConcurrent` and `CreateSession` APIs on the backend.
    // Apply for a concurrency (`ApplyConcurrent`). https://www.tencentcloud.com/zh/document/product/1158/49969
    // Create a session (`CreateSession`). https://www.tencentcloud.com/zh/document/product/1158/49968
    const StartProject = async () => {
      const url = 'https://xxxx/StartProject'; // For backend implementation, see the backend demo solution.

      // For more information on other optional parameters, see the document of the `ApplyConcurrent` API.
      const { data } = await axios.post(url, {
        ProjectId: 'project-id',
        UserId: 'user-id',
        ClientSession: TCGSDK.getClientSession(),
      });

      console.log('%c StartProject res', 'color: blue; font-size: 14px', data);

      const { Code, SessionDescribe: { ServerSession } } = data;

      if (Code === 0) {
        TCGSDK.start(ServerSession);
      } else {
        // Process the request exception
      }
    }

    // For two-finger touch, record the position of the last touch point to facilitate coordinate calculation.
    let lastX = null;
    let lastY = null;

    // For more information on the SDK lifecycle, visit https://github.com/tencentyun/cloudgame-js-sdk.
    TCGSDK.init({
      appid: 1234567,
      mount: 'mount-point',
      debugSetting: {
        showLog: true,
      },
      // Connected successfully.
      onConnectSuccess: async (res) => {
        console.log('onConnectSuccess', res);
      },
      // The network was disconnected or the user was kicked out.
      onDisconnect: (res) => {
        console.log('onDisconnect', res);
      },
      onWebrtcStatusChange: (res) => {
        console.log('onWebrtcStatusChange', res);
      },
      // The user touched the mobile client to simulate an instruction sent on a PC.
      onTouchEvent: async (res) => {
        // console.log('onTouchEvent', res);
        // The code for a single-finger touch operation
        if (res.length === 1) {
          const { id, type, pageX, pageY } = res.pop();
          // console.log('onTouchEvent', id, type, pageX, pageY);
          TCGSDK.mouseMove(id, type, pageX, pageY);
          if (type === 'touchstart') {
            TCGSDK.sendMouseEvent({ type: 'mouseleft', down: true });
          }
          if (type === 'touchend' || type === 'touchcancel') {
            TCGSDK.sendMouseEvent({ type: 'mouseleft', down: false });
          }
        }
        // The code for a two-finger pinch zoom operation. Here, the two fingers simulate a mouse scroll wheel event on a PC.
        if (res.length === 2) {
          const [{ pageX: oneX, pageY: oneY }, { pageX: twoX, pageY: twoY }] = res;

          const currentX = Math.ceil(Math.abs(oneX - twoX));
          const currentY = Math.ceil(Math.abs(oneY - twoY));
          // `lastX` and `lastY` indicates the previous position and can be defined globally like this: `let lastX = null, lastY = null`.
          lastX || (lastX = currentX);
          lastY || (lastY = currentY);

          if (lastX && currentX - lastX < 0 && lastY && currentY - lastY < 0) {
            TCGSDK.sendMouseEvent({ type: 'mousescroll', delta: 1 });
            lastX = currentX;
            lastY = currentY;
          }

          if (lastX && currentX - lastX > 0 && lastY && currentY - lastY > 0) {
            TCGSDK.sendMouseEvent({ type: 'mousescroll', delta: -1 });
            lastX = currentX;
            lastY = currentY;
          }
        }
      },
      onInitSuccess: async (res) => {
        console.log('%c onInitSuccess', 'color: red', res);

        await StartProject();
      }
    });

  </script>
</body>

</html>

Importing the Plugin

For movement operations on the mobile client, Real-Time Cloud Rendering provides an official stick plugin (Joystick) to map W, A, S, D, up, down, left, and right keys on the keyboard.

Stick

  1. Add the following code:
<script type="text/javascript" src="path/to/joystick.js"></script>
  1. Create a stick in onConnectSuccess.
// Add `plugin-point` of the stick as the ID of the element to which the plugin needs to be mounted.
const j = new CloudGamingPlugin.joystick({
  zone: document.querySelector('#plugin-point'),
});