背景
前面已经完成了登录页了,接下来就是游戏玩法,我原先第一版的游戏是一个类似三消的游戏,玩家通过滑动自己剑诀(方块)到战场上,叠出剑式(区域块),通过剑式里面的三消关系,产生一次出招。具体可以试玩一下抖音“仙剑出鞘”(当前还是老版本,可能比较卡)。因为游戏的玩法已经基本确定了,接下来就是一步一步的用ai生成的这个ecs架构去实现它。
目标
分析出游戏中的一些实体已经大致的实现规划。设计整个游戏架构,实现满足ecs架构的组件和对象
设计过程
1、游戏场景的规划
游戏场景是27*27个网格,每个网格是100*100像素。其中中心部分为5*5网格,一个关卡内有4个方位的小关卡。每个小关卡的交战区域为5*10个网格
在固定关卡中,玩家不能随意切换视角,有关卡控制摄像头的位置
在家园模式中,玩家可以随意切换视角,可平移可视范围
2、实体
玩家(player)
界面(gui)
npc(npc)
音效(audio)
战役(battle)
环境(env)
3、对象池
envs(环境单位,sprite,实体“env”的一个组件)
blocks(剑诀方块,sprite,实体“battle”的一个组件)
enemys(敌方单位,sprite,实体“battle”的一个组件)
effects(特效单位,sprite+ani,实体“battle”的一个组件)
4、操控
上下左右滑动操作 (实体“gui”上的一个组件)
按钮操作 (实体“gui”上的一个组件)
5、游戏关卡
关卡配置是原本是从后端获取的,想的是动态优化关卡,但从第一版上的效果来说不理想。还是保存在本地。
每十关一张地图
6、游戏基础配置
游戏关卡json数据(实体“battle”上的一个组件)
剑诀数据(实体“battle”上的一个组件)
PS: 当前的设计是当时开发日志时的,在后期的开发中做了优化(后面附目录结构和说明)
界面设计
做一个loading的视图
开发过程
有了这些基础信息,接下来就是通过一个loading页面,将需要的配置信息和场景建设在loading中做好。等loading结束就显示游戏关卡页面。
玩家点击开始游戏按钮
export class GateViewSystem {
apply(entity: Entity) {
}
static listenClick(entity: Entity) {
const comp = entity.getComponent(GateViewComp);
if (comp) {
comp.node.getChildByName('bottom').getChildByName('startGame').on(Node.EventType.TOUCH_END, this.onStartGameClick, comp);
}
}
static unListenClick(entity: Entity) {
const comp = entity.getComponent(GateViewComp);
if (comp) {
comp.node.getChildByName('bottom').getChildByName('startGame').off(Node.EventType.TOUCH_END, this.onStartGameClick, comp);
}
}
static onStartGameClick(event: EventTouch) {
let comp: GateViewComp = (this as unknown as GateViewComp)
console.log('start Game click', event, this)
event.target.off(Node.EventType.TOUCH_END, this.onStartGameClick, this);
// 创建一个loading的实体
const loading_entity = ooxh.entityManager.createEntity();
// // 加入视图组件
let _LoadingViewComp = PooledComponent.requestComponent(LoadingViewComp)
_LoadingViewComp.callback = () => {
console.log('_LoadingViewComp加载显示完成')
Logger.logBusiness('移除gate实体')
ooxh.entityManager.removeEntity(comp.entity)
}
loading_entity.attachComponent(_LoadingViewComp);
}
}
export class GateViewComp extends PooledComponent {
node: Node = null
callback: Function = null
reset() {
this.node = null
this.callback = null
}
onAttach(entity: Entity) {
this.entity = entity
console.log('实体', entity, '挂载了 GateViewComp')
resources.load('gui/gate_index', Prefab, (err, prefab) => {
if (err) {
console.error('Failed to load prefab:', err);
return;
}
this.node = instantiate(prefab);
ooxh.gui.root.addChild(this.node);
GateViewSystem.listenClick(entity)
this.callback && this.callback()
});
}
onDetach(entity: Entity) {
this.entity = null
console.log('实体', entity, '移除了 GateViewComp')
this.node.destroy()
GateViewSystem.unListenClick(entity)
}
}
然后loading组件进行加载资源,并显示进度
测试效果
效果预期的达成情况
基本完成加载,后面还需要补充其他加载过程
下一个开发计划
游戏关卡内环境及单位的显示
PS:2023年6月7日补充:
下面是整个的架构
├── Globle.d.ts
├── Main.ts
├── comps
│ ├── battle (实体)
│ │ ├── BattleChuQiaoComp.ts // 出鞘效果组件
│ │ ├── BattleGridComp.ts // 技能网格组件
│ │ ├── BattleGuideComp.ts // 新手指导组件
│ │ ├── BattleInitComp.ts // 战役初始化组件
│ │ ├── BattleOverLoseComp.ts // 检测游戏结束组件
│ │ ├── BattleOverWinComp.ts // 检测游戏胜利组件
│ │ └── BattleStateComp.ts // 战役状态数据组件
│ ├── player (实体)
│ │ ├── PlayerLoginComp.ts // 玩家登录组件
│ │ ├── PlayerShareComp.ts // 玩家分享组件
│ │ ├── PlayerStateComp.ts // 玩家状态组件
│ └── PlayerTouchMoveComp.ts // 玩家触控组件
├── items (对象及对象池)
│ ├── BaseItem.ts
│ ├── BlockItem.ts // “剑诀”块item对象
│ ├── EffectItem.ts // 特效item对象
│ ├── GoodsItem.ts // 物品item对象
│ ├── GuideItem.ts // 指引动画item对象
│ ├── SwordItem.ts // 飞剑item对象
│ ├── TipsItem.ts // ui提示item对象
│ └── UnitItem.ts // 单位item对象
├── shared (如果是全栈项目,前后端通用共享的定义)
│ ├── Consts.ts // 常量定义
│ ├── class // 特殊class(目前是无法归类到items里面时放这里)
│ │ └── Block.ts
│ ├── class.meta
│ ├── interfaces // 各个对象的interfaces
│ │ └── Item.ts
│ ├── types // enum枚举
│ │ └── Enum.ts
│ └── types.meta
├── utils (工具目录)
│ ├── DyUtil.ts // 抖音sdk
│ ├── GridUtil.ts // 网格中用到的方法规律
│ ├── HttpUtil.ts // http
│ ├── NodeUtil.ts // cocos中坐标系等常用方法
│ └── SpineUtil.ts // spine相关
├── views
│ ├── BattleLoseView.ts // 失败弹窗页
│ ├── BattleView.ts // 战役操作页
│ ├── BattleWinView.ts // 胜利弹窗页
│ ├── GateView.ts // 登录页
│ ├── GetMorePsView.ts // 获得更多体力弹窗
│ ├── GetReviveView.ts // 复活弹窗
│ ├── LoadingView.ts // 加载页
│ ├── PopupView.ts
│ └── UiView.ts // ui的基类
└──