feat(SS) 故事场景控制场景备份

This commit is contained in:
chicrobot committed 2026-02-11 21:16:48 +08:00
1 parent 062d950583
commit 5644f9c1eb
13 files changed
+108 -1072

No files matched your search

+2
View File
@@ -60,6 +60,8 @@ import BreatheLife from './scenes/storeScenes/BreatheLife.js';
// 伏羲画卦,创建角色控制与信息栏 // 伏羲画卦,创建角色控制与信息栏
import Control from './scenes/storeScenes/Control.js'; import Control from './scenes/storeScenes/Control.js';
// import InfoBar from './scenes/storeScenes/InfoBar.js'; // import InfoBar from './scenes/storeScenes/InfoBar.js';
// // 钻木取火,添加合成系统
// import Synthesis from './scenes/storeScenes/Synthesis.js';
// // 神农百草,创建耕种系统 // // 神农百草,创建耕种系统
// import Farming from './scenes/storeScenes/Farming.js'; // import Farming from './scenes/storeScenes/Farming.js';
// // 涿鹿之战,创建战斗系统 // // 涿鹿之战,创建战斗系统
+28 -17
View File
@@ -52,10 +52,8 @@ export default class BreatheLife extends WorldLand {
} }
initSceneTransition() { initSceneTransition() {
// 初始化角色计数器,用于跟踪创建的角色数量 // 初始化角色计数器,用于跟踪创建的角色数量
this.spriteCount = 0
this.spriteTextureCount = 0
this.spriteAnimCount = 0
this.targetCount = 3 // 目标角色数量 this.targetCount = 3 // 目标角色数量
this.NPCObjects = [] // 维护角色集合
this.smallGrassObjects = [] // 维护小草集合 this.smallGrassObjects = [] // 维护小草集合
} }
initInput() { initInput() {
@@ -91,22 +89,31 @@ export default class BreatheLife extends WorldLand {
const clickedSprite = this.getClickedSprite(x, y) const clickedSprite = this.getClickedSprite(x, y)
console.log("点击到的精灵:", clickedSprite) console.log("点击到的精灵:", clickedSprite)
// 如果满足条件则切换到下一场景 // 如果满足条件则切换到下一场景
if (clickedSprite) { // 如果点击到了精灵 if (clickedSprite && this.NPCObjects.includes(clickedSprite)) { // 如果点击到了角色
this.handleSpriteClick(clickedSprite) this.handleSpriteClick(clickedSprite)
}else if (this.spriteCount >= this.targetCount && this.spriteTextureCount >= this.targetCount && this.spriteAnimCount >= this.targetCount) { }else if (this.NPCObjects.length >= this.targetCount) {
this.scene.start(this.nextScene) // 如果角色列表中角色数量超过目标数量,且动态效果的数量也超过目标数量
}else if (this.spriteCount < 3) { let moveCount = 0
for (const sprite of this.NPCObjects) {
// 如果角色当前的纹理在player-move的动画帧中,计数加一
const moveAnimationFrames = ['player1-1', 'player1-2']
if (moveAnimationFrames.includes(sprite.texture.key)) {
moveCount++
}
}
if (moveCount >= this.targetCount) {
this.scene.start(this.nextScene)
}
}else if (this.NPCObjects.length < this.targetCount) {
// 如果角色数量不足目标数量
// 创建一个新的角色 sprite,缩放为1倍,并设置原点为中心底部 // 创建一个新的角色 sprite,缩放为1倍,并设置原点为中心底部
const sprite = this.physics.add.sprite(x, y, 'player').setScale(1).setOrigin(0.5, 1) const sprite = this.physics.add.sprite(x, y, 'player').setScale(1).setOrigin(0.5, 1)
sprite.setDepth(this.SpriteDepth) // 设置角色层级 sprite.setDepth(this.SpriteDepth) // 设置角色层级
this.NPCObjects.push(sprite) // 加入角色集合
// 设置角色碰撞世界边界 // // 设置角色碰撞世界边界
sprite.setCollideWorldBounds(true) // sprite.setCollideWorldBounds(true)
// 增加角色计数器
this.spriteCount++
console.log("已设置纹理的角色数量:", this.spriteTextureCount)
console.log("已创建的角色数量:", this.spriteCount)
} }
} }
@@ -235,8 +242,8 @@ export default class BreatheLife extends WorldLand {
targets: clickedSprite, // 角色精灵 targets: clickedSprite, // 角色精灵
x: nearestGrass.x, // 目标小草位置x x: nearestGrass.x, // 目标小草位置x
y: nearestGrass.y, // 目标小草位置y y: nearestGrass.y, // 目标小草位置y
duration: 1000, // 移动时间1秒 duration: minDistance * 10, // 移动时间根据距离计算
ease: 'Power2', // 移动缓动效果 ease: 'Linear', // 匀速移动
onComplete: () => { onComplete: () => {
// 从数组中移除已收集的小草 // 从数组中移除已收集的小草
this.smallGrassObjects = this.smallGrassObjects.filter( this.smallGrassObjects = this.smallGrassObjects.filter(
@@ -244,7 +251,11 @@ export default class BreatheLife extends WorldLand {
) )
nearestGrass.destroy() // 移动完成后销毁小草 nearestGrass.destroy() // 移动完成后销毁小草
this.sound.play('coin-a') // 播放收集小草音效 this.sound.play('coin-a') // 播放收集小草音效
this.searchAndAddSmallGrass(clickedSprite) // 递归调用,继续搜索下一个小草 // 等待随机时间后,继续搜索下一个小草
const delay = Phaser.Math.Between(500, 1000)
this.time.delayedCall(delay, () => {
this.searchAndAddSmallGrass(clickedSprite) // 递归调用,继续搜索下一个小草
})
} }
}) })
} }
+71 -5
View File
@@ -16,11 +16,77 @@ export default class Control extends BreatheLife {
create() { create() {
super.create() super.create()
// 覆盖场景切换条件 // 设置 Control 场景的目标角色数量
this.initSceneTransition() this.targetCount = 2 // 目标角色数量
// 初始化输入事件
this.initInput()
// 添加随机NPC
this.addRandomNPCs()
} }
initSceneTransition() { // Control 场景不再需要覆盖 initSceneTransition 方法
// 初始化角色计数器,用于跟踪创建的角色数量 // 数组初始化由父类 BreatheLife.create() 中的 initSceneTransition() 完成
this.smallGrassObjects = [] // 维护小草集合 // targetCount 通过在 create() 中直接设置来覆盖
initInput() {
// 移除父类的输入事件监听器,避免重复监听
super.removeListener()
// 监听鼠标点击事件
this.input.on('pointerdown', () => {
// 获取点击位置的坐标
const { x, y } = this.input.activePointer
this.handleClick(x, y)
})
}
/**
* 处理点击事件
* @param {number} x - 点击的 x 坐标
* @param {number} y - 点击的 y 坐标
*/
handleClick(x, y) {
// 获取点击位置的精灵
const clickedSprite = this.getClickedSprite(x, y)
console.log("点击到的精灵:", clickedSprite)
if (clickedSprite && this.NPCObjects.includes(clickedSprite)) { // 如果点击到了角色
this.handleSpriteClick(clickedSprite)
}else {
// 创建玩家可控制角色
// this.createCharacter(x, y)
}
}
/**
* 创建NPC
* @param {number} x - NPC的 x 坐标
* @param {number} y - NPC的 y 坐标
*/
createNPC(x, y) {
// 创建一个新的角色 sprite,缩放为1倍,并设置原点为中心底部
const sprite = this.physics.add.sprite(x, y, `player1-0`).setScale(1).setOrigin(0.5, 1)
sprite.setDepth(this.SpriteDepth) // 设置角色层级
this.NPCObjects.push(sprite) // 加入角色集合
this.addSpriteAnimation(sprite) // 添加角色动画
this.searchAndAddSmallGrass(sprite) // 添加搜索逻辑,自动检测最近的小草
// // 设置角色碰撞世界边界
// sprite.setCollideWorldBounds(true)
}
/**
* 添加随机NPC
*/
addRandomNPCs() {
// 随机生成NPC数量
const randomCount = 5
for (let i = 0; i < randomCount; i++) {
// 随机间隔随机位置生成NPC
const interval = Phaser.Math.Between(0, 500)
this.time.delayedCall(interval, () => {
const x = Phaser.Math.Between(0, this.game.config.width)
const y = Phaser.Math.Between(0, this.game.config.height)
this.createNPC(x, y)
})
}
} }
} }
+7
View File
@@ -98,6 +98,13 @@ export default class WorldTime extends Phaser.Scene {
fontFamily: 'Arial' fontFamily: 'Arial'
} }
).setScrollFactor(0).setDepth(this.UIDepth) // 固定文本,不随相机移动,UI层级 ).setScrollFactor(0).setDepth(this.UIDepth) // 固定文本,不随相机移动,UI层级
// 当场景是WorldTime时,突出,显示在中心
if (this.scene.key === 'WorldTime') {
this.timeText.setPosition(
this.cameras.main.width/2,
this.cameras.main.height/2
).setOrigin(0.5, 0.5)
}
// 添加黑夜遮罩 // 添加黑夜遮罩
this.nightMask = this.add.rectangle( this.nightMask = this.add.rectangle(
0, 0, 0, 0,
-34
View File
@@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Phaser</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
}
canvas {
display: block;
max-width: 100vw;
max-height: 100vh;
}
</style>
</head>
<body>
<script src="../phaser.min.js"></script>
<script type="module" src="main.js"></script>
</body>
</html>
-46
View File
@@ -1,46 +0,0 @@
// main.js
import { GameScene } from './scenes/GameScene.js';
import { JoystickTestScene } from './scenes/JoystickTestScene.js';
import { InputPlugin } from './plugins/InputPlugin.js';
console.log('InputPlugin 导入:', InputPlugin);
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
physics: {
default: 'arcade',
arcade: {
debug: false
}
},
scene: [JoystickTestScene, GameScene],
plugins: {
scene: [
{
key: 'InputPlugin',
plugin: InputPlugin,
mapping: 'inputPlugin'
}
]
},
// 添加缩放配置,解决拉伸问题
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
min: {
width: 400,
height: 300
},
max: {
width: 1600,
height: 1200
}
}
};
console.log('游戏配置:', config);
window.game = new Phaser.Game(config);
-113
View File
@@ -1,113 +0,0 @@
// plugins/InputPlugin.js
import { InputSystem } from './core/InputSystem.js';
import { PhaserInputAdapter } from './adapters/PhaserInputAdapter.js';
/**
* InputPlugin 场景插件
* 作为 Phaser 场景插件的包装器,使用适配器架构
*/
export class InputPlugin extends Phaser.Plugins.ScenePlugin {
constructor(scene, pluginManager) {
super(scene, pluginManager);
console.log('InputPlugin 场景插件初始化');
// 创建 Phaser 适配器
this.adapter = new PhaserInputAdapter(scene);
// 创建核心输入系统
this.inputSystem = new InputSystem(this.adapter);
// 初始化
this.inputSystem.initialize();
}
/**
* 启动插件
*/
boot() {
console.log('InputPlugin 场景插件启动');
}
/**
* 测试方法
* @returns {string} 测试结果
*/
testMethod() {
return 'InputPlugin 测试方法';
}
/**
* 创建触摸轮盘
* @param {Object} config 轮盘配置
* @returns {string} 轮盘ID
*/
createJoystick(config) {
return this.inputSystem.createJoystick(config);
}
/**
* 创建屏幕按钮
* @param {Object} config 按钮配置
* @returns {string} 按钮ID
*/
createButton(config) {
return this.inputSystem.createButton(config);
}
/**
* 获取轮盘方向向量
* @param {string} joystickId 轮盘ID
* @returns {Object} 方向向量 {x, y}
*/
getJoystickDirection(joystickId) {
return this.inputSystem.getJoystickDirection(joystickId);
}
/**
* 获取轮盘力度
* @param {string} joystickId 轮盘ID
* @returns {number} 力度值 (0-1)
*/
getJoystickMagnitude(joystickId) {
return this.inputSystem.getJoystickMagnitude(joystickId);
}
/**
* 获取归一化的轮盘方向
* @param {string} joystickId 轮盘ID
* @returns {Object} 归一化向量 {x, y} (-1 到 1)
*/
getJoystickNormalized(joystickId) {
return this.inputSystem.getJoystickNormalized(joystickId);
}
/**
* 检查按钮是否按下
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否按下
*/
isButtonDown(buttonId) {
return this.inputSystem.isButtonDown(buttonId);
}
/**
* 检查按钮是否释放
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否释放
*/
isButtonUp(buttonId) {
return this.inputSystem.isButtonUp(buttonId);
}
/**
* 销毁插件
*/
destroy() {
console.log('InputPlugin 场景插件销毁');
if (this.inputSystem) {
this.inputSystem.destroy();
}
super.destroy();
}
}
-74
View File
@@ -1,74 +0,0 @@
// plugins/adapters/CocosInputAdapter.js
export class CocosInputAdapter {
constructor(director) {
this.director = director;
this.keyMap = new Map();
this.isInitialized = false;
}
initialize() {
if (this.isInitialized) return;
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event) => {
this.handleKeyDown(event);
});
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, (event) => {
this.handleKeyUp(event);
});
this.isInitialized = true;
console.log('CocosInputAdapter 已初始化');
}
handleKeyDown(event) {
const keyCode = event.keyCode;
this.keyState.set(keyCode, true);
}
handleKeyUp(event) {
const keyCode = event.keyCode;
this.keyState.set(keyCode, false);
}
registerKey(key, aliases = []) {
const keyCode = this.getKeyCode(key);
this.keyMap.set(key, keyCode);
aliases.forEach(alias => {
const aliasKeyCode = this.getKeyCode(alias);
this.keyMap.set(alias, keyCode);
});
}
getKeyCode(key) {
const keyMap = {
'W': cc.macro.KEY.w,
'A': cc.macro.KEY.a,
'S': cc.macro.KEY.s,
'D': cc.macro.KEY.d,
'UP': cc.macro.KEY.up,
'DOWN': cc.macro.KEY.down,
'LEFT': cc.macro.KEY.left,
'RIGHT': cc.macro.KEY.right
};
return keyMap[key] || key;
}
isDown(key) {
const keyCode = this.keyMap.get(key);
return this.keyState.get(keyCode) || false;
}
isUp(key) {
return !this.isDown(key);
}
destroy() {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN);
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP);
this.keyMap.clear();
this.keyState.clear();
}
}
-90
View File
@@ -1,90 +0,0 @@
// plugins/adapters/IInputAdapter.js
/**
* 输入适配器接口
* 所有引擎适配器必须实现这些方法
*/
export class IInputAdapter {
constructor() {
if (this.constructor === IInputAdapter) {
throw new Error('IInputAdapter 是抽象类,不能直接实例化');
}
}
/**
* 初始化适配器
*/
initialize() {
throw new Error('initialize() 必须由子类实现');
}
/**
* 创建触摸轮盘
* @param {Object} config 轮盘配置
* @returns {Object} 轮盘实例
*/
createJoystick(config) {
throw new Error('createJoystick() 必须由子类实现');
}
/**
* 创建屏幕按钮
* @param {Object} config 按钮配置
* @returns {Object} 按钮实例
*/
createButton(config) {
throw new Error('createButton() 必须由子类实现');
}
/**
* 获取轮盘方向向量
* @param {string} joystickId 轮盘ID
* @returns {Object} 方向向量 {x, y}
*/
getJoystickDirection(joystickId) {
throw new Error('getJoystickDirection() 必须由子类实现');
}
/**
* 获取轮盘力度
* @param {string} joystickId 轮盘ID
* @returns {number} 力度值 (0-1)
*/
getJoystickMagnitude(joystickId) {
throw new Error('getJoystickMagnitude() 必须由子类实现');
}
/**
* 获取归一化的轮盘方向
* @param {string} joystickId 轮盘ID
* @returns {Object} 归一化向量 {x, y} (-1 到 1)
*/
getJoystickNormalized(joystickId) {
throw new Error('getJoystickNormalized() 必须由子类实现');
}
/**
* 检查按钮是否按下
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否按下
*/
isButtonDown(buttonId) {
throw new Error('isButtonDown() 必须由子类实现');
}
/**
* 检查按钮是否释放
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否释放
*/
isButtonUp(buttonId) {
throw new Error('isButtonUp() 必须由子类实现');
}
/**
* 销毁适配器
*/
destroy() {
throw new Error('destroy() 必须由子类实现');
}
}
-288
View File
@@ -1,288 +0,0 @@
// plugins/adapters/PhaserInputAdapter.js
import { IInputAdapter } from './IInputAdapter.js';
/**
* Phaser 输入适配器
* 实现 IInputAdapter 接口,使用 Phaser API
*/
export class PhaserInputAdapter extends IInputAdapter {
constructor(scene) {
super();
this.scene = scene;
this.joysticks = new Map();
this.buttons = new Map();
console.log('PhaserInputAdapter 初始化');
}
/**
* 初始化适配器
*/
initialize() {
if (!this.scene.input) {
console.warn('Phaser 输入系统不可用');
}
console.log('PhaserInputAdapter 已初始化');
}
/**
* 创建触摸轮盘
* @param {Object} config 轮盘配置
* @returns {Object} 轮盘实例
*/
createJoystick(config) {
try {
const joystick = {
id: config.id,
base: null,
thumb: null,
isActive: false,
startX: config.x || 100,
startY: config.y || this.scene.sys.game.config.height - 100,
radius: config.radius || 60,
maxDistance: config.maxDistance || 40,
currentX: 0,
currentY: 0,
normalizedX: 0,
normalizedY: 0,
magnitude: 0
};
// 创建轮盘底座
joystick.base = this.scene.add.circle(joystick.startX, joystick.startY, joystick.radius, 0x444444, 0.5);
joystick.base.setScrollFactor(0);
// 创建轮盘拇指
joystick.thumb = this.scene.add.circle(joystick.startX, joystick.startY, joystick.radius * 0.5, 0x888888, 0.8);
joystick.thumb.setScrollFactor(0);
// 监听触摸事件
const self = this;
this.scene.input.on('pointerdown', function(pointer) {
if (self.calculateDistance(pointer.x, pointer.y, joystick.startX, joystick.startY) < joystick.radius) {
joystick.isActive = true;
joystick.thumb.setPosition(pointer.x, pointer.y);
self.updateJoystick(joystick, pointer);
}
});
this.scene.input.on('pointermove', function(pointer) {
if (joystick.isActive) {
self.updateJoystick(joystick, pointer);
}
});
this.scene.input.on('pointerup', function() {
if (joystick.isActive) {
joystick.isActive = false;
joystick.thumb.setPosition(joystick.startX, joystick.startY);
joystick.currentX = 0;
joystick.currentY = 0;
joystick.normalizedX = 0;
joystick.normalizedY = 0;
joystick.magnitude = 0;
}
});
this.joysticks.set(config.id, joystick);
return joystick;
} catch (error) {
console.error('创建轮盘失败:', error);
return null;
}
}
/**
* 创建屏幕按钮
* @param {Object} config 按钮配置
* @returns {Object} 按钮实例
*/
createButton(config) {
try {
const button = {
id: config.id,
sprite: null,
text: null,
isDown: false,
x: config.x || this.scene.sys.game.config.width - 100,
y: config.y || this.scene.sys.game.config.height - 100,
width: config.width || 80,
height: config.height || 80,
label: config.label || 'Button',
onDown: config.onDown || null,
onUp: config.onUp || null
};
// 创建按钮背景
button.sprite = this.scene.add.rectangle(button.x, button.y, button.width, button.height, 0x444444, 0.5);
button.sprite.setScrollFactor(0);
button.sprite.setInteractive();
// 创建按钮文字
button.text = this.scene.add.text(button.x, button.y, button.label, {
fill: '#ffffff',
fontSize: '16px',
fontFamily: 'Arial'
});
button.text.setScrollFactor(0);
button.text.setOrigin(0.5, 0.5);
// 监听触摸事件
button.sprite.on('pointerdown', function() {
button.isDown = true;
button.sprite.setFillStyle(0x666666, 0.8);
if (button.onDown) {
button.onDown();
}
});
button.sprite.on('pointerup', function() {
button.isDown = false;
button.sprite.setFillStyle(0x444444, 0.5);
if (button.onUp) {
button.onUp();
}
});
button.sprite.on('pointerout', function() {
if (button.isDown) {
button.isDown = false;
button.sprite.setFillStyle(0x444444, 0.5);
}
});
this.buttons.set(config.id, button);
return button;
} catch (error) {
console.error('创建按钮失败:', error);
return null;
}
}
/**
* 计算两点之间的距离
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @returns {number} 距离
*/
calculateDistance(x1, y1, x2, y2) {
const dx = x2 - x1;
const dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* 计算两点之间的角度
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @returns {number} 角度
*/
calculateAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
/**
* 更新轮盘状态
* @param {Object} joystick 轮盘实例
* @param {Object} pointer 指针事件
*/
updateJoystick(joystick, pointer) {
const distance = this.calculateDistance(joystick.startX, joystick.startY, pointer.x, pointer.y);
const angle = this.calculateAngle(joystick.startX, joystick.startY, pointer.x, pointer.y);
// 限制最大距离
const limitedDistance = Math.min(distance, joystick.maxDistance);
joystick.magnitude = limitedDistance / joystick.maxDistance;
// 计算位置
joystick.currentX = Math.cos(angle) * limitedDistance;
joystick.currentY = Math.sin(angle) * limitedDistance;
// 归一化(-1 到 1 之间)
joystick.normalizedX = joystick.currentX / joystick.maxDistance;
joystick.normalizedY = joystick.currentY / joystick.maxDistance;
// 更新拇指位置
joystick.thumb.setPosition(
joystick.startX + joystick.currentX,
joystick.startY + joystick.currentY
);
}
/**
* 获取轮盘方向向量
* @param {string} joystickId 轮盘ID
* @returns {Object} 方向向量 {x, y}
*/
getJoystickDirection(joystickId) {
const joystick = this.joysticks.get(joystickId);
if (!joystick) return { x: 0, y: 0 };
return { x: joystick.currentX, y: joystick.currentY };
}
/**
* 获取轮盘力度
* @param {string} joystickId 轮盘ID
* @returns {number} 力度值 (0-1)
*/
getJoystickMagnitude(joystickId) {
const joystick = this.joysticks.get(joystickId);
if (!joystick) return 0;
return joystick.magnitude;
}
/**
* 获取归一化的轮盘方向
* @param {string} joystickId 轮盘ID
* @returns {Object} 归一化向量 {x, y} (-1 到 1)
*/
getJoystickNormalized(joystickId) {
const joystick = this.joysticks.get(joystickId);
if (!joystick) return { x: 0, y: 0 };
return { x: joystick.normalizedX, y: joystick.normalizedY };
}
/**
* 检查按钮是否按下
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否按下
*/
isButtonDown(buttonId) {
const button = this.buttons.get(buttonId);
return button ? button.isDown : false;
}
/**
* 检查按钮是否释放
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否释放
*/
isButtonUp(buttonId) {
return !this.isButtonDown(buttonId);
}
/**
* 销毁适配器
*/
destroy() {
// 清理轮盘
this.joysticks.forEach(joystick => {
if (joystick.base) joystick.base.destroy();
if (joystick.thumb) joystick.thumb.destroy();
});
this.joysticks.clear();
// 清理按钮
this.buttons.forEach(button => {
if (button.sprite) button.sprite.destroy();
if (button.text) button.text.destroy();
});
this.buttons.clear();
console.log('PhaserInputAdapter 已销毁');
}
}
-116
View File
@@ -1,116 +0,0 @@
// plugins/core/InputSystem.js
/**
* 核心输入系统 - 引擎无关
* 使用适配器模式实现跨引擎兼容
*/
export class InputSystem {
constructor(adapter) {
if (!adapter) {
throw new Error('InputSystem 需要一个适配器实例');
}
this.adapter = adapter;
this.joysticks = new Map();
this.buttons = new Map();
console.log('InputSystem 初始化');
}
/**
* 初始化输入系统
*/
initialize() {
this.adapter.initialize();
console.log('InputSystem 已初始化');
}
/**
* 创建触摸轮盘
* @param {Object} config 轮盘配置
* @returns {string} 轮盘ID
*/
createJoystick(config) {
const joystickId = config.id || `joystick_${this.joysticks.size}`;
const createdJoystick = this.adapter.createJoystick({
...config,
id: joystickId
});
if (createdJoystick) {
this.joysticks.set(joystickId, createdJoystick);
console.log('创建轮盘:', joystickId);
}
return joystickId;
}
/**
* 创建屏幕按钮
* @param {Object} config 按钮配置
* @returns {string} 按钮ID
*/
createButton(config) {
const buttonId = config.id || `button_${this.buttons.size}`;
const createdButton = this.adapter.createButton({
...config,
id: buttonId
});
if (createdButton) {
this.buttons.set(buttonId, createdButton);
console.log('创建按钮:', buttonId);
}
return buttonId;
}
/**
* 获取轮盘方向向量
* @param {string} joystickId 轮盘ID
* @returns {Object} 方向向量 {x, y}
*/
getJoystickDirection(joystickId) {
return this.adapter.getJoystickDirection(joystickId);
}
/**
* 获取轮盘力度
* @param {string} joystickId 轮盘ID
* @returns {number} 力度值 (0-1)
*/
getJoystickMagnitude(joystickId) {
return this.adapter.getJoystickMagnitude(joystickId);
}
/**
* 获取归一化的轮盘方向
* @param {string} joystickId 轮盘ID
* @returns {Object} 归一化向量 {x, y} (-1 到 1)
*/
getJoystickNormalized(joystickId) {
return this.adapter.getJoystickNormalized(joystickId);
}
/**
* 检查按钮是否按下
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否按下
*/
isButtonDown(buttonId) {
return this.adapter.isButtonDown(buttonId);
}
/**
* 检查按钮是否释放
* @param {string} buttonId 按钮ID
* @returns {boolean} 是否释放
*/
isButtonUp(buttonId) {
return this.adapter.isButtonUp(buttonId);
}
/**
* 销毁输入系统
*/
destroy() {
this.adapter.destroy();
this.joysticks.clear();
this.buttons.clear();
console.log('InputSystem 已销毁');
}
}
-74
View File
@@ -1,74 +0,0 @@
// scenes/GameScene.js
export class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
this.moveSpeed = 200;
this.joystickId = null;
this.inputPlugin = null;
}
preload() {
}
create() {
const graphics = this.make.graphics();
graphics.fillStyle(0xffffff, 1);
graphics.fillRect(0, 0, 32, 32);
graphics.generateTexture('player', 32, 32);
graphics.destroy();
this.player = this.physics.add.sprite(400, 300, 'player');
this.player.setCollideWorldBounds(true);
// 获取插件实例(更可靠的方式)
this.inputPlugin = this.plugins.get('InputPlugin');
if (this.inputPlugin) {
// 添加触摸轮盘
this.joystickId = this.inputPlugin.createJoystick({
id: 'movement',
x: 100,
y: this.sys.game.config.height - 100,
radius: 60,
maxDistance: 40
});
} else {
console.error('InputPlugin 未找到!');
}
// 添加提示文字
this.add.text(10, 10, '使用 WASD/方向键 或 触摸轮盘移动', { fill: '#ffffff', fontSize: '16px' });
}
update() {
// 重置速度
this.player.setVelocity(0);
// 键盘输入
const cursors = this.input.keyboard.createCursorKeys();
const keys = this.input.keyboard.addKeys('W,A,S,D');
if (cursors.up.isDown || keys.W.isDown) {
this.player.setVelocityY(-this.moveSpeed);
}
if (cursors.down.isDown || keys.S.isDown) {
this.player.setVelocityY(this.moveSpeed);
}
if (cursors.left.isDown || keys.A.isDown) {
this.player.setVelocityX(-this.moveSpeed);
}
if (cursors.right.isDown || keys.D.isDown) {
this.player.setVelocityX(this.moveSpeed);
}
// 触摸轮盘输入(带归一化)
if (this.inputPlugin && this.joystickId) {
const joystickNormalized = this.inputPlugin.getJoystickNormalized(this.joystickId);
if (joystickNormalized.x !== 0 || joystickNormalized.y !== 0) {
this.player.setVelocityX(joystickNormalized.x * this.moveSpeed);
this.player.setVelocityY(joystickNormalized.y * this.moveSpeed);
}
}
}
}
-215
View File
@@ -1,215 +0,0 @@
// scenes/JoystickTestScene.js
import { InputPlugin } from '../plugins/InputPlugin.js';
export class JoystickTestScene extends Phaser.Scene {
constructor() {
super('JoystickTestScene');
this.moveSpeed = 200;
this.sprintSpeed = 400; // 冲刺速度
this.inputPlugin = null;
this.joystickId = null;
this.sprintButtonId = null;
this.isSprinting = false;
}
preload() {
}
create() {
// 创建背景
this.cameras.main.setBackgroundColor('#2c3e50');
// 创建玩家
const graphics = this.make.graphics();
graphics.fillStyle(0x3498db, 1);
graphics.fillRect(0, 0, 40, 40);
graphics.generateTexture('player', 40, 40);
graphics.destroy();
this.player = this.physics.add.sprite(400, 300, 'player');
this.player.setCollideWorldBounds(true);
// 直接创建 InputPlugin 实例(绕过插件系统)
try {
this.inputPlugin = new InputPlugin(this, this.plugins);
console.log('直接创建 InputPlugin:', this.inputPlugin);
// 手动启动插件
this.inputPlugin.boot();
// 测试插件方法
const testResult = this.inputPlugin.testMethod();
console.log('插件测试结果:', testResult);
// 添加移动轮盘
this.joystickId = this.inputPlugin.createJoystick({
id: 'movement',
x: 150,
y: this.sys.game.config.height - 150,
radius: 80,
maxDistance: 60
});
console.log('创建轮盘:', this.joystickId);
// 添加冲刺按钮
this.sprintButtonId = this.inputPlugin.createButton({
id: 'sprint',
x: this.sys.game.config.width - 150,
y: this.sys.game.config.height - 150,
width: 100,
height: 100,
label: '冲刺',
onDown: () => {
this.isSprinting = true;
console.log('开始冲刺');
},
onUp: () => {
this.isSprinting = false;
console.log('结束冲刺');
}
});
console.log('创建冲刺按钮:', this.sprintButtonId);
// 添加提示文字
this.add.text(10, 10, '触摸轮盘测试场景', {
fill: '#ffffff',
fontSize: '24px',
fontFamily: 'Arial'
});
this.add.text(10, 50, '使用左侧轮盘移动', {
fill: '#ffffff',
fontSize: '16px',
fontFamily: 'Arial'
});
this.add.text(10, 80, '使用右侧按钮冲刺', {
fill: '#ffffff',
fontSize: '16px',
fontFamily: 'Arial'
});
this.add.text(10, 110, '使用 WASD 或方向键也可以移动', {
fill: '#ffffff',
fontSize: '16px',
fontFamily: 'Arial'
});
// 显示轮盘状态
this.statusText = this.add.text(10, 150, '轮盘状态: 未激活', {
fill: '#ffffff',
fontSize: '14px',
fontFamily: 'Arial'
});
// 添加适配器架构信息
this.add.text(10, 300, '适配器架构信息:', {
fill: '#ffffff',
fontSize: '16px',
fontFamily: 'Arial'
});
this.add.text(10, 330, '- 核心: InputSystem (引擎无关)', {
fill: '#ffffff',
fontSize: '14px',
fontFamily: 'Arial'
});
this.add.text(10, 360, '- 适配器: PhaserInputAdapter', {
fill: '#ffffff',
fontSize: '14px',
fontFamily: 'Arial'
});
this.add.text(10, 390, '- 插件: InputPlugin (场景插件)', {
fill: '#ffffff',
fontSize: '14px',
fontFamily: 'Arial'
});
} catch (error) {
console.error('创建 InputPlugin 失败:', error);
this.add.text(10, 10, 'InputPlugin 初始化失败!', {
fill: '#ff0000',
fontSize: '24px'
});
this.add.text(10, 50, '错误: ' + error.message, {
fill: '#ffffff',
fontSize: '16px'
});
}
}
update() {
// 重置速度
this.player.setVelocity(0);
// 确定当前速度(根据是否冲刺)
const currentSpeed = this.isSprinting ? this.sprintSpeed : this.moveSpeed;
// 键盘输入
const cursors = this.input.keyboard.createCursorKeys();
const keys = this.input.keyboard.addKeys('W,A,S,D,SHIFT');
let hasKeyboardInput = false;
// 检查冲刺键(Shift)
if (keys.SHIFT.isDown) {
this.isSprinting = true;
} else if (!this.inputPlugin || this.inputPlugin.isButtonUp(this.sprintButtonId)) {
this.isSprinting = false;
}
if (cursors.up.isDown || keys.W.isDown) {
this.player.setVelocityY(-currentSpeed);
hasKeyboardInput = true;
}
if (cursors.down.isDown || keys.S.isDown) {
this.player.setVelocityY(currentSpeed);
hasKeyboardInput = true;
}
if (cursors.left.isDown || keys.A.isDown) {
this.player.setVelocityX(-currentSpeed);
hasKeyboardInput = true;
}
if (cursors.right.isDown || keys.D.isDown) {
this.player.setVelocityX(currentSpeed);
hasKeyboardInput = true;
}
// 触摸轮盘输入
if (this.inputPlugin && this.joystickId) {
try {
const joystickNormalized = this.inputPlugin.getJoystickNormalized(this.joystickId);
const joystickMagnitude = this.inputPlugin.getJoystickMagnitude(this.joystickId);
if (joystickNormalized.x !== 0 || joystickNormalized.y !== 0) {
this.player.setVelocityX(joystickNormalized.x * currentSpeed);
this.player.setVelocityY(joystickNormalized.y * currentSpeed);
}
// 更新状态文字
if (this.statusText) {
const sprintStatus = this.isSprinting ? '(冲刺中)' : '';
if (joystickMagnitude > 0) {
this.statusText.setText(`轮盘状态: 激活${sprintStatus}\n力度: ${joystickMagnitude.toFixed(2)}\n方向: X=${joystickNormalized.x.toFixed(2)}, Y=${joystickNormalized.y.toFixed(2)}\n速度: ${currentSpeed}`);
} else if (hasKeyboardInput) {
this.statusText.setText(`轮盘状态: 未激活${sprintStatus} (使用键盘)\n速度: ${currentSpeed}`);
} else {
this.statusText.setText(`轮盘状态: 未激活${sprintStatus}\n速度: ${currentSpeed}`);
}
}
} catch (error) {
console.error('轮盘更新失败:', error);
}
}
}
destroy() {
if (this.inputPlugin) {
this.inputPlugin.destroy();
}
super.destroy();
}
}