跳转至

Phaser3常识答问(一)

注译说明#

注、译自Phaser 3 FAQ/常识答问,作者为Samme。

How do I learn Phaser?#

// 怎么学Phaser?

And see next questions.

I'm new to web development#

//我是web开发新手

I'm new to JavaScript#

// 我是JavaScript新手

I know JavaScript but I've never made a game before#

// 我了解JavaScript,但是从来没有做过游戏

Should I use Phaser 3 or Phaser 2/CE?#

// 我该用Phaser3还是Phaser2/CE?

Probably Phaser 3, especially if you're new to both of them. // 可能是Phaser3,如果你对二者都是新手的话,更是如此。

Phaser 3 doesn't have // Phaser3没有:

  • Creature animations // Creature动画
  • Box2D physics // Box2D物理引擎
  • P2 physics // P2物理引擎
  • Impact physics (soon) // Impact物理引擎

See // 参见

Will Phaser 2 code work in Phaser 3?#

// Phaser2代码在Phaser3中有效吗?

No.

Should I convert this Phaser 2 project/tutorial to Phaser 3?#

// 我应该把Phaser2项目或教程转成3吗?

Probably not, especially if you're new to Phaser 3. // 不要了吧,如果你不熟悉3更没必要。

Does Phaser 3 use PixiJS?#

// Phaser3使用PixiJS吗?

No.

Which Phaser am I using?#

// 我用的是哪个版本的Phaser呀?

Look in the browser console after creating a game, or in Phaser.VERSION.

Should I use phaser.js or phaser.min.js?#

// 我该用 phaser.js 还是 phaser.min.js

Use phaser.js until your game is done, then switch to phaser.min.js.

phaser.min.js is the minified (packed) build. // 游戏做完前用 phaser.js ,发布时用压缩、包装过的 phaser.min.js

But I switched and now my game doesn't work! :(#

//我换了以后游戏不运行了

That is nearly impossible. Make sure you haven't switched Phaser versions by accident (look in browser console). // 不大可能。看看是不是版本搞错了

Which web server should I use (on my own computer)?#

// 本机上用什么web服务器

There are many and you may have some already installed. // 有很多选择,Node的http-server就挺好,安装、运行如下:

If you already have Node/npm, then http-server is a good choice. Install once with

1
2
::shell
npm i -g http-server

Then run in your project directory:

1
2
::shell
http-server . -c-1 --open

-c-1 means don't cache(不缓存) and --open means open a browser(打开一个浏览器).

How should I organize my project?#

// 我该怎么组织工程?

There's no particular requirement, except one HTML file that loads the Phaser library and your own game script.

How can I code in modules?#

// 怎么使用模块化编程

Use a bundler such as parcel, rollup or webpack. // 使用包装器,比如……

You can't use Phaser 3 as an ES module (<script type=module>). // 可以把Phaser3当作一个ES模块

Can I use ES6 syntax?#

// 可以用ES6语法吗?

Yes. If you're publishing a game for general use, you should probably transpile it.

How do I use Phaser with TypeScript?#

// 怎么配合使用TypeScript和Phaser?

Since v3.17.0, Phaser's declaration file is included. //已经含有声明文件

It's usually found automatically, but if it's not, you can add node_modules/phaser/types/phaser.d.ts to the files entry of your project's tsconfig file. //如果不能自动发现,可以把声明文件放到入口文件中

Can Phaser do (something) / How can I do (something) with Phaser?#

// Phaser能做/怎么做某事?

Study the examples.

How do I use the API Reference?#

//怎么使用API参考文档?

Start at new Phaser.Game() or the Scene menu. // 从……这两个地方开始

How can I fix errors in the API docs or TypeScript definitions?#

// 怎么修正文档或类型定义的错误

Make a pull request. Phaser uses the JSDoc format and generates the TypeScript definitions from them for each release.

How do I use Phaser with webpack?#

// 怎么使用webpack

phaser3-project-template is a simple configuration, and there are others. //这是个简单配置模板

How do I make a custom build of Phaser?#

// 怎么定制Phaser

See phaser3-custom-build.

I tried to run my Phaser game and all I see is a blank page/black canvas.#

//运行游戏是得到白页/黑画面

Open the browser console. //打开浏览器控制台

Why don't my assets load?#

// 为什么我的资源没有加载?

Look in your browser's address bar. If you see a file: URL, you need to run a local web server and open the game from there instead. The URL in the address bar should start with http: or https:, like http://localhost or http://127.0.0.1.

Open your browser's console and look for errors.

If you see Not found errors, open the full URL and check it for mistakes.

If you see error messages similar to Cross origin requests are only supported for HTTP, you need to run a local web server and open the game from there instead.

If you see errors similar to Origin [origin] is not allowed by Access-Control-Allow-Origin, you can try making cross-origin requests.

How do I load cross-origin assets?#

// 怎么加载跨域资源?

Set loader.crossOrigin to 'anonymous' in your game config, or use this.load.setCORS('anonymous'). But this doesn't guarantee the cross-origin request will succeed; the server hosting the asset also has to agree to share it.

If you're loading assets from the same origin (usually the same domain or server), don't set crossOrigin. // 同域加载资源时不应设置 crossOrigin。【注意,本机的127.0.0.1、localhost、0.0.0.0三者之间构成跨域】

How can I make a game object stay the same size when the camera zooms?#

// 镜头拉动时怎么保持对象尺寸不变?

  • Scale the object by the camera zoom; or
  • Create a second camera and split your game objects between it and the main camera, using ignore (this is a bit of a pain); or
  • Create a second scene atop the first

How do I pause/resume the game?#

// 怎么暂停、续播游戏?

Call pause or resume on each scene.

How do I stop the game from pausing when switching tabs/applications?#

// 切换tab键/应用时暂停的游戏怎么停止?

This is not a true game pause but the browser suspending the page, which necessarily halts halt the update loop. //这不是真的暂停了游戏,二十浏览器页面挂起

Use the game events BLUR, FOCUS, HIDDEN, and VISIBLE to respond to these changes. //请使用这些游戏事件和属性

setTimeout calls may run as often as once per second while in the background, depending on the browser. Web Workers can run more frequently.

How does AUTO choose the renderer?#

//auto是怎么选择渲染器的?

It chooses WebGL if the device appears to support it and Canvas otherwise. //优先选择webgl

How do I make a high-resolution canvas?#

// 怎么做高解析度的画布?

In v3.15, pass a resolution value larger than 1 in the game config.

Since v3.16, resolution is unsupported.

How do I use high-resolution text / Why is my text blurry?#

// 怎么用高解析文本/为什么我的文本模糊?

How do I scale/resize the game canvas?#

// 游戏画布怎么缩放/重订尺寸?

Since v3.16.0, use the Scale Manager. //v3.16.0版以后,请使用尺寸管理器/Scale Manager.

Why do my sprites look blurry?#

// 为什么我的精灵看起来模糊?

Set antialias: false or pixelArt: true in your game config. You don't need to set both.

Why is my text blurry?#

// 为什么我的文本模糊?

Avoid scaling a Text object or the game canvas larger than 100%.

How do scenes work?#

// 场景是怎么运作的?

A scene is like a self-contained "world" within the game. Every game has at least one scene. If you've used preload(), create(), or update(), then you've already used a scene.

In multi-scene games, a scene can be a "screen", a menu, a level, or a window. // 在多场景游戏中,场景可以用来做“屏”、菜单、“级”、窗口。 // 缺省情况下,Phaser加入你指定的所有场景,但只启动第一个。Phaser也能同时运行、显示多个场景。【并行场景可做UI】

How do I use this in a scene?#

// 在场景中怎么用this

  • Within a scene's method hooks (init, preload, create, update), this is the current scene. // 在场景的方法钩子(init, preload, create, update)中,this指向当前场景。
  • If you define your own scene methods, call them as this.method(…) to keep the scene context. // 你自定义的场景方法,用this.myMethod(…)这样调用,以持有场景上下文。
  • If you pass a callback that uses this, you must also pass a callback context. Pass this if you want to keep the scene context. // 如果传递一个使用this的回调函数,你也要传递上下文。——传递this以持有场景上下文。

Can I use just one scene?#

//可以只用一个场景吗

For simple games, yes. Most of the examples are written this way.

When should I use different scenes?#

//什么时候该用不同的场景

It depends, but if you want to pause it, start/restart it, or move it, it could be a scene.

How do I switch scenes?#

//怎么切换场景

this.scene.start('key') stops the current scene and starts another (named by 'key'). Using only start, you can move through scenes one at a time.

launch, run, and switch are variations on start. They affect the calling scene differently. // launch, run, switchstart的变体。

How do I restart a scene?#

//怎么重启场景

this.scene.restart() or this.scene.launch('key')### What happens when I stop/restart a scene?

When you stop a scene, the scene's display and update lists are emptied and the game objects they contained are destroyed (unlinked). The scene systems (clock, input, physics, tweens) shut down and clear their own data and event handlers. The scene's own event handlers are not cleared. The scene becomes inactive and invisible, but it's still there, and it can be started again. // 停止场景时,场景的显示列表、更新列表将清空,其中的游戏对象将销毁。场景的插件将关闭,插件的数据(输入事件、时间事件、补间动画,等等)将清除。场景的事件处理器不会被清楚。场景不再活动,不再可见。

When you restart a scene, it's stopped and then started again, calling init(), preload(), and create(). // 重启场景,场景将关闭后重启,调用init(), preload(), create()方法。

Why do I get errors when I restart a scene?#

//重启场景出错

Look at the error message and trace. You may be able to figure out which object or event handler is involved.

  • Before restarting, remove any scene event handlers (this.events) that reference game objects.
  • Before restarting, reset your own state variables, if you have any.
  • Avoid setInterval() and setTimeout().

What's the difference between the add. and make. methods?#

// add.*make.*两个方法的区别是什么?

The add methods use ordered arguments and register the new object with scene. // add.*方法使用顺序参数/位置参数,在场景中注册新对象。

The make methods use configuration objects and register the new object with the scene only if specified, or by default, depending on the method. You might always pass an add/addToScene value to avoid confusion. // make.*方法使用配置对象,是否注册新对象要指定,缺省情况下因方法不同情况不同。——可以始终添加add/addToScene值,以免混乱。

Do I have to load the assets I need in every scene?#

//每个场景需要的资源都需要重新加载一次吗?

No. All of Phaser's caches are global. Assets need to be loaded (only once) before they can be used, in any scene. //不需要。Phaser的缓存是全局的

How do I make a loading progress indicator?#

// 怎么做加载进度条?

Bind to the loader's start, progress, and loadcomplete events during the preload callback, or earlier.

I need per-file loading progress.#

// 我需要单文件的加载进度。

Bind to the fileprogress event. // 绑定到fileprogress事件。

Can I queue files during loading?#

// 加载过程中可以请求文件吗?

Yes.

How do I add a child sprite?#

// 怎么加入子精灵?

Phaser 3's display list is flat, so there are no child sprites. It does have a special game object, Container, that applies transformations to its children (including other containers). // Phaser3的显示列表是扁平的,所有没有子精灵。不过另有一个特殊的游戏对象Container(容器),可以对子项(包括子容器)统一应用变形。

Blitters and particle managers can shift-transform their children (bobs and particle emitters). // 位块传送器和粒子管理器可以对子项(bob和粒子发射器)进行位移变换。

Can I nest containers?#

// 可以嵌套容器吗

Yes.

Can I mask a container?#

//容器可以遮罩吗

Yes, only if that container is not in another container.

Can I mask a game object in a container?#

//容器内的游戏对象可以遮罩吗

Yes, only if the mask source is not in the container.

Can I set a container's origin?#

//可以设置容器的原点吗

No, but you can position children around (0, 0).

How do I extend a game object?#

// 怎么扩展游戏对象(类继承)?

You can use the traditional ES5 form, the Phaser.Class helper, or ES6 classes.

The most common mistake is to add the instance to the scene incorrectly, or not at all. From the scene, you can call // 最常见的错误是添加实例不正确,或无法添加。可以从场景调用:

1
2
::JavaScript
this.add.existing( new ExtendedObject(this, /* ... */) );

or from the class

1
2
::JavaScript
this.scene.add.existing(this);

For a physics-enabled game object, use the physics plugin's existing method as well. // 对于开启物理引擎的游戏对象,同样可以使用物理引擎插件的existing方法:

1
2
::JavaScript
this.physics.add.existing( new ExtendedObject(this, /* ... */) );

When in doubt, imitate the factory method of the parent class. Make sure you're passing the parent constructor's arguments correctly.

You can also write your own factory method and call it, or register your game object with the plugin manager. // 也可以写自己的工厂函数(方法),然后调用,或在插件管理器中注册你的游戏对象。

How do I run a game object's update method automatically?#

// 怎么自动地运行游戏对象的update方法。

  • Bind to the scene's update event; or // 绑定到场景的update事件上;或者
  • Add the game object to a group and set the group's runChildUpdate; or // 把游戏对象添加到组,然后设置组的runChildUpdate;或者
  • Use a plugin // 使用插件

If the game object has a preUpdate method (such as a Sprite, but not an Image), you can override the preUpdate method instead. Make sure you call the parent class's method as well. // 如果游戏对象有preUpdate方法(比如是Sprite而不是Image),你也可以重载preUpdate方法。请确保你也调用了父类的方法。

If the game object has a preUpdate method (such as a Sprite, but not an Image), you can override the preUpdate method instead. Make sure you call the parent class's method as well. // 如果游戏对象有preUpdate方法,你也可以覆盖/重载此方法。别忘了还要调用父类的方法。

How do I make a button?#

// 怎么做按钮?

Make an interactive game object and go from there. See Buttons in Phaser 3.

Which physics system should I use?#

// 我该用那个物理引擎?

Arcade Physics is a simple, high-performance model. It uses only circular or rectangular shapes. // Arcade物理引擎模块简单、高性能。它只使用圆形和方形两种形状。

Impact Physics is similar. You'll probably use it only if you're already familiar with it (from ImpactJS). // Impact物理引擎近似。假如你已经熟悉,也许可以用。

Matter is a complex 2d physics engine. Matter是复杂的2d物理引擎。

Do Arcade Physics bodies rotate?#

Arcade物理体会旋转吗?

Geometrically, no. 几何旋转不行。

Can I give a sprite more than one Arcade Physics body?#

//一个精灵可以赋予多个Arcade物理体吗?

No.

How do I find out which sprite is colliding?#

//怎么知道哪个精灵在碰撞

Use the arguments in the collision callback.

What's the difference between an Arcade Physics body's blocked and touching?#

// Arcade物理体的 blocked (受阻)和 touching (接触)的区别是什么?

blocked is a collision/overlap with the world bounds, a tile, or a static body. // blocked(受阻)是与世界边界、地砖、静态物体的碰撞/重叠。

touching is a collision/overlap between two bodies (dynamic or static), but not embedded. // touching(接触)指两个不镶嵌的静态或动态物理体之间的碰撞/重叠。

embedded is a collision/overlap between two bodies where, on at least axis, both bodies aren't moving. //镶嵌是两个不动的物理题之间的碰撞/重叠。

Why do my tilemap tiles show small gaps/lines/seams?#

// 为什么我的地图砖块显得有缝隙、细线、接缝?

It's a visual artifact of normal WebGL rendering. Use a tool to extrude the tileset image.

Why do I get the warning The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page?#

//这个警告是怎么回事……

This is normal when using Phaser with Web Audio in Chrome. By itself it doesn't signify a problem. Phaser will automatically resume the audio context when the user clicks/taps. Sound may be muted before that, though.

If your game doesn't use sound, disable it and you won't see the warning:

1
2
::JavaScript
new Phaser.Game({ audio: { noAudio: true } });

//如果不使用声音,可以关闭警告

How do I fix/debug my game?#

//怎么改正/调试游戏

  • Open the console. Read errors and warnings.
  • Expand error stack traces. Find the last point your own code was involved.
  • Break on exceptions. Examine values in the debugger.
  • If the problem isn't in the paused function, step backwards through the call stack and find it.
  • Don't use the minified script (phaser.min.js) during development; the traces are hard to read. Use phaser.js instead.

Use Phaser's debugging tools: //使用Phaser调试工具

Use a plugin: //使用插件

Check your code against Phaser's API documentation. // 使用Phaser API文档

Use your browser's debugging tools. You don't have to use Chrome; most of these are similar across the main browsers.

A few tools can be especially helpful for games: // 一些对游戏会特别有用的的工具

Cannot read property 'property' of undefined / undefined is not an object / undefined is not a function#

// 无法读取未定义的属性'property',或未定义者不是一个对象

You tried to read a property from an undefined value, which is impossible (undefined has no properties). // 你试图读取未定义的值的属性

You need to find the expression that evaluated to undefined. Firefox and Safari give more helpful error messages in this respect. // 你需要找到被确定为未定义的那个表达式。在这个方面,Firefox和Safari会给出更有用的错误信息。

If this is involved, you've likely made a scope error: either accessing an undefined scope (this === undefined) or a scope different from the object you're expecting (so missing the named property). // 如果牵扯到this,你可能犯了一个作用域的错误:或者是访问了未定义的域(this === undefined),或者是访问的域有别于你期望的对象(因此缺少所指称的属性)。

How do I ask for help?#

Help people help you. :)

Clearly describe your original problem, e.g., what you expect to happen and what happens instead. Remember only you know how your game is supposed to work and what it's supposed to look like.

Provide a runnable example or the minimal code to produce the problem.

If there is an error message, include the error message and trace.

I want to X but it doesn't work, by itself, is not a good way to ask for help.

Why doesn't my question get answered?#

Possibly:

  • It's not clear what you're asking
  • You haven't given enough information
  • The code is too long/complex to assess
  • People who know the answer haven't seen your question yet

Why is my game slow?#

//为什么我的游戏会慢

Use your browser's Performance/Profile/Timeline tool to identify bottlenecks. Usually, you'll use the Bottom-Up view or sort by Self Time. // 使用浏览器的Profile/Timeline,以便找出瓶颈。

Generally, it depends, but try: // 通常有赖于:

  • Combine images into atlases/spritesheets // 图像打包【音频文件也能打包】
  • Render same-texture and same-blend-mode objects consecutively (by keeping them adjacent on the display list) //连续地渲染有相同纹理、相容混色模式的对象(使他们在显示列表上连在一起)【???】
  • Reduce the use of nested Containers, complex Graphics, or Text // 降低Graphics(自绘图形)对象的数量、复杂程度。【如果Graphics变化不大,可生成纹理后再使用】
  • Reduce texture dimensions // 降低纹理的尺寸
  • Reduce game canvas dimensions // 降低游戏画布的尺寸

If the game slows consistently over a few seconds, you may have made a programming mistake, e.g.,

  • drawing repeatedly to a Graphic without clearing it
  • adding duplicate event handlers

Where can I publish my game (for free)?#

//到哪里(免费)发布游戏

On itch.io (cli) or GitHub Pages or Surge.

Node-based apps can be deployed on Heroku.