JAVA斗地主,客服端与服务端交互,显示扑克牌
一.客服端代码
package com.wowowo.view;
import java.net.Socket;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import com.wowowo.model.Player;
import com.wowowo.model.Poker;
import com.wowowo.model.Player;
import com.wowowo.model.PokerLabel;
import com.wowowo.thread.ReceiveThread;
import com.wowowo.thread.SendThread;
import com.wowowo.util.GameUtil;
//斗地主 客服端主窗口
public class MainFrame extends JFrame{
//MyPanel麦陪儿,添加到主窗口
public MyPanel myPanel;
public String uname; //定义用户名
public Socket socket;
public SendThread sendThread; //发消息线程
public ReceiveThread receiveThread; // 接收信息的线程
public Player currentPlayer; // 存放当前玩家对象
public List<PokerLabel> pokerLabels=new ArrayList<PokerLabel>(); // 存放扑克标签列表
public MainFrame(String uname,Socket socket)
{
//接收用户名
this.uname=uname;
this.socket=socket;
// 设置窗口的属性//
//窗口的大小
this.setSize(1200, 700);
this.setVisible(true);
//窗口位置居中
this.setLocationRelativeTo(null);
//设置窗口关闭的操作
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 添加mypanel面板
myPanel=new MyPanel();
myPanel.setBounds(0, 0, 1200, 700);
this.add(myPanel);
//启动发消息线程
sendThread=new SendThread(socket,uname);
sendThread.start();
//启动收消息线程
receiveThread=new ReceiveThread(socket,this);
receiveThread.start();
}
public void showAllPlayersInfo(List<Player>players)
{
//1.显示三个玩家的名称
//2.显示玩家的扑克列表
for(int i=0;i<players.size();i++)
{
if(players.get(i).getName().equals(uname))
{
currentPlayer=players.get(i);
}
}
List<Poker>pokers= currentPlayer.getPokers();
for (int i = 0; i < pokers.size(); i++)
{
// 创建扑克标签
Poker poker=pokers.get(i);
PokerLabel pokerLabel=new PokerLabel(poker.getId(),poker.getName(), poker.getNum());
pokerLabel.turnUp(); // 显示正面图
//添加到面板中
this.myPanel.add(pokerLabel);
this.pokerLabels.add(pokerLabel);
// 动态的显示出来
this.myPanel.setComponentZOrder(pokerLabel,0);
// 一张一张地显示出来
GameUtil.move(pokerLabel, 300+30*i,450);
}
//扑克牌列表排序
Collections.sort(pokerLabels);
//重新移动位置
for(int i=0;i<pokerLabels.size();i++)
{
this.myPanel.setComponentZOrder(pokerLabels.get(i),0);
GameUtil.move(pokerLabels.get(i),300+30*i,450);
}
}
}
package com.wowowo.view;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
//客服端 MyPanel麦陪儿存放背景图,extends继承JPanel街拍儿 ,面板
public class MyPanel extends JPanel{
public MyPanel()
{
this.setLayout(null); //如果需要用到setLocation() setBounds() 就需要设置布局为null
}
//Source里找OverrdodnplemrtMothods..重写pantCompcnent..打钩确认
//重写方法
@Override
protected void paintComponent(Graphics g) {
//super.paintComponent(arg0);
//画图片(图片路径"images/be/bel.png").getImage图片对象
Image image=new ImageIcon("images/bg/bg1.png").getImage();
//画图对象
g.drawImage(image,0,0,this.getWidth(),this.getHeight(),null);
}
}
package com.wowowo.view;
//客服端Main(麦函数)起动窗口类
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Login();
}
}
package com.wowowo.view;
import java.awt.GridLayout;
//客服端登录窗口
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Login extends JFrame{
//private泼特此,一种访问控制方式:私用模式(私人的),JLabel窗口,unameJLabel窗口用户名
private JLabel unameJLabel;
//unameJTextField街泰斯得鱼儿,用户名的输入框
private JTextField unameJTextField;
//btnJButton街帕特 ,登录按钮
private JButton btnJButton;
//cancelJButton,取消按钮
private JButton cancelJButton;
public Login()
{
this.unameJLabel=new JLabel("用户名");
this.unameJTextField=new JTextField();
this.btnJButton=new JButton("登录");
this.cancelJButton=new JButton("取消");
//设置窗口大小
this.setSize(400, 300);
//setVisible思特威思博,设置为空(true)
this.setVisible(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置窗口关闭的操作
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置网格布局二行二连
this.setLayout(new GridLayout(2,2));
//add添加窗口,输入框.登录按钮.取消按钮
this.add(unameJLabel);
this.add(unameJTextField);
this.add(btnJButton);
this.add(cancelJButton);
//创建监听器对象 绑定到按钮上
MyEvent myEvent=new MyEvent();
this.btnJButton.addActionListener(myEvent);
}
//创建事件监听器类 ActionListener监听接口
class MyEvent implements ActionListener
{
@Override
public void actionPerformed(ActionEvent arg0) {
//点击登录
//1.获取用户名
String uname=unameJTextField.getText();
//2 创建一个socket链接服务器
try {
Socket socket=new Socket("127.0.0.1",8888);
//3 跳到主窗口
new MainFrame(uname,socket);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.wowowo.util;
import com.wowowo.model.PokerLabel;
//客服端工具类
public class GameUtil {
public static void move(PokerLabel pokerLabel,int x,int y)
{
pokerLabel.setLocation(x, y);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.wowowo.thread;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wowowo.model.Player;
import com.wowowo.model.Poker;
import com.wowowo.view.MainFrame;
//客服端 创建一个接消息的线程
public class ReceiveThread extends Thread {
private Socket socket;
private MainFrame mainFrame;
public ReceiveThread(Socket socket, MainFrame mainFrame)
{
this.socket = socket;
this.mainFrame=mainFrame;
}
public void run()
{
try {
DataInputStream dataInputStream=new DataInputStream(socket.getInputStream());
while (true)
{
String jsonString= dataInputStream.readUTF();
List<Player> players=new ArrayList<Player>();
System.out.println(jsonString);
JSONArray playerJsonArray = JSONArray.parseArray(jsonString);
for (int i=0;i<playerJsonArray.size();i++)
{
JSONObject playerJson=(JSONObject) playerJsonArray.get(i);
int id=playerJson.getInteger("id");
String name=playerJson.getString("name");
// 存放扑克列表
List<Poker> pokers=new ArrayList<Poker>();
JSONArray pokerJsonArray = playerJson.getJSONArray("pokers");
for(int j=0;j<pokerJsonArray.size();j++)
{
// 每循环一次 获得一个扑克对象
JSONObject pokerJSon= (JSONObject) pokerJsonArray.get(j);
int pid=pokerJSon.getInteger("id");
String pname=pokerJSon.getString("name");
int num=pokerJSon.getInteger("num");
Poker poker=new Poker(pid,pname,num);
pokers.add(poker);
}
Player player=new Player(id,name,pokers);
players.add(player);
}
// 获得3个玩家的信息了
if(players.size()==3)
{
mainFrame.showAllPlayersInfo(players);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("服务端异常");
}
}
}
package com.wowowo.thread;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
//客服端 发消息线程
public class SendThread extends Thread{
//有参构造函数 //msg(赛)方法
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
private Socket socket;
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket)
{
this.socket = socket;
}
public SendThread(Socket socket,String msg)
{
this.socket=socket;
this.msg=msg;
}
//无参构造函数
public SendThread()
{
}
//run(容)方法
public void run()
{
//发送用DataOutputStream(奥特普特往外写)
DataOutputStream dataOutputStream;
try {
dataOutputStream = new DataOutputStream(socket.getOutputStream());
//用while循环可以发送多条数据
while(true)
{
//如果消息不为null
if(msg!=null)
{
dataOutputStream.writeUTF(msg);
//消息发送完毕 消息内容清空
msg=null;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.wowowo.model;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
//客服端 端玩家类
public class Player {
private int id; //玩家id
private String name; //玩家姓名
private Socket socket; //玩家对应的socket
private List<Poker> pokers = new ArrayList<>();//玩家的扑克列表
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public List<Poker> getPokers() {
return pokers;
}
public void setPokers(List<Poker> pokers) {
this.pokers = pokers;
}
public Player()
{
}
//四个参
public Player(int id,String name,Socket socket,List<Poker>pokers)
{
this.id=id;
this.name=name;
this.socket=socket;
this.pokers=pokers;
}
//一个参
public Player(int id)
{
this.id=id;
}
//二个参
public Player(int id,String name)
{
this.id=id;
this.name=name;
}
//三个参
public Player(int id,String name,List<Poker>pokers)
{
this.id=id;
this.name=name;
this.pokers=pokers;
}
public String toString()
{
return "player[id:"+this.id+"name:"+this.name+"]";
}
}
package com.wowowo.model;
//客服端 端扑克类
public class Poker {
private int id; //扑克id
private String name;//扑克名称
private int num; //扑克数量
private boolean isOut; //扑克是否打出
public boolean isOut() {
return isOut;
}
public void setOut(boolean isOut) {
this.isOut = isOut;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Poker()
{}
public Poker(int id,String name,int num)
{
this.id=id;
this.name=name;
this.num=num;
}
public Poker(int id,String name,int num,boolean isOut)
{
this.id=id;
this.name=name;
this.num=num;
this.isOut=isOut;
}
}
package com.wowowo.model;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
//客服端 扑克标签类
public class PokerLabel extends JLabel implements Comparable{
private int id; //扑克id
private String name; //扑克名称
private int num;
private boolean isOut;
private boolean isUp;
private boolean isSelected; //是否选中 //14
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public boolean isOut() {
return isOut;
}
public void setOut(boolean isOut) {
this.isOut = isOut;
}
public boolean isUp() {
return isUp;
}
public void setUp(boolean isUp) {
this.isUp = isUp;
}
public PokerLabel()
{
this.setSize(105, 150);
}
public PokerLabel(int id,String name,int num)
{
this.id=id;
this.name=name;
this.num=num;
this.setSize(105, 150);
}
public PokerLabel(int id,String name,int num,boolean isOut,boolean isUp)
{
this.id=id;
this.name=name;
this.num=num;
this.isOut=isOut;
this.isUp=isUp;
if(isUp)
turnUp();
else {
turnDown();
}
this.setSize(105, 150);
}
public void turnUp()
{
this.setIcon(new ImageIcon("images/poker/"+id+".jpg"));
}
public void turnDown()
{
this.setIcon(new ImageIcon("images/poker/down.jpg"));
}
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
PokerLabel pokerLabel=(PokerLabel)arg0;
if(this.num>pokerLabel.num)
return 1;
else if(this.num<pokerLabel.num)
return -1;
else
return 0;
}
}
}
//服务端代码
package com.wowowo.view;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import com.alibaba.fastjson.JSON;
import com.wowowo.model.Player;
import com.wowowo.model.Poker;
//服务器端斗地主服务端主窗口
public class MainFrame extends JFrame{
//MyPanel麦陪儿,添加到主窗口
public MyPanel myPanel;
public String uname; //定义用户名
public Socket socket;
//创建玩家列表
public List<Player> players=new ArrayList<Player>();
public int index=0;
//存放扑克列表
public List<Poker> allPokers=new ArrayList<Poker>();
//存放底牌
public List<Poker> lordPokers=new ArrayList<Poker>();
public int step=0; //牌局的进展步骤
public MainFrame(String uname)
{
//创建扑克列表
createPokers();
//接收用户名
this.uname=uname;
this.socket=socket;
//窗口的大小
this.setSize(800, 600);
this.setVisible(true);
//窗口位置居中
this.setLocationRelativeTo(null);
//设置窗口关闭的操作
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 添加mypanel面板
myPanel=new MyPanel();
myPanel.setBounds(0, 0, 1000, 800);//1.创建服务端socket
this.add(myPanel);
try {
//1.创建服务器端socket
ServerSocket serverSocket=new ServerSocket(8888);
//用while循环可以接收多条数据
while(true)
{
//2.接收客服端的socket
Socket socket=serverSocket.accept();
//3.开启线程处理客服端的socket
AcceptThread acceptThread =new AcceptThread(socket);
acceptThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//服务器端创建一个内不类来接收,客服端的上线消息
private class AcceptThread extends Thread{
Socket socket;
public AcceptThread(Socket socket)
{
this.socket=socket;
}
public void run()
{
try {
//接收消息
DataInputStream dataInputStream=new DataInputStream(socket.getInputStream());
while(true)
{
String msg=dataInputStream.readUTF();
//创建Player对象
Player player=new Player(index++,msg);
player.setSocket(socket);
players.add(player);
System.out.println(msg+"上线了");
System.out.println("当前上线人数:"+players.size());
//发给三个玩家
if(players.size()==3)
{
fapai();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//创建所有的扑克列表
public void createPokers()
{
//创建大王,小王
Poker dawang=new Poker(0,"大王",17);
Poker xiaowang=new Poker(1,"小王",16);
allPokers.add(dawang);
allPokers.add(xiaowang);
//创建其他扑克
String[] names=new String[] {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
String[]colors=new String[]{"黑桃","红桃","梅花","方块"};
//id从2开始, num从15开始
int id=2;
int num=15;
//用加强佛遍历
for(String name:names)
{
for(String color:colors)
{
Poker poker=new Poker(id++,color+name,num);
allPokers.add(poker);
}
num--;
}
//洗牌把顺序打乱
Collections.shuffle(allPokers);
}
//发牌
public void fapai() throws IOException
{
//发给三个玩家
for(int i=0;i<allPokers.size();i++)
{
//最后三张留给地主
if(i>=51)
{
lordPokers.add(allPokers.get(i));
}
else {
//依次分发给三个玩家
if(i%3==0)
players.get(0).getPokers().add(allPokers.get(i));
else if(i%3==1)
players.get(1).getPokers().add(allPokers.get(i));
else
players.get(2).getPokers().add(allPokers.get(i));
}
}
//将玩家的信息发送到客服端
//{"id":1,"name":"aa","socket":"","pokers":[{"id":1,"name":"黑桃k","num":13},{},{}]}
for(int i=0;i<players.size();i++)
{
try {
DataOutputStream dataOutputStream=new DataOutputStream(players.get(i).getSocket().getOutputStream());
String jsonString=JSON.toJSONString(players);
dataOutputStream.writeUTF(jsonString);
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
}
}
package com.wowowo.view;
//服务器端Main(麦函数)起动窗口类
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Login();
}
}
package com.wowowo.view;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
//服务端登录窗口
public class Login extends JFrame{
//private泼特此,一种访问控制方式:私用模式(私人的),JLabel窗口,unameJLabel窗口用户名
private JLabel unameJLabel;
//unameJTextField街泰斯得鱼儿,用户名的输入框
private JTextField unameJTextField;
//btnJButton街帕特 ,登录按钮
private JButton btnJButton;
//cancelJButton,取消按钮
private JButton cancelJButton;
public Login()
{
this.unameJLabel=new JLabel("用户名");
this.unameJTextField=new JTextField();
this.btnJButton=new JButton("登录");
this.cancelJButton=new JButton("取消");
//设置窗口大小
this.setSize(400, 300);
//setVisible思特威思博,设置为空(true)
this.setVisible(true);
//设置窗口居中
this.setLocationRelativeTo(null);
//设置窗口关闭的操作
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置网格布局二行二连
this.setLayout(new GridLayout(2,2));
//add添加窗口,输入框.登录按钮.取消按钮
this.add(unameJLabel);
this.add(unameJTextField);
this.add(btnJButton);
this.add(cancelJButton);
//创建监听器对象 绑定到按钮上
MyEvent myEvent=new MyEvent();
this.btnJButton.addActionListener(myEvent);
}
//创建事件监听器类 ActionListener监听接口
class MyEvent implements ActionListener
{
@Override
public void actionPerformed(ActionEvent arg0) {
//点击登录
//1.获取用户名
String uname=unameJTextField.getText();
//2
//3
new MainFrame(uname);
}
}
}
package com.wowowo.view;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
// 服务器端MyPanel麦陪儿存放背景图,extends继承JPanel街拍儿 ,面板
public class MyPanel extends JPanel{
public MyPanel()
{
this.setLayout(null); //如果需要用到setLocation() setBounds() 就需要设置布局为null
}
//Source里找OverrdodnplemrtMothods..重写pantCompcnent..打钩确认
//重写方法
@Override
protected void paintComponent(Graphics g) {
//super.paintComponent(arg0);
//画图片(图片路径"images/be/bel.png").getImage图片对象
Image image=new ImageIcon("images/bg/15.png").getImage();
//画图对象
g.drawImage(image,0,0,this.getWidth(),this.getHeight(),null);
}
}
package com.wowowo.model;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
//服务器端玩家类
public class Player {
private int id; //玩家id
private String name; //玩家姓名
private Socket socket; //玩家对应的socket
private List<Poker> pokers = new ArrayList<>();//玩家的扑克列表
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public List<Poker> getPokers() {
return pokers;
}
public void setPokers(List<Poker> pokers) {
this.pokers = pokers;
}
public Player()
{
}
//四个参
public Player(int id,String name,Socket socket,List<Poker>pokers)
{
this.id=id;
this.name=name;
this.socket=socket;
this.pokers=pokers;
}
//一个参
public Player(int id)
{
this.id=id;
}
//二个参
public Player(int id,String name)
{
this.id=id;
this.name=name;
}
//三个参
public Player(int id,String name,List<Poker>pokers)
{
this.id=id;
this.name=name;
this.pokers=pokers;
}
public String toString()
{
return "player[id:"+this.id+"name:"+this.name+"]";
}
}
package com.wowowo.model;
//服务器端扑克类
public class Poker {
private int id; //扑克id
private String name;//扑克名称
private int num; //扑克数量
private boolean isOut; //扑克是否打出
public boolean isOut() {
return isOut;
}
public void setOut(boolean isOut) {
this.isOut = isOut;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Poker()
{}
public Poker(int id,String name,int num)
{
this.id=id;
this.name=name;
this.num=num;
}
public Poker(int id,String name,int num,boolean isOut)
{
this.id=id;
this.name=name;
this.num=num;
this.isOut=isOut;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210619175911400.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXIzNTM2Mzc=,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210619180403938.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXIzNTM2Mzc=,size_16,color_FFFFFF,t_70#pic_center)