100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 第二十三章《斗地主游戏》第3节:项目完整代码

第二十三章《斗地主游戏》第3节:项目完整代码

时间:2019-04-10 10:28:19

相关推荐

第二十三章《斗地主游戏》第3节:项目完整代码

对于初学者来说,斗地主游戏是一个比较复杂的项目,它涉及的类很多,以下是这个项目所有类的源代码,源码中有两个Main.java文件,它们虽然文件名称相同,但位于不同的包下,读者在复制粘贴这两个文件时需要注意要把它们放在正确的位置。

Message.java

package client.model;import java.io.*;import java.util.*;public class Message implements Serializable {private int typeid; //消息类型private int playerid; //玩家idprivate String content; //消息内容private List<Poker> pokers = new ArrayList<Poker>(); //扑克列表public int getTypeid() {return typeid;}public void setTypeid(int typeid) {this.typeid = typeid;}public int getPlayerid() {return playerid;}public void setPlayerid(int playerid) {this.playerid = playerid;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<Poker> getPokers() {return pokers;}public void setPokers(List<Poker> pokers) {this.pokers = pokers;}public Message() {}public Message(int typeid, int playerid, String content, List<Poker> pokers) {this.typeid = typeid;this.playerid = playerid;this.content = content;this.pokers = pokers;}}

Player.java

package client.model;import java.io.*;import .*;import java.util.*;//玩家类public class Player implements Serializable {private int id; //玩家idprivate String name; //玩家姓名private Socket socket; //玩家对应的socketprivate List<Poker> pokers=new ArrayList<Poker>();//玩家的扑克列表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+"]";}}

Poker.java

package client.model;import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;//扑克类public class Poker {private int id; //扑克idprivate 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;}}

PokerLabel.java

package client.model;import javax.swing.*;//扑克标签类public class PokerLabel extends JLabel implements Comparable{private int id;private String name;private int num;private boolean isOut;private boolean isUp;private boolean isSelected; //是否选中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"));}@Overridepublic int compareTo(Object arg0) {PokerLabel pokerLabel=(PokerLabel)arg0;if(this.num>pokerLabel.num)return 1;else if(this.num<pokerLabel.num)return -1;elsereturn 0;}}

ChuPaiThread.java

package client.thread;import java.util.*;import com.alibaba.fastjson.JSON;import client.model.*;import client.view.*;public class ChuPaiThread extends Thread {private int time;private MainFrame mainFrame;private boolean isRun;public int getTime() {return time;}public void setTime(int time) {this.time = time;}public MainFrame getMainFrame() {return mainFrame;}public void setMainFrame(MainFrame mainFrame) {this.mainFrame = mainFrame;}public boolean isRun() {return isRun;}public void setRun(boolean isRun) {this.isRun = isRun;}public ChuPaiThread(int time, MainFrame mainFrame) {isRun = true;this.time = time;this.mainFrame = mainFrame;}public void run() {while (time >= 0 && isRun) {mainFrame.timeLabel.setText(time + "");time--;try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}Message message = null;//如果是不出 (一种是时间到了 一种是 选择不出)if (time == -1 || isRun == false && mainFrame.isOut == false) {//时间到了不出,则将出牌按钮隐藏mainFrame.chupaiJLabel.setVisible(false);mainFrame.buchuJLabel.setVisible(false);mainFrame.timeLabel.setVisible(false);message = new Message(3, mainFrame.currentPlayer.getId(), "不出", null);//转换为json 交给 sendThread发送到服务器去String msg = JSON.toJSONString(message);mainFrame.sendThread.setMsg(msg);}//出牌if (isRun == false && mainFrame.isOut == true) {message = new Message(4, mainFrame.currentPlayer.getId(), "出牌",changePokerLableToPoker(mainFrame.selectedPokerLabels));//转换为json 交给 sendThread发送到服务器去String msg = JSON.toJSONString(message);mainFrame.sendThread.setMsg(msg);//将当前发送出去的扑克牌 从扑克牌列表中移除mainFrame.removeOutPokerFromPokerList();//如果扑克列表的数量为0 代表赢了if (mainFrame.pokerLabels.size() == 0) {//产生游戏结束的消息message = new Message(5, mainFrame.currentPlayer.getId(),"游戏结束", null);msg = JSON.toJSONString(message);try {Thread.sleep(100);//发送消息mainFrame.sendThread.setMsg(msg);} catch (InterruptedException e) {e.printStackTrace();}}}}public List<Poker> changePokerLableToPoker(List<PokerLabel> selectedPokerLabels) {List<Poker> list = new ArrayList<Poker>();for (int i = 0; i < selectedPokerLabels.size(); i++) {PokerLabel pokerLabel = selectedPokerLabels.get(i);Poker poker = new Poker(pokerLabel.getId(), pokerLabel.getName(),pokerLabel.getNum());list.add(poker);}return list;}}

CountThread.java

package client.thread;import com.alibaba.fastjson.JSON;import client.model.*;import client.view.*;//计时器的线程public class CountThread extends Thread{private int i;private MainFrame mainFrame;private boolean isRun;public boolean isRun() {return isRun;}public void setRun(boolean isRun) {this.isRun = isRun;}public CountThread(int i,MainFrame mainFrame){isRun=true;this.i=i;this.mainFrame=mainFrame;}public void run(){while(i>=0 && isRun){mainFrame.timeLabel.setText(i+"");i--;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}Message msg=null;//时间到了 或者 点击过不抢地主的按钮了if(i==-1 || isRun==false && mainFrame.isLord==false){msg=new Message(1,mainFrame.currentPlayer.getId(),"不抢",null);}//点了抢地主的按钮了if(isRun==false && mainFrame.isLord==true){msg=new Message(2,mainFrame.currentPlayer.getId(),"抢地主",null);}//将消息传到服务器端mainFrame.sendThread.setMsg(JSON.toJSONString(msg));}}

ReceiveThread.java

package client.thread;import java.awt.*;import javax.swing.*;import java.io.*;import .*;import java.util.*;import com.alibaba.fastjson.*;import client.model.*;import client.view.*;//创建一个接收消息的线程public class ReceiveThread extends Thread {private Socket socket;private MainFrame mainFrame;private int step = 0;private boolean isRun = true;public boolean isRun() {return isRun;}public void setRun(boolean isRun) {this.isRun = isRun;}public ReceiveThread(Socket socket, MainFrame mainFrame) {this.socket = socket;this.mainFrame = mainFrame;}public void run() {try {DataInputStream dataInputStream =new DataInputStream(socket.getInputStream());while (true) {if (isRun == false)break;//接收从服务器端传递过来的消息 json字符串String jsonString = dataInputStream.readUTF();if (step == 0) {java.util.List<Player> players = new ArrayList<Player>();//System.out.println(jsonString);//解析json字符串 "[{},{}]" [{},{}]//将json字符串转换为json数组JSONArray playerJsonArray = JSONArray.parseArray(jsonString);for (int i = 0; i < playerJsonArray.size(); i++) {//获得当个json对象--> 玩家对象JSONObject playerJson = (JSONObject) playerJsonArray.get(i);int id = playerJson.getInteger("id");String name = playerJson.getString("name");//存放扑克列表java.util.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);step = 1; //玩家到齐 进展到第二步}} else if (step == 1) {//接收抢地主的消息或者出牌的消息JSONObject msgJsonObject = JSONObject.parseObject(jsonString);//解析消息对象int typeid = msgJsonObject.getInteger("typeid");int playerid = msgJsonObject.getInteger("playerid");String contentString = msgJsonObject.getString("content");//消息类型为不抢if (typeid == 1) {//1.主窗口显示不抢的信息mainFrame.showMsg(playerid, 1);//2.设置下一家开始抢地主if (playerid + 1 == mainFrame.currentPlayer.getId())mainFrame.getLord();}//抢地主的消息if (typeid == 2) {//获得地主牌JSONArray pokersJsonArray =msgJsonObject.getJSONArray("pokers");java.util.List<Poker> lordPokers = new ArrayList<Poker>();for (int i = 0; i < pokersJsonArray.size(); i++) {JSONObject pokerJsonObject = (JSONObject) pokersJsonArray.get(i);int id = pokerJsonObject.getInteger("id");String name = pokerJsonObject.getString("name");int num = pokerJsonObject.getInteger("num");Poker p = new Poker(id, name, num);System.out.println(p);lordPokers.add(p);}//如果是自己抢的地主if (mainFrame.currentPlayer.getId() == playerid) {//添加地主牌mainFrame.addLordPokers(lordPokers);//第一家出牌 显示出牌的按钮mainFrame.showChuPaiJabel();}//显示地主图标mainFrame.showLordIcon(playerid);//之前的消息框隐藏mainFrame.msgLabel.setVisible(false);//所有玩家 都可以选择出牌列表 (不代表能出牌)mainFrame.addClickEventToPoker();}if (typeid == 3) //不出牌{//显示不出牌的消息mainFrame.showMsg(playerid, 3);//判断自己是不是下一家 如果是 显示出牌按钮 0->1 1-> 2 2-> 0if (playerid + 1 == mainFrame.currentPlayer.getId() ||playerid - 2 == mainFrame.currentPlayer.getId()) {mainFrame.showChuPaiJabel();}}if (typeid == 4) //出牌{//获得出牌列表JSONArray pokersJsonArray =msgJsonObject.getJSONArray("pokers");java.util.List<Poker> outPokers = new ArrayList<Poker>();for (int i = 0; i < pokersJsonArray.size(); i++) {JSONObject pokerJsonObject = (JSONObject) pokersJsonArray.get(i);int id = pokerJsonObject.getInteger("id");String name = pokerJsonObject.getString("name");int num = pokerJsonObject.getInteger("num");Poker p = new Poker(id, name, num);System.out.println(p);outPokers.add(p);}//显示出牌列表mainFrame.showOutPokerList(playerid, outPokers);//判断自己是不是下一家 如果是 显示出牌按钮 0->1 1-> 2 2-> 0if (playerid + 1 == mainFrame.currentPlayer.getId() ||playerid - 2 == mainFrame.currentPlayer.getId()) {mainFrame.showChuPaiJabel();}mainFrame.prevPlayerid = playerid; //记录上一个出牌的玩家id}//如果是游戏结束的消息if (typeid == 5) {if (playerid == mainFrame.currentPlayer.getId()) {JOptionPane.showMessageDialog(mainFrame, "赢了");} else {JOptionPane.showMessageDialog(mainFrame, "输了");}//游戏结束 关闭线程 清理窗口等mainFrame.gameOver();}}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

SendThread.java

package client.thread;import java.io.*;import .Socket;//发送消息的线程public class SendThread extends Thread {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;}private boolean isRun = true;public boolean isRun() {return isRun;}public void setRun(boolean isRun) {this.isRun = isRun;}public SendThread(Socket socket) {this.socket = socket;}public SendThread(Socket socket, String msg) {this.socket = socket;this.msg = msg;}public SendThread() {}public void run() {DataOutputStream dataOutputStream;try {dataOutputStream = new DataOutputStream(socket.getOutputStream());while (true) {if (isRun == false) {break;}//如果消息不为nullif (msg != null) {System.out.println("消息在发送中:" + msg);//发送消息dataOutputStream.writeUTF(msg);//消息发送完毕 消息内容清空msg = null;}Thread.sleep(50); //暂停 等待新消息进来}} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}

GameUtil.java

package client.util;import client.model.*;public class GameUtil {public static void move(PokerLabel pokerLabel,int x,int y){pokerLabel.setLocation(x, y);try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}public static void move2(PokerLabel pokerLabel,int x,int y){pokerLabel.setLocation(x, y);}}

PokerRule.java

package client.util;import java.util.*;import client.model.*;public class PokerRule {//判断牌型public static PokerType checkPokerType(List<PokerLabel> list) {Collections.sort(list);int count = list.size();if (count == 1) {//单张return PokerType.p_1;} else if (count == 2) {//对子if (isSame(list, count)) {return PokerType.p_2;}//王炸if (isWangZha(list)) {return PokerType.p_2w;}return PokerType.p_error;} else if (count == 3) {//三个头if (isSame(list, count)) {return PokerType.p_3;}return PokerType.p_error;} else if (count == 4) {//炸弹if (isSame(list, count)) {return PokerType.p_4;}//三带一if (isSanDaiYi(list)) {return PokerType.p_31;}return PokerType.p_error;} else if (count >= 5) {//顺子if (isShunZi(list)) {return PokerType.p_n;} else if (isSanDaiYiDui(list)) {//三代一对return PokerType.p_32;} else if (isLianDui(list)) {//连对return PokerType.p_1122;} else if (isFeiJI(list)) {//双飞or双飞双带return PokerType.p_111222;} else if (isFeiJIDaiChiBang1(list)) {//双飞or双飞双带return PokerType.p_11122234;} else if (isFeiJIDaiChiBang2(list)) {//双飞or双飞双带return PokerType.p_1112223344;}}return PokerType.p_error;}public static boolean isWangZha(List<PokerLabel> list) {if ((list.get(0).getNum() == 16 && list.get(1).getNum() == 17) ||(list.get(0).getNum() == 17 && list.get(1).getNum() == 16)) {return true;}return false;}//判断list内扑克是否相同public static boolean isSame(List<PokerLabel> list, int count) {for (int j = 0; j < count - 1; j++) {int a = list.get(j).getNum();int b = list.get(j + 1).getNum();if (a != b) {return false;}}return true;}//判断是否是三带一public static boolean isSanDaiYi(List<PokerLabel> list) {List<PokerLabel> temp = new ArrayList<PokerLabel>();temp.addAll(list);if (isSame(temp, 3)) {return true;}temp.remove(0);if (isSame(temp, 3)) {return true;}return false;}//判断是否是三带一对public static boolean isSanDaiYiDui(List<PokerLabel> list) {List<PokerLabel> temp = new ArrayList<PokerLabel>();temp.addAll(list);if (temp.size() == 5) {if (isSame(temp, 3)) {temp.remove(0);temp.remove(0);temp.remove(0);if (isSame(temp, 2)) {return true;}return false;}if (isSame(temp, 2)) {temp.remove(0);temp.remove(0);if (isSame(temp, 3)) {return true;}return false;}}return false;}// 判断是否是顺子public static boolean isShunZi(List<PokerLabel> list) {for (int i = 0; i < list.size() - 1; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();if (b - a != 1) {return false;}}return true;}// 判断是否是连对public static boolean isLianDui(List<PokerLabel> list) {int size = list.size();if (size < 6 && size % 2 != 0) {return false;}for (int i = 0; i < size; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();if (a != b) {return false;}i++;}for (int i = 0; i < size; i++) {int a = list.get(i).getNum();int b = list.get(i + 2).getNum();if (b - a != 1) {return false;}i++;i++;}return true;}//判断是不是双飞public static boolean isFeiJI(List<PokerLabel> list) {List<Integer> count = feiCount(list);if (count != null && count.size() >= 2) {int len = count.size();for (int i = 0; i < len - 1; i++) {if (count.get(i + 1) - count.get(i) != 1) {return false;}}int dui = feiDuiCount(list, count);if (dui == 0) {return true;}}return false;}//飞机带翅膀 3311public static boolean isFeiJIDaiChiBang2(List<PokerLabel> list) {List<Integer> feiji = feiCount(list);if (feiji != null && feiji.size() >= 2) {int len = feiji.size();for (int i = 0; i < len - 1; i++) {if (feiji.get(i + 1) - feiji.get(i) != 1) {return false;}}int dui = feiDuiCount(list, feiji);if (dui == feiji.size()) {return true;}}return false;}//飞机带翅膀3322public static boolean isFeiJIDaiChiBang1(List<PokerLabel> list) {List<Integer> feiji = feiCount(list);if (feiji != null && feiji.size() >= 2) {int len = feiji.size();for (int i = 0; i < len - 1; i++) {if (feiji.get(i + 1) - feiji.get(i) != 1) {return false;}}int dui = feiDanZhangCount(list, feiji);if (dui == feiji.size()) {return true;}}return false;}//判断三个头有几个public static List<Integer> feiCount(List<PokerLabel> list) {List<Integer> cnt = new ArrayList<Integer>();for (int i = 0; i < list.size() - 2; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();int c = list.get(i + 2).getNum();if (a == b && a == c) {cnt.add(a);}}return cnt;}// 判断双飞中对子有几个public static int feiDuiCount(List<PokerLabel> list,List<Integer> feiji) {List<PokerLabel> temp = new ArrayList<PokerLabel>();temp.addAll(list);int cnt = 0;for (int i = 0; i < temp.size(); i++) {for (int j = 0; j < feiji.size(); j++) {int a = list.get(i).getNum();if (a == feiji.get(j)) {temp.remove(i);}}}int size = temp.size();if (size > 0 && size % 2 == 0) {for (int i = 0; i < temp.size() - 1; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();if (a == b) {cnt++;}}}return cnt;}//判断双飞中单张有几个public static int feiDanZhangCount(List<PokerLabel> list,List<Integer> feiji) {List<PokerLabel> temp = new ArrayList<PokerLabel>();temp.addAll(list);int cnt = 0;for (int i = 0; i < temp.size(); i++) {for (int j = 0; j < feiji.size(); j++) {int a = list.get(i).getNum();if (a == feiji.get(j)) {temp.remove(i);}}}int size = temp.size();if (size > 0) {for (int i = 0; i < temp.size() - 1; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();if (a != b) {cnt++;}}}return cnt;}//判断是否符合出牌规则,即根据上家牌面判断本次出牌是否合规public static boolean legal(List<PokerLabel> prevList,List<PokerLabel> currentList) {// 首先判断牌型是不是一样PokerType paiXing = checkPokerType(prevList);if (paiXing.equals(checkPokerType(currentList))) {// 根据牌型来判断大小if (PokerType.p_1.equals(paiXing)) {// 单张if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_2w.equals(paiXing)) {// 王炸return false;} else if (PokerType.p_2.equals(paiXing)) {// 对子if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_3.equals(paiXing)) {// 三张if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_31.equals(paiXing)) {// 三带一if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_32.equals(paiXing)) {// 三带一对if (compare(prevList, currentList)) {return true;}return false;} else if (PokerType.p_4.equals(paiXing)) {// 炸弹if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_n.equals(paiXing)) {// 顺子if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_1122.equals(paiXing)) {// 连对if (compareLast(prevList, currentList)) {return true;}return false;} else if (PokerType.p_111222.equals(paiXing)) {// 双飞if (compare(prevList, currentList)) {return true;}return false;} else if (PokerType.p_11122234.equals(paiXing)) {// 飞机带翅膀(单张)if (compare(prevList, currentList)) {return true;}return false;} else if (PokerType.p_1112223344.equals(paiXing)) {// 飞机带翅膀(对子)if (compare(prevList, currentList)) {return true;}return false;}} else if (currentList.size() == 2) {//判断是不是王炸if (isWangZha(currentList)) {return true;}return false;} else if (currentList.size() == 4) {//判断是不是炸弹if (isSame(currentList, 4)) {return true;}return false;}return false;}public static boolean compareLast(List<PokerLabel> prevList,List<PokerLabel> currentList) {if (prevList.get(prevList.size() - 1).getNum() <currentList.get(currentList.size() - 1).getNum()) {return true;}return false;}public static boolean compare(List<PokerLabel> prevList,List<PokerLabel> currentList) {int a = san(prevList);int b = san(currentList);if (a == -1 || b == -1) {return false;}if (b > a) {return true;}return false;}public static int san(List<PokerLabel> list) {for (int i = 0; i < list.size() - 2; i++) {int a = list.get(i).getNum();int b = list.get(i + 1).getNum();int c = list.get(i + 2).getNum();if (a == b && a == c) {return a;}}return -1;}}

PokerType.java

package client.util;public enum PokerType {p_1,//单牌。p_2,//对子。p_2w,//王炸p_3,//3不带。p_4,//炸弹。p_n,//顺子。p_31,//3带1。p_32,//3带2。p_1122,//连队。p_111222,//飞机。p_11122234,//飞机带单排.p_1112223344,//飞机带对子.p_error//不能出牌}

LoginFrame.java

package client.view;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.io.*;import .*;public class LoginFrame extends JFrame {private JLabel lblUserName;private JTextField txtUserName;private JButton btnLogin;private JButton btnCancel;private void init() {Container container = this.getContentPane();//创建组件对象lblUserName = new JLabel("用户名:");txtUserName = new JTextField();btnLogin = new JButton("登录");btnCancel = new JButton("取消");//设置窗口属性setSize(400, 220);setVisible(true);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);container.setLayout(null);//设置组件属性lblUserName.setSize(80, 25);lblUserName.setLocation(90, 50);lblUserName.setFont(new Font("微软雅黑", Font.PLAIN, 20));txtUserName.setSize(120, 25);txtUserName.setLocation(180, 50);txtUserName.setFont(new Font("微软雅黑", Font.PLAIN, 20));btnLogin.setSize(80, 25);btnLogin.setLocation(100, 100);btnLogin.setFont(new Font("微软雅黑", Font.PLAIN, 20));btnCancel.setSize(80, 25);btnCancel.setLocation(200, 100);btnCancel.setFont(new Font("微软雅黑", Font.PLAIN, 20));//添加组件到窗口中container.add(lblUserName);container.add(txtUserName);container.add(btnLogin);container.add(btnCancel);//创建监听器对象 绑定到按钮上MyEvent myEvent = new MyEvent();btnLogin.addActionListener(myEvent);}public LoginFrame() {init();}//创建事件监听器类class MyEvent implements ActionListener {@Overridepublic void actionPerformed(ActionEvent arg0) {//点击登录//1.获得用户名String uname = txtUserName.getText();//2.创建一个socket链接服务器端try {Socket socket = new Socket("127.0.0.1", 8888);//3.跳转到主窗口new MainFrame(uname, socket);dispose();//关闭当前窗口} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}}

MainFrame.java

package client.view;import java.awt.*;import java.awt.event.*;import java.io.*;import .*;import java.util.*;import javax.swing.*;import client.model.*;import client.util.*;import client.thread.*;public class MainFrame extends JFrame {public MyPanel myPanel;public String uname;public Socket socket;public SendThread sendThread; // 发送消息的线程public ReceiveThread receiveThread;// 接收消息的线程public Player currentPlayer; // 存放当前玩家对象public java.util.List<PokerLabel> pokerLabels =new ArrayList<PokerLabel>(); // 存放扑克标签列表public JLabel lordLabel1; // 抢地主标签public JLabel lordLabel2; // 不叫public JLabel timeLabel; // 定时器标签public CountThread countThread; // 计数器的线程public boolean isLord; // 是否是地主public JLabel msgLabel; // 存放消息public JLabel lordIconLabel; //地主图标public JLabel chupaiJLabel;//出牌标签public JLabel buchuJLabel; //不出牌标签public ChuPaiThread chuPaiThread; //出牌定时器线程public java.util.List<PokerLabel> selectedPokerLabels =new ArrayList<PokerLabel>();//存放选中的扑克列表public java.util.List<PokerLabel> showOutPokerLabels =new ArrayList<PokerLabel>(); //存放当前出牌的列表public boolean isOut; //选择的是出牌还是不出牌public int prevPlayerid = -1; //上一个出牌的玩家idpublic MainFrame(String uname, Socket socket) {this.uname = uname;this.socket = socket;// 设置窗口的属性this.setTitle(uname);this.setSize(1200, 700);this.setVisible(true);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 添加mypanelmyPanel = new MyPanel();myPanel.setBounds(0, 0, 1200, 700);this.add(myPanel);//初始化窗口信息init();// 启动发消息的线程sendThread = new SendThread(socket, uname);sendThread.start();// 启动接收消息的线程receiveThread = new ReceiveThread(socket, this);receiveThread.start();}//窗口初始化public void init() {//创建消息框msgLabel = new JLabel();chupaiJLabel = new JLabel();chupaiJLabel.setBounds(330, 350, 110, 53);chupaiJLabel.setIcon(new ImageIcon("images/bg/chupai.png"));chupaiJLabel.addMouseListener(new MyMouseEvent());chupaiJLabel.setVisible(false);this.myPanel.add(chupaiJLabel);buchuJLabel = new JLabel();buchuJLabel.setBounds(440, 350, 110, 53);buchuJLabel.setIcon(new ImageIcon("images/bg/buchupai.png"));buchuJLabel.addMouseListener(new MyMouseEvent());buchuJLabel.setVisible(false);this.myPanel.add(buchuJLabel);timeLabel = new JLabel();timeLabel.setBounds(550, 350, 50, 50);timeLabel.setFont(new Font("Dialog", 0, 30));timeLabel.setForeground(Color.red);timeLabel.setVisible(false);this.myPanel.add(timeLabel);}public void showAllPlayersInfo(java.util.List<Player> players) {// 1.显示三个玩家的名称// 2.显示当前玩家的扑克列表for (int i = 0; i < players.size(); i++) {if (players.get(i).getName().equals(uname)) {currentPlayer = players.get(i);}}java.util.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);}if (currentPlayer.getId() == 0) {getLord(); // 抢地主}}//抢地主public void getLord() {// 显示抢地主的按钮 和 定时器按钮lordLabel1 = new JLabel();lordLabel1.setBounds(330, 400, 104, 46);lordLabel1.setIcon(new ImageIcon("images/bg/jiaodizhu.png"));lordLabel1.addMouseListener(new MyMouseEvent());this.myPanel.add(lordLabel1);lordLabel2 = new JLabel();lordLabel2.setBounds(440, 400, 104, 46);lordLabel2.setIcon(new ImageIcon("images/bg/bujiao.png"));lordLabel2.addMouseListener(new MyMouseEvent());this.myPanel.add(lordLabel2);//显示定时器的图标this.timeLabel.setVisible(true);this.setVisible(true);// 重绘this.repaint();// 启动计时器的线程countThread = new CountThread(10, this);countThread.start();}//显示出牌的标签public void showChuPaiJabel() {if (prevPlayerid == currentPlayer.getId()) {//从窗口上移除之前的出牌的列表for (int i = 0; i < showOutPokerLabels.size(); i++) {myPanel.remove(showOutPokerLabels.get(i));}//清空之前出牌的列表showOutPokerLabels.clear();}// 显示出牌和不出牌的按钮 和 定时器按钮chupaiJLabel.setVisible(true);buchuJLabel.setVisible(true);timeLabel.setVisible(true);this.repaint();chuPaiThread = new ChuPaiThread(30, this);chuPaiThread.start();}// 显示消息(不抢 或 不出)public void showMsg(int playerid, int typeid) {msgLabel.setVisible(true);msgLabel.setBounds(500, 300, 129, 77);if (typeid == 1) {msgLabel.setIcon(new ImageIcon("images/bg/buqiang.png"));}if (typeid == 3) {msgLabel.setIcon(new ImageIcon("images/bg/buchu.png"));}if (playerid == currentPlayer.getId()) {msgLabel.setLocation(400, 300);} else if (playerid + 1 == currentPlayer.getId() ||playerid - 2 == currentPlayer.getId()) //上家 // 2 0 0 1 1 2{msgLabel.setLocation(300, 100);} else { // 下家msgLabel.setLocation(800, 100);}this.myPanel.add(msgLabel);this.repaint();}// 添加地主牌public void addLordPokers(java.util.List<Poker> lordPokers) {for (int i = 0; i < lordPokers.size(); i++) {Poker poker = lordPokers.get(i);PokerLabel pokerLabel = new PokerLabel(poker.getId(),poker.getName(), poker.getNum());pokerLabel.turnUp(); // 显示正面图this.pokerLabels.add(pokerLabel);}Collections.sort(pokerLabels);for (int i = 0; i < pokerLabels.size(); i++) {// 添加到面板中this.myPanel.add(pokerLabels.get(i));// 动态的显示出来this.myPanel.setComponentZOrder(pokerLabels.get(i), 0);// 一张一张的显示出来GameUtil.move(pokerLabels.get(i), 300 + 30 * i, 450);}currentPlayer.getPokers().addAll(lordPokers);}//显示地主图标public void showLordIcon(int playerid) {//创建地主图标对象lordIconLabel = new JLabel();lordIconLabel.setIcon(new ImageIcon("images/bg/dizhu.png"));lordIconLabel.setSize(60, 89);//根据玩家id显示到具体的位置//如果自己是地主if (playerid == currentPlayer.getId()) {lordIconLabel.setLocation(200, 450);} else if (playerid + 1 == currentPlayer.getId() ||playerid - 2 == currentPlayer.getId()) //上家 // 2 0 0 1 1 2{lordIconLabel.setLocation(200, 100);} else { // 下家lordIconLabel.setLocation(950, 100);}//添加地主图标到面板上this.myPanel.add(lordIconLabel);this.repaint(); //重绘}//给扑克牌添加单击事件public void addClickEventToPoker() {for (int i = 0; i < pokerLabels.size(); i++) {pokerLabels.get(i).addMouseListener(new PokerEvent());}}//显示出牌的列表public void showOutPokerList(int playerid,java.util.List<Poker> outPokers) {//从窗口上移除之前的出牌的列表for (int i = 0; i < showOutPokerLabels.size(); i++) {myPanel.remove(showOutPokerLabels.get(i));}//清空之前出牌的列表showOutPokerLabels.clear();//显示当前出牌的列表for (int i = 0; i < outPokers.size(); i++) {Poker poker = outPokers.get(i);PokerLabel pokerLabel = new PokerLabel(poker.getId(),poker.getName(), poker.getNum());if (playerid == currentPlayer.getId()) {pokerLabel.setLocation(400 + 30 * i, 300);} else if (playerid + 1 == currentPlayer.getId() ||playerid - 2 == currentPlayer.getId()) {pokerLabel.setLocation(200 + 30 * i, 100);} else {pokerLabel.setLocation(700 + 30 * i, 100);}pokerLabel.turnUp();myPanel.add(pokerLabel);showOutPokerLabels.add(pokerLabel);myPanel.setComponentZOrder(pokerLabel, 0);}this.repaint(); //窗口重绘}//出牌 将出的牌从当前玩家的扑克列表中移除public void removeOutPokerFromPokerList() {//1.从当前玩家的扑克列表中移除pokerLabels.removeAll(selectedPokerLabels);//2.从面板中移除for (int i = 0; i < selectedPokerLabels.size(); i++) {myPanel.remove(selectedPokerLabels.get(i));}//3.剩下的扑克列表重新定位for (int i = 0; i < pokerLabels.size(); i++) {myPanel.setComponentZOrder(pokerLabels.get(i), 0);GameUtil.move2(pokerLabels.get(i), 300 + 30 * i, 450);}//4.清空选择的扑克牌列表selectedPokerLabels.clear();this.repaint();}//游戏结束public void gameOver() {this.myPanel.removeAll();this.repaint();try {this.socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.countThread.setRun(false);this.chuPaiThread.setRun(false);this.sendThread.setRun(false);this.receiveThread.setRun(false);}// 创建鼠标事件监听器类class MyMouseEvent extends MouseAdapter {@Overridepublic void mouseClicked(MouseEvent event) {// 点击的是抢地主if (event.getSource().equals(lordLabel1)) {// 停止计时器countThread.setRun(false);isLord = true;// 设置抢地主的按钮不可见lordLabel1.setVisible(false);lordLabel2.setVisible(false);timeLabel.setVisible(false);}// 点击的不抢if (event.getSource().equals(lordLabel2)) {// 停止计时器countThread.setRun(false);isLord = false;lordLabel1.setVisible(false);lordLabel2.setVisible(false);timeLabel.setVisible(false);}//点击出牌if (event.getSource().equals(chupaiJLabel)) {PokerType pokerType = PokerRule.checkPokerType(selectedPokerLabels);//判断是否符合牌型if (!pokerType.equals(PokerType.p_error)) {System.out.println(prevPlayerid + "," + currentPlayer.getId());//符合牌型,判断是不是比上家大 或者上家就是自己if (prevPlayerid == -1 || prevPlayerid == currentPlayer.getId() ||PokerRule.legal(showOutPokerLabels, selectedPokerLabels)) {isOut = true;//计时器停止chuPaiThread.setRun(false);chupaiJLabel.setVisible(false);buchuJLabel.setVisible(false);timeLabel.setVisible(false);} else {JOptionPane.showMessageDialog(null, "请按规则出牌");}} else {JOptionPane.showMessageDialog(null, "不符合牌型");}}if (event.getSource().equals(buchuJLabel)) {isOut = false;//计时器停止chuPaiThread.setRun(false);chupaiJLabel.setVisible(false);buchuJLabel.setVisible(false);timeLabel.setVisible(false);}}}//创建扑克牌的事件监听器类class PokerEvent extends MouseAdapter {@Overridepublic void mouseClicked(MouseEvent arg0) {// TODO Auto-generated method stubPokerLabel pokerLabel = (PokerLabel) arg0.getSource();//如果之前选择过了 则取消选择(设置选中属性为false 位置回到原位,从选择的扑克牌列表中移除)if (pokerLabel.isSelected()) {pokerLabel.setSelected(false);pokerLabel.setLocation(pokerLabel.getX(), pokerLabel.getY() + 30);selectedPokerLabels.remove(pokerLabel);}//如果之前没有选择 则选中(设置选中属性为true 位置往上移动一点,添加到选择的扑克牌列表中)else {pokerLabel.setSelected(true);pokerLabel.setLocation(pokerLabel.getX(), pokerLabel.getY() - 30);selectedPokerLabels.add(pokerLabel);}}}}

MyPanel.java

package client.view;import java.awt.*;import javax.swing.*;public class MyPanel extends JPanel{public MyPanel(){this.setLayout(null);}@Overrideprotected void paintComponent(Graphics g) {Image image=new ImageIcon("images/bg/bg1.png").getImage();g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);}}

Main.java

package client.view;public class Main {public static void main(String[] args) {new LoginFrame();//打开第一个玩家的登录窗口new LoginFrame();//打开第二个玩家的登录窗口new LoginFrame();//打开第三个玩家的登录窗口}}

MainServer.java

package server;import java.io.*;import .*;import java.util.*;import com.alibaba.fastjson.*;import client.model.*;public class MainServer {//创建玩家列表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 MainServer() {//创建扑克列表createPokers();try {//1.创建服务器端socketServerSocket serverSocket = new ServerSocket(8888);while (true) {//2.接收客户端的socketSocket socket = serverSocket.accept();//3.开启线程 处理客户端的socketAcceptThread acceptThread = new AcceptThread(socket);acceptThread.start();}} catch (IOException e) {e.printStackTrace();System.out.println("服务器端异常");}}//创建一个接收线程 处理客户端的信息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();if (step == 0) {//创建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) {deal();//发牌step = 1;}} else if (step == 1) //接收抢地主的信息{System.out.println("接收抢地主的消息");JSONObject msgJsonObject = JSON.parseObject(msg);int typeid = msgJsonObject.getInteger("typeid");int playerid = msgJsonObject.getInteger("playerid");String content = msgJsonObject.getString("content");//抢地主if (typeid == 2) {//重新组将一个 消息对象 ,添加地主牌Message sendMessage =new Message(typeid, playerid, content, lordPokers);msg = JSON.toJSONString(sendMessage);step = 2;}//不抢 将客户端发过来的不抢的信息 原样群发到所有玩家sendMessageToClient(msg);} else if (step == 2) //出牌和不出牌和游戏结束{sendMessageToClient(msg); //转发到所有的客户端}}} catch (IOException e) {e.printStackTrace();System.out.println("服务器异常:" + e.getMessage());}}}//群发消息到客户端public void sendMessageToClient(String msg) {for (int i = 0; i < players.size(); i++) {DataOutputStream dataOutputStream;try {dataOutputStream = new DataOutputStream(players.get(i).getSocket().getOutputStream());dataOutputStream.writeUTF(msg);} catch (IOException e) {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[]{"黑桃", "红桃", "梅花", "双块"};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 deal() {//发给三个玩家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));elseplayers.get(2).getPokers().add(allPokers.get(i));}}//将玩家的信息发送到客户端for (int i = 0; i < players.size(); i++) {try {DataOutputStream dataOutputStream =new DataOutputStream(players.get(i).getSocket().getOutputStream());String jsonString = JSON.toJSONString(players);System.out.println(jsonString);dataOutputStream.writeUTF(jsonString);} catch (IOException e) {e.printStackTrace();}}}}

Main.java

package server;public class Main {public static void main(String[] args) {new MainServer();}}

除阅读文章外,各位小伙伴还可以点击这里观看我在本站的视频课程学习Java!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。