与React和PHP的游戏开发:它们的兼容性如何?
核心要点
- 使用React和PHP可以共同开发游戏,React负责前端用户界面,PHP管理后端和游戏逻辑。
- 游戏开发的设置过程包括设置异步PHP服务器,在非Laravel项目中使用Laravel Mix,以及使用WebSockets连接后端和前端。
- Aerys库可用于应用程序的HTTP和WebSocket部分,支持高并发和WebSockets。
- Laravel Mix可用于构建ReactJS文件,即使在非Laravel项目中也是如此,它提供了一种简单的方法来配置和扩展构建链。
- WebSockets可用于连接后端和前端,允许服务器和客户端之间进行实时通信。
我从决定尝试使用PHP和React构建游戏的那一刻起,就开始思考这个问题。“我想制作一个多人经济类游戏,类似于《星露谷物语》,但没有交友方面的内容,并且拥有玩家驱动的经济系统。” 问题是,我对多人游戏的动态性,或者如何思考和实现基于玩家的经济系统一无所知。
我甚至不确定自己是否了解足够的React知识来证明使用它的合理性。我的意思是,我最初的界面——我非常关注服务器和游戏的经济方面——非常适合React。但是当我开始制作耕作/互动方面的内容时呢?我喜欢围绕经济系统构建等距界面的想法。
我曾经观看过dead_lugosi的演讲,她描述了用PHP构建中世纪游戏的过程。Margaret激励了我,那次演讲是我写一本关于JS游戏开发书籍的原因之一。我决心要写下我的经验。也许其他人也可以从我的错误中学习。
(本部分的代码可在以下地址找到:github.com/assertchris-tutorials/sitepoint-making-games/tree/part-1。我已经在PHP 7.1和最新版本的Google Chrome中对其进行了测试。)
后端设置
我首先搜索的是关于构建多人经济系统的指导。我找到一个优秀的Stack Overflow帖子,其中人们解释了需要考虑的各种事情。在我意识到我可能从错误的地方开始之前,我已经看了一半了。“首先:我需要一个PHP服务器。我将有一堆React客户端,所以我想要一个能够处理高并发(甚至可能是WebSockets)的东西。它需要是持久性的:即使玩家不在线,事情也必须发生。”
我开始设置一个异步PHP服务器——来处理高并发并支持WebSockets。我添加了我最近使用PHP预处理器的工作,使事情更清晰,并创建了前几个端点。
来自config.pre
:
$host = new Aerys\Host(); $host->expose("*", 8080); $host->use($router = Aerys\router()); $host->use($root = Aerys\root(.."/public")); $web = process .."/routes/web.pre"; $web($router); $api = process .."/routes/api.pre"; $api($router);
我决定对应用程序的HTTP和WebSocket部分使用Aerys。这段代码与Aerys文档看起来非常不同,但这是因为我对所需内容有很好的了解。
运行Aerys应用程序的通常过程是使用类似这样的命令:
vendor/bin/aerys -d -c config.php
有很多代码需要重复,而且它没有处理我想使用PHP预处理的事实。我创建了一个加载器文件。
来自loader.php
:
return Pre\processAndRequire(__DIR__ . "/config.pre");
然后我安装了我的依赖项。这是来自composer.json
:
"require": { "amphp/aerys": "dev-amp_v2", "amphp/parallel": "dev-master", "league/container": "^2.2", "league/plates": "^3.3", "pre/short-closures": "^0.4.0" }, "require-dev": { "phpunit/phpunit": "^6.0" },
我想使用amphp/parallel
将阻塞代码从异步服务器中移出,但它无法与amphp/aerys
的稳定标签一起安装。这就是我使用dev-amp_v2
分支的原因。
我认为包含某种模板引擎和服务定位器是个好主意。我选择了PHP League的每个版本。最后,我添加了pre/short-closures
,既用于处理config.pre
中的自定义语法,也用于我之后计划使用的短闭包……
然后我开始创建路由文件。来自routes/web.pre
:
use Aerys\Router; use App\Action\HomeAction; return (Router $router) => { $router->route( "GET", "/", new HomeAction ); };
以及来自routes/api.pre
:
use Aerys\Router; use App\Action\Api\HomeAction; return (Router $router) => { $router->route( "GET", "/api", new HomeAction ); };
虽然是简单的路由,但这有助于我测试config.pre
中的代码。我决定让这些路由文件返回闭包,这样我就可以向它们传递一个类型化的$router
,它们可以向其中添加自己的路由。最后,我创建了两个(类似的)操作。
来自app/Actions/HomeAction.pre
:
namespace App\Action; use Aerys\Request; use Aerys\Response; class HomeAction { public function __invoke(Request $request, Response $response) { $response->end("hello world"); } }
最后的润色是添加快捷脚本,以启动Aerys服务器的开发和生产版本。
来自composer.json
:
"scripts": { "dev": "vendor/bin/aerys -d -c loader.php", "prod": "vendor/bin/aerys -c loader.php" }, "config": { "process-timeout": 0 },
完成所有这些后,我可以启动一个新的服务器,只需键入以下命令即可访问http://127.0.0.1:8080:
composer dev
前端设置
“好的,既然我已经让PHP方面的事情相对稳定了;我该如何构建ReactJS文件呢?也许我可以使用Laravel Mix……?”
我不太想创建一个全新的构建链,而且Mix也已被重建为可在非Laravel项目中良好工作。虽然配置和扩展相对容易,但它默认情况下更偏向VueJS。
我首先要做的是安装一些NPM依赖项。来自package.json
:
"devDependencies": { "babel-preset-react": "^6.23.0", "bootstrap-sass": "^3.3.7", "jquery": "^3.1.1", "laravel-mix": "^0.7.5", "react": "^15.4.2", "react-dom": "^15.4.2", "webpack": "^2.2.1" },
Mix使用Webpack来预处理和捆绑JS和CSS文件。我还需要安装React和相关的Babel库来构建jsx文件。最后,我添加了Bootstrap文件,以获得一些默认样式。
Mix自动加载自定义配置文件,所以我添加了以下内容。来自webpack.mix.js
:
let mix = require("laravel-mix") // load babel presets for jsx files mix.webpackConfig({ "module": { "rules": [ { "test": /jsx$/, "exclude": /(node_modules)/, "loader": "babel-loader" + mix.config.babelConfig(), "query": { "presets": [ "react", "es2015", ], }, }, ], }, }) // set up front-end assets mix.setPublicPath("public") mix.js("assets/js/app.jsx", "public/js/app.js") mix.sass("assets/scss/app.scss", "public/css/app.css") mix.version()
我需要告诉Mix如何处理jsx文件,所以我添加了与通常放在.babelrc
中的配置相同的配置。我计划让单个JS和CSS入口点进入应用程序的各个部分。
注意:未来版本的Mix将内置支持构建ReactJS资产。届时,可以删除mix.webpackConfig
代码。
再一次,我创建了一些快捷脚本,以节省大量的打字工作。来自package.json
:
$host = new Aerys\Host(); $host->expose("*", 8080); $host->use($router = Aerys\router()); $host->use($root = Aerys\root(.."/public")); $web = process .."/routes/web.pre"; $web($router); $api = process .."/routes/api.pre"; $api($router);
所有三个脚本都使用了Webpack变量命令,但它们在除此之外的操作方面有所不同。dev
构建了JS和CSS文件的调试版本。-w
开关启动了Webpack监视器(以便可以部分重建捆绑包)。-p
开关启用了精简的生产版本的捆绑包。
由于我使用了捆绑版本控制,所以我需要一种方法来引用类似/js/app.60795d5b3951178abba1.js
的文件,而无需知道哈希值。我注意到Mix喜欢创建清单文件,所以我制作了一个辅助函数来查询它。来自helpers.pre
:
vendor/bin/aerys -d -c config.php
Aerys知道如何在它们以$val = yield $promise
的形式出现时处理promise,所以我使用了Amp的Promise实现。读取并解码文件后,我可以查找匹配的文件路径。我调整了HomeAction
。来自app/Actions/HomeAction.pre
:
return Pre\processAndRequire(__DIR__ . "/config.pre");
我意识到我可以继续创建返回promise的函数,并以这种方式使用它们来保持代码的异步性。这是我的JS代码,来自assets/js/component.jsx
:
"require": { "amphp/aerys": "dev-amp_v2", "amphp/parallel": "dev-master", "league/container": "^2.2", "league/plates": "^3.3", "pre/short-closures": "^0.4.0" }, "require-dev": { "phpunit/phpunit": "^6.0" },
……以及来自assets/js/app.jsx
:
use Aerys\Router; use App\Action\HomeAction; return (Router $router) => { $router->route( "GET", "/", new HomeAction ); };
毕竟,我只是想看看Mix是否会编译我的jsx文件,以及我是否可以使用异步mix
函数再次找到它们。事实证明它有效!
注意:每次都使用mix
函数是很昂贵的,特别是如果我们正在加载相同的文件。相反,我们可以在服务器引导阶段加载所有模板,并在需要时从操作内部引用它们。我们启动Aerys的配置文件可以返回一个promise(例如Amp\all
给我们的那种),因此我们可以在服务器启动之前解析所有模板。
使用WebSockets连接
我几乎已经设置好了。最后要做的是通过WebSockets连接后端和前端。我发现这相对简单,使用一个新类。来自app/Socket/GameSocket.pre
:
use Aerys\Router; use App\Action\Api\HomeAction; return (Router $router) => { $router->route( "GET", "/api", new HomeAction ); };
……以及对web路由的轻微修改(来自routes/web.pre
):
namespace App\Action; use Aerys\Request; use Aerys\Response; class HomeAction { public function __invoke(Request $request, Response $response) { $response->end("hello world"); } }
现在,我可以更改JS以连接到此WebSocket,并将消息发送到连接到它的每个人。来自assets/js/component.jsx
:
"scripts": { "dev": "vendor/bin/aerys -d -c loader.php", "prod": "vendor/bin/aerys -c loader.php" }, "config": { "process-timeout": 0 },
当我创建一个新的Component
对象时,它将连接到WebSocket服务器,并为新消息添加一个事件监听器。我添加了一些调试代码——以确保它能够正确连接,并发送新的消息。
我们稍后会详细介绍PHP和WebSockets,别担心。
总结
在本部分中,我们研究了如何设置一个简单的异步PHP Web服务器,如何在非Laravel项目中使用Laravel Mix,甚至如何使用WebSockets将后端和前端连接在一起。
哇!涵盖了很多内容,而且我们还没有编写一行游戏代码。加入我在第二部分,我们将开始构建游戏逻辑和React界面。
(本文由Niklas Keller同行评审。感谢所有SitePoint的同行评审者,使SitePoint的内容达到最佳状态!)
使用ReactJS和PHP进行游戏开发的常见问题解答(FAQ)
ReactJS和PHP在游戏开发中的兼容性如何?
ReactJS和PHP在游戏开发中具有高度的兼容性。ReactJS是一个JavaScript库,非常适合构建用户界面,尤其适用于单页应用程序。它允许快速、响应迅速的网页设计。另一方面,PHP是一种服务器端脚本语言,非常适合后端开发。它可以处理数据库、用户身份验证和服务器端逻辑。当一起使用时,ReactJS可以处理前端,创建动态且交互式用户界面,而PHP则管理后端。
我可以在ReactJS游戏中使用PHP进行游戏逻辑吗?
是的,你可以在ReactJS游戏中使用PHP进行游戏逻辑。虽然ReactJS处理用户界面,但PHP可以在服务器端管理游戏逻辑。这包括处理数据、管理用户会话和控制游戏规则。这种关注点分离允许更井然有序且高效的开发过程。
使用ReactJS进行游戏开发的好处是什么?
ReactJS为游戏开发提供了许多好处。它的虚拟DOM允许高效的更新和渲染,使游戏运行更流畅。它还支持可重用的组件,这可以大大加快开发时间。此外,ReactJS拥有庞大的社区和丰富的资源,使查找问题的解决方案或学习新技术更容易。
使用PHP进行游戏开发的优势是什么?
PHP在游戏开发中具有多项优势。它是一种服务器端语言,这意味着它可以处理数据管理、用户身份验证和服务器端游戏逻辑。PHP也很容易学习,语法简单,并且拥有庞大的开发者社区。它也具有高度的可扩展性,使其适合可能需要处理大量用户的游戏。
如何开始使用ReactJS和PHP开发游戏?
要开始使用ReactJS和PHP开发游戏,你首先需要学习这两种语言的基础知识。有很多在线资源和教程可用。一旦你熟悉了这些语言,你可以从构建简单的游戏开始。这可以是一个基本的文本游戏或一个简单的益智游戏。随着你获得更多经验,你可以开始构建更复杂的游戏。
有哪些资源或库可以帮助使用ReactJS和PHP进行游戏开发?
是的,有几个资源和库可以帮助使用ReactJS和PHP进行游戏开发。对于ReactJS,像React Game Kit和React Game Engine这样的库非常有用。对于PHP,你可能会发现像PHP-SDL或Wyvern这样的库很有用。此外,在线还有很多教程、指南和论坛,你可以在那里学习更多知识并获得帮助。
我可以使用ReactJS和PHP构建多人游戏吗?
是的,你可以使用ReactJS和PHP构建多人游戏。ReactJS可以处理用户界面,而PHP可以管理服务器端逻辑,包括管理玩家会话和跨多个客户端同步游戏状态。
我可以使用ReactJS和PHP构建什么类型的游戏?
使用ReactJS和PHP,你可以构建各种各样的游戏。这包括简单的文本游戏、益智游戏、平台游戏、角色扮演游戏,甚至是多人在线游戏。可能性是巨大的,限制实际上是你的想象力和技能水平。
如何在一个使用ReactJS和PHP开发的游戏中处理数据?
在一个使用ReactJS和PHP开发的游戏中,可以使用服务器端的PHP处理数据。这可以包括玩家数据、游戏状态、分数等等。这些数据可以存储在数据库中,并且可以使用PHP与这个数据库进行交互,根据需要检索和更新数据。
如何在一个使用ReactJS开发的游戏中处理用户输入?
在一个使用ReactJS开发的游戏中,可以使用React的事件处理系统处理用户输入。这可以包括鼠标点击、键盘按键和触摸事件。React的事件处理系统功能强大且灵活,允许你轻松控制游戏如何响应用户输入。
以上是与React和PHP的游戏开发:它们的兼容性如何?的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

PHP中有四种主要错误类型:1.Notice:最轻微,不会中断程序,如访问未定义变量;2.Warning:比Notice严重,不会终止程序,如包含不存在文件;3.FatalError:最严重,会终止程序,如调用不存在函数;4.ParseError:语法错误,会阻止程序执行,如忘记添加结束标签。

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

HTTP请求方法包括GET、POST、PUT和DELETE,分别用于获取、提交、更新和删除资源。1.GET方法用于获取资源,适用于读取操作。2.POST方法用于提交数据,常用于创建新资源。3.PUT方法用于更新资源,适用于完整更新。4.DELETE方法用于删除资源,适用于删除操作。

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

在PHPOOP中,self::引用当前类,parent::引用父类,static::用于晚静态绑定。1.self::用于静态方法和常量调用,但不支持晚静态绑定。2.parent::用于子类调用父类方法,无法访问私有方法。3.static::支持晚静态绑定,适用于继承和多态,但可能影响代码可读性。

PHP通过$\_FILES变量处理文件上传,确保安全性的方法包括:1.检查上传错误,2.验证文件类型和大小,3.防止文件覆盖,4.移动文件到永久存储位置。
