在上一节中,我们介绍了如何在Phaser引擎中处理用户输入的基本方法。现在,我们将通过具体的案例来深入理解和实践用户输入与交互的实现。通过这些案例,你将能够掌握更复杂的输入处理技术,如多点触控、游戏手柄支持、键盘和鼠标组合输入等。
实现一个简单的射击游戏,玩家可以通过鼠标点击屏幕来发射子弹,击中移动的敌人目标。
首先,我们需要创建一个Phaser游戏实例,并设置基本的游戏场景。
// 引入Phaser引擎
import Phaser from 'phaser';
// 创建游戏配置
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
// 创建游戏实例
const game = new Phaser.Game(config);
// 预加载资源
function preload() {
this.load.image('player', 'assets/player.png');
this.load.image('bullet', 'assets/bullet.png');
this.load.image('enemy', 'assets/enemy.png');
}
// 创建游戏场景
function create() {
// 创建玩家
this.player = this.physics.add.sprite(400, 500, 'player');
this.player.setCollideWorldBounds(true);
// 创建子弹组
this.bullets = this.physics.add.group({
key: 'bullet',
maxSize: 10,
runChildUpdate: true
});
// 创建敌人组
this.enemies = this.physics.add.group({
key: 'enemy',
runChildUpdate: true
});
// 生成敌人
for (let i = 0; i < 10; i++) {
const enemy = this.enemies.create(Phaser.Math.Between(50, 750), Phaser.Math.Between(50, 150), 'enemy');
enemy.setVelocity(Phaser.Math.Between(-200, 200), Phaser.Math.Between(100, 300));
enemy.setCollideWorldBounds(true);
enemy.setBounce(1);
}
// 设置玩家射击
this.input.on('pointerdown', this.shootBullet, this);
}
// 更新游戏场景
function update(time, delta) {
// 更新子弹
this.bullets.children.iterate(function (bullet) {
if (bullet.active) {
bullet.setVelocityY(-400);
}
});
// 检测碰撞
this.physics.add.collider(this.bullets, this.enemies, this.hitEnemy, null, this);
}
// 射击子弹
function shootBullet(pointer) {
const bullet = this.bullets.get();
if (bullet) {
bullet.setActive(true);
bullet.setVisible(true);
bullet.setPosition(this.player.x, this.player.y);
}
}
// 敌人被击中
function hitEnemy(bullet, enemy) {
bullet.setActive(false);
bullet.setVisible(false);
enemy.destroy();
}
预加载资源:
this.load.image
方法用于加载图像资源,这里我们加载了玩家、子弹和敌人的图像。创建游戏场景:
this.player
创建了一个玩家角色,使用 setCollideWorldBounds
方法确保玩家不会移出屏幕边界。
this.bullets
和 this.enemies
分别创建了子弹和敌人的物理组,maxSize
设置了子弹组的最大大小,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
使用 for
循环生成10个敌人,每个敌人随机移动速度和方向,使用 setCollideWorldBounds
和 setBounce
方法确保敌人在屏幕内反弹。
设置玩家射击:
this.input.on
用于监听鼠标点击事件,当点击屏幕时调用 this.shootBullet
方法。更新游戏场景:
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
实现一个支持多点触控的游戏,玩家可以通过触摸屏幕上的多个点来控制多个角色的移动。
// 引入Phaser引擎
import Phaser from 'phaser';
// 创建游戏配置
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
// 创建游戏实例
const game = new Phaser.Game(config);
// 预加载资源
function preload() {
this.load.image('player', 'assets/player.png');
}
// 创建游戏场景
function create() {
// 创建角色组
this.players = this.physics.add.group({
key: 'player',
runChildUpdate: true
});
// 生成角色
for (let i = 0; i < 5; i++) {
const player = this.players.create(100 + i * 100, 500, 'player');
player.setCollideWorldBounds(true);
}
// 设置多点触控
this.input acknowlegeFirstPointer = false;
this.input.on('pointerdown', this.handleTouch, this);
this.input.on('pointerup', this.handleTouch, this);
this.input.on('pointermove', this.handleTouch, this);
}
// 更新游戏场景
function update(time, delta) {
// 更新角色
this.players.children.iterate(function (player) {
if (player.active) {
player.body.setVelocity(0);
}
});
}
// 处理触摸事件
function handleTouch(pointer) {
if (pointer.isDown) {
// 查找最近的角色
const closestPlayer = this.findClosestPlayer(pointer.x, pointer.y);
if (closestPlayer) {
closestPlayer.setVelocityX(Phaser.Math.Between(-200, 200));
closestPlayer.setVelocityY(Phaser.Math.Between(-200, 200));
}
} else {
// 停止角色移动
this.players.children.iterate(function (player) {
player.body.setVelocity(0);
});
}
}
// 查找最近的角色
function findClosestPlayer(x, y) {
let closestPlayer = null;
let closestDistance = Infinity;
this.players.children.iterate(function (player) {
const distance = Phaser.Math.Distance.Between(player.x, player.y, x, y);
if (distance < closestDistance) {
closestDistance = distance;
closestPlayer = player;
}
});
return closestPlayer;
}
预加载资源:
this.load.image
方法用于加载玩家的图像资源。创建游戏场景:
this.players
创建了一个角色组,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
使用 for
循环生成5个角色,每个角色的初始位置不同,确保它们不会重叠。
this.input.acknowledgeFirstPointer = false;
设置多点触控支持。
this.input.on
用于监听触摸事件,包括 pointerdown
、pointerup
和 pointermove
。
更新游戏场景:
this.players.children.iterate
遍历角色组中的每个角色,停止其移动。处理触摸事件:
pointer.isDown
判断触摸点是否按下,如果是则调用 findClosestPlayer
方法查找最近的角色并设置其移动速度。
pointer.isUp
判断触摸点是否抬起,如果是则停止所有角色的移动。
查找最近的角色:
Phaser.Math.Distance.Between
方法用于计算两个点之间的距离,查找离触摸点最近的角色并返回。实现一个支持游戏手柄的游戏,玩家可以通过手柄控制角色的移动和射击。
// 引入Phaser引擎
import Phaser from 'phaser';
// 创建游戏配置
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
// 创建游戏实例
const game = new Phaser.Game(config);
// 预加载资源
function preload() {
this.load.image('player', 'assets/player.png');
this.load.image('bullet', 'assets/bullet.png');
}
// 创建游戏场景
function create() {
// 创建玩家
this.player = this.physics.add.sprite(400, 500, 'player');
this.player.setCollideWorldBounds(true);
// 创建子弹组
this.bullets = this.physics.add.group({
key: 'bullet',
maxSize: 10,
runChildUpdate: true
});
// 初始化游戏手柄
this.input.gamepad.once('connected', (pad) => {
this.pad = pad;
});
// 设置玩家移动
this.input.gamepad.on('down', this.handleGamepad, this);
this.input.gamepad.on('up', this.handleGamepad, this);
}
// 更新游戏场景
function update(time, delta) {
// 检查手柄连接状态
if (this.pad) {
// 移动玩家
this.player.setVelocity(0);
if (this.pad.axes[0].value !== 0) {
this.player.setVelocityX(this.pad.axes[0].value * 200);
}
if (this.pad.axes[1].value !== 0) {
this.player.setVelocityY(this.pad.axes[1].value * 200);
}
// 射击
if (this.pad.A) {
this.shootBullet();
}
}
// 更新子弹
this.bullets.children.iterate(function (bullet) {
if (bullet.active) {
bullet.setVelocityY(-400);
}
});
// 检测碰撞
this.physics.add.collider(this.bullets, this.enemies, this.hitEnemy, null, this);
}
// 处理游戏手柄事件
function handleGamepad(button, pad, duration, value) {
if (button.index === 0 && value) {
this.shootBullet();
}
}
// 射击子弹
function shootBullet() {
const bullet = this.bullets.get();
if (bullet) {
bullet.setActive(true);
bullet.setVisible(true);
bullet.setPosition(this.player.x, this.player.y);
}
}
// 敌人被击中
function hitEnemy(bullet, enemy) {
bullet.setActive(false);
bullet.setVisible(false);
enemy.destroy();
}
更新游戏场景:
this.player.setVelocity(0);
用于重置玩家的移动速度,确保在没有按键按下时玩家停止移动。
if (this.cursors.left.isDown) { this.player.setVelocityX(-200); }
判断左箭头键是否按下,如果是则设置玩家的水平速度为-200,使其向左移动。
else if (this.cursors.right.isDown) { this.player.setVelocityX(200); }
判断右箭头键是否按下,如果是则设置玩家的水平速度为200,使其向右移动。
if (this.cursors.up.isDown) { this.player.setVelocityY(-200); }
判断上箭头键是否按下,如果是则设置玩家的垂直速度为-200,使其向上移动。
else if (this.cursors.down.isDown) { this.player.setVelocityY(200); }
判断下箭头键是否按下,如果是则设置玩家的垂直速度为200,使其向下移动。
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
用于根据玩家的朝向设置子弹的初始速度,使其沿玩家的朝向发射。
更新角色朝向:
const dx = pointer.x - this.player.x;
计算鼠标指针与玩家角色在水平方向上的差值。
const dy = pointer.y - this.player.y;
计算鼠标指针与玩家角色在垂直方向上的差值。
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
使用 Math.atan2
计算玩家角色与鼠标指针之间的角度,并将其转换为度数,设置玩家角色的朝向。
敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
实现一个支持键盘、鼠标和游戏手柄组合输入的游戏,玩家可以通过键盘控制角色的移动,通过鼠标点击发射子弹,通过鼠标移动调整角色的朝向,同时可以通过游戏手柄进行同样的操作。
// 引入Phaser引擎
import Phaser from 'phaser';
// 创建游戏配置
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
// 创建游戏实例
const game = new Phaser.Game(config);
// 预加载资源
function preload() {
this.load.image('player', 'assets/player.png');
this.load.image('bullet', 'assets/bullet.png');
}
// 创建游戏场景
function create() {
// 创建玩家
this.player = this.physics.add.sprite(400, 500, 'player');
this.player.setCollideWorldBounds(true);
// 创建子弹组
this.bullets = this.physics.add.group({
key: 'bullet',
maxSize: 10,
runChildUpdate: true
});
// 初始化键盘输入
this.cursors = this.input.keyboard.createCursorKeys();
// 初始化游戏手柄
this.input.gamepad.once('connected', (pad) => {
this.pad = pad;
});
// 设置射击
this.input.on('pointerdown', this.shootBullet, this);
this.input.gamepad.on('down', this.handleGamepad, this);
// 设置角色朝向
this.input.on('pointermove', this.updatePlayerDirection, this);
}
// 更新游戏场景
function update(time, delta) {
// 移动玩家
this.player.setVelocity(0);
if (this.cursors.left.isDown || (this.pad && this.pad.axes[0].value < -0.5)) {
this.player.setVelocityX(-200);
} else if (this.cursors.right.isDown || (this.pad && this.pad.axes[0].value > 0.5)) {
this.player.setVelocityX(200);
}
if (this.cursors.up.isDown || (this.pad && this.pad.axes[1].value < -0.5)) {
this.player.setVelocityY(-200);
} else if (this.cursors.down.isDown || (this.pad && this.pad.axes[1].value > 0.5)) {
this.player.setVelocityY(200);
}
// 更新子弹
this.bullets.children.iterate(function (bullet) {
if (bullet.active) {
bullet.setVelocityY(-400);
}
});
// 检测碰撞
this.physics.add.collider(this.bullets, this.enemies, this.hitEnemy, null, this);
}
// 射击子弹
function shootBullet(pointer) {
const bullet = this.bullets.get();
if (bullet) {
bullet.setActive(true);
bullet.setVisible(true);
bullet.setPosition(this.player.x, this.player.y);
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
}
}
// 更新角色朝向
function updatePlayerDirection(pointer) {
const dx = pointer.x - this.player.x;
const dy = pointer.y - this.player.y;
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
}
// 处理游戏手柄事件
function handleGamepad(button, pad, duration, value) {
if (button.index === 0 && value) {
this.shootBullet();
}
}
// 敌人被击中
function hitEnemy(bullet, enemy) {
bullet.setActive(false);
bullet.setVisible(false);
enemy.destroy();
}
预加载资源:
this.load.image
方法用于加载玩家和子弹的图像资源。创建游戏场景:
this.player
创建了一个玩家角色,使用 setCollideWorldBounds
方法确保玩家不会移出屏幕边界。
this.bullets
创建了子弹组,maxSize
设置了子弹组的最大大小,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
this.input.keyboard.createCursorKeys()
用于初始化键盘输入,包括上下左右键。
this.input.gamepad.once('connected', (pad) => { this.pad = pad; });
用于监听手柄连接事件并初始化手柄。
this.input.on('pointerdown', this.shootBullet, this);
用于监听鼠标点击事件,当点击屏幕时调用 this.shootBullet
方法。
this.input.gamepad.on('down', this.handleGamepad, this);
用于监听手柄按钮按下事件,当按下A按钮时调用 this.shootBullet
方法。
this.input.on('pointermove', this.updatePlayerDirection, this);
用于监听鼠标移动事件,当鼠标移动时调用 this.updatePlayerDirection
方法。
更新游戏场景:
this.player.setVelocity(0);
用于重置玩家的移动速度,确保在没有按键按下时玩家停止移动。
if (this.cursors.left.isDown || (this.pad && this.pad.axes[0].value < -0.5)) { this.player.setVelocityX(-200); }
判断左箭头键或手柄左摇杆是否向左偏移,如果是则设置玩家的水平速度为-200,使其向左移动。
else if (this.cursors.right.isDown || (this.pad && this.pad.axes[0].value > 0.5)) { this.player.setVelocityX(200); }
判断右箭头键或手柄左摇杆是否向右偏移,如果是则设置玩家的水平速度为200,使其向右移动。
if (this.cursors.up.isDown || (this.pad && this.pad.axes[1].value < -0.5)) { this.player.setVelocityY(-200); }
判断上箭头键或手柄左摇杆是否向上偏移,如果是则设置玩家的垂直速度为-200,使其向上移动。
else if (this.cursors.down.isDown || (this.pad && this.pad.axes[1].value > 0.5)) { this.player.setVelocityY(200); }
判断下箭头键或手柄左摇杆是否向下偏移,如果是则设置玩家的垂直速度为200,使其向下移动。
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
用于根据玩家的朝向设置子弹的初始速度,使其沿玩家的朝向发射。
更新角色朝向:
const dx = pointer.x - this.player.x;
计算鼠标指针与玩家角色在水平方向上的差值。
const dy = pointer.y - this.player.y;
计算鼠标指针与玩家角色在垂直方向上的差值。
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
使用 Math.atan2
计算玩家角色与鼠标指针之间的角度,并将其转换为度数,设置玩家角色的朝向。
处理游戏手柄事件:
button.index === 0 && value
判断A按钮是否按下,如果是则调用 this.shootBullet
方法发射子弹。敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
通过这些案例,你已经掌握了在Phaser引擎中处理用户输入的多种方法,包括鼠标、键盘、游戏手柄以及多点触控。这些技术可以灵活组合,以实现更复杂和丰富的游戏交互体验。希望这些案例对你在开发游戏时有所帮助!## 案例3:实现游戏手柄支持(续)
预加载资源:
this.load.image
方法用于加载玩家和子弹的图像资源。创建游戏场景:
this.player
创建了一个玩家角色,使用 setCollideWorldBounds
方法确保玩家不会移出屏幕边界。
this.bullets
创建了子弹组,maxSize
设置了子弹组的最大大小,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
this.input.gamepad.once('connected', (pad) => { this.pad = pad; });
用于监听手柄连接事件并初始化手柄。
this.input.gamepad.on('down', this.handleGamepad, this);
用于监听手柄按钮按下事件,当按下A按钮时调用 this.handleGamepad
方法。
更新游戏场景:
this.player.setVelocity(0);
用于重置玩家的移动速度,确保在没有按键按下时玩家停止移动。
if (this.pad.axes[0].value !== 0) { this.player.setVelocityX(this.pad.axes[0].value * 200); }
判断手柄左摇杆在水平方向上的值,如果非零则设置玩家的水平速度。
if (this.pad.axes[1].value !== 0) { this.player.setVelocityY(this.pad.axes[1].value * 200); }
判断手柄左摇杆在垂直方向上的值,如果非零则设置玩家的垂直速度。
if (this.pad.A) { this.shootBullet(); }
判断A按钮是否按下,如果是则调用 this.shootBullet
方法发射子弹。
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
用于根据玩家的朝向设置子弹的初始速度,使其沿玩家的朝向发射。
处理游戏手柄事件:
button.index === 0 && value
判断A按钮是否按下,如果是则调用 this.shootBullet
方法发射子弹。敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
实现一个支持鼠标和键盘组合输入的游戏,玩家可以通过键盘控制角色的移动,通过鼠标点击发射子弹,通过鼠标移动调整角色的朝向。
// 引入Phaser引擎
import Phaser from 'phaser';
// 创建游戏配置
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
// 创建游戏实例
const game = new Phaser.Game(config);
// 预加载资源
function preload() {
this.load.image('player', 'assets/player.png');
this.load.image('bullet', 'assets/bullet.png');
}
// 创建游戏场景
function create() {
// 创建玩家
this.player = this.physics.add.sprite(400, 500, 'player');
this.player.setCollideWorldBounds(true);
// 创建子弹组
this.bullets = this.physics.add.group({
key: 'bullet',
maxSize: 10,
runChildUpdate: true
});
// 初始化键盘输入
this.cursors = this.input.keyboard.createCursorKeys();
// 设置射击
this.input.on('pointerdown', this.shootBullet, this);
// 设置角色朝向
this.input.on('pointermove', this.updatePlayerDirection, this);
}
// 更新游戏场景
function update(time, delta) {
// 移动玩家
this.player.setVelocity(0);
if (this.cursors.left.isDown) {
this.player.setVelocityX(-200);
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(200);
}
if (this.cursors.up.isDown) {
this.player.setVelocityY(-200);
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(200);
}
// 更新子弹
this.bullets.children.iterate(function (bullet) {
if (bullet.active) {
bullet.setVelocityY(-400);
}
});
// 检测碰撞
this.physics.add.collider(this.bullets, this.enemies, this.hitEnemy, null, this);
}
// 射击子弹
function shootBullet(pointer) {
const bullet = this.bullets.get();
if (bullet) {
bullet.setActive(true);
bullet.setVisible(true);
bullet.setPosition(this.player.x, this.player.y);
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
}
}
// 更新角色朝向
function updatePlayerDirection(pointer) {
const dx = pointer.x - this.player.x;
const dy = pointer.y - this.player.y;
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
}
// 敌人被击中
function hitEnemy(bullet, enemy) {
bullet.setActive(false);
bullet.setVisible(false);
enemy.destroy();
}
预加载资源:
this.load.image
方法用于加载玩家和子弹的图像资源。创建游戏场景:
this.player
创建了一个玩家角色,使用 setCollideWorldBounds
方法确保玩家不会移出屏幕边界。
this.bullets
创建了子弹组,maxSize
设置了子弹组的最大大小,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
this.cursors = this.input.keyboard.createCursorKeys();
用于初始化键盘输入,包括上下左右键。
this.input.on('pointerdown', this.shootBullet, this);
用于监听鼠标点击事件,当点击屏幕时调用 this.shootBullet
方法。
this.input.on('pointermove', this.updatePlayerDirection, this);
用于监听鼠标移动事件,当鼠标移动时调用 this.updatePlayerDirection
方法。
更新游戏场景:
this.player.setVelocity(0);
用于重置玩家的移动速度,确保在没有按键按下时玩家停止移动。
if (this.cursors.left.isDown) { this.player.setVelocityX(-200); }
判断左箭头键是否按下,如果是则设置玩家的水平速度为-200,使其向左移动。
else if (this.cursors.right.isDown) { this.player.setVelocityX(200); }
判断右箭头键是否按下,如果是则设置玩家的水平速度为200,使其向右移动。
if (this.cursors.up.isDown) { this.player.setVelocityY(-200); }
判断上箭头键是否按下,如果是则设置玩家的垂直速度为-200,使其向上移动。
else if (this.cursors.down.isDown) { this.player.setVelocityY(200); }
判断下箭头键是否按下,如果是则设置玩家的垂直速度为200,使其向下移动。
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
用于根据玩家的朝向设置子弹的初始速度,使其沿玩家的朝向发射。
更新角色朝向:
const dx = pointer.x - this.player.x;
计算鼠标指针与玩家角色在水平方向上的差值。
const dy = pointer.y - this.player.y;
计算鼠标指针与玩家角色在垂直方向上的差值。
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
使用 Math.atan2
计算玩家角色与鼠标指针之间的角度,并将其转换为度数,设置玩家角色的朝向。
敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
预加载资源:
this.load.image
方法用于加载玩家和子弹的图像资源。创建游戏场景:
this.player
创建了一个玩家角色,使用 setCollideWorldBounds
方法确保玩家不会移出屏幕边界。
this.bullets
创建了子弹组,maxSize
设置了子弹组的最大大小,runChildUpdate
允许子对象在每一帧更新时运行更新函数。
this.cursors = this.input.keyboard.createCursorKeys();
用于初始化键盘输入,包括上下左右键。
this.input.gamepad.once('connected', (pad) => { this.pad = pad; });
用于监听手柄连接事件并初始化手柄。
this.input.on('pointerdown', this.shootBullet, this);
用于监听鼠标点击事件,当点击屏幕时调用 this.shootBullet
方法。
this.input.gamepad.on('down', this.handleGamepad, this);
用于监听手柄按钮按下事件,当按下A按钮时调用 this.shootBullet
方法。
this.input.on('pointermove', this.updatePlayerDirection, this);
用于监听鼠标移动事件,当鼠标移动时调用 this.updatePlayerDirection
方法。
更新游戏场景:
this.player.setVelocity(0);
用于重置玩家的移动速度,确保在没有按键按下时玩家停止移动。
if (this.cursors.left.isDown || (this.pad && this.pad.axes[0].value < -0.5)) { this.player.setVelocityX(-200); }
判断左箭头键或手柄左摇杆是否向左偏移,如果是则设置玩家的水平速度为-200,使其向左移动。
else if (this.cursors.right.isDown || (this.pad && this.pad.axes[0].value > 0.5)) { this.player.setVelocityX(200); }
判断右箭头键或手柄左摇杆是否向右偏移,如果是则设置玩家的水平速度为200,使其向右移动。
if (this.cursors.up.isDown || (this.pad && this.pad.axes[1].value < -0.5)) { this.player.setVelocityY(-200); }
判断上箭头键或手柄左摇杆是否向上偏移,如果是则设置玩家的垂直速度为-200,使其向上移动。
else if (this.cursors.down.isDown || (this.pad && this.pad.axes[1].value > 0.5)) { this.player.setVelocityY(200); }
判断下箭头键或手柄左摇杆是否向下偏移,如果是则设置玩家的垂直速度为200,使其向下移动。
this.bullets.children.iterate
遍历子弹组中的每个子弹,设置其垂直速度使其向上飞行。
this.physics.add.collider
用于检测子弹和敌人之间的碰撞,当发生碰撞时调用 this.hitEnemy
方法。
射击子弹:
this.bullets.get
从子弹组中获取一个未活跃的子弹,设置其状态为活跃并显示在屏幕上,位置为玩家的位置。
bullet.setVelocity(Phaser.Math.Normalize(Phaser.Math.Vector2.FromAngle(this.player.angle, 400)));
用于根据玩家的朝向设置子弹的初始速度,使其沿玩家的朝向发射。
更新角色朝向:
const dx = pointer.x - this.player.x;
计算鼠标指针与玩家角色在水平方向上的差值。
const dy = pointer.y - this.player.y;
计算鼠标指针与玩家角色在垂直方向上的差值。
this.player.angle = Phaser.Math.RAD_TO_DEG * Math.atan2(dy, dx);
使用 Math.atan2
计算玩家角色与鼠标指针之间的角度,并将其转换为度数,设置玩家角色的朝向。
处理游戏手柄事件:
button.index === 0 && value
判断A按钮是否按下,如果是则调用 this.shootBullet
方法发射子弹。敌人被击中:
bullet.setActive(false)
和 bullet.setVisible(false)
使子弹失效并隐藏。
enemy.destroy()
销毁敌人对象。
通过这些案例,你已经掌握了在Phaser引擎中处理用户输入的多种方法,包括鼠标、键盘、游戏手柄以及多点触控。这些技术可以灵活组合,以实现更复杂和丰富的游戏交互体验。希望这些案例对你在开发游戏时有所帮助!
如果你有任何问题或需要进一步的解释,请随时提问!