小白后端游戏开发:装备系统篇

2023年 10月 11日 31.2k 0

前言

上班的第一天,你坐在崭新的工位上,一个头发稀疏、佩戴方形镜框、身穿蓝色立领衬衫黑色牛仔裤,腰间佩戴一串钥匙,名叫李叔的斯文中年男子向你走来。你望着他强者一般的发型和程序员本体的衬衫,心想坏了,又来活了

李叔一脸笑容道:小白,我给你找了一个好活,对你来说一定很简单。

小白假笑问:是什么好活(啊这,我都没有熟悉项目)

李叔:写一个卡牌的装备系统的demo出来,先不用对接属性,完成装备卸下的基础功能就好了,正好一边做一边熟悉项目

李叔:你电脑的环境已经装好了,使用的jdk1.8,mysql是8.0,数据库和协议是封装好了的,使用教程已经发给了你。

差不多就这些了,是不是很简单,你先设计一下数据库表结构和大致的思路,设计完成之后,再找我。

小白:啊?好的(虽然还有些疑惑,不过没有问题,小小的一个装备系统而已难不倒帅气的我)

需求

  • 4个装备槽类型:武器、头盔、铠甲、靴子
  • 每个不同类型装备槽,可以装备或卸下对应类型的装备
  • 一个人可以拥有多个装备,但同时一个装备槽只能装备一件装备

分析

  • 建立数据库,用来保存所有已获得的装备,每个装备需要一个唯一标识id(equip_uid作为装备唯一id)
  • 需要枚举类:装备槽类型和查询类型,有助于代码的可阅读性,避免误计
  • 可通过装备唯一id(equip_uid)或装备槽、从数据库或内存查询对应装备
  • 装备的穿戴/卸下可能涉及多种情况
    • 当前身上已有装备
    • 当前身上没有装备
  • 功能相关协议

    • 查询装备
      • 传参
        • 类型:用于判断查询什么装备(1:所有装备;2:某个类型的所有装备,3:某个装备)
        • 类型参数值:根据类型自定义
    • 装备
      • 传参
        • equip_uid 要穿戴的装备唯一id
        • pos 要穿戴的装备槽
    • 卸下
      • 传参
        • pos 卸下装备的装备槽

    开发

    建立数据库

    建立数据库前,分析自身需要保存的数据:

    • equip_uid 游戏中装备的唯一id,用于定位装备
    • uid 装备属于哪一个玩家,玩家的唯一标识id
    • equip_id 配表中装备的唯一id,用于查询配表中的数据(品质,装备类型,可增加的属性等)
    • hero_id 玩家穿戴此装备的英雄id(如果玩家有多个名叫盖伦的英雄并且可以给多个盖伦穿戴装备,每个盖伦都要有一个唯一的英雄id:hero_uid)
    • level 装备等级

    建表语句

    CREATE TABLE `u_equip` (
      `equip_uid` bigint(20) NOT NULL AUTO_INCREMENT,
      `uid` bigint(20) NOT NULL DEFAULT '0',
      `equip_id` int(11) DEFAULT NULL,
      `hero_id` int(11) DEFAULT '0',
      `level` int(11) DEFAULT '0',
      PRIMARY KEY (`equip_uid`),
      KEY `idx_equip_2` (`uid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=100000700 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    

    大致说明一下建表语句后面的属性(一般数据库配置,不需要每次建表都写):

    • ENGINE=InnoDB:指定数据库表存储引擎。存储引擎是一种决定如何存储和管理数据的技术。不做详细解释,InnoDB是MYSQL中常用引擎之一。
    • AUTO_INCREMENT=100000700:表明自增逐渐从100000700开始递增,每插入一行记录该列的值会自动加1
    • DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci:这部分定义了表中的字符集和字符排序规则。

    创建好数据库表后,就可以通过sql语句对装备操作进行序列化。

    公司一般都有完整的导表、到数据库表的工具,将表和数据库表转化为javabean。类似于下面的结构:

    public class TBI_U_Equip implements Serializable {
        private long equip_uid;
        private long uid;
        private int equip_id;
        private int hero_id;
        private int level;
    
    
        public long getEquip_uid() {
            return equip_uid;
        }
    
        public void setEquip_uid(long equip_uid) {
            this.equip_uid = equip_uid;
        }
    
        public long getUid() {
            return uid;
        }
    
        public void setUid(long uid) {
            this.uid = uid;
        }
    
        public int getEquip_id() {
            return equip_id;
        }
    
        public void setEquip_id(int equip_id) {
            this.equip_id = equip_id;
        }
    
        public int getHero_id() {
            return hero_id;
        }
    
        public void setHero_id(int hero_id) {
            this.hero_id = hero_id;
        }
    
        public int getLevel() {
            return level;
        }
    
        public void setLevel(int level) {
            this.level = level;
        }
    }
    

    公司工具导出的类可能会包含更多的信息,但是使用的逻辑大致相同。

    创建枚举类

    //装备槽枚举
    public enum EquipTypeEnum {
        武器(1),
        头盔(2),
        铠甲(3),
        靴子(4),
        ;
    
        private int id;
    
        EquipTypeEnum(int id) {
            this.id = id;
        }
    
    
        public int getId() {
            return id;
        }
    }
    
    //  装备查询类型枚举
    public enum EquipQueryEnum {
        ALL(1),
        POS(2),
        DETAIL_ONE(3),
        ;
    
        private int id;
    
        EquipQueryEnum(int id) {
            this.id = id;
        }
    
    
        public int getId() {
            return id;
        }
    }
    

    为了方便代码的可阅读性,避免记错装备槽的id

    创建装备管理类

    通过装备管理类来进行数据库的查询、穿戴装备、卸下装备。下面是一个简单的实例:

    public enum EquipMgr {
        Instance;
    
    
        public List queryAll( long uid){
            List list = new ArrayList();
            /**
             *  todo sql语句查询数据库得到所有装备
            */
            return list;
        }
    
        public List queryPoAll(long uid,int pos){
            List list = new ArrayList();
            /**
             *  todo sql语句查询数据库指定位置的所有的装备
             */
            return list;
        }
    
        public TBI_U_Equip queryOne(long equipUid){
            //  todo sql语句查询数据库中指定装备,有则返回,无则返回null
            return new TBI_U_Equip();
        }
    
        public TBI_U_Equip queryHeroPos(int heroId, int pos){
            //  TODO    sql语句查询数据中指定英雄某个pos的装备,有则返回,无则返回null
            return new TBI_U_Equip();
        }
    
        public void insert(int equipId){
            //  todo    根据equipId查询配表,得到相关数据
            
            //  todo    写sql语句插入装备
        }
    
        public void takeOn(long equipUid,int heroId,int pos) throws Exception {
            TBI_U_Equip one = queryOne(equipUid);
    
            //  todo    1.检测装备是否存在,不存在抛出异常,一般使用自动的exception供客户端检测并显示文本
            if(one == null){
                throw new Exception("无此装备");
            }
    
            int equipId = one.getEquip_id();
            //  todo    2.根据配表id(equip_id)查询配表检测是否与pos相同
    
            /**
             * 根据equipId读取配表拿到数据
             * 检测配表数据中的pos与指定pos是否相同,不同,抛出异常
             */
    
            //  todo    3.查询指定英雄指定pos是否存在装备
            takeOff(heroId,pos);
    
            //  todo    4.更新javabean并更新数据库
        }
    
        public void takeOff(int heroId,int pos){
            /**
             * todo
             * 1.   检测指定英雄位置是否有装备,没有装备直接return
             * 3.   更新穿戴装备one的hero_id为0
             */
            TBI_U_Equip one = queryHeroPos(heroId, pos);
            if(one == null){
                return;
            }
            one.setHero_id(0);
    
            //  todo    更新数据库...
        }
    }
    

    实际业务会更加复杂,但是总体思路并无太大区别。

    最后

    希望对大家有所帮助,以上内容就到这里,感谢各位看官老爷们的观看,后续我会写数据库转换工具和配表转换工具包,如果觉得写得好,给个赞支持一下哈!!!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论