从零开始手写mmo游戏从框架到爆炸(二十三)— 装备系统一

导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客

目录

装备模板

装备模型

装备模板配置

加载装备模板


        下一步,就是要考虑经验、金币、和装备掉落的问题。经验金币都好说,装备系统是目前需要考虑的问题。

       为了简化我们把装备分成武器、胸甲两个部位,后期可以慢慢扩展。此时我们还是需要装备

模板。这个功能和之前的野怪模板、地图模板差不多。

装备模板

        物品模板类- GoodsTemplate :

@Data
public class GoodsTemplate implements Serializable {

    private int id;

    private String name;

    private String type;

    private int level;

    private String desc;
}

       装备模板类:

/**
 * @version 1.0.0
 * @description: 装备的模板类
 * @author: eric
 * @date: 2024-02-23 10:33
 **/
@Data
public class EquipmentTemplate extends GoodsTemplate {

    private String strength;                  // 力量 影响物理输出 物理技能输出
    private String armature;                 // 护甲值 影响物理防御和法术防御
    private String constitution;               // 体质 影响生命值 一点体质增加10点生命值
    private String magic;                       // 魔力 影响法术输出 法术技能输出
    private String technique;                   // 技巧 影响闪避率、暴击率
    private String speed;                         // 攻击速度

    private String hp;                            // 生命值

    private String evasion;

    private String fortune;

    private int weaponType;

    private int suitId;

    // 毒抗
    private String poisonResistance;

    // 火抗
    private String flameResistance;

    // 电抗
    private String thunderResistance;

    // 冰抗
    private String iceResistance;

    // 特殊效果
    private String effects;
    
    @Override
    public String toString() {
        return "EquipmentTemplate{" +
                "id='" + getId() + '\'' +
                ", name='" + getName() + '\'' +
                ", type='" + getType() + '\'' +
                ", level=" + getLevel() +
                ", desc='" + getDesc() + '\'' +
                ", strength=" + strength +
                ", armature=" + armature +
                ", constitution=" + constitution +
                ", magic=" + magic +
                ", technique=" + technique +
                ", speed=" + speed +
                ", hp=" + hp +
                ", evasion='" + evasion + '\'' +
                ", fortune='" + fortune + '\'' +
                ", weaponType=" + weaponType +
                '}';
    }
}

装备模型

          装备是物品的一种,物品应该包括装备、耗材、任务物品、宠物蛋等等。

          所以首先定义一个物品父类 Goods:

@Data
public abstract class Goods implements Serializable {

    private String id;

    private Integer goods_id = 0;

    private String name;

    private String type;

    private int level;

    private String desc;

    public  String string ="\t\t\t\t\t\t\t\t\t";

    // 品质
    public QualityEnum quality;

    // 毒抗
    private int poisonResistance;

    // 火抗
    private int flameResistance;

    // 电抗
    private int thunderResistance;

    // 冰抗
    private int iceResistance;

    public Goods(){

    }

    // 没有等级的物品
    public Goods(String name, String type, String desc, QualityEnum quality, int goodsId) {
        this.name = name;
        this.type = type;
        this.desc = desc;
        this.quality = quality;
        this.goods_id = goodsId;
        this.id = UUID.randomUUID().toString().replace("-","");
    }

    // 有等级的物品
    public Goods(String name, String type, String desc, QualityEnum quality, int level,
                 int poisonResistance, int flameResistance, int thunderResistance, int iceResistance,
                 int goodsId) {
        this(name,type,desc,quality,goodsId);
        this.level = level;
        this.poisonResistance = poisonResistance;
        this.flameResistance = flameResistance;
        this.thunderResistance = thunderResistance;
        this.iceResistance = iceResistance;
    }

    // 物品打印信息的重写
    public String toString() {
        return  string+"****物品信息****\n"+
                string+"名称:"+this.name+"\n"+
                string+"类型:"+this.type +"\n"+
                string+"说明:"+this.desc +"\n"+
                string+""+"***************";
    }

    // 物品打印信息的重写
    public String prettyPrint() {
        return  string+"****物品信息****\n"+
                string+"名称:"+ this.name+"\n"+
                string+"品质:"+ this.quality.getDesc() +"\n"+
                string+"说明:"+ this.desc +"\n"+
                string+""+"***************";
    }
}

        接着对装备进行定义,装备就要有位置,武器就要有类型,这里我们定义两个枚举类 EquipmentEnum 和 WeaponTypeEnum

/**
 * 装备的位置
 *
 * @author eric
 * @version 1.0.0
 */
public enum EquipmentEnum {

    WEAPON("weapon", "武器", 1),
    SHIELD("shield", "盾牌",2),
    SHOES("shoes", "鞋子", 3),
    HELMET("helmet", "头盔", 4),
    GLOVES("gloves", "手套", 5),
    NECKLACE("necklace", "项链", 6),
    TALISMAN("talisman", "护身符", 7),
    LEFTRING("leftRing", "左戒", 8),
    RIGHTRING("rightRing", "右戒", 9),
    LEGARMOR("legArmor", "腿甲", 10),
    BELT("belt", "腰带", 11),
    BARCER("barcer", "护臂", 12),
    SHOULDER("shoulder", "肩甲", 13),
    BREASTPLATE("breastplate", "胸甲",14),
    UNKOWN("unkown", "其他", 15);

    public final static int total = 14;

    private String code;

    private String desc;

    private int posNum;

    EquipmentEnum(String code, String desc, int posNum) {
        this.code = code;
        this.desc = desc;
        this.posNum = posNum;
    }

    public static EquipmentEnum getByCode(String code){
        Optional<EquipmentEnum> optional =
                Arrays.stream(EquipmentEnum.values())
                        .filter(v -> Objects.equals(v.getCode(), code))
                        .findFirst();

        return optional.orElse(EquipmentEnum.UNKOWN);
    }

    public static EquipmentEnum getByPosNum(int posNum){
        Optional<EquipmentEnum> optional =
                Arrays.stream(EquipmentEnum.values())
                        .filter(v -> v.getPosNum() == posNum)
                        .findFirst();

        return optional.orElse(EquipmentEnum.UNKOWN);
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public int getPosNum() {
        return posNum;
    }
}
/**
 * 武器类型
 *
 * @author eric
 * @version 1.0.0
 */
public enum WeaponTypeEnum {

    SWORD(1, "长剑"),
    WAND(2, "魔杖"),
    DAGGER(3, "匕首"),
    GUN(4, "枪类"),
    HAMMER(5, "锤类"),
    AXE(6, "斧类"),
    STICK(7, "棍类");

    private Integer code;

    private String desc;

    WeaponTypeEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public static WeaponTypeEnum getByCode(int code){
        Optional<WeaponTypeEnum> optional =
                Arrays.stream(WeaponTypeEnum.values())
                        .filter(v -> Objects.equals(v.getCode(), code))
                        .findFirst();

        return optional.orElse(WeaponTypeEnum.SWORD);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

        武器的类型其实很有用处,比如不同的职业只能使用一种武器类型。

       我们来定义装备模型 - Equipment:

@Data
public class Equipment extends Goods {

    private int suitId;                   // 如果是套装,套装的id
    private int strength;                  // 力量 影响物理输出 物理技能输出
    private int armature;                 // 护甲值 影响物理防御和法术防御
    private int constitution;               // 体质 影响生命值 一点体质增加10点生命值
    private int magic;                       // 魔力 影响法术输出 法术技能输出
    private int technique;                   // 技巧 影响闪避率、暴击率
    private int speed;                         // 攻击速度

    private int hp;                            // 生命值
    private int evasion;

    private int fortune;

    private boolean used = false;   // 是否被使用

    // 如果constant == true,不能增加前缀,属于固定属性装备
    private boolean constant = false;

    // 如果specifyDrop == true,只有特定的副本或者特定的野怪才能掉落
    private boolean specifyDrop = false;

    // 武器位置
    public EquipmentEnum equipmentPosition;

    // 武器类型
    private WeaponTypeEnum weaponTypeEnum;

    private int difference;

    public Equipment(String name, String type, String desc, QualityEnum quality, int strength,
                     int armature, int constitution, int magic, int technique, int speed, int hp,
                     int evasion, int fortune, boolean used, boolean constant, boolean specifyDrop,
                     EquipmentEnum equipmentPosition, List<String> affixList,
                     WeaponTypeEnum weaponTypeEnum, int suitId, int level, int poisonResistance,
                     int flameResistance, int thunderResistance, int iceResistance,  int goodsId) {
        this(name, type, desc, quality, strength, armature, constitution, magic, technique, speed,
                hp, evasion, fortune, used, equipmentPosition, weaponTypeEnum, affixList, level,
                poisonResistance,flameResistance,thunderResistance,iceResistance,goodsId);
        this.constant = constant;
        this.specifyDrop = specifyDrop;
        this.suitId = suitId;
    }

    public Equipment(String name, String type, String desc, QualityEnum quality, int strength,
                     int armature, int constitution, int magic, int technique, int speed, int hp,
                     int evasion, int fortune, boolean used, EquipmentEnum equipmentPosition,
                     WeaponTypeEnum weaponTypeEnum, List<String> affixList, int level,
                     int poisonResistance, int flameResistance, int thunderResistance, int iceResistance,
                     int goodsId) {
        super(name, type, desc, quality, level,poisonResistance,flameResistance,
                thunderResistance,iceResistance,goodsId);
        this.strength = strength;
        this.armature = armature;
        this.constitution = constitution;
        this.magic = magic;
        this.technique = technique;
        this.speed = speed;
        this.hp = hp;
        this.evasion = evasion;
        this.fortune = fortune;
        this.equipmentPosition = equipmentPosition;
        this.weaponTypeEnum = weaponTypeEnum;
        this.used = used;
        if(affixList == null){
            affixList = new ArrayList<>();
        }
    }

    public Equipment(String name, String type, String desc, EquipmentEnum equipmentEnum,
                     QualityEnum quality, int goodsId) {
        super(name, type, desc, quality,goodsId);
        this.equipmentPosition = equipmentEnum;
    }

    // 物品打印信息的重写
    @Override
    public String toString() {
        return "*物品信息* " +
                "名称:" + getName() + " " + "级别:" + getLevel() + " " +
                "品质:" + this.quality.getColor() + this.quality.getDesc() + ConsoleColors.RESET + " " +
                (strength > 0 ? ("力量:" + strength + " ") : "") +
                (armature > 0 ? ("护甲:" + armature + " ") : "") +
                (constitution > 0 ? ("体力:" + constitution + " ") : "") +
                (magic > 0 ? ("魔力:" + magic + " ") : "") +
                (technique > 0 ? ("技巧:" + technique + " ") : "") +
                (speed > 0 ? ("速度:" + speed + " ") : "") +
                (getPoisonResistance() > 0 ? ("毒抗:" + getPoisonResistance() + " ") : "") +
                (getFlameResistance() > 0 ? ("火抗:" + getFlameResistance() + " ") : "") +
                (getThunderResistance() > 0 ? ("雷抗:" + getThunderResistance() + " ") : "") +
                (getIceResistance() > 0 ? ("冰抗:" + getIceResistance() + " ") : "") +
                ";";
    }

    // 物品打印信息的重写
    public String prettyPrint() {
        return string + "****物品信息****\n" +
                string + "名称:" + getName() + "\n" +
                string + "品质:" + this.quality.getColor() + this.quality.getDesc() + ConsoleColors.RESET + "\n" +
                string + "位置:" + Optional.ofNullable(this.getEquipmentPosition()).orElse(EquipmentEnum.UNKOWN).getDesc() + "\n" +
                string + "说明:" + getDesc() + "\n" +
                (strength > 0 ? (string + "力量:" + strength + "\n") : "") +
                (armature > 0 ? (string + "护甲:" + armature + "\n") : "") +
                (constitution > 0 ? (string + "体力:" + constitution + "\n") : "") +
                (magic > 0 ? (string + "魔力:" + magic + "\n") : "") +
                (technique > 0 ? (string + "技巧:" + technique + "\n") : "") +
                (speed > 0 ? (string + "速度:" + speed + "\n") : "") +
                (getPoisonResistance() > 0 ? (string + "毒抗:" + getPoisonResistance() + "\n") : "") +
                (getFlameResistance() > 0 ? (string + "火抗:" + getFlameResistance() + "\n") : "") +
                (getThunderResistance() > 0 ? (string + "雷抗:" + getThunderResistance() + "\n") : "") +
                (getIceResistance() > 0 ? (string + "冰抗:" + getIceResistance() + "\n") : "") +
                string + "" + "***************";
    }

}

针对武器,我们再定义武器的模型:

public class Weapon extends Equipment {

    public Weapon(String name, String type, String desc, EquipmentEnum equipmentEnum,
                  WeaponTypeEnum weaponTypeEnum,
                  QualityEnum quality, int goodsId) {
        super(name, type, desc, equipmentEnum, quality,goodsId);
        this.setWeaponTypeEnum(weaponTypeEnum);
    }

}

装备模板配置

       在resource路径下补充装备的json,我们不同部位的装备,使用不同的json来区分。

内容如下:

 weapon.json

[
  {
    "id":1,
    "name":"木剑",
    "type":"weapon",
    "level":1,
    "desc":"最普通的剑,无任何附加属性",
    "strength":"1-10",
    "armature":"0-0",
    "constitution":"0-0",
    "technique":"0-0",
    "speed":"0-0",
    "hp":"0-0",
    "magic":"0-0",
    "evasion":"0-0",
    "fortune":"0-0",
    "weaponType":1,
    "total":10
  },
  {
    "id":10,
    "name":"短剑",
    "type":"weapon",
    "level":5,
    "desc":"最普通的剑,无任何附加属性",
    "strength":"10-20",
    "armature":"0-0",
    "constitution":"10-20",
    "technique":"10-20",
    "speed":"0-0",
    "hp":"0-0",
    "magic":"0-0",
    "evasion":"0-0",
    "fortune":"0-0",
    "weaponType":1,
    "total":"60"
  }
]

breastplate.json

[
  {
    "id":301,
    "name":"布甲",
    "type":"breastplate",
    "level": 1,
    "desc":"布甲",
    "strength": "0-0",
    "armature": "5-10",
    "constitution": "5-20",
    "technique": "0-0",
    "speed": "0-0",
    "hp": "0-0",
    "magic": "0-0",
    "evasion": "0-0",
    "fortune": "0-0"
  }
]

加载装备模板

        我们创建一个装备工厂,用于加载装备模板,同时生产装备 - EquipmentFactory

/**
 * @version 1.0.0
 * @description: 装备工厂
 * @author: eric
 * @date: 2023-02-23 10:34
 **/
public class EquipmentFactory {

    private static List<EquipmentTemplate> allEquipmentTemplates;
    private static List<EquipmentTemplate> weaponTemplates;
    private static Map<Integer,EquipmentTemplate> weaponTemplateIdMap;


    static {
        try {
            // 读取配置文件,然后加载到weaponTemplates中
            ClassLoader classLoader = EquipmentFactory.class.getClassLoader();

            InputStream inputStream = classLoader.getResourceAsStream("template/equipments/weapon.json");

            BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();

            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            weaponTemplates = JSONArray.parseArray(responseStrBuilder.toString(),EquipmentTemplate.class);
            weaponTemplateIdMap = weaponTemplates.stream().collect(Collectors.toMap(EquipmentTemplate::getId, e->e));


            if(allEquipmentTemplates == null){
                allEquipmentTemplates = new ArrayList<>();
            }
            allEquipmentTemplates.addAll(weaponTemplates);

            // 加载其他的普通装备
            String path = classLoader.getResource("template/equipments").getFile();//注意getResource("")里面是空字符串
            File file = new File(path);
            File[] files = file.listFiles();
            for (File f : files) {
                if(f.getName().equals("weapon.json")){
                    continue;
                }
                String fileName = "template/equipments/" + f.getName();
                inputStream = classLoader.getResourceAsStream(fileName);

                streamReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                responseStrBuilder = new StringBuilder();

                String str;
                while ((str = streamReader.readLine()) != null)
                    responseStrBuilder.append(str);

                List<EquipmentTemplate> equipmentTemplates = JSONArray.parseArray(responseStrBuilder.toString(),EquipmentTemplate.class);
                allEquipmentTemplates.addAll(equipmentTemplates);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }

    public static List<EquipmentTemplate> getWeaponTemplates() {
        return weaponTemplates;
    }

    public static void main(String[] args) {
        for (EquipmentTemplate template : allEquipmentTemplates) {
            System.out.println(template.toString());
        }

    }

}

        好,下一章我们来完成装备的生成

全部源码详见:

gitee : eternity-online: 多人在线mmo游戏 - Gitee.com

分支:step-12

请各位帅哥靓女帮忙去gitee上点个星星,谢谢! 

  • 25
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值