【问题标题】:How to get 2D Javascript Game Script to run on a React Page?如何让 2D Javascript 游戏脚本在 React 页面上运行?
【发布时间】:2022-10-17 09:02:28
【问题描述】:

我有一个 HTML 网站,可以玩完全用 javascript 编写的游戏。我正在尝试将网站从 HTML 布局转换为更现代的 React 布局,但无法弄清楚如何让游戏呈现。

在 HTML 版本中,我将以下代码加载到页面中的游戏脚本中:

window.addEventListener('loadGameEngine', loadGameEngine); 

async function loadGameEngine() {
  window.removeEventListener('loadGameEngine', loadGameEngine); 
  const canvas = document.getElementById("playground");
  const context = canvas.getContext('2d');

  const map = new GameMap(canvas); 
  const loader = new Loader(); 
  await loader.init(); 
  const renderer = new Renderer(context, map, loader); 
  const mouse = new Mouse(canvas); 
  const ui = new UI(canvas, context, loader, mouse); 
  const economics = new Economics(map); 

  const game = new Game(canvas, renderer, ui, map, mouse); 
  game.init(); 
}

然后在 Game HTML 页面的正文中,我有这个:

    <div class="body">
      <div class="Game__container">
        <div class="canvas">
          <canvas
            id="playground"
            width="1152"
            height="576"
            class="game"
          ></canvas>
        </div>
      </div>
    </div>
    <script type="module" src="Scripts/Engine/main.js"></script>
    <script type="module" src="Scripts/Blockchain/web3.js"></script>
    <script type="module" src="Scripts/Blockchain/metamask.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

我已经尝试了多种不同的方法来加载我的 React 项目中的脚本,但主脚本似乎永远不会运行。我尝试将脚本添加到 React 项目的 index.html 中,如下所示:

    <script type="text/babel" data-type="module" src="../src/Scripts/Engine/main.js"></script>
    <script type="text/babel" data-type="module" src="../src/Scripts/Blockchain/metamask.js"></script>
    <script type="text/babel" data-type="module" src="../src/Scripts/Blockchain/web3.js"></script> 
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

我还尝试使用 react 钩子函数将脚本直接加载到 React 页面,如下所示:

const useScript = url => {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = url;
    script.async = true;
    script.type = "text/babel";
    document.body.appendChild(script);
    return () => {
      document.body.removeChild(script);
    };
  }, [url]);
};

然后在 Game 组件中调用 useScript。当我检查本地 Web 服务器上的元素时,我可以双向查看脚本。这是我的游戏组件的代码:

const Game = props => {

  useScript("../../Scripts/Engine/main.js");
  useScript("../../Scripts/Blockchain/web3.js");
  useScript("../../Scripts/Blockchain/metamask.js");
  useScript("https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js");

  return (
    <>
      <div style={{ margin: "6px 0px" }}>
        Gaming
      </div>

      <div className="body">
        <div className="Game__container">
          <div className="canvas">
            <canvas
              id="playground"
              width="1152"
              height="576"
              className="game"
            ></canvas>
          </div>
        </div>
      </div>
    </>
  )
}

【问题讨论】:

    标签: javascript reactjs web3js


    【解决方案1】:

    不是像在 HTML 中那样加载脚本,而是从文件中 export 类和函数,然后将 import 它们放入最顶部的 App.js 文件中:

    首先从您的文件中导出正确的函数和类(我不知道您的文件看起来如何,因此您需要展示它或自己弄清楚):

    // in the file Scripts/Engine/main.js
    export { map, Economics, game }
    
    // in the file Scripts/Blockchain/web3.js
    export { renderer, mouse, ui, loader }
    

    然后将其导入到您的主 App.js 文件中:

    import { map, Economics, game } from "Scripts/Engine/main.js"
    import { renderer, mouse, ui, loader } from "Scripts/Blockchain/web3.js"
    import /* your stuff */ from "Scripts/Blockchain/metamask.js"
    

    然后在同一个组件内部调用useEffect 钩子:

    useEffect(() => {
        const canvas = document.getElementById("playground");
        const context = canvas.getContext('2d');
    
        const map = new GameMap(canvas); 
        const loader = new Loader(); 
        await loader.init(); 
        const renderer = new Renderer(context, map, loader); 
        const mouse = new Mouse(canvas); 
        const ui = new UI(canvas, context, loader, mouse); 
        const economics = new Economics(map); 
    
        const game = new Game(canvas, renderer, ui, map, mouse); 
        game.init();
    }, []}
    

    这将在渲染页面时加载您的脚本,但会在您的组件正确渲染后立即初始化它们。

    您还可以像通常在反应中所做的那样进行改进以完成工作。在组件顶部创建变量const canvasRef = useRef(null),将const canvas = document.getElementById("playground")const canvas = canvasRef.current 交换,并在return 语句中将ref 添加到画布:&lt;canvas ref={canvasRef}&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      相关资源
      最近更新 更多