Phaser 输入处理 #
输入系统概述 #
Phaser 提供了统一的输入系统,支持键盘、鼠标、触摸和游戏手柄等多种输入设备。
text
┌─────────────────────────────────────────────────────────────┐
│ 输入系统架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Input Manager │
│ ├── Keyboard │
│ │ ├── Keys │
│ │ └── Combos │
│ ├── Pointer │
│ │ ├── Mouse │
│ │ └── Touch │
│ ├── Gamepad │
│ │ ├── Pads │
│ │ └── Buttons │
│ └── Interactive Objects │
│ ├── Sprites │
│ └── Zones │
│ │
└─────────────────────────────────────────────────────────────┘
键盘输入 #
方向键 #
javascript
create() {
this.cursors = this.input.keyboard.createCursorKeys();
}
update() {
if (this.cursors.left.isDown) {
console.log('Left arrow pressed');
}
if (this.cursors.right.isDown) {
console.log('Right arrow pressed');
}
if (this.cursors.up.isDown) {
console.log('Up arrow pressed');
}
if (this.cursors.down.isDown) {
console.log('Down arrow pressed');
}
}
自定义按键 #
javascript
create() {
this.keyW = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W);
this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
this.keyS = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S);
this.keyD = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
this.enterKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ENTER);
}
update() {
if (Phaser.Input.Keyboard.JustDown(this.keyW)) {
console.log('W key just pressed');
}
if (this.keyA.isDown) {
console.log('A key is down');
}
if (Phaser.Input.Keyboard.JustUp(this.keyS)) {
console.log('S key just released');
}
}
按键码 #
javascript
Phaser.Input.Keyboard.KeyCodes.A
Phaser.Input.Keyboard.KeyCodes.B
Phaser.Input.Keyboard.KeyCodes.SPACE
Phaser.Input.Keyboard.KeyCodes.ENTER
Phaser.Input.Keyboard.KeyCodes.ESC
Phaser.Input.Keyboard.KeyCodes.SHIFT
Phaser.Input.Keyboard.KeyCodes.CONTROL
Phaser.Input.Keyboard.KeyCodes.ALT
Phaser.Input.Keyboard.KeyCodes.ONE
Phaser.Input.Keyboard.KeyCodes.F1
Phaser.Input.Keyboard.KeyCodes.BACKSPACE
Phaser.Input.Keyboard.KeyCodes.DELETE
Phaser.Input.Keyboard.KeyCodes.TAB
批量添加按键 #
javascript
create() {
this.keys = this.input.keyboard.addKeys({
up: Phaser.Input.Keyboard.KeyCodes.W,
down: Phaser.Input.Keyboard.KeyCodes.S,
left: Phaser.Input.Keyboard.KeyCodes.A,
right: Phaser.Input.Keyboard.KeyCodes.D,
space: Phaser.Input.Keyboard.KeyCodes.SPACE
});
}
update() {
if (this.keys.left.isDown) {
this.player.x -= 5;
}
if (this.keys.right.isDown) {
this.player.x += 5;
}
if (Phaser.Input.Keyboard.JustDown(this.keys.space)) {
this.player.jump();
}
}
键盘事件 #
javascript
create() {
this.input.keyboard.on('keydown', (event) => {
console.log('Key down:', event.key, event.keyCode);
});
this.input.keyboard.on('keyup', (event) => {
console.log('Key up:', event.key, event.keyCode);
});
this.input.keyboard.on('keydown-A', (event) => {
console.log('A key pressed');
});
this.input.keyboard.on('keydown-SPACE', (event) => {
console.log('Space pressed');
});
}
组合键 #
javascript
create() {
this.keyA = this.input.keyboard.addKey('A');
this.keyB = this.input.keyboard.addKey('B');
}
update() {
if (this.keyA.isDown && this.keyB.isDown) {
console.log('A + B combo!');
}
const shiftKey = this.input.keyboard.addKey('SHIFT');
if (shiftKey.isDown && Phaser.Input.Keyboard.JustDown(this.keyA)) {
console.log('Shift + A combo!');
}
}
捕获按键 #
javascript
create() {
this.input.keyboard.addCapture([
Phaser.Input.Keyboard.KeyCodes.SPACE,
Phaser.Input.Keyboard.KeyCodes.UP,
Phaser.Input.Keyboard.KeyCodes.DOWN
]);
this.input.keyboard.addCapture('W,A,S,D');
}
removeCapture() {
this.input.keyboard.removeCapture(Phaser.Input.Keyboard.KeyCodes.SPACE);
}
禁用/启用键盘 #
javascript
this.input.keyboard.enabled = false;
this.input.keyboard.enabled = true;
this.input.keyboard.disableGlobalCapture();
this.input.keyboard.enableGlobalCapture();
鼠标输入 #
鼠标指针 #
javascript
create() {
this.input.on('pointerdown', (pointer) => {
console.log('Mouse down at:', pointer.x, pointer.y);
console.log('Button:', pointer.leftButtonDown(), pointer.rightButtonDown());
});
this.input.on('pointerup', (pointer) => {
console.log('Mouse up at:', pointer.x, pointer.y);
});
this.input.on('pointermove', (pointer) => {
console.log('Mouse moved to:', pointer.x, pointer.y);
});
this.input.on('pointerover', (pointer) => {
console.log('Pointer entered game');
});
this.input.on('pointerout', (pointer) => {
console.log('Pointer left game');
});
}
鼠标按钮 #
javascript
this.input.on('pointerdown', (pointer) => {
if (pointer.leftButtonDown()) {
console.log('Left button');
}
if (pointer.rightButtonDown()) {
console.log('Right button');
}
if (pointer.middleButtonDown()) {
console.log('Middle button');
}
if (pointer.backButtonDown()) {
console.log('Back button');
}
if (pointer.forwardButtonDown()) {
console.log('Forward button');
}
});
this.input.on('wheel', (pointer, deltaX, deltaY, deltaZ) => {
console.log('Wheel:', deltaY);
if (deltaY > 0) {
console.log('Scrolling down');
} else {
console.log('Scrolling up');
}
});
指针属性 #
javascript
this.input.on('pointerdown', (pointer) => {
console.log('Position:', pointer.x, pointer.y);
console.log('World position:', pointer.worldX, pointer.worldY);
console.log('Previous position:', pointer.prevPosition.x, pointer.prevPosition.y);
console.log('Velocity:', pointer.velocity.x, pointer.velocity.y);
console.log('Delta:', pointer.deltaX, pointer.deltaY);
console.log('Duration:', pointer.getDuration());
console.log('Distance:', pointer.getDistance());
console.log('Angle:', pointer.angle);
console.log('Is down:', pointer.isDown);
console.log('Buttons:', pointer.buttons);
});
多指针 #
javascript
const config = {
input: {
activePointers: 3
}
};
create() {
this.input.on('pointerdown', (pointer) => {
console.log('Pointer ID:', pointer.id);
});
const pointer1 = this.input.pointer1;
const pointer2 = this.input.pointer2;
console.log('Pointer 1:', pointer1.x, pointer1.y);
console.log('Pointer 2:', pointer2.x, pointer2.y);
}
触摸输入 #
触摸事件 #
javascript
create() {
this.input.on('pointerdown', (pointer) => {
console.log('Touch started');
});
this.input.on('pointermove', (pointer) => {
console.log('Touch moved');
});
this.input.on('pointerup', (pointer) => {
console.log('Touch ended');
});
this.input.on('gameover', (pointer) => {
console.log('Pointer left game area');
});
this.input.on('gameout', (pointer) => {
console.log('Pointer entered game area');
});
}
多点触控 #
javascript
const config = {
input: {
activePointers: 4,
touch: {
capture: true
}
}
};
create() {
this.input.on('pointerdown', (pointer) => {
console.log(`Touch ${pointer.id} at ${pointer.x}, ${pointer.y}`);
});
this.input.addPointer(3);
}
update() {
const pointers = this.input.manager.pointers;
pointers.forEach((pointer, index) => {
if (pointer.isDown) {
console.log(`Pointer ${index}: ${pointer.x}, ${pointer.y}`);
}
});
}
手势识别 #
javascript
create() {
this.input.on('pointerdown', (pointer) => {
this.touchStartX = pointer.x;
this.touchStartY = pointer.y;
this.touchStartTime = this.time.now;
});
this.input.on('pointerup', (pointer) => {
const deltaX = pointer.x - this.touchStartX;
const deltaY = pointer.y - this.touchStartY;
const deltaTime = this.time.now - this.touchStartTime;
if (Math.abs(deltaX) > 50 && Math.abs(deltaY) < 30) {
if (deltaX > 0) {
console.log('Swipe right');
} else {
console.log('Swipe left');
}
}
if (Math.abs(deltaY) > 50 && Math.abs(deltaX) < 30) {
if (deltaY > 0) {
console.log('Swipe down');
} else {
console.log('Swipe up');
}
}
if (deltaTime < 200 && Math.abs(deltaX) < 10 && Math.abs(deltaY) < 10) {
console.log('Tap');
}
if (deltaTime > 500 && Math.abs(deltaX) < 10 && Math.abs(deltaY) < 10) {
console.log('Long press');
}
});
}
捏合缩放 #
javascript
create() {
this.input.on('pointermove', this.handlePinch, this);
}
handlePinch(pointer) {
if (this.input.pointer1.isDown && this.input.pointer2.isDown) {
const p1 = this.input.pointer1;
const p2 = this.input.pointer2;
const distance = Phaser.Math.Distance.Between(p1.x, p1.y, p2.x, p2.y);
if (this.lastPinchDistance) {
const scale = distance / this.lastPinchDistance;
this.camera.zoom *= scale;
}
this.lastPinchDistance = distance;
}
}
游戏对象交互 #
启用交互 #
javascript
create() {
const sprite = this.add.sprite(400, 300, 'button');
sprite.setInteractive();
sprite.setInteractive({
useHandCursor: true,
pixelPerfect: true,
alphaTolerance: 1
});
sprite.setInteractive(new Phaser.Geom.Rectangle(0, 0, 100, 50), Phaser.Geom.Rectangle.Contains);
sprite.setInteractive(new Phaser.Geom.Circle(50, 50, 50), Phaser.Geom.Circle.Contains);
}
交互事件 #
javascript
const sprite = this.add.sprite(400, 300, 'button').setInteractive();
sprite.on('pointerdown', (pointer, localX, localY, event) => {
console.log('Clicked on sprite');
console.log('Local coordinates:', localX, localY);
});
sprite.on('pointerup', (pointer, localX, localY, event) => {
console.log('Released on sprite');
});
sprite.on('pointerover', (pointer, localX, localY, event) => {
sprite.setTint(0xcccccc);
});
sprite.on('pointerout', (pointer, event) => {
sprite.clearTint();
});
sprite.on('pointermove', (pointer, localX, localY, event) => {
console.log('Moving over sprite');
});
sprite.on('wheel', (pointer, deltaX, deltaY, deltaZ, event) => {
console.log('Wheel on sprite:', deltaY);
});
拖拽功能 #
javascript
const sprite = this.add.sprite(400, 300, 'draggable')
.setInteractive({ draggable: true });
this.input.setDraggable(sprite);
this.input.on('dragstart', (pointer, gameObject) => {
gameObject.setTint(0xff0000);
});
this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragend', (pointer, gameObject) => {
gameObject.clearTint();
});
this.input.on('dragenter', (pointer, gameObject, dropZone) => {
console.log('Entered drop zone');
});
this.input.on('dragleave', (pointer, gameObject, dropZone) => {
console.log('Left drop zone');
});
this.input.on('drop', (pointer, gameObject, dropZone) => {
console.log('Dropped on zone');
});
拖拽区域限制 #
javascript
const sprite = this.add.sprite(400, 300, 'draggable')
.setInteractive({ draggable: true });
this.input.setDraggable(sprite);
this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
dragX = Phaser.Math.Clamp(dragX, 50, 750);
dragY = Phaser.Math.Clamp(dragY, 50, 550);
gameObject.x = dragX;
gameObject.y = dragY;
});
放置区域 #
javascript
const zone = this.add.zone(600, 300, 100, 100)
.setRectangleDropZone(100, 100);
const graphics = this.add.graphics();
graphics.lineStyle(2, 0xffff00);
graphics.strokeRect(zone.x - 50, zone.y - 50, 100, 100);
const sprite = this.add.sprite(100, 300, 'item')
.setInteractive({ draggable: true });
this.input.setDraggable(sprite);
this.input.on('drop', (pointer, gameObject, dropZone) => {
gameObject.x = dropZone.x;
gameObject.y = dropZone.y;
});
游戏手柄 #
检测手柄 #
javascript
create() {
this.input.gamepad.once('connected', (pad) => {
console.log('Gamepad connected:', pad.id);
this.gamepad = pad;
});
if (this.input.gamepad.total > 0) {
this.gamepad = this.input.gamepad.getPad(0);
}
}
手柄按钮 #
javascript
update() {
if (this.gamepad) {
if (this.gamepad.A) {
console.log('A button pressed');
}
if (this.gamepad.B) {
console.log('B button pressed');
}
if (this.gamepad.X) {
console.log('X button pressed');
}
if (this.gamepad.Y) {
console.log('Y button pressed');
}
if (this.gamepad.left) {
console.log('D-pad left');
}
if (this.gamepad.right) {
console.log('D-pad right');
}
if (this.gamepad.up) {
console.log('D-pad up');
}
if (this.gamepad.down) {
console.log('D-pad down');
}
}
}
摇杆 #
javascript
update() {
if (this.gamepad) {
const leftStick = this.gamepad.leftStick;
console.log('Left stick:', leftStick.x, leftStick.y);
const rightStick = this.gamepad.rightStick;
console.log('Right stick:', rightStick.x, rightStick.y);
if (Math.abs(leftStick.x) > 0.1) {
this.player.setVelocityX(leftStick.x * 200);
}
if (Math.abs(leftStick.y) > 0.1) {
this.player.setVelocityY(leftStick.y * 200);
}
}
}
手柄事件 #
javascript
create() {
this.input.gamepad.on('down', (pad, button, index) => {
console.log('Button down:', index);
});
this.input.gamepad.on('up', (pad, button, index) => {
console.log('Button up:', index);
});
this.input.gamepad.on('A', (value) => {
console.log('A button:', value);
});
}
update() {
if (this.gamepad) {
const leftTrigger = this.gamepad.L2;
const rightTrigger = this.gamepad.R2;
if (leftTrigger > 0) {
console.log('Left trigger:', leftTrigger);
}
}
}
虚拟控制器 #
创建虚拟摇杆 #
javascript
class VirtualJoystick extends Phaser.GameObjects.Container {
constructor(scene, x, y, radius) {
super(scene, x, y);
this.radius = radius;
this.base = scene.add.circle(0, 0, radius, 0x000000, 0.5);
this.thumb = scene.add.circle(0, 0, radius * 0.4, 0xffffff, 0.8);
this.add([this.base, this.thumb]);
this.pointer = null;
this.vector = { x: 0, y: 0 };
this.setInteractive(new Phaser.Geom.Circle(0, 0, radius), Phaser.Geom.Circle.Contains);
this.on('pointerdown', this.startDrag, this);
scene.input.on('pointermove', this.drag, this);
scene.input.on('pointerup', this.endDrag, this);
}
startDrag(pointer) {
this.pointer = pointer;
}
drag(pointer) {
if (this.pointer !== pointer) return;
const dx = pointer.x - this.x;
const dy = pointer.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.radius) {
this.thumb.setPosition(dx, dy);
this.vector.x = dx / this.radius;
this.vector.y = dy / this.radius;
} else {
const angle = Math.atan2(dy, dx);
this.thumb.setPosition(
Math.cos(angle) * this.radius,
Math.sin(angle) * this.radius
);
this.vector.x = Math.cos(angle);
this.vector.y = Math.sin(angle);
}
}
endDrag(pointer) {
if (this.pointer !== pointer) return;
this.pointer = null;
this.thumb.setPosition(0, 0);
this.vector.x = 0;
this.vector.y = 0;
}
}
create() {
this.joystick = new VirtualJoystick(this, 100, 500, 50);
this.add.existing(this.joystick);
}
update() {
if (this.joystick.vector.x !== 0 || this.joystick.vector.y !== 0) {
this.player.setVelocity(
this.joystick.vector.x * 200,
this.joystick.vector.y * 200
);
}
}
创建虚拟按钮 #
javascript
class VirtualButton extends Phaser.GameObjects.Container {
constructor(scene, x, y, key, label) {
super(scene, x, y);
this.key = key;
this.isPressed = false;
this.circle = scene.add.circle(0, 0, 30, 0x444444, 0.8);
this.text = scene.add.text(0, 0, label, {
fontSize: '20px',
fill: '#ffffff'
}).setOrigin(0.5);
this.add([this.circle, this.text]);
this.setInteractive(new Phaser.Geom.Circle(0, 0, 30), Phaser.Geom.Circle.Contains);
this.on('pointerdown', () => {
this.isPressed = true;
this.circle.setFillStyle(0x888888, 0.8);
});
this.on('pointerup', () => {
this.isPressed = false;
this.circle.setFillStyle(0x444444, 0.8);
});
this.on('pointerout', () => {
this.isPressed = false;
this.circle.setFillStyle(0x444444, 0.8);
});
}
}
create() {
this.jumpButton = new VirtualButton(this, 700, 500, 'jump', 'A');
this.add.existing(this.jumpButton);
}
update() {
if (this.jumpButton.isPressed) {
this.player.jump();
}
}
输入配置 #
全局配置 #
javascript
const config = {
input: {
keyboard: true,
mouse: true,
touch: true,
gamepad: true,
activePointers: 1
}
};
触摸配置 #
javascript
const config = {
input: {
touch: {
capture: true,
target: null
}
}
};
完整示例 #
移动控制 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.player = this.physics.add.sprite(400, 300, 'player');
this.cursors = this.input.keyboard.createCursorKeys();
this.wasd = this.input.keyboard.addKeys({
up: Phaser.Input.Keyboard.KeyCodes.W,
down: Phaser.Input.Keyboard.KeyCodes.S,
left: Phaser.Input.Keyboard.KeyCodes.A,
right: Phaser.Input.Keyboard.KeyCodes.D
});
this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
this.input.on('pointerdown', (pointer) => {
this.player.setPosition(pointer.x, pointer.y);
});
}
update() {
const speed = 200;
if (this.cursors.left.isDown || this.wasd.left.isDown) {
this.player.setVelocityX(-speed);
} else if (this.cursors.right.isDown || this.wasd.right.isDown) {
this.player.setVelocityX(speed);
} else {
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown || this.wasd.up.isDown) {
this.player.setVelocityY(-speed);
} else if (this.cursors.down.isDown || this.wasd.down.isDown) {
this.player.setVelocityY(speed);
} else {
this.player.setVelocityY(0);
}
if (Phaser.Input.Keyboard.JustDown(this.spaceKey)) {
this.player.jump();
}
}
}
下一步 #
现在你已经掌握了输入处理,接下来学习 物理引擎,了解如何使用物理引擎实现碰撞和运动!
最后更新:2026-03-29