Skip to content

A simplified Hearthstone-like game as my Java class project

Notifications You must be signed in to change notification settings

CSWellesSun/Hearthstone-Swing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

简易炉石传说

Java程序设计报告——作业五

2022-2023学年秋冬学期

[TOC]

引言

设计目的

我想要做一款简易的炉石传说,起因是暴雪和网易没有续约代理,导致炉石传说、守望先锋等众多暴雪游戏将在1月23日退出中国市场。我也算得上是个暴雪游戏的深度玩家,炉石传说是我第一款爱上的游戏,守望先锋是第二款,所以希望在这个特殊的时间点,做一款简易的炉石,致敬青春。

设计说明

无奈本学期时间紧迫,同时考试后还有3项大作业,另外swing的图形效果我也不敢恭维,最终呈现的效果只能说差强人意。简单说,实现了多人联机,实现对战的基础功能,有较多卡牌的效果没来得及实现但已经预留较好的接口,UI部分不够美观和便于操作。

代码包含两个项目,分别是HearthstoneHearthstone-server,两者都使用maven架构,前者是客户端使用较明晰的MVC架构,可拓展性较好,后者架构相对糅杂,未来需要重构,或者使用成熟后端框架。

由于使用maven构建,因此只需要在两个文件夹下执行maven package即可在target目录下生成可执行的jar包,在target文件夹下执行jar包的指令是java -jar -Dfile.encoding=GBK -jar ./Hearthstone-1.0-SNAPSHOT.jar

先执行server程序,然后再启动两个client程序,即可。server使用的IP地址和端口是localhost:80client程序也是直接连接到本地80端口。

总体设计

客户端

MVC

采用MVC架构,其中Model独立存在,View和Controller中包含同一个Model,Controller中包含View。首先,Controller负责处理用户的输入(本游戏只有鼠标),Controller给View中的组件添加鼠标事件监听器(和处理函数),当用户的点击触发View上的鼠标监听器时Controller就会修改Model中的数据;Model存储各类数据结构,Model的数据上有View的监听器,当Model的数据改变的时候会触发事件导致View发生改变;View负责给Model中的数据添加监听器(和处理函数)。

因此总体流程是:用户点击View上的组件,触发Controller的鼠标监听函数,Controller修改Model的数据,触发Model数据改变事件,接着触发View对Model的监听函数,导致View发生改变。

网络

客户端和服务器的通信完全放在Model部分。如果在Player阶段,当Model的数据发生修改的时候,客户端会将数据修改发送给服务器;如果在Opponent阶段,客户端会等待服务器发来的指令,并将Model的内容进行修改(这会导致View的变化)。

客户端一般都会新开一个线程来处理和网络的通信,此时存在一些多线程问题,Swing可以用SwingUtilities.InvokeLater等函数处理多线程GUI问题。

服务器端

服务器端是比较常见的SocketServer架构,服务器监听一个端口(本项目是80),当有客户端连接的时候就记录该客户端的socket,当有两个以上客户端连接的时候,就可以开始一场对局,通过从一个客户端中读取数据并处理,然后交给另一个客户端执行达到两台客户端交互的效果。

详细设计

客户端

Model

Card

记录卡牌的名称、卡牌原画地址、卡牌的效果、卡牌消耗的MP,另外还有两个子类:随从牌和法术牌,这里可以主要介绍效果的实现:

image-20230115233516556

此处维护了一个TargetEffectPhase类,其中包含释放对象、释放效果和释放时机。

image-20230115233540633

最重要的是这个释放效果:

image-20230115233635071

可以看到这里使用了函数式编程,即每个效果都是一个多参数无返回值的函数,后续只要提供函数的操作对象和操作数作为参数即可使用,这里我已经实现了扣血和回血两种效果,其他有时间也可以再丰富。

GameState

image-20230115233833297

GameState中有三种全局state,分别是GamePhase、Round、RoundPhase,分别表示不同粒度的对局状态:

GamePhase有关闭、等待对手、对战进行中、对手赢、本人赢。

image-20230115233926268

Round有未开始、本人阶段、对手阶段。

image-20230115233936252

RoundPhase有:无阶段、等待鼠标选择、等待卡牌对象、等待英雄技能对象、等待随从对象。

image-20230115233949140

Target

image-20230115234152674

Target是一个主类,它表示可选的对象,它的子类有PlayerOpponentServant。当这三个类内容发生改变的时候会触发事件让View发生改变,另外也会在适当时间向服务器报告它内容的改变。

image-20230115234306097

image-20230115234314911

image-20230115234332807

Model

最重要的Model,其中包含了GameState和Target中的两种即Player和Opponent。

image-20230115234455894

同时它还负责与服务器的交互:

image-20230115234537737

View

View我使用GridBagLayout,但是这种Layout使用起来并不方便,最后的效果也不算好看。我是分成5*6的方格,然后在里面填充不同的部分,例如卡牌区、随从区、英雄信息区等。

这里重点介绍View对Model数据改变的监听函数。

Player数据监听:

Opponent数据监听:

image-20230115234856895

GameState数据监听:

image-20230115234912751

Servant数据监听:

image-20230115234930609

里面都是当Model数据改变的时候,就会触发Update函数,注意两个点:

  1. 这些Listener都使用Swing的多线程invokeLater,否则会出现画面崩坏
  2. 由于GridBagLayout的效果很差,但是我没时间改,最后只能动态添加组件,例如下图,可以看到了先removeAll然后添加,最后再重新显示。

image-20230115235104293

另外为了实现背景图片效果,这里重写了JPanel的paintComponent函数:

image-20230115235159348

Controller

Controller负责获取鼠标,然后对Model进行修改:

GamePhase转移:

image-20230115235255971

卡牌使用:

image-20230115235340489

对方英雄点击:

image-20230115235356953

结束按钮点击:

image-20230115235408774

友方随从点击:

image-20230115235420274

敌方随从点击:

image-20230115235436910

服务器端

Server类负责开始对局:

image-20230115235612471

Game类负责具体的对战逻辑:

状态初始化:

image-20230115235706390

每个Round的对战逻辑:

image-20230115235738516

转发client的消息给另一个client:

image-20230115235804460

测试与运行

点击开始匹配:

image-20230115235455875

等待匹配:

image-20230115235521194

游戏初始化:

image-20230115235533194

游戏画面:

image-20230115232829175

总结

主要还是由于时间问题,没有完美地实现出一开始的目标,但是也许从零到一分的过程比从一分到一百分的过程更加重要。在做这个项目的过程中,我最大的收获是学会了maven和MVC,这两个架构方法让我的项目非常清晰而且可扩展性很高,项目的编译构建也很方便,同时我还用到了Java的函数式编程(刚好本学期学了PPL),还学到了Event-Listener模式,写的过程中一遍一遍重构代码的感觉非常舒服。最后还是衷心希望不在乎中国玩家的暴雪永远不要再回归中国,我的青春到此为止。

参考文献

About

A simplified Hearthstone-like game as my Java class project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages