上一篇
AI也能写游戏啦,用ChatGPT生成cocos creator代码,编写回合制文字rpg游戏(二) - 掘金 (juejin.cn)
背包系统
上节完成了游戏的结算页面,这节我们让AI写一个背包,用于存储胜利时获得的道具
提问
生成的代码
const {ccclass, property} = cc._decorator;
// 物品数据类型
interface Item {
id: number; // 物品ID
name: string; // 物品名称
description: string; // 物品描述
}
@ccclass
export default class InventorySystem {
private static _instance: InventorySystem = null; // 单例实例
private constructor() {
// 私有构造函数,防止外部创建实例
}
private inventory: Item[] = []; // 背包物品列表
// 获取背包系统的单例实例
public static getInstance(): InventorySystem {
if (InventorySystem._instance === null) {
InventorySystem._instance = new InventorySystem();
}
return InventorySystem._instance;
}
start () {
}
// 添加物品到背包
addItem(item: Item) {
this.inventory.push(item);
this.updateInventoryLabel();
}
// 从背包移除物品
removeItem(item: Item) {
const index = this.inventory.findIndex(i => i.id === item.id);
if (index !== -1) {
this.inventory.splice(index, 1);
this.updateInventoryLabel();
}
}
// 更新背包显示
updateInventoryLabel() {
let inventoryStr = "背包物品:\n";
for (let i = 0; i < this.inventory.length; i++) {
inventoryStr += `${this.inventory[i].name}\n`;
}
cc.log("背包里的物品"+inventoryStr);
//this.inventoryLabel.string = inventoryStr;
}
// update (dt) {}
}
实际上我生成了2次,第一次不是单例,我又追加提问了,2次代码粘贴合并,得出了这个结果
测试背包脚本
我们在前面生成的Game.ts的onLoad()里添加几行测试代码
//添加物品
InventorySystem.getInstance().addItem({id:1,name:"小血瓶",description:"恢复10点HP"})
//添加物品
InventorySystem.getInstance().addItem({id:2,name:"小木棍",description:"一把简陋的武器"})
//移除物品
InventorySystem.getInstance().removeItem({id:1})
按F12打开控制台,可以看到,正常增减物品了
添加UI界面显示背包物品
生成的代码
// InventoryUI.ts 背包界面脚本
import InventoryItem from "./InventoryItem";
import InventorySystem from "./InventorySystem";
const {ccclass, property} = cc._decorator;
@ccclass
export default class InventoryUI extends cc.Component {
@property(cc.Prefab)
ItemPrefab: cc.Prefab = null; // 背包物品预制体
@property(cc.Node)
itemListNode: cc.Node = null; // 物品列表节点
start() {
this.refreshItemList();
}
// 刷新物品列表
private refreshItemList(): void {
const backpack = InventorySystem.getInstance();
const items = backpack.getItems();
this.itemListNode.removeAllChildren();
items.forEach(item => {
const itemNode = cc.instantiate(this.ItemPrefab);
const itemComponent = itemNode.getComponent(InventoryItem);
itemComponent.setItemInfo(item.name,1);
this.itemListNode.addChild(itemNode);
});
}
}
// InventoryItem.ts 背包物品脚本
const {ccclass, property} = cc._decorator;
@ccclass
export default class InventoryItem extends cc.Component {
@property(cc.Label)
itemNameLabel: cc.Label = null; // 物品名称 Label
@property(cc.Label)
itemCountLabel: cc.Label = null; // 物品数量 Label
private itemName: string = ""; // 物品名称
private itemCount: number = 0; // 物品数量
// 设置物品信息
public setItemInfo(itemName: string, itemCount: number): void {
this.itemName = itemName;
this.itemCount = itemCount;
this.itemNameLabel.string = this.itemName;
this.itemCountLabel.string = `x${this.itemCount}`;
}
}
再来一个单例,方便在任何地方调用UI
生成的代码
// UIManager.ts UI管理器脚本
const {ccclass, property} = cc._decorator;
@ccclass
export default class UIManager extends cc.Component {
private static instance: UIManager = null; // 单例实例
//这里我自己添加的,背包UI关联
@property(InventoryUI)
public inventoryUI:InventoryUI;
// 获取UIManager单例
public static getInstance(): UIManager {
if (!UIManager.instance) {
UIManager.instance = new UIManager();
}
return UIManager.instance;
}
// 在onLoad生命周期中初始化单例
onLoad() {
}
// 显示某个UI界面
public showUI(uiNode: cc.Node): void {
uiNode.active = true;
}
// 隐藏某个UI界面
public hideUI(uiNode: cc.Node): void {
uiNode.active = false;
}
}
创建一个Scrollview,挂上InventoryUI,背包格子做成预制体,挂上InventoryItem脚本,各种要拖进检视面板的预制体都拖进去,在Game.ts的里测试添加物品后面的代码加上这个
if(UIManager.getInstance().inventoryUI){
UIManager.getInstance().inventoryUI.node.active= true;
}
运行游戏
背包是弹出来了,可他要怎么关闭呢,继续让AI帮忙
// UIManager.ts UI管理器单例
export default class UIManager {
private static _instance: UIManager = null;
public static getInstance(): UIManager {
if (!this._instance) {
this._instance = new UIManager();
}
return this._instance;
}
//这一部分我放进onload里,并稍微改了下,UIManager是挂在canvas上的
private constructor() {
// 初始化UI管理器
// 添加触摸事件监听器
//cc.director.on(cc.Director.EVENT_AFTER_INIT, () => {
// cc.systemEvent.on(cc.SystemEvent.EventType.TOUCH_END, this.onTouchEnd, this);
//}, this);
this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
}
private onTouchEnd(event: cc.Touch) {
// 获取点击的位置
const touchPos = event.getLocation();
// 遍历当前场景的所有UI节点
cc.director.getScene().children.forEach((node: cc.Node) => {
// 判断点击的位置是否在UI节点内
if (node.getBoundingBoxToWorld().contains(touchPos)) {
return;
}
// 如果点击位置不在UI节点内,则关闭UI节点
// 这里假设UI节点的名字中包含"UI",你可以根据实际情况修改,注意把背包的节点名字改成带UI的
if (node.name.includes("UI")) {
node.active = false;
}
});
}
}
出来的效果
本节结束,下一节,要在结算界面接入获得的道具,并实现某些道具的效果