从零开始手写mmo游戏从框架到爆炸(二十七)— 英雄属性展示及穿戴装备-1

本文主要是介绍从零开始手写mmo游戏从框架到爆炸(二十七)— 英雄属性展示及穿戴装备-1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

        本章我们把命令行客户端与后台串起来,并完成穿戴装备的功能。

服务端改造

        首先改造角色抽象类

         增加穿戴的装备抽象(野怪也可以穿戴装备)

public abstract class Character implements Attackable, Serializable {// 装备的装备private Equips equips;public Equips getEquips() {if(equips == null){equips = new Equips();}return equips;}public void setEquips(Equips equips) {this.equips = equips;}

        穿戴装备的抽象

@Data
public class Equips implements Serializable {public  String string ="\t\t\t\t\t\t\t\t\t";public  String tt ="\t\t";private List<Equipment> all;public Equips(){all = new ArrayList<>();}public Equips(String string, Equipment weapon, Equipment leftRing, Equipment rightRing, Equipment breastplate, Equipment shoes,Equipment helmet, Equipment glove, Equipment necklace, Equipment legArmor, Equipment belt, Equipment barcer,Equipment shoulder, Equipment shield) {all = new ArrayList<>();this.string = string;this.weapon = weapon;this.leftRing = leftRing;this.rightRing = rightRing;this.breastplate = breastplate;this.shoes = shoes;this.helmet = helmet;this.glove = glove;this.necklace = necklace;this.legArmor = legArmor;this.belt = belt;this.barcer = barcer;this.shoulder = shoulder;this.shield = shield;initAll();}private void initAll() {if(weapon != null){all.add(weapon);}if(leftRing != null){all.add(leftRing);}if(leftRing != null){all.add(leftRing);}if(breastplate != null)all.add(breastplate);if(shoes != null)all.add(shoes);if(helmet != null)all.add(helmet);if(glove != null)all.add(glove);if(necklace != null)all.add(necklace);if(legArmor != null)all.add(legArmor);if(belt != null)all.add(belt);if(barcer != null)all.add(barcer);if(shoulder != null)all.add(shoulder);if(shield != null)all.add(shield);}// 装备的武器private Equipment weapon;// 装备的戒指 左戒private Equipment leftRing;// 装备的戒指 右戒private Equipment rightRing;// 装备的护甲private Equipment breastplate;// 装备的鞋private Equipment shoes;// 装备的头盔private Equipment helmet;// 装备的手套private Equipment glove;// 装备的项链private Equipment necklace;// 装备的腿甲private Equipment legArmor;// 装备的腰带private Equipment belt;// 装备的护壁private Equipment barcer;// 装备的肩甲private Equipment shoulder;// 装备的盾牌private Equipment shield;public String prettyPrint() {return  string+"****装备信息**********************************************************\n"+tt + "武器:" + (getWeapon() == null ? "无" : getWeapon().toString()) +"\n"+tt + "盾牌:" + (getShield() == null ? "无" : getShield().toString()) +"\n"+tt + "胸甲:" + (getBreastplate() == null ? "无" : getBreastplate().toString()) +"\n"+tt + "头盔:" + (getHelmet() == null ? "无" : getHelmet().toString()) +"\n"+tt + "肩甲:" + (getShoulder() == null ? "无" : getShoulder().toString()) +"\n"+tt + "护壁:" + (getBarcer() == null ? "无" : getBarcer().toString()) +"\n"+tt + "手套:" + (getGlove() == null ? "无" : getGlove().toString()) +"\n"+tt + "腰带:" + (getBelt() == null ? "无" : getBelt().toString()) +"\n"+tt + "腿甲:" + (getLegArmor() == null ? "无" : getLegArmor().toString()) +"\n"+tt + "鞋子:" + (getShoes() == null ? "无" : getShoes().toString()) +"\n"+tt + "左戒:" + (getLeftRing() == null ? "无" : getLeftRing().toString()) +"\n"+tt + "右戒:" + (getRightRing() == null ? "无" : getRightRing().toString()) +"\n"+tt + "项链:" + (getNecklace() == null ? "无" : getNecklace().toString()) +"\n"+string+""+"************************************************************";}public Equipment findByPosition(EquipmentEnum equipmentEnum){if(equipmentEnum.equals(EquipmentEnum.WEAPON))return this.getWeapon();if(equipmentEnum.equals(EquipmentEnum.BARCER))return this.getBarcer();if(equipmentEnum.equals(EquipmentEnum.BELT))return this.getBelt();if(equipmentEnum.equals(EquipmentEnum.BREASTPLATE))return this.getBreastplate();if(equipmentEnum.equals(EquipmentEnum.GLOVES))return this.getGlove();if(equipmentEnum.equals(EquipmentEnum.HELMET))return this.getHelmet();if(equipmentEnum.equals(EquipmentEnum.LEFTRING))return this.getLeftRing();if(equipmentEnum.equals(EquipmentEnum.LEGARMOR))return this.getLegArmor();if(equipmentEnum.equals(EquipmentEnum.NECKLACE))return this.getNecklace();if(equipmentEnum.equals(EquipmentEnum.RIGHTRING))return this.getRightRing();if(equipmentEnum.equals(EquipmentEnum.SHIELD))return this.getShield();if(equipmentEnum.equals(EquipmentEnum.SHOES))return this.getShoes();if(equipmentEnum.equals(EquipmentEnum.SHOULDER))return this.getShoulder();return null;}public List<Equipment> getAll() {return all;}
}

       穿脱装备的功能开发

        新增一个接口 WearEquipment

public interface WearEquipment {String wear(Equipment equipment, int weaponType);String takeOff(Equipment equipment);
}

        在角色抽象类Character 中来实现:

 @Overridepublic Tuple<String, List<String>> wear(Equipment equipment, int weaponType) {Tuple<String, List<String>> result = new Tuple<>();result.setValue(new ArrayList<>());String takeOffEquipmentId = null;// 装备级别要小于等于英雄的等级if(equipment.getLevel() > 1 && equipment.getLevel() > getLevel()){result.getValue().add("对不起,装备等级高于英雄,无法穿戴");result.setKey(null);return result;}// 先看同类的是否存在,如果存在,先脱再穿EquipmentEnum equipmentPosition = equipment.getEquipmentPosition();switch (equipmentPosition.getCode().toLowerCase()) {case "weapon":if(weaponType != equipment.getWeaponTypeEnum().getCode()){result.getValue().add("对不起,该武器不适合英雄,无法穿戴");result.setKey(null);return result;}if (equips.getWeapon() != null) {takeOffEquipmentId = takeOff(equips.getWeapon());}equips.setWeapon(equipment);break;case "breastplate":if (equips.getBreastplate() != null) {takeOffEquipmentId = takeOff(equips.getBreastplate());}equips.setBreastplate(equipment);break;case "shield":if (equips.getShield() != null) {takeOffEquipmentId = takeOff(equips.getShield());}equips.setShield(equipment);break;case "shoes":if (equips.getShoes() != null) {takeOffEquipmentId = takeOff(equips.getShoes());}equips.setShoes(equipment);break;case "helmet":if (equips.getHelmet() != null) {takeOffEquipmentId = takeOff(equips.getHelmet());}equips.setHelmet(equipment);break;case "gloves":if (equips.getGlove() != null) {takeOffEquipmentId = takeOff(equips.getGlove());}equips.setGlove(equipment);break;case "necklace":if (equips.getNecklace() != null) {takeOffEquipmentId = takeOff(equips.getNecklace());}equips.setNecklace(equipment);break;case "leftring":if (equips.getLeftRing() != null) {takeOffEquipmentId = takeOff(equips.getLeftRing());}equips.setLeftRing(equipment);break;case "rightring":if (equips.getRightRing() != null) {takeOffEquipmentId = takeOff(equips.getRightRing());}equips.setRightRing(equipment);break;case "legarmor":if (equips.getLegArmor() != null) {takeOffEquipmentId = takeOff(equips.getLegArmor());}equips.setLegArmor(equipment);break;case "belt":if (equips.getBelt() != null) {takeOffEquipmentId =  takeOff(equips.getBelt());}equips.setBelt(equipment);break;case "barcer":if (equips.getBarcer() != null) {takeOffEquipmentId = takeOff(equips.getBarcer());}equips.setBarcer(equipment);break;case "shoulder":if (equips.getShoulder() != null) {takeOffEquipmentId = takeOff(equips.getShoulder());}equips.setShoulder(equipment);break;default:result.getValue().add("穿戴装备失败" + equipment.getName());result.setKey(null);return result;}List<String> lines = wearEquipment(equipment);result.getValue().addAll(lines);result.setKey(takeOffEquipmentId);return result;}@Overridepublic String takeOff(Equipment equipment) {// 脱装备就是整体属性下降this.setStrength(this.strength - equipment.getStrength());this.setArmature(this.armature - equipment.getArmature());this.setConstitution(this.constitution - equipment.getConstitution());this.hp.addAndGet(-equipment.getHp());this.setMagic(this.magic - equipment.getMagic());this.setTechnique(this.technique - equipment.getTechnique());this.setSpeed(this.speed - equipment.getSpeed());this.setPoisonResistance(this.poisonResistance - equipment.getPoisonResistance());this.setFlameResistance(this.flameResistance - equipment.getFlameResistance());this.setThunderResistance(this.thunderResistance - equipment.getThunderResistance());this.setIceResistance(this.iceResistance - equipment.getIceResistance());equipment.setUsed(false);return equipment.getId();}private List<String> wearEquipment(Equipment equipment) {List<String> result = new ArrayList<>();result.add("穿戴装备" + equipment.getName() + " 成功");// 穿装备就是整体属性提升this.setStrength(this.strength + equipment.getStrength());this.setArmature(this.armature + equipment.getArmature());this.setConstitution(this.constitution + equipment.getConstitution());this.hp.addAndGet(equipment.getConstitution() * 10 + equipment.getHp());this.hpMax = this.hp.get();this.setMagic(this.magic + equipment.getMagic());this.setTechnique(this.technique + equipment.getTechnique());this.setSpeed(this.speed + equipment.getSpeed());// 装备提升的抗性this.setThunderResistance(this.thunderResistance + equipment.getThunderResistance());this.setFlameResistance(this.flameResistance + equipment.getFlameResistance());this.setPoisonResistance(this.poisonResistance + equipment.getPoisonResistance());this.setIceResistance(this.iceResistance + equipment.getIceResistance());equipment.setUsed(true);return result;}

         新增接口

          新增装备列表和穿戴装备接口,以及获得个人属性接口- ServerHeroTag

package com.loveprogrammer.command.server;public interface ServerHeroTag {/**** 创建英雄*/int TAG_HERO_CREATE = 1;/**** 英雄的详情*/int TAG_HERO_INFO = 2;/**** 英雄装备列表*/int TAG_HERO_EQUIP_LIST = 3;/**** 英雄穿戴装备*/int TAG_HERO_EQUIP_WEAR = 4;
}

          英雄详情查询

           英雄查询返回体:

HeroInfo

@Data
public class HeroInfo extends RequestBase {public HeroInfo() {}public String string = "\t\t\t\t\t\t\t\t\t";private int id;                         // 角色idprivate String name;                   // 角色信息模板private int strength;                  // 力量 影响物理输出 物理技能输出private int armature;                 // 护甲值 影响物理防御和法术防御private int constitution;               // 体质 影响生命值 一点体质增加10点生命值private int magic;                       // 魔力 影响法术输出 法术技能输出private int technique;                   // 技巧 影响闪避率、暴击率private int speed;                         // 攻击速度private int hpMax;                        // 最大生命值private int level;                           // 级别private Integer currentExp;/*** 下一级所需经验值**/private Integer nextLevelNeedExp;// 毒抗private int poisonResistance;// 火抗private int flameResistance;// 电抗private int thunderResistance;// 冰抗private int iceResistance;//角色打印信息的重写public String prettyPrint() {return string + "*****信息****\n" +string + "姓名:" + this.name + "\n" +string + "级别" + this.level + "\n" +string + "血量:" + this.hpMax + "\n" +string + "力量:" + this.strength + "\n" +string + "法力:" + this.magic + "\n" +string + "技巧:" + this.technique + "\n" +string + "护甲值" + this.armature + "\n" +string + "速度" + this.speed + "\n" +string + "毒抗" + this.poisonResistance + "\n" +string + "火抗" + this.flameResistance + "\n" +string + "雷抗" + this.thunderResistance + "\n" +string + "冰抗" + this.iceResistance + "\n" +string + "当前经验" + this.currentExp + "\n" +string + "下一级经验" + this.nextLevelNeedExp + "\n" +string + "" + "*************";}//角色打印信息的重写public String toString() {return "**** 名称:" + this.name + " " +"级" + this.level + " " +"血:" + this.hpMax + " " +"甲: " + this.armature + " " +"力:" + this.strength + " " +"法:" + this.magic + " " +"技:" + this.technique + " " +"速:" + this.speed + " " +"抗性[毒:" + this.poisonResistance + " " +"火:" + this.flameResistance + " " +"雷:" + this.thunderResistance + " " +"冰:" + this.iceResistance + "] " +"经验(" + this.currentExp + "/" + this.nextLevelNeedExp + ") ****";}
}

        

HeroHandler

@TagListener(tag = ServerHeroTag.TAG_HERO_INFO,messageClass = StringRequest.class)public StringMessage getHeroInfo(ChannelHandlerContext ctx, StringRequest data) throws Exception {int sessionId = getSessionId(ctx.channel());UserGameWrapper gameWrapper = SessionGameContext.USER_GAME_MAP.get(sessionId);HeroWrapper currentHero = gameWrapper.getCurrentHero();// 转成英雄详情HeroInfo heroInfo = HeroConvert.INSTANCE.toHeroInfo(currentHero.getHero());StringMessage message = StringMessage.create(data.getSuccessCallbackTopic(), data.getSuccessCallbackTag());message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);message.setBody(JSON.toJSONString(heroInfo));return message;}

客户端改造

        补充展示命令 ClientSceneTag

public interface ClientSceneTag {/**** 战斗场景*/int TAG_SCENE_BATTLE = 1;/**** 英雄属性查看*/int TAG_SCENE_HERO = 2;
}

        展示功能- 改造portalMenu

@TagListener(tag = ClientMenuTag.TAG_MENU_PORTAL,messageClass = StringRequest.class)public void portalMenu(ChannelHandlerContext ctx, StringRequest msg){ConsolePrint.publishMessage(msg.getContent());// 展示首页数据ConsolePrint.publishMessage("请选择您要进行的操作");ConsolePrint.publishMessage("【1.打怪】  【2.属性及装备】  【3.战兽】");ConsolePrint.publishMessage("【4.冒险者工会】   【5.副本】  【6.工会】 ");ConsolePrint.publishMessage("【8.配置】  【9.退出】");ConsolePrint.publishMessage("请选择:");int choose = ScannerInput.inputInt(1, 9, 9);if (choose != 9) {switch (choose) {case 1:// 请求地图列表,同时跳转到地图菜单StringMessage message = StringMessage.create(ServerTopic.TOPIC_BATTLE, ServerBattleTag.TAG_BATTLE_MAPS);message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);StringRequest request = new StringRequest(ClientTopic.TOPIC_MENU,ClientMenuTag.TAG_MENU_MAP_CHOOSE, ClientTopic.TOPIC_MENU,ClientMenuTag.TAG_MENU_PORTAL);message.setBody(JSON.toJSONString(request));ChannelUtils.pushToServer(ctx.channel(), message);break;case 2:// 请求英雄数据message = StringMessage.create(ServerTopic.TOPIC_HERO, ServerHeroTag.TAG_HERO_INFO);message.setStatusCode(CommonValue.MSG_STATUS_CODE_SUCCESS);request = new StringRequest(ClientTopic.TOPIC_SCENE,ClientSceneTag.TAG_SCENE_HERO, ClientTopic.TOPIC_MENU,ClientMenuTag.TAG_MENU_PORTAL);message.setBody(JSON.toJSONString(request));ChannelUtils.pushToServer(ctx.channel(), message);...

        增加新的handler方法

@TagListener(tag = ClientSceneTag.TAG_SCENE_HERO, messageClass = HeroInfo.class)public void heroInfo(ChannelHandlerContext ctx, HeroInfo data) {ConsolePrint.publishMessage("英雄属性如下");ConsolePrint.publishMessage(data.prettyPrint());ConsolePrint.publishMessage("英雄装备如下");ConsolePrint.publishMessage("请选择操作");ConsolePrint.publishMessage("【1.根据系统推荐更换装备】  【2.查看已有装备,自选装备更换】 【3.卖掉装备】", 1);ConsolePrint.publishMessage("【4.合成装备】   【5.查看共享装备】  【6.返回】", 1);ConsolePrint.publishMessage("请选择:");int choose = ScannerInput.inputInt(1, 6, 6);if (choose != 6) {switch (choose) {case 1:ConsolePrint.publishMessage("暂未开放");break;case 2:ConsolePrint.publishMessage("暂未开放");break;case 3:ConsolePrint.publishMessage("暂未开放");break;case 4:ConsolePrint.publishMessage("暂未开放");break;case 5:ConsolePrint.publishMessage("暂未开放");break;default:ConsolePrint.publishMessage("暂未开放");break;}}// 返回上一级菜单 主菜单StringRequest msg = new StringRequest();NetworkClientListener.getInstance().forward(ctx,ClientTopic.TOPIC_MENU, ClientMenuTag.TAG_MENU_PORTAL, JSON.toJSONString(msg));}

效果

【1.登录已有账户】  【2.注册新账户】  【3.退出】
请选择:
1
请输入账户名:
eric
请输入密码:
111111
234:234
请选择要创建的职业
1:JobChoose.JobItem(id=1, name=战士, desc=剑类武器, strength=60, armature=5, constitution=80, magic=0, technique=15, speed=130)
1
选择的职业为战士
请输入角色的名称:
haha
124:124
英雄创建成功
请选择您要进行的操作
【1.打怪】  【2.属性及装备】  【3.战兽】
【4.冒险者工会】   【5.副本】  【6.工会】 
【8.配置】  【9.退出】
请选择:
2
暂未开放,敬请期待
367:367
英雄属性如下*****信息****姓名:haha级别0血量:800力量:60法力:0技巧:15护甲值5速度130毒抗0火抗0雷抗0冰抗0当前经验0下一级经验100*************
英雄装备如下
请选择操作
【1.根据系统推荐更换装备】  【2.查看已有装备,自选装备更换】 【3.卖掉装备】
【4.合成装备】   【5.查看共享装备】  【6.返回】
请选择:

全部源码详见:

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

分支:step-14

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

这篇关于从零开始手写mmo游戏从框架到爆炸(二十七)— 英雄属性展示及穿戴装备-1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/758291

相关文章

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告:

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

HTML5中下拉框<select>标签的属性和样式详解

《HTML5中下拉框<select>标签的属性和样式详解》在HTML5中,下拉框(select标签)作为表单的重要组成部分,为用户提供了一个从预定义选项中选择值的方式,本文将深入探讨select标签的... 在html5中,下拉框(<select>标签)作为表单的重要组成部分,为用户提供了一个从预定义选项中

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE