移除landlords-client-javafx子项目
@@ -1,59 +0,0 @@
|
||||
## 介绍
|
||||
本项目是一个使用 `javafx` + `netty` 技术构建的一个桌面应用,
|
||||
是对`ratel`应用命令行客户端的扩展,为`ratel`应用提供可视化界面操作方式。
|
||||
|
||||
### 系统架构
|
||||
* 使用`netty`构建和**ratel**服务端的通讯
|
||||
* 使用`javafx`构建`GUI`界面
|
||||
|
||||
## 快速启动
|
||||
### 依赖
|
||||
* `jdk`
|
||||
本项目是一个`java`应用,所以运行需要`java`环境,前往[oracle](https://www.oracle.com/java/technologies/java-downloads.html)下载最新版本jdk进行安装
|
||||
|
||||
* `maven`
|
||||
本项目由maven构建,构建本应用需要先安装maven,前往[apache maven](https://maven.apache.org)下载最新版本maven进行安装
|
||||
|
||||
### 安装
|
||||
```powershell
|
||||
git clone https://github.com/ainilili/ratel.git
|
||||
cd ratel
|
||||
mvn install package
|
||||
```
|
||||
#### 启动服务器
|
||||
```shell
|
||||
java -jar landlords-server/target/landlords-server-#{version}.jar -p 1024
|
||||
```
|
||||
|
||||
#### 启动`javafx`客户端
|
||||
```shell
|
||||
java -jar landlords-client-javafx/target/landlords-client-javafx-#{version}.jar
|
||||
```
|
||||
|
||||
## 使用
|
||||
1. 选择服务器地址连接
|
||||

|
||||
2. 输入昵称
|
||||

|
||||
3. 选择模式
|
||||

|
||||
4. 选择房间
|
||||

|
||||
5. 开始游戏
|
||||

|
||||
|
||||
## TODO List
|
||||
- [X] PVE模式
|
||||
- [ ] PVP模式
|
||||
- [ ] 优化界面
|
||||
- [ ] 页面切换
|
||||
- [ ] 挂机检测
|
||||
|
||||
## 反馈
|
||||
如果你发现此客户端的bug或有任何疑问,欢迎提[issue](https://github.com/ainilili/ratel/issues),
|
||||
或者你也可以直接联系我([zhangxunweia@gmail.com](zhangxunweia@gmail.com))
|
||||
|
||||
## 参考
|
||||
* [NaiveChat](https://github.com/fuzhengwei/NaiveChat)
|
||||
* [ratel部分协议](https://github.com/ainilili/ratel/blob/master/PROTOCO_CN.md)
|
||||
* [javafx和netty之间的通信](./javafx-netty-communication.md)
|
||||
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 27 KiB |
@@ -1,178 +0,0 @@
|
||||
## 页面如何将用户信息传递给服务端
|
||||
### UI组件的介绍
|
||||
* `UIObject`:继承于`Stage`的一个抽象类,用于用户视图扩展
|
||||
* `Controller`:基础于`UIObject`,代表一个自定义视图
|
||||
* `Method`:定义视图上可以进行的操作
|
||||
* `EventRegister`:用于视图上元素的事件注册
|
||||
* `IEvent`:定义事件可以进行的操作
|
||||
|
||||
### ui类结构
|
||||

|
||||
1. `Controller`通过`EventRegister`进行页面元素的事件注册
|
||||
2. `EventRegister`将`IEvent`注册为页面元素上的事件回调函数
|
||||
3. `IEvent`的实现类`DemoEvent`可以操纵`channel`和`netty`服务端进行通信
|
||||
|
||||
以上组件的简单流程图如下:
|
||||
```
|
||||
// 注册元素事件
|
||||
controller -> init -> EventRegister.registerEvent -> element.setOnAction
|
||||
|
||||
// 元素事件响应
|
||||
elemnt -> onAction -> event -> channel -> netty server
|
||||
```
|
||||
|
||||
### 示例
|
||||
场景:编写一个页面,点击页面上的退出按钮向`netty`服务端发送退出房间信号
|
||||
|
||||
1. 编写一个`demo.fxml`视图文件
|
||||
```fxml
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Button fx:id="quitButton">退出房间</Button>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
```
|
||||
2. 编写一个`Controller`用于视图展示
|
||||
```java
|
||||
public class Controller extends UIObject implements Method {
|
||||
private IEvent event;
|
||||
private EventRegister demoEventRegister;
|
||||
|
||||
public Controller(IEvent event) throws IOException {
|
||||
super();
|
||||
|
||||
// 加载fxml视图文件
|
||||
root = FXMLLoader.load(getClass().getClassLoader().getResource("demo.fxml"));
|
||||
setScene(new Scene(root));
|
||||
|
||||
this.roomEvent = roomEvent;
|
||||
|
||||
// 注册元素事件
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
demoEventRegister = new DemoEventRegister(this, event);
|
||||
}
|
||||
}
|
||||
```
|
||||
3. 编写一个`Event`用于事件处理
|
||||
```java
|
||||
public interface Event {
|
||||
void quit();
|
||||
}
|
||||
|
||||
public class DemoEvent implements Event {
|
||||
@Override
|
||||
public void quit() {
|
||||
// 获取channel,通过工具类向netty服务端发送退出房间信号
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
ChannelUtil.pushToServer(channel, ServerEventCode.CODE_CLIENT_EXIT, null);
|
||||
}
|
||||
}
|
||||
```
|
||||
4. 编写一个`EventDefiner`用于页面元素事件注册
|
||||
```java
|
||||
public class DemoEventRegister implements EventRegister {
|
||||
|
||||
private UIObject uiObject;
|
||||
private IEvent event;
|
||||
|
||||
public DemoEventRegister(UIObject uiObject, IEvent event) {
|
||||
this.uiObject = uiObject;
|
||||
this.event = event;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
quitRoom();
|
||||
}
|
||||
|
||||
private void quitRoom() {
|
||||
// 为退出按钮设置点击事件回调函数
|
||||
uiObject.$("#quitButton", Button.clas).setOnAction(e -> event.quit());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 服务端如何将信息传递给页面
|
||||
如果您还不清楚`netty`服务端和`netty`客户端之间的事件通信,请先阅读[ratel部分协议](https://github.com/ainilili/ratel/blob/master/PROTOCO_CN.md)。
|
||||
|
||||
### 编写客户端事件监听器
|
||||
编写自己的事件监听器,设置感兴趣的服务端事件编码,当对应事件出现时,会执行事件监听器中的代码。实现`ClientListener`或者继承`AbstractClientListener`编写自己的客户端事件监听器:
|
||||
```java
|
||||
public class ClientExitListener extends AbstractClientListener {
|
||||
|
||||
public ClientExitListener() {
|
||||
// 设置感兴趣的服务端事件编码(CODE_CLIENT_EXIT 客户端退出事件编码)
|
||||
super(ClientEventCode.CODE_CLIENT_EXIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件处理业务
|
||||
* @param channel 客户端通信channel
|
||||
* @param json 事件数据
|
||||
*/
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// do something ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 在客户端事件监听器中改变页面
|
||||
每一个客户端事件监听器中都有`uiService`属性,通过`uiService`可以获取各个`Method`对页面进行操作:
|
||||
```java
|
||||
@Override
|
||||
public void handler(Channel channel, String json) {
|
||||
Method method = uiService.getMethod(Controller.METHOD_NAME);
|
||||
|
||||
// 一定要在javafx线程中进行视图的更改
|
||||
Platform.runLater(() -> method.updateView(json));
|
||||
}
|
||||
```
|
||||
|
||||
### 示例
|
||||
场景:客户端退出后服务端向客户端发送退出成功事件响应,客户端接收事件后弹出弹框提示退出成功。
|
||||
1. 编写一个`Method`定义视图的弹出弹框行为
|
||||
```java
|
||||
public interface Method {
|
||||
void alert(String message);
|
||||
}
|
||||
|
||||
public class Controller extends UIObject implements Method {
|
||||
private static final String METHOD_NAME = "method";
|
||||
|
||||
@Override
|
||||
public void alert(String message) {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
```
|
||||
2. 编写一个客户端事件监听器
|
||||
```java
|
||||
public class ClientExitListener extends AbstractClientListener {
|
||||
|
||||
public ClientExitListener() {
|
||||
// 设置感兴趣的服务端事件编码(CODE_CLIENT_EXIT 客户端退出事件编码)
|
||||
super(ClientEventCode.CODE_CLIENT_EXIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件处理业务
|
||||
* @param channel 客户端通信channel
|
||||
* @param json 事件数据
|
||||
*/
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method method = uiService.getMethod(Controller.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> method.alert(json));
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,78 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>landlords</artifactId>
|
||||
<groupId>com.smallnico.ratel</groupId>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>landlords-client-javafx</artifactId>
|
||||
|
||||
<properties>
|
||||
<start-class>priv.zxw.ratel.landlords.client.javafx.SimpleClient</start-class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.smallnico.ratel</groupId>
|
||||
<artifactId>landlords-common</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- logback -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<!-- 实现lsf4j接口并整合 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.56</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>${start-class}</mainClass>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,116 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import org.nico.noson.util.string.StringUtils;
|
||||
import priv.zxw.ratel.landlords.client.javafx.listener.ClientListenerUtils;
|
||||
import priv.zxw.ratel.landlords.client.javafx.handler.DefaultChannelInitializer;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.UIService;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
|
||||
public class NettyClient {
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
private ExecutorService executorService;
|
||||
|
||||
private Channel channel;
|
||||
private EventLoopGroup workerGroup;
|
||||
|
||||
private int id = -1;
|
||||
private String username;
|
||||
|
||||
public NettyClient(UIService uiService) {
|
||||
executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
ClientListenerUtils.setUIService(uiService);
|
||||
}
|
||||
|
||||
public void start(String host, int port) throws Exception {
|
||||
if (StringUtils.isBlank(host)) {
|
||||
throw new IllegalArgumentException("不合法的host:" + host);
|
||||
}
|
||||
|
||||
if (port < 0) {
|
||||
throw new IllegalArgumentException("不合法的端口:" + port);
|
||||
}
|
||||
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
try {
|
||||
// 直接启动netty会别javafx阻塞消息接受
|
||||
// 使用线程池启动则可以正常运行,why !!!!
|
||||
Future<Channel> channelFuture = executorService.submit(new ClientThread());
|
||||
Channel channel = channelFuture.get();
|
||||
|
||||
if (!channel.isActive()) {
|
||||
Exception gotoCatch = new Exception();
|
||||
throw gotoCatch;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 清理资源
|
||||
if (channel != null) {
|
||||
channel.close().syncUninterruptibly();
|
||||
}
|
||||
workerGroup.shutdownGracefully().syncUninterruptibly();
|
||||
|
||||
throw new IOException(String.format("连接netty服务端(%s:%d)失败", host, port), e);
|
||||
}
|
||||
|
||||
BeanUtil.addBean("channel", channel);
|
||||
}
|
||||
|
||||
private class ClientThread implements Callable<Channel> {
|
||||
|
||||
@Override
|
||||
public Channel call() throws Exception {
|
||||
workerGroup = new NioEventLoopGroup();
|
||||
Bootstrap bootstrap = new Bootstrap()
|
||||
.group(workerGroup)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(new DefaultChannelInitializer());
|
||||
channel = bootstrap.connect(host, port).syncUninterruptibly().channel();
|
||||
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
channel.close().syncUninterruptibly();
|
||||
workerGroup.shutdownGracefully().syncUninterruptibly();
|
||||
|
||||
executorService.shutdown();
|
||||
try {
|
||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.stage.Stage;
|
||||
import org.nico.ratel.landlords.utils.StreamUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.event.IndexEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.event.LobbyEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.event.LoginEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.event.RoomEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.UIService;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.index.IndexController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.index.IndexMethod;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.login.LoginController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SimpleClient extends Application {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleClient.class);
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
UIService uiService = new UIService();
|
||||
IndexMethod indexMethod = new IndexController(new IndexEvent());
|
||||
uiService.addMethods(indexMethod, new LoginController(new LoginEvent()),
|
||||
new LobbyController(new LobbyEvent()), new RoomController(new RoomEvent()));
|
||||
uiService.getMethod(IndexController.METHOD_NAME).doShow();
|
||||
|
||||
NettyClient nettyClient = new NettyClient(uiService);
|
||||
BeanUtil.addBean("nettyClient", nettyClient);
|
||||
|
||||
try {
|
||||
List<String> remoteServerAddressList = fetchRemoteServerAddresses();
|
||||
Platform.runLater(() -> indexMethod.generateRemoteServerAddressOptions(remoteServerAddressList));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("获取远程服务器列表失败", e);
|
||||
Platform.runLater(() -> indexMethod.setFetchRemoteServerAddressErrorTips());
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> fetchRemoteServerAddresses() throws IOException {
|
||||
String serverInfo = StreamUtils.convertToString(
|
||||
new URL("https://raw.githubusercontent.com/ainilili/ratel/master/serverlist.json"));
|
||||
return JSONArray.parseArray(serverInfo, String.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.entity;
|
||||
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CurrentRoomInfo {
|
||||
private int roomId;
|
||||
private String roomOwner;
|
||||
|
||||
private User player;
|
||||
private String prevPlayerName;
|
||||
private ClientType prevPlayerRole;
|
||||
private int prevPlayerSurplusPokerCount;
|
||||
private String nextPlayerName;
|
||||
private ClientType nextPlayerRole;
|
||||
private int nextPlayerSurplusPokerCount;
|
||||
|
||||
private String recentPlayerName;
|
||||
private List<Poker> recentPokers;
|
||||
|
||||
private List<Poker> checkedPokers;
|
||||
|
||||
public CurrentRoomInfo(int roomId, String roomOwner) {
|
||||
this.roomId = roomId;
|
||||
this.roomOwner = roomOwner;
|
||||
this.checkedPokers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setLandlord(String landlordName) {
|
||||
if (landlordName.equals(player.getNickname())) {
|
||||
player.setRole(ClientType.LANDLORD);
|
||||
prevPlayerRole = nextPlayerRole = ClientType.PEASANT;
|
||||
} else if (landlordName.equals(prevPlayerName)) {
|
||||
prevPlayerRole = ClientType.LANDLORD;
|
||||
nextPlayerRole = ClientType.PEASANT;
|
||||
player.setRole(ClientType.PEASANT);
|
||||
} else {
|
||||
nextPlayerRole = ClientType.LANDLORD;
|
||||
prevPlayerRole = ClientType.PEASANT;
|
||||
player.setRole(ClientType.PEASANT);
|
||||
}
|
||||
}
|
||||
|
||||
public String getRecentPlayerName() {
|
||||
return recentPlayerName;
|
||||
}
|
||||
|
||||
public void setRecentPlayerName(String recentPlayerName) {
|
||||
this.recentPlayerName = recentPlayerName;
|
||||
}
|
||||
|
||||
public List<Poker> getRecentPokers() {
|
||||
return recentPokers;
|
||||
}
|
||||
|
||||
public void setRecentPokers(List<Poker> recentPokers) {
|
||||
this.recentPokers = recentPokers;
|
||||
}
|
||||
|
||||
public void setPlayer(User player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public User getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void setPrevPlayerName(String prevPlayerName) {
|
||||
this.prevPlayerName = prevPlayerName;
|
||||
}
|
||||
|
||||
public void setNextPlayerName(String nextPlayerName) {
|
||||
this.nextPlayerName = nextPlayerName;
|
||||
}
|
||||
|
||||
public String getPrevPlayerName() {
|
||||
return prevPlayerName;
|
||||
}
|
||||
|
||||
public String getNextPlayerName() {
|
||||
return nextPlayerName;
|
||||
}
|
||||
|
||||
public ClientType getPrevPlayerRole() {
|
||||
return prevPlayerRole;
|
||||
}
|
||||
|
||||
public ClientType getNextPlayerRole() {
|
||||
return nextPlayerRole;
|
||||
}
|
||||
|
||||
public void addCheckedPoker(Poker poker) {
|
||||
checkedPokers.add(poker);
|
||||
}
|
||||
|
||||
public void removeUncheckedPoker(Poker poker) {
|
||||
checkedPokers.remove(poker);
|
||||
}
|
||||
|
||||
public List<Poker> pollCheckedPokers() {
|
||||
List<Poker> pokers = new ArrayList<>(checkedPokers);
|
||||
checkedPokers.clear();
|
||||
|
||||
return pokers;
|
||||
}
|
||||
|
||||
public int getPrevPlayerSurplusPokerCount() {
|
||||
return prevPlayerSurplusPokerCount;
|
||||
}
|
||||
|
||||
public void setPrevPlayerSurplusPokerCount(int prevPlayerSurplusPokerCount) {
|
||||
this.prevPlayerSurplusPokerCount = prevPlayerSurplusPokerCount;
|
||||
}
|
||||
|
||||
public int getNextPlayerSurplusPokerCount() {
|
||||
return nextPlayerSurplusPokerCount;
|
||||
}
|
||||
|
||||
public void setNextPlayerSurplusPokerCount(int nextPlayerSurplusPokerCount) {
|
||||
this.nextPlayerSurplusPokerCount = nextPlayerSurplusPokerCount;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.entity;
|
||||
|
||||
|
||||
public class RoomInfo {
|
||||
private Integer roomId;
|
||||
private String roomOwner;
|
||||
private Integer roomClientCount;
|
||||
private String roomType;
|
||||
|
||||
public Integer getRoomId() {
|
||||
return roomId;
|
||||
}
|
||||
|
||||
public void setRoomId(Integer roomId) {
|
||||
this.roomId = roomId;
|
||||
}
|
||||
|
||||
public String getRoomOwner() {
|
||||
return roomOwner;
|
||||
}
|
||||
|
||||
public void setRoomOwner(String roomOwner) {
|
||||
this.roomOwner = roomOwner;
|
||||
}
|
||||
|
||||
public Integer getRoomClientCount() {
|
||||
return roomClientCount;
|
||||
}
|
||||
|
||||
public void setRoomClientCount(Integer roomClientCount) {
|
||||
this.roomClientCount = roomClientCount;
|
||||
}
|
||||
|
||||
public String getRoomType() {
|
||||
return roomType;
|
||||
}
|
||||
|
||||
public void setRoomType(String roomType) {
|
||||
this.roomType = roomType;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.entity;
|
||||
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class User {
|
||||
private String nickname;
|
||||
|
||||
private boolean playing = false;
|
||||
private int currentRoomId = -1;
|
||||
private List<Poker> pokers;
|
||||
|
||||
// null, ClientType.LANDLORD, ClientType.PEASANT
|
||||
private ClientType role;
|
||||
|
||||
public User(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public void joinRoom(int roomId) {
|
||||
currentRoomId = roomId;
|
||||
playing = true;
|
||||
}
|
||||
|
||||
public void exitRoom() {
|
||||
currentRoomId = -1;
|
||||
playing = false;
|
||||
role = null;
|
||||
pokers.clear();
|
||||
pokers = null;
|
||||
}
|
||||
|
||||
public void addPokers(List<Poker> pokers) {
|
||||
if (this.pokers != null) {
|
||||
this.pokers.addAll(pokers);
|
||||
} else {
|
||||
this.pokers = pokers;
|
||||
}
|
||||
|
||||
this.pokers = this.pokers.stream()
|
||||
.sorted((a, b) -> Integer.compare(b.getLevel().getLevel(), a.getLevel().getLevel()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void removePokers(List<Poker> sellPokerList) {
|
||||
for (Poker sellPoker : sellPokerList) {
|
||||
pokers.remove(sellPoker);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Poker> getPokers() {
|
||||
return pokers;
|
||||
}
|
||||
|
||||
public ClientType getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return playing;
|
||||
}
|
||||
|
||||
public void setRole(ClientType role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.event;
|
||||
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IIndexEvent;
|
||||
|
||||
public class IndexEvent implements IIndexEvent {
|
||||
|
||||
@Override
|
||||
public void connect(String host, int port) throws Exception {
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
|
||||
nettyClient.start(host, port);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.event;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.listener.ClientListener;
|
||||
import priv.zxw.ratel.landlords.client.javafx.listener.ClientListenerUtils;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILobbyEvent;
|
||||
|
||||
|
||||
public class LobbyEvent implements ILobbyEvent {
|
||||
|
||||
@Override
|
||||
public void selectPVPModal() {
|
||||
ClientListener listener = ClientListenerUtils.getListener(ClientEventCode.CODE_SHOW_OPTIONS_PVP);
|
||||
|
||||
listener.handle(BeanUtil.getBean("channel"), ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectPVEModal() {
|
||||
ClientListener listener = ClientListenerUtils.getListener(ClientEventCode.CODE_SHOW_OPTIONS_PVE);
|
||||
|
||||
listener.handle(BeanUtil.getBean("channel"), ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPVPRoom() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_ROOM_CREATE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPVERoom(int modal) {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_ROOM_CREATE_PVE, String.valueOf(modal));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRooms() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GET_ROOMS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinRoom(int roomId) {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_ROOM_JOIN, String.valueOf(roomId));
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.event;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILoginEvent;
|
||||
|
||||
public class LoginEvent implements ILoginEvent {
|
||||
|
||||
@Override
|
||||
public void setNickname(String nickname) {
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
nettyClient.setUsername(nickname);
|
||||
|
||||
User user = new User(nickname);
|
||||
BeanUtil.addBean("user", user);
|
||||
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_CLIENT_NICKNAME_SET, nickname);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.event;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IRoomEvent;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RoomEvent implements IRoomEvent {
|
||||
|
||||
@Override
|
||||
public void robLandlord() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_LANDLORD_ELECT, "TRUE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notRobLandlord() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_LANDLORD_ELECT, "FALSE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitPokers(List<Poker> pokerList) {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
String[] chars = pokerList.stream()
|
||||
.sorted(Comparator.comparingInt(poker -> poker.getLevel().getLevel()))
|
||||
.map(p -> {
|
||||
String name = p.getLevel().getName();
|
||||
// 10 实际出牌值为 0
|
||||
return name.length() > 1 ? name.substring(1, 2) : name;
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new String[] {});
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY, JSONObject.toJSONString(chars));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passRound() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_PASS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
Channel channel = BeanUtil.getBean("channel");
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_CLIENT_EXIT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.handler;
|
||||
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.protobuf.ProtobufDecoder;
|
||||
import io.netty.handler.codec.protobuf.ProtobufEncoder;
|
||||
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
|
||||
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import org.nico.ratel.landlords.entity.ClientTransferData;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @ClassName DefaultChannelInitializer
|
||||
* @Desc TODO
|
||||
* @Author zxw
|
||||
* @Date 2020/8/5 13:25
|
||||
* @Version 1.0
|
||||
*/
|
||||
public class DefaultChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
ch.pipeline()
|
||||
.addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS))
|
||||
.addLast(new ProtobufVarint32FrameDecoder())
|
||||
.addLast(new ProtobufDecoder(ClientTransferData.ClientTransferDataProtoc.getDefaultInstance()))
|
||||
.addLast(new ProtobufVarint32LengthFieldPrepender())
|
||||
.addLast(new ProtobufEncoder())
|
||||
.addLast(new SecondProtobufCodec())
|
||||
.addLast(new TransferHandler());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.handler;
|
||||
|
||||
import com.google.protobuf.MessageLite;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageCodec;
|
||||
import org.nico.ratel.landlords.entity.ClientTransferData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SecondProtobufCodec
|
||||
* @Desc TODO
|
||||
* @Author zxw
|
||||
* @Date 2020/8/5 13:26
|
||||
* @Version 1.0
|
||||
*/
|
||||
public class SecondProtobufCodec extends MessageToMessageCodec<ClientTransferData.ClientTransferDataProtoc, MessageLite> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, MessageLite msg, List<Object> out) throws Exception {
|
||||
out.add(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ClientTransferData.ClientTransferDataProtoc msg, List<Object> out) throws Exception {
|
||||
out.add(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.handler;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.entity.ClientTransferData.ClientTransferDataProtoc;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import org.nico.ratel.landlords.print.SimplePrinter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.listener.ClientListener;
|
||||
import priv.zxw.ratel.landlords.client.javafx.listener.ClientListenerUtils;
|
||||
|
||||
|
||||
public class TransferHandler extends ChannelInboundHandlerAdapter {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TransferHandler.class);
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
try {
|
||||
ClientTransferDataProtoc clientTransferData = (ClientTransferDataProtoc) msg;
|
||||
|
||||
if (clientTransferData.getInfo() != null && !clientTransferData.getInfo().isEmpty()) {
|
||||
SimplePrinter.printNotice(clientTransferData.getInfo());
|
||||
}
|
||||
|
||||
ClientEventCode code = ClientEventCode.valueOf(clientTransferData.getCode());
|
||||
|
||||
LOGGER.info("接受服务端信息, 编码:{},数据:{}.", code, clientTransferData.getData());
|
||||
|
||||
if (code != null) {
|
||||
ClientListener listener = ClientListenerUtils.getListener(code);
|
||||
|
||||
if (listener != null) {
|
||||
listener.handle(ctx.channel(), clientTransferData.getData());
|
||||
} else {
|
||||
LOGGER.warn("未知的消息编码 {},忽略该条消息: {}", code, clientTransferData.getData());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ReferenceCountUtil.release(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (evt instanceof IdleStateEvent) {
|
||||
IdleStateEvent event = (IdleStateEvent) evt;
|
||||
if (event.state() == IdleState.WRITER_IDLE) {
|
||||
ChannelUtils.pushToServer(ctx.channel(), ServerEventCode.CODE_CLIENT_HEAD_BEAT, "heartbeat");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.UIService;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public abstract class AbstractClientListener implements ClientListener {
|
||||
protected ClientEventCode code;
|
||||
|
||||
protected UIService uiService;
|
||||
|
||||
public AbstractClientListener(ClientEventCode code) {
|
||||
Objects.requireNonNull(code, "子事件监听器需要自定义专属的事件编码");
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientEventCode getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUIService(UIService uiService) {
|
||||
this.uiService = uiService;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
|
||||
public class ClientCantPassListener extends AbstractClientListener {
|
||||
|
||||
public ClientCantPassListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_CANT_PASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// 不允许跳过,即简单的不响应用户操作即可
|
||||
RoomController roomController = (RoomController) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Label tips = ((Label) roomController.$("playerPane", Pane.class).lookup(".error-tips"));
|
||||
tips.setVisible(true);
|
||||
tips.setText("此回合不能不出牌");
|
||||
roomController.delayHidden(tips, 2);
|
||||
});
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientConfirmLandlordListener extends AbstractClientListener {
|
||||
|
||||
public ClientConfirmLandlordListener() {
|
||||
super(ClientEventCode.CODE_GAME_LANDLORD_CONFIRM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
String landlordName = jsonObject.getString("landlordNickname");
|
||||
List<Poker> surplusPokerList = jsonObject.getJSONArray("additionalPokers").toJavaList(Poker.class);
|
||||
|
||||
// 给地主发底牌
|
||||
User user = BeanUtil.getBean("user");
|
||||
if (landlordName.equals(user.getNickname())) {
|
||||
user.addPokers(surplusPokerList);
|
||||
}
|
||||
|
||||
// 设置玩家的角色
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
currentRoomInfo.setLandlord(landlordName);
|
||||
|
||||
// 视图更新
|
||||
RoomMethod method = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
method.showSurplusPokers(surplusPokerList);
|
||||
method.hideRobButtons();
|
||||
method.setLandLord(landlordName);
|
||||
});
|
||||
|
||||
// 重定向玩家
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
|
||||
|
||||
public class ClientConnectListener extends AbstractClientListener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClientConnectListener.class);
|
||||
|
||||
public ClientConnectListener() {
|
||||
super(ClientEventCode.CODE_CLIENT_CONNECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
nettyClient.setId(Integer.parseInt(json));
|
||||
|
||||
LOGGER.info("当前客户端被分配的id为 {}", nettyClient.getId());
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientExitListener extends AbstractClientListener {
|
||||
|
||||
public ClientExitListener() {
|
||||
super(ClientEventCode.CODE_CLIENT_EXIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
LobbyMethod lobbyMethod = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
roomMethod.doClose();
|
||||
lobbyMethod.doShow();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ClientType;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientGameOverListener extends AbstractClientListener {
|
||||
|
||||
public ClientGameOverListener() {
|
||||
super(ClientEventCode.CODE_GAME_OVER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
String winnerName = jsonObject.getString("winnerNickname");
|
||||
ClientType clientType = jsonObject.getObject("winnerType", ClientType.class);
|
||||
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
Platform.runLater(() -> roomMethod.gameOver(winnerName, clientType));
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientJoinRoomSuccessfulListener extends AbstractClientListener {
|
||||
|
||||
public ClientJoinRoomSuccessfulListener() {
|
||||
super(ClientEventCode.CODE_ROOM_JOIN_SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method lobbyMethod = uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
lobbyMethod.doClose();
|
||||
roomMethod.joinRoom();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.AlertUtils;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientKickListener extends AbstractClientListener {
|
||||
|
||||
public ClientKickListener() {
|
||||
super(ClientEventCode.CODE_CLIENT_KICK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method lobbyMethod = uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
RoomMethod roomMethod = (RoomController) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
// 防止出现多次触发 CODE_CLIENT_KICK 事件后导致页面显示错误的情况
|
||||
if (roomMethod.isShow()) {
|
||||
Platform.runLater(() -> {
|
||||
AlertUtils.warn("您已经退出房间", "您因长时间未操作,请出已被房间");
|
||||
|
||||
roomMethod.doClose();
|
||||
lobbyMethod.doShow();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.UIService;
|
||||
|
||||
|
||||
public interface ClientListener {
|
||||
void handle(Channel channel, String json);
|
||||
|
||||
ClientEventCode getCode();
|
||||
|
||||
void setUIService(UIService uiService);
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.UIService;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class ClientListenerUtils {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClientListenerUtils.class);
|
||||
|
||||
/** code - listener 映射 */
|
||||
private static final Map<ClientEventCode, ClientListener> LISTENER_MAP = new HashMap<>(16);
|
||||
|
||||
/**
|
||||
* 获取code对应的事件监听器
|
||||
*
|
||||
* @param code 事件编码
|
||||
* @return code对应的事件监听器,如果不存在对应的事件监听器则返回null
|
||||
*/
|
||||
public static ClientListener getListener(ClientEventCode code) {
|
||||
ClientListener clientListener = LISTENER_MAP.get(code);
|
||||
|
||||
return clientListener;
|
||||
}
|
||||
|
||||
public static ClientEventCode[] supportCodes() {
|
||||
return LISTENER_MAP.keySet().toArray(new ClientEventCode[] {});
|
||||
}
|
||||
|
||||
public static void setUIService(UIService uiService) {
|
||||
for (ClientListener listener : LISTENER_MAP.values()) {
|
||||
listener.setUIService(uiService);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
List<Class<ClientListener>> listenerClassList = findListener();
|
||||
|
||||
for (Class<ClientListener> clazz : listenerClassList) {
|
||||
try {
|
||||
ClientListener listener = clazz.newInstance();
|
||||
LISTENER_MAP.put(listener.getCode(), listener);
|
||||
|
||||
LOGGER.info("添加 {} -> {} 事件监听器映射", listener.getCode(), listener.getClass().getName());
|
||||
} catch (InstantiationException e) {
|
||||
LOGGER.warn(clazz.getName() + " 不能被实例化");
|
||||
} catch (IllegalAccessException e) {
|
||||
LOGGER.warn(clazz.getName() + " 没有默认构造函数或默认构造函数不可访问", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Class<ClientListener>> findListener() {
|
||||
ClassLoader defaultClassLoader = ClientListenerUtils.class.getClassLoader();
|
||||
URL classWorkPath = ClientListenerUtils.class.getResource("");
|
||||
File classWorkDir = new File(classWorkPath.getPath());
|
||||
|
||||
return loadClasses(defaultClassLoader, classWorkDir.listFiles(ClientListenerUtils::isNormalClass))
|
||||
.stream()
|
||||
.filter(clazz -> clazz.getSuperclass() == AbstractClientListener.class)
|
||||
.map(clazz -> (Class<ClientListener>) clazz)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static boolean isNormalClass(File file) {
|
||||
String fileName = file.getName();
|
||||
boolean isClassFile = fileName.endsWith(".class");
|
||||
boolean isNotInnerClassFile = !fileName.matches("[A-Z]\\w+\\$\\w+.class");
|
||||
|
||||
return isClassFile && isNotInnerClassFile;
|
||||
}
|
||||
|
||||
private static List<Class<?>> loadClasses(ClassLoader classLoader, File[] classFiles) {
|
||||
String classpath = classLoader.getResource("").getPath();
|
||||
|
||||
List<Class<?>> classList = new ArrayList<>(classFiles.length);
|
||||
for (File classFile : classFiles) {
|
||||
String absolutePath = classFile.getAbsolutePath();
|
||||
String classFullName = absolutePath.substring(classpath.length() - 1, absolutePath.lastIndexOf("."))
|
||||
.replace(File.separator, ".");
|
||||
|
||||
try {
|
||||
classList.add(classLoader.loadClass(classFullName));
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOGGER.warn("默认类加载器在 {} 路径下没有找到 {} 类", classpath, classFullName);
|
||||
}
|
||||
}
|
||||
|
||||
return classList;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class ClientPassListener extends AbstractClientListener {
|
||||
|
||||
public ClientPassListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_PASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
RoomMethod method = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
|
||||
// 更新当前玩家和出牌信息
|
||||
String clientNickname = jsonObject.getString("clientNickname");
|
||||
currentRoomInfo.setRecentPlayerName(clientNickname);
|
||||
currentRoomInfo.setRecentPokers(Collections.emptyList());
|
||||
|
||||
// 视图更新
|
||||
String nextClientNickname = jsonObject.getString("nextClientNickname");
|
||||
Platform.runLater(() -> {
|
||||
method.play(nextClientNickname);
|
||||
method.showMessage(clientNickname, "不出");
|
||||
});
|
||||
|
||||
// 如果下一个出牌的是本玩家进行出牌重定向
|
||||
int turnClientId = jsonObject.getIntValue("nextClientId");
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
if (turnClientId == nettyClient.getId()) {
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
|
||||
public class ClientPokerInvalidListener extends AbstractClientListener {
|
||||
|
||||
public ClientPokerInvalidListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// 牌无效,不允许出牌,即简单的不响应用户操作即可
|
||||
RoomController roomController = (RoomController) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Label tips = ((Label) roomController.$("playerPane", Pane.class).lookup(".error-tips"));
|
||||
tips.setVisible(true);
|
||||
tips.setText("您的出牌不符合规则");
|
||||
roomController.delayHidden(tips, 2);
|
||||
});
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
|
||||
public class ClientPokerLessListener extends AbstractClientListener {
|
||||
|
||||
public ClientPokerLessListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_LESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// 出牌太少,不允许出牌,即简单的不响应用户操作即可
|
||||
RoomController roomController = (RoomController) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
Platform.runLater(() -> {
|
||||
Label tips = ((Label) roomController.$("playerPane", Pane.class).lookup(".error-tips"));
|
||||
tips.setVisible(true);
|
||||
tips.setText("您的出牌应该大于上家的牌");
|
||||
roomController.delayHidden(tips, 2);
|
||||
});
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
|
||||
public class ClientPokerMismatchListener extends AbstractClientListener {
|
||||
|
||||
public ClientPokerMismatchListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_MISMATCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// 出牌不匹配,不允许出牌,即简单的不响应用户操作即可
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
RoomController roomController = (RoomController) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
Platform.runLater(() -> {
|
||||
Label tips = ((Label) roomController.$("playerPane", Pane.class).lookup(".error-tips"));
|
||||
tips.setVisible(true);
|
||||
tips.setText("您需要出" + jsonObject.getIntValue("preCount") + "张牌");
|
||||
roomController.delayHidden(tips, 2);
|
||||
});
|
||||
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GAME_POKER_PLAY_REDIRECT, null);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientPokerPlayListener extends AbstractClientListener {
|
||||
|
||||
public ClientPokerPlayListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
User user = BeanUtil.getBean("user");
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> roomMethod.play(user.getNickname()));
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
|
||||
public class ClientPokerPlayRedirectListener extends AbstractClientListener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClientPokerPlayRedirectListener.class);
|
||||
|
||||
public ClientPokerPlayRedirectListener() {
|
||||
super(ClientEventCode.CODE_GAME_POKER_PLAY_REDIRECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
int sellClientId = jsonObject.getIntValue("sellClientId");
|
||||
|
||||
// 通知下一个玩家出牌
|
||||
if (sellClientId == nettyClient.getId()) {
|
||||
ClientListenerUtils.getListener(ClientEventCode.CODE_GAME_POKER_PLAY).handle(channel, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
|
||||
public class ClientRestartGameListener extends AbstractClientListener {
|
||||
|
||||
public ClientRestartGameListener() {
|
||||
super(ClientEventCode.CODE_GAME_LANDLORD_CYCLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
System.out.println("无人抢地主,重新发牌");
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientRoomCreateSuccessfulListener extends AbstractClientListener {
|
||||
|
||||
public ClientRoomCreateSuccessfulListener() {
|
||||
super(ClientEventCode.CODE_ROOM_CREATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method lobbyMethod = uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
lobbyMethod.doClose();
|
||||
roomMethod.joinRoom();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
|
||||
public class ClientRoomFullJoinFailListener extends AbstractClientListener {
|
||||
|
||||
public ClientRoomFullJoinFailListener() {
|
||||
super(ClientEventCode.CODE_ROOM_JOIN_FAIL_BY_FULL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
LobbyMethod lobbyMethod = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
lobbyMethod.joinRoomFail("房间已经满人", "该房间人数已满,开始游戏,请挑选其它未满房间进行游戏。");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
|
||||
public class ClientRoomNotExistsJoinFailListener extends AbstractClientListener {
|
||||
|
||||
public ClientRoomNotExistsJoinFailListener() {
|
||||
super(ClientEventCode.CODE_ROOM_JOIN_FAIL_BY_INEXIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
LobbyMethod lobbyMethod = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
lobbyMethod.joinRoomFail("房间已经不存在", "该房间已经不存在,可能房主已经解散该房间了,请挑选其它房间进行游戏。");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
public class ClientSelectLandlordListener extends AbstractClientListener {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClientSelectLandlordListener.class);
|
||||
|
||||
public ClientSelectLandlordListener() {
|
||||
super(ClientEventCode.CODE_GAME_LANDLORD_ELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
// 计算出玩家的顺序
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
String nextClientNickname = jsonObject.getString("nextClientNickname");
|
||||
|
||||
// 决定接下来谁抢地主
|
||||
int turnClientId = jsonObject.getIntValue("nextClientId");
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
|
||||
if (turnClientId == nettyClient.getId()) {
|
||||
RoomMethod method = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
Platform.runLater(() -> method.showRobButtons());
|
||||
}
|
||||
|
||||
LOGGER.info("接下来由 {} 抢地主", nextClientNickname);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.index.IndexController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.login.LoginController;
|
||||
|
||||
public class ClientSetNicknameListener extends AbstractClientListener {
|
||||
|
||||
public ClientSetNicknameListener() {
|
||||
super(ClientEventCode.CODE_CLIENT_NICKNAME_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method indexMethod = uiService.getMethod(IndexController.METHOD_NAME);
|
||||
Method loginMethod = uiService.getMethod(LoginController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
indexMethod.doClose();
|
||||
loginMethod.doShow();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.login.LoginController;
|
||||
|
||||
public class ClientShowOptionsListener extends AbstractClientListener {
|
||||
|
||||
public ClientShowOptionsListener() {
|
||||
super(ClientEventCode.CODE_SHOW_OPTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
Method loginMethod = uiService.getMethod(LoginController.METHOD_NAME);
|
||||
Method lobbyMethod = uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
loginMethod.doClose();
|
||||
lobbyMethod.doShow();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
|
||||
|
||||
public class ClientShowOptionsPVEListener extends AbstractClientListener {
|
||||
|
||||
public ClientShowOptionsPVEListener() {
|
||||
super(ClientEventCode.CODE_SHOW_OPTIONS_PVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
LobbyMethod lobbyMethod = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(lobbyMethod::toggleToPVEMenu);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.channel.ChannelUtils;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import org.nico.ratel.landlords.enums.ServerEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
|
||||
|
||||
public class ClientShowOptionsPVPListener extends AbstractClientListener {
|
||||
|
||||
public ClientShowOptionsPVPListener() {
|
||||
super(ClientEventCode.CODE_SHOW_OPTIONS_PVP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
LobbyMethod lobbyMethod = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(lobbyMethod::toggleToPVPMenu);
|
||||
ChannelUtils.pushToServer(channel, ServerEventCode.CODE_GET_ROOMS, null);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Label;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientShowPokersListener extends AbstractClientListener {
|
||||
|
||||
public ClientShowPokersListener() {
|
||||
super(ClientEventCode.CODE_SHOW_POKERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
String clientNickname = jsonObject.getString("clientNickname");
|
||||
List<Poker> sellPokerList = jsonObject.getJSONArray("pokers").toJavaList(Poker.class);
|
||||
|
||||
// 更新当前玩家和出牌信息
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
User user = currentRoomInfo.getPlayer();
|
||||
|
||||
if (user.getNickname().equals(clientNickname)) {
|
||||
user.removePokers(sellPokerList);
|
||||
} else if (currentRoomInfo.getPrevPlayerName().equals(clientNickname)) {
|
||||
currentRoomInfo.setPrevPlayerSurplusPokerCount(currentRoomInfo.getPrevPlayerSurplusPokerCount() - sellPokerList.size());
|
||||
} else if (currentRoomInfo.getNextPlayerName().equals(clientNickname)) {
|
||||
currentRoomInfo.setNextPlayerSurplusPokerCount(currentRoomInfo.getNextPlayerSurplusPokerCount() - sellPokerList.size());
|
||||
}
|
||||
|
||||
currentRoomInfo.setRecentPlayerName(clientNickname);
|
||||
currentRoomInfo.setRecentPokers(sellPokerList);
|
||||
|
||||
// 视图更新
|
||||
String nextPlayerName = jsonObject.getString("sellClinetNickname");
|
||||
RoomMethod method = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
Platform.runLater(() -> {
|
||||
method.showPokers(clientNickname, sellPokerList);
|
||||
if (nextPlayerName != null) {
|
||||
method.play(nextPlayerName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.RoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientShowRoomsListner extends AbstractClientListener {
|
||||
|
||||
public ClientShowRoomsListner() {
|
||||
super(ClientEventCode.CODE_SHOW_ROOMS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
List<RoomInfo> rooms = JSONArray.parseArray(json, RoomInfo.class);
|
||||
|
||||
LobbyMethod method = (LobbyMethod) uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
Platform.runLater(() -> method.showRoomList(rooms));
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import javafx.application.Platform;
|
||||
import org.nico.ratel.landlords.entity.ClientSide;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientEventCode;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.lobby.LobbyController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomController;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.room.RoomMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientStartGameListener extends AbstractClientListener {
|
||||
|
||||
public ClientStartGameListener() {
|
||||
super(ClientEventCode.CODE_GAME_STARTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Channel channel, String json) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
|
||||
// 设置用户信息和当前对局房间信息
|
||||
User user = BeanUtil.getBean("user");
|
||||
user.addPokers(jsonObject.getJSONArray("pokers").toJavaList(Poker.class));
|
||||
user.joinRoom(jsonObject.getIntValue("roomId"));
|
||||
|
||||
CurrentRoomInfo currentRoomInfo = new CurrentRoomInfo(jsonObject.getIntValue("roomId"),
|
||||
jsonObject.getString("roomOwner"));
|
||||
currentRoomInfo.setPlayer(user);
|
||||
currentRoomInfo.setPrevPlayerSurplusPokerCount(17);
|
||||
currentRoomInfo.setNextPlayerSurplusPokerCount(17);
|
||||
BeanUtil.addBean("currentRoomInfo", currentRoomInfo);
|
||||
|
||||
// 计算出玩家的顺序
|
||||
List<ClientSide> clientOrderList = jsonObject.getJSONArray("clientOrderList").toJavaList(ClientSide.class);
|
||||
ClientSide clientSide = clientOrderList.stream().filter(c -> user.getNickname().equals(c.getNickname())).findFirst().get();
|
||||
currentRoomInfo.setPrevPlayerName(clientSide.getPre().getNickname());
|
||||
currentRoomInfo.setNextPlayerName(clientSide.getNext().getNickname());
|
||||
|
||||
// 更新试图
|
||||
Method lobbyMethod = uiService.getMethod(LobbyController.METHOD_NAME);
|
||||
RoomMethod roomMethod = (RoomMethod) uiService.getMethod(RoomController.METHOD_NAME);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
// 客户端加入房间时,可能没有触发 joinRoomSuccessful 的事件
|
||||
// 导致视图未正常切换,判断视图是否切换,否则进行试图切换
|
||||
if (!roomMethod.isShow()) {
|
||||
lobbyMethod.doClose();
|
||||
roomMethod.joinRoom();
|
||||
}
|
||||
|
||||
roomMethod.startGame(user.getPokers());
|
||||
});
|
||||
|
||||
// 触发抢地主(CODE_GAME_LANDLORD_ELECT)事件
|
||||
ClientListenerUtils.getListener(ClientEventCode.CODE_GAME_LANDLORD_ELECT).handle(channel, json);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui;
|
||||
|
||||
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class UIService {
|
||||
private Map<String, Method> methodMap = new HashMap<>(16);
|
||||
|
||||
public void addMethods(Method... methods) {
|
||||
for (Method method : methods) {
|
||||
methodMap.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
public Method getMethod(String name) {
|
||||
return methodMap.get(name);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.event;
|
||||
|
||||
|
||||
public interface IIndexEvent {
|
||||
|
||||
void connect(String host, int port) throws Exception;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.event;
|
||||
|
||||
|
||||
public interface ILobbyEvent {
|
||||
|
||||
void selectPVPModal();
|
||||
|
||||
void selectPVEModal();
|
||||
|
||||
void createPVPRoom();
|
||||
|
||||
void createPVERoom(int modal);
|
||||
|
||||
void showRooms();
|
||||
|
||||
void joinRoom(int roomId);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.event;
|
||||
|
||||
|
||||
public interface ILoginEvent {
|
||||
|
||||
void setNickname(String nickname);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.event;
|
||||
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IRoomEvent {
|
||||
void robLandlord();
|
||||
|
||||
void notRobLandlord();
|
||||
|
||||
void submitPokers(List<Poker> pokerList);
|
||||
|
||||
void passRound();
|
||||
|
||||
void exit();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
|
||||
public class AlertUtils {
|
||||
|
||||
public static void info(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.INFORMATION, headerText, contentText);
|
||||
}
|
||||
|
||||
private static void createAndShowAlert(Alert.AlertType alertType,
|
||||
String headerText, String contentText) {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle(Alert.AlertType.INFORMATION.equals(alertType) ? "信息" :
|
||||
Alert.AlertType.WARNING.equals(alertType) ? "警告" : "错误");
|
||||
alert.setHeaderText(headerText);
|
||||
alert.setContentText(contentText);
|
||||
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
public static void warn(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.WARNING, headerText, contentText);
|
||||
}
|
||||
|
||||
public static void error(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.ERROR, headerText, contentText);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view;
|
||||
|
||||
|
||||
import javafx.scene.Node;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CountDownTask {
|
||||
public static final int DEFAULT_TIME_OUT = 30;
|
||||
|
||||
private Consumer<Node> finallyExecuteConsumer;
|
||||
private Consumer<Integer> preSecondExecuteConsumer;
|
||||
private Node targetElement;
|
||||
private int duration;
|
||||
|
||||
public CountDownTask(Node targetElement,
|
||||
Consumer<Node> finallyExecuteConsumer, Consumer<Integer> preSecondExecuteConsumer) {
|
||||
this.finallyExecuteConsumer = finallyExecuteConsumer;
|
||||
this.preSecondExecuteConsumer = preSecondExecuteConsumer;
|
||||
this.targetElement = targetElement;
|
||||
}
|
||||
|
||||
public CountDownTask(Node targetElement, int duration,
|
||||
Consumer<Node> finallyExecuteConsumer, Consumer<Integer> preSecondExecuteConsumer) {
|
||||
Objects.requireNonNull(finallyExecuteConsumer);
|
||||
|
||||
this.finallyExecuteConsumer = finallyExecuteConsumer;
|
||||
this.preSecondExecuteConsumer = preSecondExecuteConsumer;
|
||||
this.duration = duration < 0 ? DEFAULT_TIME_OUT : duration;
|
||||
this.targetElement = targetElement;
|
||||
}
|
||||
|
||||
public CountDownFuture start() {
|
||||
targetElement.setVisible(true);
|
||||
|
||||
CountDownFuture future = new CountDownFuture();
|
||||
future.start();
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public class CountDownFuture extends Thread {
|
||||
|
||||
private volatile boolean done = false;
|
||||
|
||||
private CountDownFuture() {
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long startTimeMillis = System.currentTimeMillis();
|
||||
|
||||
long interval;
|
||||
try {
|
||||
while (true) {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
interval = (currentTimeMillis - startTimeMillis) / 1000;
|
||||
|
||||
if (interval > duration) {
|
||||
break;
|
||||
}
|
||||
|
||||
preSecondExecuteConsumer.accept((int) (duration - interval));
|
||||
|
||||
sleep(1000L);
|
||||
}
|
||||
|
||||
finallyExecuteConsumer.accept(targetElement);
|
||||
} catch (InterruptedException cancelFlag) {
|
||||
// exit
|
||||
return;
|
||||
} finally {
|
||||
done = true;
|
||||
targetElement.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
|
||||
done = true;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view;
|
||||
|
||||
|
||||
public interface EventRegister {
|
||||
|
||||
void registerEvent();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view;
|
||||
|
||||
|
||||
public interface Method {
|
||||
String getName();
|
||||
|
||||
void doShow();
|
||||
|
||||
void doClose();
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view;
|
||||
|
||||
|
||||
import javafx.animation.FadeTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.NettyClient;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class UIObject extends Stage {
|
||||
|
||||
protected Parent root;
|
||||
|
||||
private ExecutorService animationExecutorService = Executors.newFixedThreadPool(2);
|
||||
|
||||
public UIObject() {
|
||||
setTitle("ratel javafx客户端");
|
||||
|
||||
// 退出程序
|
||||
setOnCloseRequest(e -> closeApplication());
|
||||
}
|
||||
|
||||
private void closeApplication() {
|
||||
// 关闭视图
|
||||
close();
|
||||
Platform.exit();
|
||||
|
||||
// 关闭用于动画执行的线程池
|
||||
animationExecutorService.shutdownNow();
|
||||
|
||||
// 关闭netty
|
||||
NettyClient nettyClient = BeanUtil.getBean("nettyClient");
|
||||
if (nettyClient != null) {
|
||||
nettyClient.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T $(String id, Class<T> clazz) {
|
||||
return (T) root.lookup("#" + id);
|
||||
}
|
||||
|
||||
public void delayShow(Node node, int secondDelay) {
|
||||
animationExecutorService.execute(new DelayRunnable(node, n -> n.setVisible(true), secondDelay));
|
||||
}
|
||||
|
||||
public void delayHidden(Node node, int secondDelay) {
|
||||
animationExecutorService.execute(new DelayRunnable(node, n -> {
|
||||
// 动画过程中的元素是无效的,不能被操作的
|
||||
n.setDisable(true);
|
||||
useTransition(n);
|
||||
n.setDisable(false);
|
||||
n.setVisible(false);
|
||||
}, secondDelay));
|
||||
}
|
||||
|
||||
private class DelayRunnable implements Runnable {
|
||||
private Object monitor = new Object();
|
||||
private Node node;
|
||||
private Consumer<Node> operate;
|
||||
private int delayTimes;
|
||||
|
||||
DelayRunnable(Node node, Consumer<Node> operate, int delayTimes) {
|
||||
this.node = node;
|
||||
this.operate = operate;
|
||||
this.delayTimes = delayTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (monitor) {
|
||||
monitor.wait(delayTimes * 1000L);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().isInterrupted();
|
||||
}
|
||||
|
||||
operate.accept(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void useTransition(Node node) {
|
||||
FadeTransition fade = new FadeTransition();
|
||||
fade.setDuration(Duration.millis(1000));
|
||||
fade.setFromValue(1);
|
||||
fade.setToValue(0.1);
|
||||
fade.setCycleCount(1000);
|
||||
fade.setAutoReverse(true);
|
||||
fade.setNode(node);
|
||||
fade.play();
|
||||
}
|
||||
|
||||
public abstract void registerEvent();
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.index;
|
||||
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.Pane;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IIndexEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class IndexController extends UIObject implements IndexMethod {
|
||||
public static final String METHOD_NAME = "index";
|
||||
|
||||
private static final String RESOURCE_NAME = "view/index.fxml";
|
||||
|
||||
private IIndexEvent indexEvent;
|
||||
private IndexEventRegister eventRegister;
|
||||
|
||||
public IndexController(IIndexEvent indexEvent) throws IOException {
|
||||
super();
|
||||
|
||||
this.indexEvent = indexEvent;
|
||||
|
||||
root = FXMLLoader.load(getClass().getClassLoader().getResource(RESOURCE_NAME));
|
||||
setScene(new Scene(root));
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateRemoteServerAddressOptions(List<String> remoteServerAddressList) {
|
||||
Pane remoteServerListPane = $("remoteServerListPane", Pane.class);
|
||||
|
||||
for (int i = 0, size = remoteServerAddressList.size(); i < size; i++) {
|
||||
Label serverAddressLabel = new ServerAddressLabel(remoteServerAddressList.get(i), i).getLabel();
|
||||
serverAddressLabel.setOnMouseClicked(e -> {
|
||||
Label label = (Label) e.getSource();
|
||||
String remoteServerAddress = label.getText().trim();
|
||||
String[] strs = remoteServerAddress.split(":");
|
||||
|
||||
$("host", TextField.class).setText(strs[0]);
|
||||
$("port", TextField.class).setText(strs[1]);
|
||||
});
|
||||
|
||||
remoteServerListPane.getChildren().add(serverAddressLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchRemoteServerAddressErrorTips() {
|
||||
$("fetchServerAddressErrorTips", TextArea.class).setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnectServerErrorTips() {
|
||||
$("connectServerErrorTips", Label.class).setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doShow() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doClose() {
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
eventRegister = new IndexEventRegister(this, indexEvent);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.index;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IIndexEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.EventRegister;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
public class IndexEventRegister implements EventRegister {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(IndexEventRegister.class);
|
||||
|
||||
private UIObject uiObject;
|
||||
private IIndexEvent indexEvent;
|
||||
|
||||
public IndexEventRegister(UIObject uiObject, IIndexEvent indexEvent) {
|
||||
this.uiObject = uiObject;
|
||||
this.indexEvent = indexEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
connectServer();
|
||||
}
|
||||
|
||||
private void connectServer() {
|
||||
uiObject.$("connectButton", Button.class).setOnAction(e -> {
|
||||
String host = uiObject.$("host", TextField.class).getText().trim();
|
||||
int port = Integer.parseInt(uiObject.$("port", TextField.class).getText().trim());
|
||||
|
||||
try {
|
||||
indexEvent.connect(host, port);
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error(String.format("连接netty服务端(%s:%d)失败", host, port), ex);
|
||||
Platform.runLater(() -> ((IndexMethod) uiObject).setConnectServerErrorTips());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.index;
|
||||
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IndexMethod extends Method {
|
||||
void generateRemoteServerAddressOptions(List<String> remoteServerAddressList);
|
||||
|
||||
void setFetchRemoteServerAddressErrorTips();
|
||||
|
||||
void setConnectServerErrorTips();
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.index;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
public class ServerAddressLabel {
|
||||
|
||||
private Label label;
|
||||
|
||||
public ServerAddressLabel(String serverAddress, int index) {
|
||||
label = new Label();
|
||||
label.setText(serverAddress);
|
||||
label.setLayoutY(index * 30);
|
||||
label.getStyleClass().add("remoteServerOption");
|
||||
}
|
||||
|
||||
public Label getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.lobby;
|
||||
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.Pane;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.RoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILobbyEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.AlertUtils;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class LobbyController extends UIObject implements LobbyMethod {
|
||||
public static final String METHOD_NAME = "lobby";
|
||||
|
||||
private static final String RESOURCE_NAME = "view/lobby.fxml";
|
||||
|
||||
private ILobbyEvent lobbyEvent;
|
||||
private LobbyEventRegister lobbyEventRegister;
|
||||
|
||||
public LobbyController(ILobbyEvent lobbyEvent) throws IOException {
|
||||
super();
|
||||
|
||||
root = FXMLLoader.load(getClass().getClassLoader().getResource(RESOURCE_NAME));
|
||||
setScene(new Scene(root));
|
||||
|
||||
this.lobbyEvent = lobbyEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
lobbyEventRegister = new LobbyEventRegister(this, lobbyEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleToPVPMenu() {
|
||||
Pane modalPane = $("modalPane", Pane.class);
|
||||
modalPane.setVisible(false);
|
||||
|
||||
Pane pvpMenuPane = $("pvpMenuPane", Pane.class);
|
||||
pvpMenuPane.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleToPVEMenu() {
|
||||
Pane modalPane = $("modalPane", Pane.class);
|
||||
modalPane.setVisible(false);
|
||||
|
||||
Pane pveMenuPane = $("pveMenuPane", Pane.class);
|
||||
pveMenuPane.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRoomList(List<RoomInfo> roomInfoList) {
|
||||
Pane roomsPane = $("roomsPane", Pane.class);
|
||||
|
||||
for (int i = 0, size = roomInfoList.size(); i < size; i++) {
|
||||
RoomInfo roomInfo = roomInfoList.get(i);
|
||||
Pane roomPane = new RoomPane(roomInfo, i).getPane();
|
||||
roomPane.setOnMouseClicked(e -> lobbyEvent.joinRoom(roomInfo.getRoomId()));
|
||||
|
||||
roomsPane.getChildren().add(roomPane);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinRoomFail(String message, String commentMessage) {
|
||||
AlertUtils.warn(message, commentMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doShow() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doClose() {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.lobby;
|
||||
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILobbyEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.EventRegister;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
public class LobbyEventRegister implements EventRegister {
|
||||
|
||||
private UIObject uiObject;
|
||||
private ILobbyEvent lobbyEvent;
|
||||
|
||||
public LobbyEventRegister(UIObject uiObject, ILobbyEvent lobbyEvent) {
|
||||
this.uiObject = uiObject;
|
||||
this.lobbyEvent = lobbyEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
selectPVPModal();
|
||||
selectPVEModal();
|
||||
createPVPRoom();
|
||||
createPVERoom();
|
||||
}
|
||||
|
||||
private void selectPVPModal() {
|
||||
uiObject.$("pvpModalButton", Button.class).setOnAction(e -> lobbyEvent.selectPVPModal());
|
||||
}
|
||||
|
||||
private void selectPVEModal() {
|
||||
uiObject.$("pveModalButton", Button.class).setOnAction(e -> lobbyEvent.selectPVEModal());
|
||||
}
|
||||
|
||||
private void createPVPRoom() {
|
||||
uiObject.$("createRoomButton", Button.class).setOnAction(e -> lobbyEvent.createPVPRoom());
|
||||
}
|
||||
|
||||
private static final int SIMPLE_MODAL = 1;
|
||||
private static final int NORMAL_MODAL = 2;
|
||||
private static final int DIFFICULT_MODAL = 3;
|
||||
|
||||
private void createPVERoom() {
|
||||
uiObject.$("simpleModalButton", Button.class).setOnAction(e -> lobbyEvent.createPVERoom(SIMPLE_MODAL));
|
||||
uiObject.$("normalModalButton", Button.class).setOnAction(e -> lobbyEvent.createPVERoom(NORMAL_MODAL));
|
||||
uiObject.$("difficultModalButton", Button.class).setOnAction(e -> lobbyEvent.createPVERoom(DIFFICULT_MODAL));
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.lobby;
|
||||
|
||||
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.RoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LobbyMethod extends Method {
|
||||
|
||||
void toggleToPVPMenu();
|
||||
|
||||
void toggleToPVEMenu();
|
||||
|
||||
void showRoomList(List<RoomInfo> roomInfoList);
|
||||
|
||||
void joinRoomFail(String message, String commentMessage);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.lobby;
|
||||
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.RoomInfo;
|
||||
|
||||
public class RoomPane {
|
||||
private static final int MARGIN_TOP = 25;
|
||||
private static final int MARGIN_LEFT = 40;
|
||||
|
||||
private Pane pane;
|
||||
|
||||
public RoomPane(RoomInfo roomInfo, int index) {
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("roomPane");
|
||||
pane.setLayoutX(35 + (index % 3) * (150 + MARGIN_LEFT));
|
||||
pane.setLayoutY(65 + ((index / 3) * (120 + MARGIN_TOP)));
|
||||
|
||||
Label idLabel = new Label();
|
||||
idLabel.setLayoutX(6);
|
||||
idLabel.setLayoutY(3);
|
||||
idLabel.getStyleClass().add("idLabel");
|
||||
idLabel.setText(roomInfo.getRoomId().toString());
|
||||
|
||||
Label roomOwnerLabel = new Label();
|
||||
roomOwnerLabel.setLayoutX(0);
|
||||
roomOwnerLabel.setLayoutY(22);
|
||||
roomOwnerLabel.getStyleClass().add("roomOwnerLabel");
|
||||
|
||||
Label roomOwnerNameLabel = new Label();
|
||||
roomOwnerNameLabel.setLayoutX(34);
|
||||
roomOwnerNameLabel.setLayoutY(32);
|
||||
roomOwnerNameLabel.setText(roomInfo.getRoomOwner());
|
||||
|
||||
Label modalLabel = new Label();
|
||||
modalLabel.setLayoutX(54);
|
||||
modalLabel.setLayoutY(60);
|
||||
modalLabel.getStyleClass().add("modalLabel");
|
||||
modalLabel.setText(roomInfo.getRoomType());
|
||||
|
||||
Label playerCountLabel = new Label();
|
||||
playerCountLabel.setLayoutX(60);
|
||||
playerCountLabel.setLayoutY(100);
|
||||
playerCountLabel.getStyleClass().add("playerCountLabel");
|
||||
playerCountLabel.setText("当前人数:" + roomInfo.getRoomClientCount() + "/3");
|
||||
|
||||
ObservableList<Node> children = pane.getChildren();
|
||||
children.add(idLabel);
|
||||
children.add(roomOwnerLabel);
|
||||
children.add(roomOwnerNameLabel);
|
||||
children.add(modalLabel);
|
||||
children.add(playerCountLabel);
|
||||
}
|
||||
|
||||
public Pane getPane() {
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.login;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILoginEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LoginController extends UIObject implements Method {
|
||||
public static final String METHOD_NAME = "login";
|
||||
|
||||
private static final String RESOURCE_NAME = "view/login.fxml";
|
||||
|
||||
private ILoginEvent loginEvent;
|
||||
private LoginEventRegister loginEventRegister;
|
||||
|
||||
public LoginController(ILoginEvent loginEvent) throws IOException {
|
||||
super();
|
||||
|
||||
root = FXMLLoader.load(getClass().getClassLoader().getResource(RESOURCE_NAME));
|
||||
setScene(new Scene(root));
|
||||
|
||||
this.loginEvent = loginEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
this.loginEventRegister = new LoginEventRegister(this, loginEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doShow() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doClose() {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.login;
|
||||
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.ILoginEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.EventRegister;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
public class LoginEventRegister implements EventRegister {
|
||||
|
||||
private UIObject uiObject;
|
||||
private ILoginEvent loginEvent;
|
||||
|
||||
public LoginEventRegister(UIObject uiObject, ILoginEvent loginEvent) {
|
||||
this.uiObject = uiObject;
|
||||
this.loginEvent = loginEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
submitNickname();
|
||||
}
|
||||
|
||||
private void submitNickname() {
|
||||
TextField field = uiObject.$("nicknameInput", TextField.class);
|
||||
|
||||
uiObject.$("submitButton", Button.class).setOnAction(e -> {
|
||||
String nickname = field.getText().trim();
|
||||
loginEvent.setNickname(nickname);
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyNickname() {
|
||||
uiObject.$("input", TextField.class).setOnAction(e -> {});
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.text.Text;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.PokerLevel;
|
||||
import org.nico.ratel.landlords.enums.PokerType;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
|
||||
public class PokerPane {
|
||||
public static final int MARGIN_LEFT = 40;
|
||||
|
||||
private Poker poker;
|
||||
// start at 0
|
||||
private int index;
|
||||
private int offsetX;
|
||||
|
||||
private Pane pane;
|
||||
|
||||
public PokerPane(int index, int offsetX, Poker poker) {
|
||||
this.poker = poker;
|
||||
this.index = index;
|
||||
this.offsetX = offsetX;
|
||||
|
||||
if (PokerLevel.LEVEL_SMALL_KING.equals(poker.getLevel()) ||
|
||||
PokerLevel.LEVEL_BIG_KING.equals(poker.getLevel())) {
|
||||
createJokerPokerPane();
|
||||
} else {
|
||||
createNormalPokerPane();
|
||||
}
|
||||
|
||||
pane.setOnMouseClicked(e -> {
|
||||
double y = pane.getLayoutY();
|
||||
boolean alreadyChecked = y == 0;
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
|
||||
// 取消选中
|
||||
if (alreadyChecked) {
|
||||
pane.setLayoutY(y + 20);
|
||||
currentRoomInfo.removeUncheckedPoker(poker);
|
||||
}
|
||||
// 选中
|
||||
else {
|
||||
pane.setLayoutY(y - 20);
|
||||
currentRoomInfo.addCheckedPoker(poker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createNormalPokerPane() {
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("horizontal-poker");
|
||||
pane.setLayoutX(index * MARGIN_LEFT + offsetX);
|
||||
pane.setLayoutY(20);
|
||||
|
||||
Text level = new Text();
|
||||
level.getStyleClass().add("level");
|
||||
level.setLayoutX(8);
|
||||
level.setLayoutY(34);
|
||||
level.setText(poker.getLevel().getName());
|
||||
|
||||
Text typeSmall = new Text();
|
||||
typeSmall.getStyleClass().add("type-small");
|
||||
typeSmall.setLayoutX(8);
|
||||
typeSmall.setLayoutY(60);
|
||||
typeSmall.setText(poker.getType().getName());
|
||||
|
||||
Text typeBig = new Text();
|
||||
typeBig.getStyleClass().add("type-big");
|
||||
typeBig.setLayoutX(50);
|
||||
typeBig.setLayoutY(120);
|
||||
typeBig.setText(poker.getType().getName());
|
||||
|
||||
if (PokerType.CLUB.equals(poker.getType()) || PokerType.SPADE.equals(poker.getType())) {
|
||||
level.setFill(Paint.valueOf("black"));
|
||||
typeSmall.setFill(Paint.valueOf("black"));
|
||||
typeBig.setFill(Paint.valueOf("black"));
|
||||
} else if (PokerType.DIAMOND.equals(poker.getType()) || PokerType.HEART.equals(poker.getType())) {
|
||||
level.setFill(Paint.valueOf("#9c2023"));
|
||||
typeSmall.setFill(Paint.valueOf("#9c2023"));
|
||||
typeBig.setFill(Paint.valueOf("#9c2023"));
|
||||
}
|
||||
|
||||
ObservableList<Node> children = pane.getChildren();
|
||||
children.add(level);
|
||||
children.add(typeSmall);
|
||||
children.add(typeBig);
|
||||
}
|
||||
|
||||
private void createJokerPokerPane() {
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("horizontal-poker");
|
||||
pane.setLayoutX(index * MARGIN_LEFT + offsetX);
|
||||
pane.setLayoutY(20);
|
||||
|
||||
Text text1 = new Text();
|
||||
text1.getStyleClass().add("joker-level");
|
||||
text1.setLayoutX(13);
|
||||
text1.setLayoutY(26);
|
||||
text1.setText("J");
|
||||
|
||||
Text text2 = new Text();
|
||||
text2.getStyleClass().add("joker-level");
|
||||
text2.setLayoutX(8);
|
||||
text2.setLayoutY(44);
|
||||
text2.setText("O");
|
||||
|
||||
Text text3 = new Text();
|
||||
text3.getStyleClass().add("joker-level");
|
||||
text3.setLayoutX(10);
|
||||
text3.setLayoutY(62);
|
||||
text3.setText("K");
|
||||
|
||||
Text text4 = new Text();
|
||||
text4.getStyleClass().add("joker-level");
|
||||
text4.setLayoutX(10);
|
||||
text4.setLayoutY(80);
|
||||
text4.setText("E");
|
||||
|
||||
Text text5 = new Text();
|
||||
text5.getStyleClass().add("joker-level");
|
||||
text5.setLayoutX(10);
|
||||
text5.setLayoutY(98);
|
||||
text5.setText("R");
|
||||
|
||||
Text logo = new Text();
|
||||
logo.setLayoutX(40);
|
||||
logo.setLayoutY(126);
|
||||
logo.setStyle("-fx-font-size: 28");
|
||||
logo.setStyle("-fx-text-fill: silver");
|
||||
logo.setText("ratel");
|
||||
|
||||
if (PokerLevel.LEVEL_SMALL_KING.equals(poker.getLevel())) {
|
||||
text1.setFill(Paint.valueOf("black"));
|
||||
text2.setFill(Paint.valueOf("black"));
|
||||
text3.setFill(Paint.valueOf("black"));
|
||||
text4.setFill(Paint.valueOf("black"));
|
||||
text5.setFill(Paint.valueOf("black"));
|
||||
} else if (PokerLevel.LEVEL_BIG_KING.equals(poker.getLevel())) {
|
||||
text1.setFill(Paint.valueOf("#9c2023"));
|
||||
text2.setFill(Paint.valueOf("#9c2023"));
|
||||
text3.setFill(Paint.valueOf("#9c2023"));
|
||||
text4.setFill(Paint.valueOf("#9c2023"));
|
||||
text5.setFill(Paint.valueOf("#9c2023"));
|
||||
}
|
||||
|
||||
ObservableList<Node> children = pane.getChildren();
|
||||
children.add(text1);
|
||||
children.add(text2);
|
||||
children.add(text3);
|
||||
children.add(text4);
|
||||
children.add(text5);
|
||||
}
|
||||
|
||||
public Pane getPane() {
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
@@ -1,452 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.text.Text;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientType;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IRoomEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RoomController extends UIObject implements RoomMethod {
|
||||
public static final String METHOD_NAME = "room";
|
||||
|
||||
private static final String RESOURCE_NAME = "view/room.fxml";
|
||||
|
||||
private IRoomEvent roomEvent;
|
||||
private RoomEventRegister roomEventDefine;
|
||||
|
||||
private PlayerPaneOperator prevPlayerPaneOperator;
|
||||
private PlayerPaneOperator nextPlayerPaneOperator;
|
||||
private PlayerPaneOperator playerPaneOperator;
|
||||
|
||||
public RoomController(IRoomEvent roomEvent) throws IOException {
|
||||
super();
|
||||
|
||||
root = FXMLLoader.load(getClass().getClassLoader().getResource(RESOURCE_NAME));
|
||||
setScene(new Scene(root));
|
||||
|
||||
this.roomEvent = roomEvent;
|
||||
|
||||
registerEvent();
|
||||
|
||||
prevPlayerPaneOperator = new PrevPlayerPaneOperator();
|
||||
nextPlayerPaneOperator = new NextPlayerPaneOperator();
|
||||
playerPaneOperator = new CurrentPlayerPaneOperator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startGame(List<Poker> pokers) {
|
||||
// 1,组件状态改变(遮蔽罩隐藏,游戏面板可用状态改变)
|
||||
// 2,组件内容填充
|
||||
// 3,元素隐藏
|
||||
// 4,牌初始化(己方和对方)
|
||||
$("waitingPane", Pane.class).setVisible(false);
|
||||
$("playingPane", Pane.class).setDisable(false);
|
||||
|
||||
Button robButton = $("robButton", Button.class);
|
||||
robButton.setText("抢地主");
|
||||
robButton.setVisible(false);
|
||||
|
||||
Button notRobButton = $("notRobButton", Button.class);
|
||||
notRobButton.setText("不抢");
|
||||
notRobButton.setVisible(false);
|
||||
|
||||
$("prevPlayerPane", Pane.class).lookup(".tips").setVisible(false);
|
||||
$("nextPlayerPane", Pane.class).lookup(".tips").setVisible(false);
|
||||
$("quitButton", Button.class).setText("退出");
|
||||
|
||||
initPokers(pokers);
|
||||
}
|
||||
|
||||
private static final int PER_PLAYER_DEFAULT_POKER_COUNT = 17;
|
||||
private static final int SURPLUS_POKER_COUNT = 3;
|
||||
|
||||
private void initPokers(List<Poker> pokers) {
|
||||
// 己方牌pane
|
||||
refreshPlayPokers(pokers);
|
||||
|
||||
// 上下游牌pane
|
||||
$("prevPlayerPokersPane", Pane.class).setVisible(true);
|
||||
$("nextPlayerPokersPane", Pane.class).setVisible(true);
|
||||
refreshPrevPlayerPokers(PER_PLAYER_DEFAULT_POKER_COUNT);
|
||||
refreshNextPlayerPokers(PER_PLAYER_DEFAULT_POKER_COUNT);
|
||||
|
||||
// 底牌
|
||||
Pane surplusPokersPane = $("surplusPokersPane", Pane.class);
|
||||
|
||||
surplusPokersPane.getChildren().clear();
|
||||
for (int n = 0; n < SURPLUS_POKER_COUNT; n++) {
|
||||
surplusPokersPane.getChildren().add(new SurplusPokerPane(n).getPane());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gameOver(String winnerName, ClientType winnerType) {
|
||||
$("playingPane", Pane.class).setDisable(true);
|
||||
Pane gameOverPane = $("gameOverPane", Pane.class);
|
||||
gameOverPane.setVisible(true);
|
||||
Text text = (Text) gameOverPane.lookup("#winnerInfo");
|
||||
text.setText(String.format("游戏结束,%s胜利", ClientType.LANDLORD.equals(winnerType) ? "地主" : "农民"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPokers(String playerName, List<Poker> pokers) {
|
||||
getPlayerPaneOperatorByPlayerName(playerName).showPokers(pokers);
|
||||
}
|
||||
|
||||
private PlayerPaneOperator getPlayerPaneOperatorByPlayerName(String playerName) {
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
|
||||
if (playerName.equals(currentRoomInfo.getPrevPlayerName())) {
|
||||
return prevPlayerPaneOperator;
|
||||
} else if (playerName.equals(currentRoomInfo.getNextPlayerName())) {
|
||||
return nextPlayerPaneOperator;
|
||||
} else if (playerName.equals(currentRoomInfo.getPlayer().getNickname())) {
|
||||
return playerPaneOperator;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("当前房间没有 " + playerName + " 用户");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String playerName, String message) {
|
||||
getPlayerPaneOperatorByPlayerName(playerName).showMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(String playerName) {
|
||||
getPlayerPaneOperatorByPlayerName(playerName).play();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPlayPokers(List<Poker> pokers) {
|
||||
final int pokersPaneWidth = 870;
|
||||
final int pokerPaneWidth = 110;
|
||||
int size = pokers.size();
|
||||
// 第一张牌的x轴偏移量
|
||||
int firstPokerPaneOffsetX = ((pokersPaneWidth - pokerPaneWidth) - PokerPane.MARGIN_LEFT * (size -1)) / 2;
|
||||
|
||||
Pane pokersPane = $("pokersPane", Pane.class);
|
||||
|
||||
// 可能之前有牌,先清理再填充
|
||||
pokersPane.getChildren().clear();
|
||||
for (int i = 0; i < size; i++) {
|
||||
pokersPane.getChildren().add(new PokerPane(i, firstPokerPaneOffsetX, pokers.get(i)).getPane());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPrevPlayerPokers(int pokerCount) {
|
||||
Pane prevPlayerPokersPane = $("prevPlayerPokersPane", Pane.class);
|
||||
((Label) prevPlayerPokersPane.lookup(".pokerCount")).setText(String.valueOf(pokerCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshNextPlayerPokers(int pokerCount) {
|
||||
Pane nextPlayerPokersPane = $("nextPlayerPokersPane", Pane.class);
|
||||
((Label) nextPlayerPokersPane.lookup(".pokerCount")).setText(String.valueOf(pokerCount));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void showRobButtons() {
|
||||
$("robButton", Button.class).setVisible(true);
|
||||
$("notRobButton", Button.class).setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideRobButtons() {
|
||||
$("robButton", Button.class).setVisible(false);
|
||||
$("notRobButton", Button.class).setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSurplusPokers(List<Poker> surplusPokers) {
|
||||
Pane surplusPokersPane = $("surplusPokersPane", Pane.class);
|
||||
|
||||
surplusPokersPane.getChildren().clear();
|
||||
for (int n = 0, size = surplusPokers.size(); n < size; n++) {
|
||||
Pane surplusPokerPane = new PokerPane(n, 0, surplusPokers.get(n)).getPane();
|
||||
surplusPokerPane.setLayoutX(45 + n * (SurplusPokerPane.MARGIN_LEFT + 110));
|
||||
surplusPokerPane.setLayoutY(0);
|
||||
|
||||
surplusPokersPane.getChildren().add(surplusPokerPane);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLandLord(String landlordName) {
|
||||
// 1,为地主加底牌(重新洗牌)
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
if (ClientType.LANDLORD.equals(currentRoomInfo.getPrevPlayerRole())) {
|
||||
currentRoomInfo.setPrevPlayerSurplusPokerCount(PER_PLAYER_DEFAULT_POKER_COUNT + SURPLUS_POKER_COUNT);
|
||||
currentRoomInfo.setNextPlayerSurplusPokerCount(PER_PLAYER_DEFAULT_POKER_COUNT);
|
||||
refreshPrevPlayerPokers(PER_PLAYER_DEFAULT_POKER_COUNT + SURPLUS_POKER_COUNT);
|
||||
} else if (ClientType.LANDLORD.equals(currentRoomInfo.getNextPlayerRole())) {
|
||||
currentRoomInfo.setNextPlayerSurplusPokerCount(PER_PLAYER_DEFAULT_POKER_COUNT + SURPLUS_POKER_COUNT);
|
||||
currentRoomInfo.setPrevPlayerSurplusPokerCount(PER_PLAYER_DEFAULT_POKER_COUNT);
|
||||
refreshNextPlayerPokers(PER_PLAYER_DEFAULT_POKER_COUNT + SURPLUS_POKER_COUNT);
|
||||
} else {
|
||||
User user = BeanUtil.getBean("user");
|
||||
refreshPlayPokers(user.getPokers());
|
||||
}
|
||||
|
||||
// 2,显示每个人的角色(地主|农民)和姓名
|
||||
$("prevPlayerRole", Label.class).setText(ClientType.LANDLORD.equals(currentRoomInfo.getPrevPlayerRole()) ? "地主" : "农民");
|
||||
$("nextPlayerRole", Label.class).setText(ClientType.LANDLORD.equals(currentRoomInfo.getNextPlayerRole()) ? "地主" : "农民");
|
||||
$("playerRole", Label.class).setText(ClientType.LANDLORD.equals(currentRoomInfo.getPlayer().getRole()) ? "地主" : "农民");
|
||||
|
||||
$("prevPlayerNickname", Label.class).setText(currentRoomInfo.getPrevPlayerName());
|
||||
$("nextPlayerNickname", Label.class).setText(currentRoomInfo.getNextPlayerName());
|
||||
$("playerNickname", Label.class).setText(currentRoomInfo.getPlayer().getNickname());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPokerPlayButtons() {
|
||||
$("submitButton", Button.class).setVisible(true);
|
||||
$("passButton", Button.class).setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hidePokerPlayButtons() {
|
||||
$("submitButton", Button.class).setVisible(false);
|
||||
$("passButton", Button.class).setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShow() {
|
||||
return super.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinRoom() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doShow() {
|
||||
super.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doClose() {
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
roomEventDefine = new RoomEventRegister(this, roomEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
interface PlayerPaneOperator {
|
||||
void showPokers(List<Poker> pokers);
|
||||
|
||||
void showMessage(String message);
|
||||
|
||||
void play();
|
||||
}
|
||||
|
||||
private abstract class AbstractPlayerPaneOperator implements PlayerPaneOperator {
|
||||
protected Pane playerShowPane;
|
||||
protected Label timer;
|
||||
protected Label tips;
|
||||
protected Pane playerShowPokersPane;
|
||||
|
||||
protected Pane playerPokersPane;
|
||||
|
||||
protected CountDownTask.CountDownFuture future;
|
||||
|
||||
AbstractPlayerPaneOperator(String parentPaneId) {
|
||||
this.playerShowPane = $(parentPaneId, Pane.class);
|
||||
this.timer = (Label) playerShowPane.lookup(".timer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void showMessage(String message) {
|
||||
if (future != null && !future.isDone()) {
|
||||
future.cancel();
|
||||
}
|
||||
|
||||
playerShowPokersPane.getChildren().clear();
|
||||
|
||||
tips.setText(message);
|
||||
tips.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void play() {
|
||||
playerShowPokersPane.getChildren().clear();
|
||||
|
||||
tips.setVisible(false);
|
||||
|
||||
if (future == null || future.isDone()) {
|
||||
CountDownTask task = new CountDownTask(timer, 30,
|
||||
node -> Platform.runLater(() -> hidePokerPlayButtons()),
|
||||
surplusTime -> Platform.runLater(() -> timer.setText(surplusTime.toString())));
|
||||
|
||||
future = task.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void showPokers(List<Poker> pokers) {
|
||||
if (future != null && !future.isDone()) {
|
||||
future.cancel();
|
||||
}
|
||||
|
||||
tips.setVisible(false);
|
||||
|
||||
renderPokers(pokers);
|
||||
refreshPlayerPokers(pokers);
|
||||
}
|
||||
|
||||
protected abstract void renderPokers(List<Poker> pokers);
|
||||
protected abstract void refreshPlayerPokers(List<Poker> pokers);
|
||||
}
|
||||
|
||||
private class PrevPlayerPaneOperator extends AbstractPlayerPaneOperator {
|
||||
|
||||
PrevPlayerPaneOperator() {
|
||||
super("prevPlayerShowPane");
|
||||
|
||||
this.tips = (Label) playerShowPane.lookup(".tips");
|
||||
this.playerShowPokersPane = (Pane) playerShowPane.lookup("#prevPlayerShowPokersPane");
|
||||
|
||||
this.playerPokersPane = $("prevPlayerPokersPane", Pane.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPokers(List<Poker> pokers) {
|
||||
final int maxPerRowPokerCount = 8;
|
||||
|
||||
for (int i = 0, size = pokers.size(); i < size; i++) {
|
||||
ShowPokerPane pokerPane = new ShowPokerPane(pokers.get(i));
|
||||
if (i < maxPerRowPokerCount) {
|
||||
pokerPane.setLayout(i * ShowPokerPane.MARGIN_LEFT, 0);
|
||||
} else {
|
||||
pokerPane.setLayout((i % maxPerRowPokerCount) * ShowPokerPane.MARGIN_LEFT, ShowPokerPane.MARGIN_TOP);
|
||||
}
|
||||
playerShowPokersPane.getChildren().add(pokerPane.getPane());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshPlayerPokers(List<Poker> pokers) {
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
|
||||
refreshPrevPlayerPokers(currentRoomInfo.getPrevPlayerSurplusPokerCount());
|
||||
}
|
||||
}
|
||||
|
||||
private class NextPlayerPaneOperator extends AbstractPlayerPaneOperator {
|
||||
|
||||
NextPlayerPaneOperator() {
|
||||
super("nextPlayerShowPane");
|
||||
|
||||
this.tips = (Label) playerShowPane.lookup(".tips");
|
||||
this.playerShowPokersPane = (Pane) playerShowPane.lookup("#nextPlayerShowPokersPane");
|
||||
|
||||
this.playerPokersPane = $("nextPlayerPokersPane", Pane.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPokers(List<Poker> pokers) {
|
||||
final int maxPerRowPokerCount = 8;
|
||||
final int parentPaneWidth = 380;
|
||||
final int showPokerPaneWidth = 40;
|
||||
|
||||
// 从右至左渲染牌
|
||||
for (int i = pokers.size() - 1; i >= 0; i--) {
|
||||
ShowPokerPane pokerPane = new ShowPokerPane(pokers.get(i));
|
||||
int layoutX = parentPaneWidth - (showPokerPaneWidth + ShowPokerPane.MARGIN_LEFT * (i % maxPerRowPokerCount));
|
||||
if (i < maxPerRowPokerCount) {
|
||||
pokerPane.setLayout(layoutX, 0);
|
||||
} else {
|
||||
pokerPane.setLayout(layoutX, ShowPokerPane.MARGIN_TOP);
|
||||
}
|
||||
playerShowPokersPane.getChildren().add(pokerPane.getPane());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshPlayerPokers(List<Poker> pokers) {
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
|
||||
refreshNextPlayerPokers(currentRoomInfo.getNextPlayerSurplusPokerCount());
|
||||
}
|
||||
}
|
||||
|
||||
private class CurrentPlayerPaneOperator extends AbstractPlayerPaneOperator {
|
||||
|
||||
CurrentPlayerPaneOperator() {
|
||||
super("playerShowPane");
|
||||
|
||||
this.tips = (Label) playerShowPane.lookup(".primary-tips");
|
||||
this.playerShowPokersPane = (Pane) playerShowPane.lookup("#playerShowPokersPane");
|
||||
|
||||
this.playerPokersPane = $("pokersPane", Pane.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message) {
|
||||
hidePokerPlayButtons();
|
||||
|
||||
super.showMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPokers(List<Poker> pokers) {
|
||||
hidePokerPlayButtons();
|
||||
|
||||
super.showPokers(pokers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
super.play();
|
||||
|
||||
showPokerPlayButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPokers(List<Poker> pokers) {
|
||||
final int parentPaneWidth = 870;
|
||||
final int showPokerPaneWidth = 40;
|
||||
int size = pokers.size();
|
||||
int offset = (parentPaneWidth - (showPokerPaneWidth + ShowPokerPane.MARGIN_LEFT * (size - 1))) / 2;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
ShowPokerPane pokerPane = new ShowPokerPane(pokers.get(i));
|
||||
pokerPane.setLayout(offset + i * ShowPokerPane.MARGIN_LEFT, 0);
|
||||
playerShowPokersPane.getChildren().add(pokerPane.getPane());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshPlayerPokers(List<Poker> pokers) {
|
||||
User user = BeanUtil.getBean("user");
|
||||
|
||||
refreshPlayPokers(user.getPokers());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import priv.zxw.ratel.landlords.client.javafx.util.BeanUtil;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.CurrentRoomInfo;
|
||||
import priv.zxw.ratel.landlords.client.javafx.entity.User;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.event.IRoomEvent;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.util.CountDownTask;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.EventRegister;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.UIObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RoomEventRegister implements EventRegister {
|
||||
|
||||
private UIObject uiObject;
|
||||
private IRoomEvent roomEvent;
|
||||
|
||||
public RoomEventRegister(UIObject uiObject, IRoomEvent roomEvent) {
|
||||
this.uiObject = uiObject;
|
||||
this.roomEvent = roomEvent;
|
||||
|
||||
registerEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent() {
|
||||
robLandlord();
|
||||
notRobLandlord();
|
||||
submitPokers();
|
||||
passRound();
|
||||
back2Lobby();
|
||||
}
|
||||
|
||||
private void robLandlord() {
|
||||
uiObject.$("robButton", Button.class).setOnAction(e -> {
|
||||
RoomController roomController = (RoomController) uiObject;
|
||||
roomController.hideRobButtons();
|
||||
|
||||
roomEvent.robLandlord();
|
||||
});
|
||||
}
|
||||
|
||||
private void notRobLandlord() {
|
||||
uiObject.$("notRobButton", Button.class).setOnAction(e -> {
|
||||
RoomController roomController = (RoomController) uiObject;
|
||||
roomController.hideRobButtons();
|
||||
|
||||
roomEvent.notRobLandlord();
|
||||
});
|
||||
}
|
||||
|
||||
private void submitPokers() {
|
||||
uiObject.$("submitButton", Button.class).setOnAction(e -> {
|
||||
CurrentRoomInfo currentRoomInfo = BeanUtil.getBean("currentRoomInfo");
|
||||
List<Poker> checkedPokers = currentRoomInfo.pollCheckedPokers();
|
||||
|
||||
if (checkedPokers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行对应的事件
|
||||
roomEvent.submitPokers(checkedPokers);
|
||||
});
|
||||
}
|
||||
|
||||
private void passRound() {
|
||||
uiObject.$("passButton", Button.class).setOnAction(e -> {
|
||||
roomEvent.passRound();
|
||||
});
|
||||
}
|
||||
|
||||
private void back2Lobby() {
|
||||
uiObject.$("quitButton", Button.class).setOnAction(e -> roomEvent.exit());
|
||||
uiObject.$("backLobbyButton", Button.class).setOnAction(e -> roomEvent.exit());
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.ClientType;
|
||||
import priv.zxw.ratel.landlords.client.javafx.ui.view.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface RoomMethod extends Method {
|
||||
boolean isShow();
|
||||
|
||||
void joinRoom();
|
||||
|
||||
void startGame(List<Poker> pokers);
|
||||
|
||||
void gameOver(String winnerName, ClientType winnerType);
|
||||
|
||||
void showPokers(String playerName, List<Poker> pokers);
|
||||
|
||||
void showMessage(String playerName, String message);
|
||||
|
||||
void play(String playerName);
|
||||
|
||||
void refreshPlayPokers(List<Poker> pokers);
|
||||
|
||||
void refreshPrevPlayerPokers(int pokerCount);
|
||||
|
||||
void refreshNextPlayerPokers(int pokerCount);
|
||||
|
||||
void showRobButtons();
|
||||
|
||||
void hideRobButtons();
|
||||
|
||||
void showSurplusPokers(List<Poker> surplusPokers);
|
||||
|
||||
void setLandLord(String landlordName);
|
||||
|
||||
void showPokerPlayButtons();
|
||||
|
||||
void hidePokerPlayButtons();
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Paint;
|
||||
import org.nico.ratel.landlords.entity.Poker;
|
||||
import org.nico.ratel.landlords.enums.PokerLevel;
|
||||
import org.nico.ratel.landlords.enums.PokerType;
|
||||
|
||||
public class ShowPokerPane {
|
||||
public static final int MARGIN_LEFT = 30;
|
||||
public static final int MARGIN_TOP = 40;
|
||||
|
||||
private Poker poker;
|
||||
|
||||
private Pane pane;
|
||||
|
||||
public ShowPokerPane(Poker poker) {
|
||||
this.poker = poker;
|
||||
|
||||
if (PokerLevel.LEVEL_SMALL_KING.equals(poker.getLevel()) ||
|
||||
PokerLevel.LEVEL_BIG_KING.equals(poker.getLevel())) {
|
||||
createJokerPokerPane();
|
||||
} else {
|
||||
createNormalPokerPane();
|
||||
}
|
||||
}
|
||||
|
||||
private void createNormalPokerPane() {
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("showPoker");
|
||||
|
||||
Label level = new Label();
|
||||
level.setLayoutX(2);
|
||||
level.setLayoutY(-2);
|
||||
level.setText(poker.getLevel().getName());
|
||||
level.getStyleClass().add("level");
|
||||
|
||||
Label type = new Label();
|
||||
type.setLayoutX(2);
|
||||
type.setLayoutY(12);
|
||||
type.setText(poker.getType().getName());
|
||||
type.getStyleClass().add("type-small");
|
||||
|
||||
if (PokerType.CLUB.equals(poker.getType()) || PokerType.SPADE.equals(poker.getType())) {
|
||||
level.setStyle("-fx-text-fill: black");
|
||||
type.setStyle("-fx-text-fill: black");
|
||||
} else if (PokerType.DIAMOND.equals(poker.getType()) || PokerType.HEART.equals(poker.getType())) {
|
||||
level.setStyle("-fx-text-fill: #9c2023");
|
||||
type.setStyle("-fx-text-fill: #9c2023");
|
||||
}
|
||||
|
||||
pane.getChildren().add(level);
|
||||
pane.getChildren().add(type);
|
||||
}
|
||||
|
||||
private void createJokerPokerPane() {
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("showPoker");
|
||||
|
||||
Label label1 = new Label();
|
||||
label1.setLayoutX(6);
|
||||
label1.setLayoutY(0);
|
||||
label1.setText("J");
|
||||
label1.getStyleClass().add("joker-level");
|
||||
|
||||
Label label2 = new Label();
|
||||
label2.setLayoutX(4);
|
||||
label2.setLayoutY(13);
|
||||
label2.setText("O");
|
||||
label2.getStyleClass().add("joker-level");
|
||||
|
||||
Label label3 = new Label();
|
||||
label3.setLayoutX(5);
|
||||
label3.setLayoutY(26);
|
||||
label3.setText("K");
|
||||
label3.getStyleClass().add("joker-level");
|
||||
|
||||
if (PokerLevel.LEVEL_SMALL_KING.equals(poker.getLevel())) {
|
||||
label1.setStyle("-fx-text-fill: black");
|
||||
label2.setStyle("-fx-text-fill: black");
|
||||
label3.setStyle("-fx-text-fill: black");
|
||||
} else if (PokerLevel.LEVEL_BIG_KING.equals(poker.getLevel())) {
|
||||
label1.setStyle("-fx-text-fill: #9c2023");
|
||||
label2.setStyle("-fx-text-fill: #9c2023");
|
||||
label3.setStyle("-fx-text-fill: #9c2023");
|
||||
}
|
||||
|
||||
pane.getChildren().add(label1);
|
||||
pane.getChildren().add(label2);
|
||||
pane.getChildren().add(label3);
|
||||
}
|
||||
|
||||
public void setLayout(double x, double y) {
|
||||
pane.setLayoutX(x);
|
||||
pane.setLayoutY(y);
|
||||
}
|
||||
|
||||
public Pane getPane() {
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.room;
|
||||
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class SurplusPokerPane {
|
||||
public static final double MARGIN_LEFT = 40;
|
||||
|
||||
private int index;
|
||||
|
||||
private Pane pane;
|
||||
|
||||
public SurplusPokerPane(int index) {
|
||||
this.index = index;
|
||||
|
||||
pane = new Pane();
|
||||
pane.getStyleClass().add("surplus-poker");
|
||||
pane.setLayoutX(45 + index * (MARGIN_LEFT + 110));
|
||||
}
|
||||
|
||||
public Pane getPane() {
|
||||
return pane;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.util;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
|
||||
public class AlertUtils {
|
||||
|
||||
public static void info(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.INFORMATION, headerText, contentText);
|
||||
}
|
||||
|
||||
private static void createAndShowAlert(Alert.AlertType alertType,
|
||||
String headerText, String contentText) {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle(Alert.AlertType.INFORMATION.equals(alertType) ? "信息" :
|
||||
Alert.AlertType.WARNING.equals(alertType) ? "警告" : "错误");
|
||||
alert.setHeaderText(headerText);
|
||||
alert.setContentText(contentText);
|
||||
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
public static void warn(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.WARNING, headerText, contentText);
|
||||
}
|
||||
|
||||
public static void error(String headerText, String contentText) {
|
||||
createAndShowAlert(Alert.AlertType.ERROR, headerText, contentText);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.ui.view.util;
|
||||
|
||||
|
||||
import javafx.scene.Node;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CountDownTask {
|
||||
public static final int DEFAULT_TIME_OUT = 30;
|
||||
|
||||
private Consumer<Node> finallyExecuteConsumer;
|
||||
private Consumer<Integer> preSecondExecuteConsumer;
|
||||
private Node targetElement;
|
||||
private int duration;
|
||||
|
||||
public CountDownTask(Node targetElement,
|
||||
Consumer<Node> finallyExecuteConsumer, Consumer<Integer> preSecondExecuteConsumer) {
|
||||
this.finallyExecuteConsumer = finallyExecuteConsumer;
|
||||
this.preSecondExecuteConsumer = preSecondExecuteConsumer;
|
||||
this.targetElement = targetElement;
|
||||
}
|
||||
|
||||
public CountDownTask(Node targetElement, int duration,
|
||||
Consumer<Node> finallyExecuteConsumer, Consumer<Integer> preSecondExecuteConsumer) {
|
||||
Objects.requireNonNull(finallyExecuteConsumer);
|
||||
|
||||
this.finallyExecuteConsumer = finallyExecuteConsumer;
|
||||
this.preSecondExecuteConsumer = preSecondExecuteConsumer;
|
||||
this.duration = duration < 0 ? DEFAULT_TIME_OUT : duration;
|
||||
this.targetElement = targetElement;
|
||||
}
|
||||
|
||||
public CountDownFuture start() {
|
||||
targetElement.setVisible(true);
|
||||
|
||||
CountDownFuture future = new CountDownFuture();
|
||||
future.start();
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public class CountDownFuture extends Thread {
|
||||
|
||||
private volatile boolean done = false;
|
||||
|
||||
private CountDownFuture() {
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long startTimeMillis = System.currentTimeMillis();
|
||||
|
||||
long interval;
|
||||
try {
|
||||
while (true) {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
interval = (currentTimeMillis - startTimeMillis) / 1000;
|
||||
|
||||
if (interval > duration) {
|
||||
break;
|
||||
}
|
||||
|
||||
preSecondExecuteConsumer.accept((int) (duration - interval));
|
||||
|
||||
sleep(1000L);
|
||||
}
|
||||
|
||||
finallyExecuteConsumer.accept(targetElement);
|
||||
} catch (InterruptedException cancelFlag) {
|
||||
// exit
|
||||
return;
|
||||
} finally {
|
||||
done = true;
|
||||
targetElement.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
|
||||
done = true;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package priv.zxw.ratel.landlords.client.javafx.util;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BeanUtil {
|
||||
private static final Map<String, Object> CACHE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
public static void addBean(String name, Object object) {
|
||||
CACHE_MAP.put(name, object);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name) {
|
||||
return (T) CACHE_MAP.get(name);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
#appInfoPane {
|
||||
-fx-pref-width: 280;
|
||||
-fx-pref-height: 80;
|
||||
}
|
||||
|
||||
#welcomeTips,
|
||||
#version {
|
||||
-fx-font-size: 16;
|
||||
-fx-font-family: "微软雅黑";
|
||||
}
|
||||
|
||||
#connectPane {
|
||||
-fx-pref-width: 280;
|
||||
-fx-pref-height: 240;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
#connectButton {
|
||||
-fx-background-color: #40b1f5;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 5;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-color: #40b1f5;
|
||||
-fx-text-fill: #000000;
|
||||
-fx-font-size: 16;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
#remoteServerInfoPane {
|
||||
-fx-pref-width: 280;
|
||||
-fx-pref-height: 340;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
#remoteServerListPane {
|
||||
-fx-pref-width: 280;
|
||||
-fx-pref-height: 300;
|
||||
-fx-background-color: white;
|
||||
}
|
||||
|
||||
#fetchServerAddressErrorTips {
|
||||
-fx-pref-width: 260;
|
||||
-fx-pref-height: 100;
|
||||
-fx-wrap-text: true;
|
||||
-fx-text-fill: red;
|
||||
}
|
||||
|
||||
.title {
|
||||
-fx-font-size: 24;
|
||||
-fx-alignment: center;
|
||||
-fx-font-family: "微软雅黑";
|
||||
}
|
||||
|
||||
.hostPortInput {
|
||||
-fx-border-width: 0;
|
||||
-fx-background-color: #dbd9d8;
|
||||
-fx-background-radius: 8;
|
||||
-fx-font-family: "微软雅黑";
|
||||
-fx-text-fill: #000000;
|
||||
-fx-font-size: 14;
|
||||
}
|
||||
|
||||
.hostPortInput:focused {
|
||||
-fx-border-width: 2;
|
||||
-fx-border-color: #dbd9d8;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-color: #f6f6f5;
|
||||
}
|
||||
|
||||
.forLabel {
|
||||
-fx-text-alignment: center;
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
|
||||
.remoteServerOption {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 260;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-color: #dbd9d8;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.remoteServerOption:hover {
|
||||
-fx-background-color: #716f6d;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
#pveMenuPane {
|
||||
-fx-pref-width: 400;
|
||||
-fx-pref-height: 600;
|
||||
}
|
||||
|
||||
#pvpModalButton,
|
||||
#pveModalButton {
|
||||
-fx-pref-width: 200;
|
||||
-fx-pref-height: 100;
|
||||
}
|
||||
|
||||
#roomsPane {
|
||||
-fx-pref-height: 400;
|
||||
-fx-pref-width: 600;
|
||||
}
|
||||
|
||||
#createRoomButton {
|
||||
-fx-pref-width: 30;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-color: #dbd9d8;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 5;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-color: #dbd9d8;
|
||||
-fx-cursor: hand;
|
||||
-fx-background-image: url("../image/add_0.png");
|
||||
}
|
||||
|
||||
.title {
|
||||
-fx-pref-width: 600;
|
||||
-fx-pref-height: 40;
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
}
|
||||
|
||||
.roomListTitle {
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
|
||||
.roomPane {
|
||||
-fx-pref-width: 150;
|
||||
-fx-pref-height: 120;
|
||||
-fx-border-color: #afadab;
|
||||
-fx-background-color: #dddbd8;
|
||||
-fx-background-radius: 10;
|
||||
-fx-border-radius: 10;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.roomPane:hover {
|
||||
-fx-border-color: #3f91af;
|
||||
}
|
||||
|
||||
.roomPane > .idLabel {
|
||||
-fx-font-size: 16;
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
}
|
||||
|
||||
.roomPane > .roomOwnerLabel {
|
||||
-fx-pref-width: 30;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-image: url("../image/face_0.png");
|
||||
}
|
||||
|
||||
.roomPane > .modalLabel {
|
||||
-fx-font-size: 30;
|
||||
-fx-text-fill: silver;
|
||||
-fx-opacity: 0.8;
|
||||
}
|
||||
|
||||
.roomPane > .playerCountLabel {
|
||||
}
|
||||
|
||||
.pveModalButton {
|
||||
-fx-pref-width: 200;
|
||||
-fx-pref-height: 40;
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#nicknameInput {
|
||||
-fx-pref-width: 260;
|
||||
-fx-border-width: 0;
|
||||
-fx-background-color: #dbd9d8;
|
||||
-fx-background-radius: 8;
|
||||
-fx-font-family: "微软雅黑";
|
||||
-fx-text-fill: #000000;
|
||||
-fx-font-size: 14;
|
||||
}
|
||||
|
||||
#nicknameInput:focused {
|
||||
-fx-border-width: 2;
|
||||
-fx-border-color: #dbd9d8;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-color: #f6f6f5;
|
||||
}
|
||||
|
||||
#submitButton {
|
||||
-fx-background-color: #40b1f5;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-radius: 5;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-color: #40b1f5;
|
||||
-fx-text-fill: #000000;
|
||||
-fx-font-size: 16;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.forLabel {
|
||||
-fx-text-alignment: center;
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
|
||||
.tips {
|
||||
-fx-font-size: 17;
|
||||
-fx-text-fill: brown;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: black;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
.horizontal-poker {
|
||||
-fx-pref-width: 120;
|
||||
-fx-pref-height: 140;
|
||||
-fx-border-color: black;
|
||||
/*-fx-background-color: #dddbd8;*/
|
||||
-fx-background-color: red;
|
||||
-fx-background-radius: 10;
|
||||
-fx-border-radius: 10;
|
||||
}
|
||||
|
||||
.vertical-poker {
|
||||
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
#waitingPane,
|
||||
#gameOverPane {
|
||||
-fx-background-color: silver;
|
||||
-fx-opacity: 0.8;
|
||||
}
|
||||
|
||||
#waitingTips,
|
||||
#winnerInfo {
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
|
||||
#prevPlayerPane,
|
||||
#nextPlayerPane {
|
||||
-fx-pref-height: 140;
|
||||
-fx-pref-width: 600;
|
||||
}
|
||||
|
||||
#prevPlayerShowPane,
|
||||
#nextPlayerShowPane {
|
||||
-fx-pref-width: 380;
|
||||
-fx-pref-height: 140;
|
||||
}
|
||||
|
||||
#playerShowPane {
|
||||
-fx-pref-width: 870;
|
||||
-fx-pref-height: 130;
|
||||
}
|
||||
|
||||
#surplusPokersPane {
|
||||
-fx-pref-height: 140;
|
||||
-fx-pref-width: 500;
|
||||
-fx-background-color: silver;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
#quitButton {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 80;
|
||||
-fx-background-size: 43px 43px;
|
||||
-fx-background-color: #40b1f5;
|
||||
-fx-cursor: hand;
|
||||
-fx-border-width: 1px;
|
||||
-fx-text-fill: black;
|
||||
-fx-font-size: 18px;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
#backLobbyButton {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 100;
|
||||
-fx-background-size: 43px 43px;
|
||||
-fx-background-color: #40b1f5;
|
||||
-fx-cursor: hand;
|
||||
-fx-border-width: 1px;
|
||||
-fx-text-fill: black;
|
||||
-fx-font-size: 18px;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
#robButton,
|
||||
#notRobButton,
|
||||
#submitButton,
|
||||
#passButton {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 60;
|
||||
-fx-pref-height: 30;
|
||||
-fx-background-color: #40b1f5;
|
||||
-fx-text-fill: black;
|
||||
-fx-cursor: hand;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
#prevPlayerRole,
|
||||
#nextPlayerRole,
|
||||
#playerRole {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 50;
|
||||
-fx-pref-height: 25;
|
||||
-fx-background-color: #a58a65;
|
||||
-fx-text-fill: black;
|
||||
-fx-border-color: #afadab;
|
||||
-fx-background-radius: 6;
|
||||
-fx-border-radius: 6;
|
||||
}
|
||||
|
||||
#prevPlayerNickname,
|
||||
#nextPlayerNickname,
|
||||
#playerNickname {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 100;
|
||||
-fx-pref-height: 25;
|
||||
-fx-text-fill: black;
|
||||
-fx-border-color: black;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
-fx-pref-height: 150;
|
||||
-fx-pref-width: 1200;
|
||||
}
|
||||
|
||||
.middle {
|
||||
-fx-pref-height: 140;
|
||||
-fx-pref-width: 1200;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
-fx-pref-height: 355;
|
||||
-fx-pref-width: 1200;
|
||||
}
|
||||
|
||||
.pokers {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-width: 870;
|
||||
-fx-pref-height: 180;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
.tips {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-height: 30;
|
||||
-fx-pref-width: 70;
|
||||
-fx-font-size: 20;
|
||||
-fx-text-fill: black;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
.primary-tips {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-height: 30;
|
||||
-fx-pref-width: 140;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
.error-tips {
|
||||
-fx-alignment: center;
|
||||
-fx-pref-height: 30;
|
||||
-fx-pref-width: 200;
|
||||
-fx-background-color: silver;
|
||||
-fx-border-radius: 8;
|
||||
-fx-background-radius: 8;
|
||||
}
|
||||
|
||||
.horizontal-poker {
|
||||
-fx-pref-width: 110;
|
||||
-fx-pref-height: 140;
|
||||
-fx-border-color: #afadab;
|
||||
-fx-background-color: #dddbd8;
|
||||
-fx-background-radius: 10;
|
||||
-fx-border-radius: 10;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.horizontal-poker > .level {
|
||||
-fx-font-size: 35;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.horizontal-poker > .joker-level {
|
||||
-fx-font-size: 22;
|
||||
}
|
||||
|
||||
.horizontal-poker > .type-small {
|
||||
-fx-font-size: 35;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.horizontal-poker > .type-big {
|
||||
-fx-font-size: 70;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.rearPoker {
|
||||
-fx-pref-width: 55;
|
||||
-fx-pref-height: 70;
|
||||
-fx-border-color: #716f6d;
|
||||
-fx-background-image: url("../image/rear.png");
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
.rearPoker > .pokerCount {
|
||||
-fx-font-size: 25;
|
||||
-fx-text-fill: #000000;
|
||||
}
|
||||
|
||||
.vertical-poker {
|
||||
-fx-pref-width: 140;
|
||||
-fx-pref-height: 90;
|
||||
-fx-border-color: #716f6d;
|
||||
-fx-background-image: url("../image/rear.png");
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.surplus-poker {
|
||||
-fx-pref-width: 110;
|
||||
-fx-pref-height: 140;
|
||||
-fx-border-color: #716f6d;
|
||||
-fx-background-image: url("../image/rear.png");
|
||||
}
|
||||
|
||||
.timer {
|
||||
-fx-alignment: center;
|
||||
-fx-font-size: 20;
|
||||
-fx-pref-width: 60;
|
||||
-fx-pref-height: 50;
|
||||
-fx-border-color: #afadab;
|
||||
-fx-background-color: #dddbd8;
|
||||
-fx-background-radius: 10;
|
||||
-fx-border-radius: 10;
|
||||
}
|
||||
|
||||
.showPoker {
|
||||
-fx-pref-width: 40;
|
||||
-fx-pref-height: 50;
|
||||
-fx-border-color: #afadab;
|
||||
-fx-background-color: #dddbd8;
|
||||
-fx-background-radius: 6;
|
||||
-fx-border-radius: 6;
|
||||
}
|
||||
|
||||
.showPoker > .level {
|
||||
-fx-font-size: 20;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.showPoker > .joker-level {
|
||||
-fx-font-size: 15;
|
||||
}
|
||||
|
||||
.showPoker > .type-small {
|
||||
-fx-font-size: 20;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.showPoker > .type-big {
|
||||
-fx-font-size: 40;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0"
|
||||
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" stylesheets="@assets/css/index.css">
|
||||
<children>
|
||||
<Pane fx:id="connectPane" layoutX="10" layoutY="20">
|
||||
<Label layoutX="5" layoutY="5" styleClass="title">连接信息</Label>
|
||||
|
||||
<Label layoutX="5" layoutY="50" styleClass="forLabel">主机:</Label>
|
||||
<TextField fx:id="host" layoutX="60" layoutY="50" styleClass="hostPortInput">127.0.0.1</TextField>
|
||||
|
||||
<Label layoutX="5" layoutY="90" styleClass="forLabel">端口:</Label>
|
||||
<TextField fx:id="port" layoutX="60" layoutY="90" styleClass="hostPortInput">1024</TextField>
|
||||
|
||||
<Label fx:id="connectServerErrorTips" layoutX="5" layoutY="140" style="-fx-text-fill: red;" visible="false">连接失败,请确认上述地址是否正确</Label>
|
||||
|
||||
<Button fx:id="connectButton" layoutX="200" layoutY="160">连接</Button>
|
||||
</Pane>
|
||||
|
||||
<Pane fx:id="appInfoPane" layoutX="10" layoutY="300">
|
||||
<Text fx:id="welcomeTips" layoutX="5" layoutY="20">欢迎使用retel javafx客户端 : )</Text>
|
||||
<Text fx:id="version" layoutX="5" layoutY="50">@version:v1.0.0</Text>
|
||||
</Pane>
|
||||
|
||||
<Pane fx:id="remoteServerInfoPane" layoutX="310" layoutY="20">
|
||||
<Label layoutX="68" layoutY="5" styleClass="forLabel">远程服务器信息</Label>
|
||||
|
||||
<Pane fx:id="remoteServerListPane" layoutY="40">
|
||||
<ScrollBar orientation="VERTICAL" layoutX="260" max="5" min="0" value="0" prefHeight="300"></ScrollBar>
|
||||
|
||||
<TextArea fx:id="fetchServerAddressErrorTips" visible="false">
|
||||
获取远程服务器地址失败(远程服务器地址清单链接为:https://raw.githubusercontent.com/ainilili/ratel/master/serverlist.json),请检查您的网络
|
||||
</TextArea>
|
||||
</Pane>
|
||||
</Pane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||