【cocos creator】养成游戏简易事件系统,每日随机事件,每日行动点重置,根据数据检测多结局

news2024/9/22 17:32:19

在这里插入图片描述

在这里插入图片描述


const { ccclass, property } = cc._decorator;


let actionEvent = {
    EVENT1: { name: "工作", need: { ap: 1 }, cost: { ap: 1 }, award: { coin: 50 }, count: 7, max_count: 5 },
    EVENT2: { name: "练功", need: { ap: 1 }, cost: { ap: 1 }, award: { attack: 10 }, count: 7, max_count: 5 },
    EVENT3: { name: "买秘籍", need: { coin: 500 }, cost: { ap: 1, coin: 1000 }, award: { attack: 100 }, count: 1, max_count: 1 },
    EVENT4: { name: "吃饭", need: { coin: 20 }, cost: { coin: 20 }, award: { ap: 2 }, count: 2, max_count: 2 },
}

//随机事件,按照条件判定,满足走分支,不满足走下一个
const reActionEvent = {
    EVENT4: { name: "捡到物品还给失主,获得赏赐", need: {}, rate: 25, weight: 1, count: 5, cost: {}, award: { coin: 100 } },
    EVENT1: { name: "采到稀有药草,卖了好价钱", need: {}, rate: 25, weight: 1, count: 5, cost: {}, award: { coin: 200 } },
    EVENT2: { name: "遇到高僧指点功夫", need: { day: 10, coin: 100 }, rate: 10, weight: 1, count: 1, cost: { coin: 100 }, award: { attack: 400 } },
    EVENT6: { name: "捡到武功秘籍", need: { day: 5, coin: 100 }, rate: 10, weight: 1, count: 3, cost: {}, award: { attack: 50 } },
    EVENT3: { name: "遇到小偷", need: { coin: 1 }, rate: 25, weight: 1, count: -2, cost: {}, award: { coin: 100 } },
    EVENT5: { name: "下雨滑了一跤,就医", need: { coin: 1 }, rate: 25, weight: 1, count: 3, cost: {}, award: { coin: -100 } },
    EVENT_END: { name: "没什么特别的事情发生" },
}

//结局事件
const endEvent = {
    EVENT4: { name: "富豪", need: { day: 30, coin: 6000 }, weight: 97, count: -2, cost: {}, desc: "达成结局:富豪\n\n成为远近闻名的大富豪", eading: 1 },
    EVENT5: { name: "武林高手", need: { day: 30, attack: 1200 }, weight: 99, count: -2, cost: {}, desc: "达成结局:武林高手\n\n战胜上任武林盟主,成为\n江湖人闻风丧胆的武林高手", eading: 1 },
    EVENT1: { name: "侠客", need: { day: 30, coin: 10, attack: 600 }, weight: 96, count: -2, cost: {}, desc: "达成结局:侠客\n\n为弱者不平,成为劫富济贫的侠客", eading: 1 },
    EVENT6: { name: "举人", need: { day: 30, attack: 1000 }, weight: 98, count: -2, cost: {}, desc: "达成结局:武举人\n\n成功通过武举人考试,成为武官", eading: 1 },
    EVENT7: { name: "店主", need: { day: 30, coin: 1500 }, weight: 95, count: -2, cost: {}, desc: "达成结局:店主\n\n开了一家属于自己的小店,为了过上更好的生活努力着", eading: 1 },
    EVENT_END: { name: "普通人", need: { day: 30 }, weight: 82, count: -2, cost: {}, desc: "达成结局:普通人\n\n继续着平凡的生活", eading: 1 }
}
//结局事件
const deathEvent = {
    EVENT3: { name: "半道崩卒", need: { day: 10 }, check: { attack: 100 }, weight: 99, canSkip: false, count: -2, cost: { life: 10 }, desc: "达成结局:强盗当道\n\n遇到强盗袭击战败,暴尸荒野", eading: 1 },

    EVENT2: { name: "无力就医", need: { day: 5 }, check: { coin: 50 }, rate: 25, weight: 99, canSkip: false, count: -2, cost: { life: 10 }, desc: "达成结局:无力就医\n\n遇到野兽袭击,没钱支付医药费,遗憾离世", eading: 1 }
}

const descName = {
    coin: "总财产",
    attack: "武力值",
    life: "生命值",
    ap: "行动点",
    max_ap: "最大行动数",
}


@ccclass
export default class TimePanel extends cc.Component {

    @property(cc.Label)
    tipsNode: cc.Label = null;
    @property(cc.Label)
    nowData: cc.Label = null;
    @property(cc.Label)
    time: cc.Label = null;
    @property(cc.Node)
    btnArr: cc.Node[] = [];

    nowDay = 1;

    defaultPlayData = {
        ap: 5,
        max_ap: 5,
        coin: 0,
        attack: 5,
        life: 10,
    }

    playData = JSON.parse(JSON.stringify(this.defaultPlayData))
    monsterData = {
        attack: 99,
        life: 1000,
    }

    end = false;

    onLoad() {
        let gameData = cc.sys.localStorage.getItem("data") || null
        if (!gameData) {
            gameData = this.getSaveData()
        }
        if (gameData) {
            const { actionEventAll, playData, nowDay } = gameData;
            if (actionEventAll) {
                for (const key in actionEventAll) {
                    if (Object.prototype.hasOwnProperty.call(actionEventAll, key)) {
                        const element1 = actionEvent[key];
                        if (!element1) continue
                        element1.count = actionEventAll[key].count || 0;
                    }
                }
            }
            if (playData) this.playData = playData;
            if (nowDay) {
                this.nowDay = nowDay;
                this.checkPlayEvent()
            }
        }

        this.tipsNode.string = ""
        this.updateNowData()
        this.updateTime()
        this.updateAction()
        for (let i = 0; i < this.btnArr.length; i++) {
            let eventName = `EVENT${i + 1}`
            let data = actionEvent[eventName]
            if (!data) return
            const element = this.btnArr[i];
            element.getComponentInChildren(cc.Label).string = `${data.name} (${data.count})`
            element.on(cc.Node.EventType.TOUCH_START, () => {
                this.onEventBtn({ target: element }, (i + 1) + "")
            })
        }
        if (this.nowDay != 1) {
            this.checkPlayEvent()
        }
    }


    getDesc(data, needN = true, showAdd = false, isAdd = true) {
        let str = ""
        for (const key in data) {
            if (Object.prototype.hasOwnProperty.call(data, key)) {
                if (key.split("max_").length > 1) continue
                const element = data[key];
                let symble = isAdd ? `${element > 0 ? "+" : "-"}${Math.abs(element)}` : `-${Math.abs(element)}`
                if (!showAdd) symble = `${Math.abs(element)}`
                str += (`${descName[key] || key} ${symble}` + (data["max_" + key] ? `/${data["max_" + key]}` : ""))
                str += (needN ? "\n" : ",")
            }
        }
        if (needN) str += ("\n")
        return str
    }



    updateNowData() {
        let str = this.getDesc(this.playData, true)
        this.nowData.string = str
    }

    updateTime() {
        this.time.string = `${this.nowDay}`
    }

    updateAction(data?) {
        if (!data) {
            this.tipsNode.string = ""
            return
        }
        // EVENT1: { name: "赚钱", need: { }, cost: { ap: 1 }, award: { coin: 50 } },
        let str = ""
        if (data.name) {
            str += (`行动:${data.name}\n\n`)
        }
        if (data.cost && Object.keys(data.cost).length > 0) {
            str += `${this.getDesc(data.cost, true, true, false)}`
        }
        if (data.award && Object.keys(data.award).length > 0) {
            str += `${this.getDesc(data.award, true, true)}`
        }
        // str += `剩余次数 ${data.count}`
        this.tipsNode.string = str
    }

    updateEvent(data?) {
        if (!data) {
            this.tipsNode.string = "无事发生"
            return
        }
        // EVENT1: { name: "赚钱", need: { }, cost: { ap: 1 }, award: { coin: 50 } },
        let str = ""
        if (data.name) {
            str += (`${data.name}\n\n`)
        }
        if (data.cost && Object.keys(data.cost).length > 0) {
            str += `${this.getDesc(data.cost, true, true, false)}`
        }
        if (data.award && Object.keys(data.award).length > 0) {
            str += `${this.getDesc(data.award, true, true)}`
        }
        this.tipsNode.string = str
    }


    onEventBtn(event, id) {
        if (this.end) return;
        id = Number(id)
        let eventName = `EVENT${id}`
        let data = actionEvent[eventName]
        if (!data) return
        // EVENT1: { name: "赚钱", need: { }, cost: { ap: 1 }, award: { coin: 50 } },
        if (!this.checkCanCost(data, true)) {

            return
        }
        this.changeData(data.cost, false);
        this.changeData(data.award);
        if (data.count != -2) data.count--;
        event.target.getComponentInChildren(cc.Label).string = `${data.name} (${data.count})`
        this.updateAction(data);
        this.updateNowData();
    }

    setTips(desc) {
        this.tipsNode.string = desc
    }

    onNextDayBtn() {
        if (this.end) return;
        this.nowDay++;
        this.cleadDayData()
        this.updateTime()
        this.updateNowData()
        this.updateAction()
        this.save()
        this.checkPlayEvent()
    }

    cleadDayData() {
        this.playData.ap = this.playData.max_ap;
        for (const key in actionEvent) {
            if (Object.prototype.hasOwnProperty.call(actionEvent, key)) {
                const data = actionEvent[key];
                data.count = data.max_count;
                let node = this.btnArr[Number(key.split("EVENT")[1]) - 1]
                if (!node) continue;
                node.getComponentInChildren(cc.Label).string = `${data.name} (${data.count})`
            }
        }
    }

    checkCanCost(data, showTips = false, isCheck = false) {
        if (data.count != -2 && data.count <= 0) {
            data.count == 0
            if (showTips) this.setTips(data.name + "次数达到每日上限")
            return false
        }
        let obj = isCheck ? data.check : data.need
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                const element = obj[key];
                if (key == "day") {
                    if (this.nowDay < element) return false
                    continue
                }
                if (!cc.isValid(this.playData[key])) continue;
                if (this.playData[key] - element < 0) {
                    if (showTips) this.setTips(`${descName[key]}不足`)
                    return false;
                }
            }
        }

        for (const key in data.award) {
            if (Object.prototype.hasOwnProperty.call(data.award, key)) {
                const element = data.award[key];
                if (!cc.isValid(this.playData[key])) continue;
                if (cc.isValid(this.playData["max_" + key]) && this.playData[key] >= this.playData["max_" + key]) {
                    if (showTips) this.setTips(`${descName[key]}已满`)
                    return false;
                }
            }
        }
        return true
    }

    changeData(data, isAdd = true) {
        for (const key in data) {
            if (Object.prototype.hasOwnProperty.call(data, key)) {
                let element = data[key];
                if (cc.isValid(data[key + "_max"])) element = this.randomInt(data[key], data[key + "_max"]);
                if (!cc.isValid(this.playData[key])) continue;
                this.playData[key] = this.playData[key] + (isAdd ? 1 : -1) * element
                if (!cc.isValid(this.playData["min_" + key]) && this.playData[key] < 0) this.playData[key] = 0
                if (cc.isValid(this.playData["max_" + key]) && this.playData[key] > this.playData["max_" + key]) {
                    this.playData[key] = this.playData["max_" + key]
                }
                if (!cc.isValid(this.playData["min_" + key]) && this.playData[key] < this.playData["min_" + key]) {
                    this.playData["min_" + key] = this.playData["min_" + key]
                }
            }
        }
    }

    getSaveData() {
        let data = {
            actionEventAll: actionEvent,
            playData: this.playData,
            nowDay: this.nowDay
        }
        return data
    }
    save() {
        let data = this.getSaveData()
        cc.sys.localStorage.setItem("data", data)
        return data
    }

    checkPlayEvent() {
        let data = null;
        let eventList = [deathEvent, endEvent, reActionEvent]
        for (let i = 0; i < eventList.length; i++) {
            const event = eventList[i];
            for (const key in event) {
                if (Object.prototype.hasOwnProperty.call(event, key)) {
                    const element = event[key];
                    if (element.canSkip == false) {
                        let show = element.rate ? element.rate > Math.random() * 100 : true
                        if (!show) continue;
                        if (!this.checkCanCost(element)) continue;
                        if (this.checkCanCost(element, false, true)) continue;
                        data = element;
                        this.playEventData(data)
                        return;
                    }
                    if (data && !element.weight) continue
                    if (data && element.weight < data.weight) continue
                    if (data && element.eading && element.weight == data.weight && Object.keys(element.need).length < Object.keys(data.need).length) continue
                    if (!this.checkCanCost(element)) continue;
                    let show = element.rate ? element.rate > Math.random() * 100 : true
                    if (!show) continue;
                    data = element;
                }
            }
        }
        this.playEventData(data)
    }

    playEventData(data) {
        if (data) {
            this.changeData(data.cost, false);
            this.changeData(data.award);
            this.updateEvent(data);
            if (data.count != -2) data.count--;
            this.updateNowData();
            if (data.eading) {
                this.setTips(data.desc)
                this.end = true
                return data
            }
            return
        }
        this.tipsNode.string = reActionEvent.EVENT_END.name
    }

    reStartBtn() {
        cc.sys.localStorage.removeItem("data")
        this.nowDay = 1;
        this.end = false;
        this.updateTime()
        this.playData = JSON.parse(JSON.stringify(this.defaultPlayData))
        this.updateNowData()
        this.updateAction()
        this.save()
    }
    randomInt(min, max?) {
        if (min == max) return min;
        if (max === undefined) {
            max = min[1];
            min = min[0];
        }
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2086158.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

渲染农场的收费会受到哪些因素的影响?

我们使用渲染农场时&#xff0c;其实渲染农场的单价并不是最终的单价&#xff0c;因为渲染农场的收费受到很多因素的影响&#xff0c;影响渲染农场收费标准的因素主要包括以下几个方面&#xff1a; 渲染类型 GPU渲染与CPU渲染&#xff1a;通常&#xff0c;GPU渲染由于其高性…

Zookeeper官网Java示例代码解读(一)

2024-08-22 1. 基本信息 官网地址&#xff1a; https://zookeeper.apache.org/doc/r3.8.4/javaExample.html 示例设计思路 Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data. I…

昇思AI框架实践2:基于T5的SQL语句生成模型推理

MindSpore 基于T5的SQL语句生成项目实施 基于T5的SQL语句生成项目介绍 本项目旨在开发一个基于T5-small模型的自然语言转SQL语句生成器。该生成器能够将用户以自然语言形式提出的查询请求转换为对应的SQL查询语句&#xff0c;从而使得即使是不熟悉SQL语言的用户也能够轻松地从…

【Java EE】JVM

目录 1. JVM简介 2.JVM运行流程 3.JVM运行时数据区 3.1 堆&#xff08;线程共享&#xff09; 3.2 Java虚拟机栈&#xff08;线程私有&#xff09; 1. JVM简介 JVM是 Java Virtual Machine 的简称&#xff0c;意为Java虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的…

马克·古尔曼:预计苹果新款Macs要到10月才会发布

马克古尔曼当地时间8月24日在社交媒体平台推特平台发文称&#xff0c;从以往模式来看&#xff0c;预计苹果公司新款Mac要到10月才会发布。 古尔曼称&#xff0c;预计Mac mini将是今年最值得关注的、配置M4芯片的Mac&#xff0c;但预计苹果还会发布新款MacBook Pro。他表示&…

【Qt】网格布局管理器QGridLayout

网格布局管理器QGridLayout Qt中提供QGridLayout用来实现网格布局的效果。 核心属性 整体和 QVBoxLayout 以及 QHBoxLayout 相似. 但是设置 spacing 的时候是按照垂直⽔平两个 ⽅向来设置的. 属性说明 layoutLeftMargin 左侧边距 layoutRightMargin 右侧边距 layoutTo…

类与Object.create之间的继承

前言 ● 下面是一段之前学习Object.create的一段代码 const PersonProto {calcAge() {console.log(2037 - this.birthYear);},init(firstName, birthYear) {this.firstName firstName;this.birthYear birthYear;} };const zhangsan Object.create(PersonProto); ● 和之前…

day-43 括号生成

思路 通过深度优先遍历&#xff0c;把所有可能的组合枚举出来&#xff0c;然后依次判断是否符合括号规则&#xff0c;符合则加入链表 解题过程 判断是否括号规则&#xff1a;第一个位置只能是(&#xff0c;维护一个val值(初始值为0)&#xff0c;遍历字符串&#xff0c;每当加入…

深度强化学习算法(四)(附带MATLAB程序)

深度强化学习&#xff08;Deep Reinforcement Learning, DRL&#xff09;结合了深度学习和强化学习的优点&#xff0c;能够处理具有高维状态和动作空间的复杂任务。它的核心思想是利用深度神经网络来逼近强化学习中的策略函数和价值函数&#xff0c;从而提高学习能力和决策效率…

【项目日记】高并发内存池---实现线程缓存

比起那些用大嗓门企图压制世界的人&#xff0c; 让全世界都安静下来听你小声说话的人更可畏。 --- 韩寒 《告白与告别》--- 高并发内存池项目---实现线程缓存 1 框架设计2 自由链表类和哈希规则2.1 自由链表类2.2 映射规则 3 实现线程缓存3.1 申请内存3.2 释放内存 4 多线程…

day-43 盛最多水的容器

思路 双指针&#xff1a;首先令i0,jheight.length-1,选取短板&#xff08;即Math.min(height[i],height[j])&#xff09;,然后将短板向内移动&#xff0c;直达i>j即可得到答案。 解题过程 短板向内移动&#xff1a;水的容量可能增大 长板向内移动&#xff1a;水的容量不可能…

树莓派5安装系统并配置SSH与VNC权限实现Windows设备远程连接

文章目录 前言1. 使用 Raspberry Pi Imager 安装 Raspberry Pi OS2. Windows安装VNC远程树莓派3. 使用VNC Viewer公网远程访问树莓派3.1 安装Cpolar步骤3.2 配置固定的公网地址3.3 VNC远程连接测试 4. 固定远程连接公网地址4.1 固定TCP地址测试 前言 本文主要介绍如何在树莓派…

数字化转型升级探索(一)

在数字化转型升级的探索中&#xff0c;我们将通过实施综合数字化战略&#xff0c;涵盖从前端用户体验优化到后端系统集成的全方位提升&#xff0c;利用大数据、人工智能、云计算等先进技术对业务流程进行智能化改造&#xff0c;推进自动化和数据驱动决策&#xff0c;推动业务模…

VMware安装Ubuntu 23.10.1系统图文版

文章目录 Ubuntu系统介绍引言Ubuntu系统的特点1. 开源免费2. 易用性3. 稳定性与安全性4. 强大的社区支持 安装与初步设置下载ISO镜像安装1.新建虚拟机2.选择“自定义(高级)”&#xff0c;并点击【下一步】3.选择虚拟机硬件兼容性(默认就好)&#xff0c;并点击【下一步】4.选择“…

爆改yolov8|利用BSAM改进YOLOv8,高效涨点

1&#xff0c;本文介绍 BSAM基于CBAM进行改进&#xff0c;经实测在多个数据集上都有涨点。 BSAM&#xff08;BiLevel Spatial Attention Module&#xff09;是一个用于提升深度学习模型在空间特征处理中的能力的模块。它主要通过双层注意力机制来增强模型对重要空间信息的关注…

一款支持固定区域,固定尺寸大小重复截图的软件

WinSnap是一款功能强大的屏幕截图软件&#xff0c;可以实现对固定区域&#xff0c;固定尺寸大小区域重复截图&#xff0c;适用于日常截图需求和专业用户进行屏幕截图和图像编辑。通过设置快捷键&#xff0c;方便快速重复截图固定区域固定大小。它支持捕捉整个屏幕、活动窗口、选…

H264码流结构讲解

所谓的码流结构就是指&#xff1a;视频经过编码之后所得到的数据是怎样排列的&#xff0c;换句话说&#xff0c;就是编码后的码流我们该如何将一帧一帧的数据分离开来&#xff0c;哪一块数据是一帧图像&#xff0c;哪一块是另外一帧图像&#xff0c;只要了解了这个&#xff0c;…

UE开发中的设计模式(四) —— 组合模式

面试中被面试官问到组合模式和继承有什么区别&#xff0c;给我问懵了&#xff0c;今天又仔细看了下&#xff0c;这不就是UE里的组件吗 >_< 文章目录 问题提出概述问题解决总结组合模式的优缺点继承的优缺点 问题提出 考虑这样一个场景&#xff0c;我们有一个敌人的基类&…

【读书笔记-《30天自制操作系统》-10】Day11

本篇内容继续围绕显示展开。首先对鼠标显示做了些优化&#xff0c;鼠标箭头在到达画面边缘时能够实现部分隐藏&#xff1b;接下来制作了窗口&#xff0c;实现了窗口显示&#xff1b;最后还在窗口的基础上实现了计数器&#xff0c;显示计数的变化并消除闪烁的问题。 1. 画面边…