Loading...
Loading...
Compare original and translation side by side
Camera system in Phaser 4 -- CameraManager, main camera, viewport vs scroll, zoom, bounds, following sprites, camera effects (fade, flash, shake, pan, zoomTo, rotateTo), ignore lists, filters, and keyboard controls.
src/cameras/2d/CameraManager.jssrc/cameras/2d/BaseCamera.jssrc/cameras/2d/Camera.jssrc/cameras/2d/effects/src/cameras/controls/Phaser 4中的相机系统——CameraManager、主相机、视口与滚动、缩放、边界、精灵跟随、相机特效(淡入淡出、闪烁、震动、平移、zoomTo、rotateTo)、忽略列表、滤镜以及键盘控制。
src/cameras/2d/CameraManager.jssrc/cameras/2d/BaseCamera.jssrc/cameras/2d/Camera.jssrc/cameras/2d/effects/src/cameras/controls/// In a Scene's create() method:
// Access the default camera (created automatically)
const cam = this.cameras.main;
// Scroll the camera to look at a different part of the world
cam.setScroll(200, 100);
// Center camera on a world coordinate
cam.centerOn(400, 300);
// Zoom in (2x) -- values < 1 zoom out, > 1 zoom in
cam.setZoom(2);
// Follow a sprite with smooth lerp
cam.startFollow(player, false, 0.1, 0.1);
// Constrain the camera to the world bounds
cam.setBounds(0, 0, 2048, 2048);
// Fade in from black over 1 second
cam.fadeIn(1000);
// Add a filter to the camera (v4 feature)
cam.filters.external.addBlur(1, 2);// 在场景的create()方法中:
// 获取默认相机(自动创建)
const cam = this.cameras.main;
// 滚动相机以查看游戏世界的其他区域
cam.setScroll(200, 100);
// 将相机居中到指定世界坐标
cam.centerOn(400, 300);
// 放大(2倍)——值<1为缩小,>1为放大
cam.setZoom(2);
// 以平滑插值方式跟随精灵
cam.startFollow(player, false, 0.1, 0.1);
// 将相机限制在世界边界内
cam.setBounds(0, 0, 2048, 2048);
// 1秒内从黑色淡入
cam.fadeIn(1000);
// 为相机添加滤镜(v4新特性)
cam.filters.external.addBlur(1, 2);CameraManagerthis.cameras'CameraManager'// The manager is at this.cameras (not this.camera)
this.cameras // CameraManager instance
this.cameras.cameras // Array of Camera objects (render order)
this.cameras.main // Reference to the "main" camera (first one by default)
this.cameras.default // Un-transformed utility camera (not in the cameras array)| Method | Signature | Description |
|---|---|---|
| | Create a new Camera. Defaults to full game size at 0,0. Returns |
| | Add a pre-built Camera instance. Returns the Camera or |
| | Remove and optionally destroy a Camera or array of Cameras. If main is removed, resets to cameras[0]. |
| | Find a Camera by its |
| | Count cameras. Pass |
| | Create cameras from a config object or array. Used for scene-level camera config. |
| | Destroy all cameras and create one fresh default camera. |
| | Resize all cameras to given dimensions. |
ignore()CameraManagerthis.cameras'CameraManager'// 管理器位于this.cameras(不是this.camera)
this.cameras // CameraManager实例
this.cameras.cameras // Camera对象数组(渲染顺序)
this.cameras.main // 主相机的引用(默认是第一个相机)
this.cameras.default // 未经过变换的工具相机(不在cameras数组中)| 方法 | 签名 | 说明 |
|---|---|---|
| | 创建一个新相机。默认以0,0位置填充整个游戏尺寸,返回 |
| | 添加一个预构建的Camera实例。如果相机已存在则返回 |
| | 移除并可选销毁单个或多个相机。如果主相机被移除,会重置为cameras[0]。 |
| | 通过名称字符串查找相机,返回Camera对象或 |
| | 统计相机数量。传入 |
| | 通过配置对象或数组创建相机,用于场景级相机配置。 |
| | 销毁所有相机并创建一个全新的默认相机。 |
| | 将所有相机调整为指定尺寸。 |
ignore()maincameras[0]makeMain: trueadd()addExisting()cameras[0]maincameras[0]add()addExisting()makeMain: truecameras[0]setPosition(x, y)setSize(w, h)setViewport(x, y, w, h)scrollXscrollYsetScroll(x, y)// Viewport: a 320x200 mini-map in the top-right corner
const miniCam = this.cameras.add(480, 0, 320, 200);
// Scroll: make the mini-map look at a different world area
miniCam.setScroll(1000, 500);
// Zoom: the mini-cam shows more of the world
miniCam.setZoom(0.25);Rectangleconst view = cam.worldView; // { x, y, width, height }setPosition(x, y)setSize(w, h)setViewport(x, y, w, h)scrollXscrollYsetScroll(x, y)// 视口:右上角的320x200小地图
const miniCam = this.cameras.add(480, 0, 320, 200);
// 滚动:让小地图查看世界的其他区域
miniCam.setScroll(1000, 500);
// 缩放:小地图显示更多世界内容
miniCam.setZoom(0.25);Rectangleconst view = cam.worldView; // { x, y, width, height }// Direct property access
cam.scrollX = 100;
cam.scrollY = 200;
// Chainable setter
cam.setScroll(100, 200);
// Center the camera on a world coordinate
cam.centerOn(500, 400);
// Get the scroll values needed to center on a point (without moving)
const point = cam.getScroll(500, 400); // returns Vector2// 直接访问属性
cam.scrollX = 100;
cam.scrollY = 200;
// 链式设置器
cam.setScroll(100, 200);
// 将相机居中到指定世界坐标
cam.centerOn(500, 400);
// 获取居中到某点所需的滚动值(不移动相机)
const point = cam.getScroll(500, 400); // 返回Vector2// Instant follow (lerp = 1, the default)
cam.startFollow(player);
// Smooth follow with lerp (0..1, lower = smoother)
cam.startFollow(player, false, 0.1, 0.1);
// Full signature:
// startFollow(target, roundPixels?, lerpX?, lerpY?, offsetX?, offsetY?)
cam.startFollow(player, true, 0.05, 0.05, 0, -50);
// Change lerp or offset after starting follow
cam.setLerp(0.08, 0.08);
cam.setFollowOffset(0, -50);
// Dead zone: camera only scrolls when target leaves this rectangle
cam.setDeadzone(200, 150);
// Stop following
cam.stopFollow();startFollowxy10.10// 即时跟随(插值系数=1,默认值)
cam.startFollow(player);
// 平滑跟随(插值系数0..1,值越小越平滑)
cam.startFollow(player, false, 0.1, 0.1);
// 完整签名:
// startFollow(target, roundPixels?, lerpX?, lerpY?, offsetX?, offsetY?)
cam.startFollow(player, true, 0.05, 0.05, 0, -50);
// 开始跟随后修改插值系数或偏移量
cam.setLerp(0.08, 0.08);
cam.setFollowOffset(0, -50);
// 死区:仅当目标离开该矩形时相机才滚动
cam.setDeadzone(200, 150);
// 停止跟随
cam.stopFollow();startFollowxy// Uniform zoom
cam.setZoom(2); // 2x zoom in
cam.setZoom(0.5); // zoom out (see twice as much)
// Independent horizontal/vertical zoom
cam.setZoom(2, 1); // stretch horizontally
// Read current zoom
cam.zoom; // shortcut -- reads zoomX (assumes uniform)
cam.zoomX;
cam.zoomY;// 等比缩放
cam.setZoom(2); // 放大2倍
cam.setZoom(0.5); // 缩小(显示2倍内容)
// 独立的水平/垂直缩放
cam.setZoom(2, 1); // 水平拉伸
// 读取当前缩放值
cam.zoom; // 快捷方式——读取zoomX(假设是等比缩放)
cam.zoomX;
cam.zoomY;// Constrain scrolling to a world area
cam.setBounds(0, 0, worldWidth, worldHeight);
// Center on the new bounds immediately
cam.setBounds(0, 0, 2048, 2048, true);
// Temporarily disable bounds without removing them
cam.useBounds = false;
// Remove bounds entirely
cam.removeBounds();
// Read the current bounds
const rect = cam.getBounds(); // returns a new Rectangle copy// 将滚动限制在指定世界区域内
cam.setBounds(0, 0, worldWidth, worldHeight);
// 立即居中到新边界
cam.setBounds(0, 0, 2048, 2048, true);
// 临时禁用边界但不删除
cam.useBounds = false;
// 完全移除边界
cam.removeBounds();
// 读取当前边界
const rect = cam.getBounds(); // 返回新的Rectangle副本// Full-screen main camera
const main = this.cameras.main;
// Mini-map in top-right corner
const minimap = this.cameras.add(600, 0, 200, 150).setZoom(0.2).setName('minimap');
minimap.setScroll(0, 0);
minimap.setBackgroundColor('rgba(0,0,0,0.5)');
// HUD camera that doesn't scroll (ignores world objects, shows HUD layer only)
const hudCam = this.cameras.add(0, 0, 800, 600).setName('hud');
hudCam.setScroll(0, 0);
// Make the main camera ignore HUD objects
main.ignore(hudGroup);
// Make the HUD camera ignore world objects
hudCam.ignore(worldGroup);
// Find a camera by name
const found = this.cameras.getCamera('minimap');
// Remove a camera
this.cameras.remove(minimap);// 全屏主相机
const main = this.cameras.main;
// 右上角的小地图
const minimap = this.cameras.add(600, 0, 200, 150).setZoom(0.2).setName('minimap');
minimap.setScroll(0, 0);
minimap.setBackgroundColor('rgba(0,0,0,0.5)');
// 不滚动的HUD相机(忽略世界对象,仅显示HUD层)
const hudCam = this.cameras.add(0, 0, 800, 600).setName('hud');
hudCam.setScroll(0, 0);
// 让主相机忽略HUD对象
main.ignore(hudGroup);
// 让HUD相机忽略世界对象
hudCam.ignore(worldGroup);
// 通过名称查找相机
const found = this.cameras.getCamera('minimap');
// 移除相机
this.cameras.remove(minimap);CameraBaseCamerathisforce: trueCameraBaseCamerathisforce: true// Fade out to black over 1 second
cam.fadeOut(1000);
// Fade out to red
cam.fadeOut(1000, 255, 0, 0);
// Fade in from black over 500ms
cam.fadeIn(500);
// Lower-level: fade (out direction) and fadeFrom (in direction)
// with a force parameter
cam.fade(1000, 0, 0, 0, true); // force start even if running
cam.fadeFrom(1000, 0, 0, 0, true);
// With per-frame callback
cam.fadeOut(1000, 0, 0, 0, (cam, progress) => {
// progress goes from 0 to 1
});fadeOutfadefadeInfadeFrom// 1秒内淡出至黑色
cam.fadeOut(1000);
// 淡出至红色
cam.fadeOut(1000, 255, 0, 0);
// 500毫秒内从黑色淡入
cam.fadeIn(500);
// 底层方法:fade(淡出方向)和fadeFrom(淡入方向)
// 带有force参数
cam.fade(1000, 0, 0, 0, true); // 强制启动,即使已在运行
cam.fadeFrom(1000, 0, 0, 0, true);
// 带每帧回调
cam.fadeOut(1000, 0, 0, 0, (cam, progress) => {
// progress从0到1
});fadeOutfadefadeInfadeFrom// White flash over 250ms (default)
cam.flash(250);
// Red flash over 500ms
cam.flash(500, 255, 0, 0);
// Full signature: flash(duration?, r?, g?, b?, force?, callback?, context?)
cam.flash(300, 255, 255, 255, true, (cam, progress) => {});// 默认闪烁:250毫秒白色闪烁(默认值)
cam.flash(250);
// 500毫秒红色闪烁
cam.flash(500, 255, 0, 0);
// 完整签名:flash(duration?, r?, g?, b?, force?, callback?, context?)
cam.flash(300, 255, 255, 255, true, (cam, progress) => {});// Default shake: 100ms at intensity 0.05
cam.shake(100);
// Stronger shake for 500ms
cam.shake(500, 0.02);
// Independent x/y intensity using a Vector2
cam.shake(300, new Phaser.Math.Vector2(0.1, 0.02));
// Full signature: shake(duration?, intensity?, force?, callback?, context?)intensity// 默认震动:100毫秒,强度0.05
cam.shake(100);
// 更强的震动,持续500毫秒
cam.shake(500, 0.02);
// 使用Vector2设置独立的x/y轴强度
cam.shake(300, new Phaser.Math.Vector2(0.1, 0.02));
// 完整签名:shake(duration?, intensity?, force?, callback?, context?)intensity// Pan camera center to world coordinate (400, 300) over 2 seconds
cam.pan(400, 300, 2000);
// With easing
cam.pan(400, 300, 2000, 'Power2');
// Full signature: pan(x, y, duration?, ease?, force?, callback?, context?)
cam.pan(800, 600, 1500, 'Sine.easeInOut', false, (cam, progress, x, y) => {});// 2秒内将相机中心平移到世界坐标(400, 300)
cam.pan(400, 300, 2000);
// 带缓动效果
cam.pan(400, 300, 2000, 'Power2');
// 完整签名:pan(x, y, duration?, ease?, force?, callback?, context?)
cam.pan(800, 600, 1500, 'Sine.easeInOut', false, (cam, progress, x, y) => {});// Animate zoom to 2x over 1 second
cam.zoomTo(2, 1000);
// With easing
cam.zoomTo(0.5, 2000, 'Cubic.easeOut');
// Full signature: zoomTo(zoom, duration?, ease?, force?, callback?, context?)// 1秒内动画缩放至2倍
cam.zoomTo(2, 1000);
// 带缓动效果
cam.zoomTo(0.5, 2000, 'Cubic.easeOut');
// 完整签名:zoomTo(zoom, duration?, ease?, force?, callback?, context?)// Rotate camera to 45 degrees (in radians) over 1 second
cam.rotateTo(Phaser.Math.DegToRad(45), false, 1000);
// Shortest path rotation
cam.rotateTo(Math.PI, true, 1500, 'Quad.easeInOut');
// Full signature: rotateTo(angle, shortestPath?, duration?, ease?, force?, callback?, context?)shortestPathtrue// 1秒内将相机旋转到45度(弧度)
cam.rotateTo(Phaser.Math.DegToRad(45), false, 1000);
// 最短路径旋转
cam.rotateTo(Math.PI, true, 1500, 'Quad.easeInOut');
// 完整签名:rotateTo(angle, shortestPath?, duration?, ease?, force?, callback?, context?)shortestPathtruecam.resetFX(); // stops and resets all running effects (rotate, pan, shake, flash, fade)cam.resetFX(); // 停止并重置所有运行中的特效(旋转、平移、震动、闪烁、淡入淡出)update(delta)updateupdateupdate(delta)// In create():
const cursors = this.input.keyboard.createCursorKeys();
this.camControl = new Phaser.Cameras.Controls.FixedKeyControl({
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
speed: 0.5 // can also be { x: 0.5, y: 0.3 }
});
// In update(time, delta):
this.camControl.update(delta);// 在create()中:
const cursors = this.input.keyboard.createCursorKeys();
this.camControl = new Phaser.Cameras.Controls.FixedKeyControl({
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
speed: 0.5 // 也可以是 { x: 0.5, y: 0.3 }
});
// 在update(time, delta)中:
this.camControl.update(delta);this.camControl = new Phaser.Cameras.Controls.SmoothedKeyControl({
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
zoomIn: this.input.keyboard.addKey('Q'),
zoomOut: this.input.keyboard.addKey('E'),
zoomSpeed: 0.02,
acceleration: 0.06,
drag: 0.0005,
maxSpeed: 1.0
});
// In update(time, delta):
this.camControl.update(delta);zoomInzoomOutzoomSpeedthis.camControl = new Phaser.Cameras.Controls.SmoothedKeyControl({
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
zoomIn: this.input.keyboard.addKey('Q'),
zoomOut: this.input.keyboard.addKey('E'),
zoomSpeed: 0.02,
acceleration: 0.06,
drag: 0.0005,
maxSpeed: 1.0
});
// 在update(time, delta)中:
this.camControl.update(delta);zoomInzoomOutzoomSpeedignorecameraFilter// Ignore a single object
cam.ignore(uiText);
// Ignore an array
cam.ignore([scoreText, livesIcon, pauseButton]);
// Ignore all children in a Group
cam.ignore(uiGroup);
// Ignore a Layer and all its children
cam.ignore(uiLayer);ignorecameraFilter// 忽略单个对象
cam.ignore(uiText);
// 忽略数组中的对象
cam.ignore([scoreText, livesIcon, pauseButton]);
// 忽略组中的所有子对象
cam.ignore(uiGroup);
// 忽略图层及其所有子对象
cam.ignore(uiLayer);// Set a deadzone of 200x150 pixels centered on the camera viewport
cam.setDeadzone(200, 150);
// Access the deadzone rectangle (read-only, updated internally)
console.log(cam.deadzone); // Phaser.Geom.Rectangle or null
// Remove the deadzone
cam.setDeadzone();// 设置一个200x150像素的死区,居中于相机视口
cam.setDeadzone(200, 150);
// 访问死区矩形(只读,内部自动更新)
console.log(cam.deadzone); // Phaser.Geom.Rectangle或null
// 移除死区
cam.setDeadzone();const worldPoint = cam.getWorldPoint(pointer.x, pointer.y);
// Reuse an output object to avoid allocation
const output = new Phaser.Math.Vector2();
cam.getWorldPoint(pointer.x, pointer.y, output);const worldPoint = cam.getWorldPoint(pointer.x, pointer.y);
// 重用输出对象以避免内存分配
const output = new Phaser.Math.Vector2();
cam.getWorldPoint(pointer.x, pointer.y, output);renderListconst visible = cam.renderList; // array of GameObjects rendered this framerenderListconst visible = cam.renderList; // 本帧渲染的GameObject数组CaptureFramecam.setForceComposite(true); // enable offscreen framebuffer
cam.setForceComposite(false); // disablesetForceComposite(true)CaptureFramecam.setForceComposite(true); // 启用离屏帧缓冲
cam.setForceComposite(false); // 禁用setForceComposite(true)CamerafiltersFilterListcam.filters.internal // FilterList -- applied by the system
cam.filters.external // FilterList -- for user-added filters// Add a blur filter to the camera
cam.filters.external.addBlur(1, 2);
// Add a glow
cam.filters.external.addGlow(0xff0000, 4, 0, false, 0.1, 10);
// Add a color matrix filter
const fx = cam.filters.external.addColorMatrix();
fx.grayscale();
// Remove all external filters
cam.filters.external.clear();setForceComposite(true)CamerafiltersFilterListcam.filters.internal // FilterList——系统应用的滤镜
cam.filters.external // FilterList——用户添加的滤镜// 为相机添加模糊滤镜
cam.filters.external.addBlur(1, 2);
// 添加发光效果
cam.filters.external.addGlow(0xff0000, 4, 0, false, 0.1, 10);
// 添加颜色矩阵滤镜
const fx = cam.filters.external.addColorMatrix();
fx.grayscale();
// 移除所有外部滤镜
cam.filters.external.clear();setForceComposite(true)EventEmittercam.on(event, handler)| Event constant | Dispatched when |
|---|---|
| |
| Fade-in finishes |
| |
| Fade-out finishes |
| Flash begins |
| Flash finishes |
| Shake begins |
| Shake finishes |
| Pan begins |
| Pan finishes |
| Zoom effect begins |
| Zoom effect finishes |
| RotateTo begins |
| RotateTo finishes |
| Camera updates its follow position (each frame while following). Args: |
| Before the camera renders |
| After the camera renders |
| Camera is destroyed |
cam.on(Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE, () => {
this.scene.start('GameOver');
});EventEmittercam.on(event, handler)| 事件常量 | 触发时机 |
|---|---|
| |
| 淡入完成时 |
| |
| 淡出完成时 |
| 闪烁开始时 |
| 闪烁完成时 |
| 震动开始时 |
| 震动完成时 |
| 平移开始时 |
| 平移完成时 |
| 缩放特效开始时 |
| 缩放特效完成时 |
| RotateTo开始时 |
| RotateTo完成时 |
| 相机更新跟随位置时(跟随期间每帧触发)。参数: |
| 相机渲染前 |
| 相机渲染后 |
| 相机被销毁时 |
cam.on(Phaser.Cameras.Scene2D.Events.FADE_OUT_COMPLETE, () => {
this.scene.start('GameOver');
});