AI也能写游戏啦,用ChatGPT生成cocos creator代码,编写回合制文字rpg游戏(三)

779 阅读1分钟

上一篇

AI也能写游戏啦,用ChatGPT生成cocos creator代码,编写回合制文字rpg游戏(二) - 掘金 (juejin.cn)

背包系统

上节完成了游戏的结算页面,这节我们让AI写一个背包,用于存储胜利时获得的道具

提问

image.png 生成的代码



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打开控制台,可以看到,正常增减物品了 image.png

添加UI界面显示背包物品

image.png

生成的代码

// 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

image.png 生成的代码

// 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;
}

运行游戏

image.png

背包是弹出来了,可他要怎么关闭呢,继续让AI帮忙

image.png

image.png

// 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;
            }
        });
    }
}

出来的效果

4.gif

本节结束,下一节,要在结算界面接入获得的道具,并实现某些道具的效果