前言
上班的第一天,你坐在崭新的工位上,一个头发稀疏、佩戴方形镜框、身穿蓝色立领衬衫黑色牛仔裤,腰间佩戴一串钥匙,名叫李叔的斯文中年男子向你走来。你望着他强者一般的发型和程序员本体的衬衫,心想坏了,又来活了
李叔一脸笑容道:小白,我给你找了一个好活,对你来说一定很简单。
小白假笑问:是什么好活(啊这,我都没有熟悉项目)
李叔:写一个卡牌的装备系统的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 装备等级
建表语句
java
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开始递增,每插入一行记录该列的值会自动加1DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
:这部分定义了表中的字符集和字符排序规则。
创建好数据库表后,就可以通过sql语句对装备操作进行序列化。
公司一般都有完整的导表、到数据库表的工具,将表和数据库表转化为javabean。类似于下面的结构:
csharp
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;
}
}
公司工具导出的类可能会包含更多的信息,但是使用的逻辑大致相同。
创建枚举类
java
//装备槽枚举
public enum EquipTypeEnum {
武器(1),
头盔(2),
铠甲(3),
靴子(4),
;
private int id;
EquipTypeEnum(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
java
// 装备查询类型枚举
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
创建装备管理类
通过装备管理类来进行数据库的查询、穿戴装备、卸下装备。下面是一个简单的实例:
java
public enum EquipMgr {
Instance;
public List<TBI_U_Equip> queryAll( long uid){
List<TBI_U_Equip> list = new ArrayList<>();
/**
* todo sql语句查询数据库得到所有装备
*/
return list;
}
public List<TBI_U_Equip> queryPoAll(long uid,int pos){
List<TBI_U_Equip> 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 更新数据库...
}
}
实际业务会更加复杂,但是总体思路并无太大区别。
最后
希望对大家有所帮助,以上内容就到这里,感谢各位看官老爷们的观看,后续我会写数据库转换工具和配表转换工具包,如果觉得写得好,给个赞支持一下哈!!!