游戏物品管理系统 - 程序设计期末大作业

游戏物品管理系统

github: https://github.com/okfanger/xiaofang-adv

@email: lovefyj616@foxmail.com

image-20211224150159195

本管理系统可以存储同一类物品的数量,支持出售、使用、移除、购买等物品操作,此外还引入了个人的生命值、法力值、金币、攻击力的属性,用来展示该系统优秀的数据绑定操作。

例如,苹果的效果是 “法力值+10” ,点击使用后,该人物对应的生命值属性+10,同时与该属性绑定的红色进度条(血条)也会同步更新;点击购买炸弹时,系统会首先判断用户是否具有足够的金钱购买,并进行响应…

部署该系统时,需要导入项目依赖(在下文会提及),并将src目录里的sql文件导入到数据库中,修改数据库连接的配置文件,方可正常运行!

1. 项目依赖(包)及结构

1.1 项目依赖

javafx-sdk-11.0.2、mysql-connector-java-8.8.16、mybatis、log4j-1.2.17

1.2 项目结构

image-20211224142811672

1.3 数据库结构

image-20211224143843672

2. 类结构(UML图)

2.1 数据bean

用来数据的存储及fx组件之间的动态绑定

image-20211224141946261

2.2 主界面

2.2.1 游戏主类 (Game.java)

image-20211224143645633

2.2.2 商店类 (MarketStage.java)

image-20211224144131029

2.2.3 登录(Login.java)、注册类(Register.java)

image-20211224144255099

2.2.4 自定义面板类(TableViewPane.java、TopPane)

image-20211224144401848

2.3 工具类 (连接数据库)

image-20211224144949755

3. 数据的存储及读入、查询

所有数据库操作都以静态方法的形式在MyBatis中定义

3.2 引入MyBatis Factory 单例模式

3.2.1 配置数据库地址、用户名、密码

在项目 cn/akfang/advanture/mybatis/mybatis-config.xml 中,配置数据库信息

在property标签中,分别填写name为 url, username, password的标签

如下代码,表示 数据库地址为 本机(127.0.0.1),数据库名为 xiaofang ,用户名为 root,密码为 root

...
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1/xiaofang?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
...
3.2.2 单例模式
static {
    System.out.println("MyBatis factory 初始化 ...");
    // 静态代码块: 初始化 SqlSessionFactory 实例
    try{
        String resource = "./cn/akfang/advanture/mybatis/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

3.3 在mapper.xml 中定义所有操作

这里篇幅有限,增删改查各选一个展示,详细请自行查看

<select id="checkUserExists" parameterType="hashmap" resultType="hashmap">
    select * from `player_profile` where nick_name=#{nick_name};
</select>
    <insert id="insertUser"  parameterType="hashmap" useGeneratedKeys="true" keyProperty="player_id" >
        INSERT INTO `player_profile` (`player_id`,`nick_name`,`password`,`registered_date`) VALUES (#{player_id},#{nick_name},#{password},#{registered_date});
    </insert>
    <update id="updatePlayerBoxItem" parameterType="hashmap" >
        update `player_box` set `amount`=#{amount} where object_id=#{object_id}
    </update>
    <delete id="removeNullItemInPlayBox" parameterType="hashmap">
        delete from player_box where object_id=#{object_id} and owner_id=#{owner_id}
    </delete>

3.4 封装Sqlsession

所有session同样以静态方法的形式,存于MyBatis 类中

public static HashMap<Integer,HashMap<String,Object>> getObjectPropertyFromDatabase(){
		HashMap<Integer,HashMap<String,Object>> objectProperty = new HashMap<>();
		try (SqlSession session = MyBatis.factory.openSession()){
			List<Map> resultList = session.selectList("getObjectClass");
			resultList.forEach(item -> {
				int key = (int) item.get("class_id");
				HashMap<String,Object> value = new HashMap<>();
				value.put("name",item.get("name"));
				value.put("cost",item.get("cost"));
				String[] effect = ((String)item.get("effect")).split(",");
				for (String effects :effect){
					String[] effectMap = effects.split(":");
					value.put(effectMap[0],Integer.parseInt(effectMap[1]));
				}
				objectProperty.put(key,value);
			});
		}
		return objectProperty;
	}
	public static void updatePlayerConditionHp(int player_id,int hp){
		try (SqlSession session = MyBatis.factory.openSession()){
			session.update("updatePlayerConditionHp",new HashMap<>(){{
				put("player_id",player_id);
				put("hp",hp);
			}});
			session.commit();
		}
	}
	public static void updatePlayerConditionMoney(int player_id,int money){
		try (SqlSession session = MyBatis.factory.openSession()){
			session.update("updatePlayerConditionMoney",new HashMap<>(){{
				put("player_id",player_id);
				put("money",money);
			}});
			session.commit();
		}
	}

4. 布局

4.1 Game.java

image-20211224152343606

4.2 TopPane.java

image-20211224152626556

4.3 TableViewPane.java

image-20211224153027754

4.4 Market.java

image-20211224154315482

5. 部分关键操作演示

5.1 登录及注册

5.1.1 注册

image-20211224155238234

点击注册按钮后,会向数据库提交一个select

 try (SqlSession session = MyBatis.factory.openSession()){
     List<Map> result = session.selectList(
         "reg.checkUserExists",
         new HashMap<>(){{
             put("nick_name",tf[0].getText());
         }}
     );
 	...
 }

若数据库中没有这个昵称的账号,就提交一个insert,并提交事务

    if(result.size()!=1){
        new Alert(Alert.AlertType.WARNING,"未找到对应的用户名").show();
    } else {
        String truePassword = (String) result.get(0).get("password");
        if(truePassword.equals(pf.getText())){
            thisStage.close();
            new Game().begin(this.thisStage,result.get(0));
        } else {
            new Alert(Alert.AlertType.WARNING,"密码错误!").show();
        }

    }
5.1.2 登录

image-20211224165319056

点击注册按钮后,会向数据库提交一个select

 try (SqlSession session = MyBatis.factory.openSession()){
     List<Map> result = session.selectList(
         "reg.checkUserExists",
         new HashMap<>(){{
             put("nick_name",tf[0].getText());
         }}
     );
 	...
 }

若数据库中没有这个昵称的账号,就弹出提示框

反之,将存有玩家数据的Map,传入Game.java,运行Game类的begin()方法

if(result.size()!=1){
    new Alert(Alert.AlertType.WARNING,"未找到对应的用户名").show();
} else {
    String truePassword = (String) result.get(0).get("password");
    if(truePassword.equals(pf.getText())){
        thisStage.close();
        new Game().begin(this.thisStage,result.get(0));
    } else {
        new Alert(Alert.AlertType.WARNING,"密码错误!").show();
    }

}

5.2 物品操作

5.2.1 物品使用
bt[0].setOnAction(event->{
                if(thisItem.getAmount()==0){
                    return;
                }
                HashMap<String, Object> usage = Game.objectProperty.get(thisItem.getClassId());
                for (String key : usage.keySet()) {
                    if (key.equals("attack")) player.setAttack(player.getAttack() + (Integer) usage.get("attack"));
                    if (key.equals("hp")) {
                        int after = player.getHp() + (Integer) usage.get("hp");
                        if (after < 0) {
                            new Alert(Alert.AlertType.WARNING, "生命值不足!").show();
                            return;
                        }
                        player.setHp(after);
                    }
                    if (key.equals("mp")) {
                        int after = player.getMp() + (Integer) usage.get("mp");
                        if (after < 0) {
                            new Alert(Alert.AlertType.WARNING, "法力值不足!").show();
                            return;
                        }
                        player.setMp(player.getMp() + (Integer) usage.get("mp"));
                    }
                }
                thisItem.setAmount(thisItem.getAmount() - 1);
                //System.out.println(player.mpProperty().get());
            });
5.2.2 物品出售
bt[1].setOnAction(event->{
    if(thisItem.getAmount()==0){
        return;
    }
    thisItem.setAmount(thisItem.getAmount()-1);
    player.setMoney(player.getMoney()+thisItem.getCost());
});
5.2.4 物品移除
Button bt33 = new Button("移除");
this.setGraphic(bt33);
bt33.setOnAction(event->{
    MyBatis.deleteNullItemInPlayerBox(thisItem.getId(),player.getPlayer_id());
    data.remove(getIndex());
});
5.2.5 物品购买
buyButton.setOnAction(event->{
                int money = player.getMoney();
                if(money<thisItem.getCost()) return;
                player.setMoney(player.getMoney()-thisItem.getCost());
                GameObjectProperty result = checkPlayerBoxExists(thisItem.getClass_id());

                if(result!=null){
                    result.setAmount(result.getAmount()+1);
                    //update
                } else {

                    int feeback_id = MyBatis.insertItemInPlayerBox(player.getPlayer_id(),thisItem.getClass_id(),1);
                    //System.out.println(feeback_id);
                    playerbox.add(new GameObjectProperty(feeback_id,thisItem.getClass_id(),thisItem.getName(),thisItem.getCost(),1));
                }
            });

5.3 属性增减

5.3.1 血条增减
public void setHp(int hp) {
    if(hp<0) return;
    MyBatis.updatePlayerConditionHp(getPlayer_id(),hp);
    this.hp.set(hp);
}
5.3.2 蓝条增减
public void setMp(int mp) {
    if(mp<0) return;
    MyBatis.updatePlayerConditionMp(getPlayer_id(),mp);
    this.mp.set(mp);
}
5.3.3 金钱增减
public void setMoney(int money) {
    if(money<0) return;
    MyBatis.updatePlayerConditionMoney(getPlayer_id(),money);
    this.money.set(money);
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很高兴听到你正在进行这样的大作业!服装管理系统可以是一个非常有用的应用,特别是对于服装店和品牌来说。 在设计这样一个系统时,你需要考虑以下几个方面: 1. 系统的用户界面:这是用户与系统交互的主要方式。你需要设计一个简单易用的界面,以便用户能够方便地浏览、搜索、添加、修改和删除服装信息。 2. 数据库设计:你需要设计一个数据库来存储服装的信息,如名称、品牌、颜色、大小、价格等。你需要考虑如何优化数据库的性能,以便在系统中进行高效的搜索和过滤。 3. 系统的业务逻辑:你需要考虑如何实现系统的业务逻辑,如如何添加、修改和删除服装信息,如何管理库存,如何处理交易等。 4. 系统的安全性:你需要确保系统的安全性,防止未经授权的访问和数据泄漏。你可以考虑实现用户认证和权限控制等功能。 5. 系统的可扩展性:你需要考虑如何实现系统的可扩展性,以便在需要时添加新的功能或模块。 在设计系统时,你可以考虑使用一些常见的软件设计模式,如MVC(Model-View-Controller)模式、观察者模式、工厂模式等。这些模式可以帮助你更好地组织代码,并提高系统的可维护性和可扩展性。 最后,你可以考虑使用一些流行的技术和框架来实现系统,如Java、Python、MySQL、Spring框架等。这些技术和框架可以帮助你更快地构建系统,并提供一些有用的功能和工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

okfang616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值