Java实现控制台麻将基本操作

Java实现客户端模拟打麻将与服务器基本操作方式相同,都是定义好协议包,若有不知道什么是协议包是什么概念,可参考我以前发布的一篇文章:PHP游戏服务器的设计思路

以下代码便是控制台麻将的JAVA基本实现效果:

 

import net.sf.json.JSONObject;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

public class Client {
    private String serverIp;
    private int port;
    private boolean running=false;//连接状态
    private Socket socket;

    private InputStream in;
    private OutputStream out;

    DataOutputStream outs;
    DataInputStream ins;

    //主函数
    public static void main(String[] args) throws Exception {
        Client client=new Client("117.48.199.137",1314);
        client.start();
    }

    //构造函数
    public Client(String serverIp,int port){
        this.serverIp=serverIp;
        this.port=port;
    }

    //启动客户端的函数
    public void start() throws Exception {
        if(running) return;
        socket=new Socket(serverIp,port);

        out=socket.getOutputStream();
        outs=new DataOutputStream(out);

        in=socket.getInputStream();
        ins=new DataInputStream(in);

        running=true;
        new Thread(new SendMsg()).start();//发送消息的线程
        new Thread(new ReceiveMsg()).start();//接收消息的线程
    }

    //关闭连接的函数
    public void stop(){
        if(running){
            running=false;
        }
    }

    //发送消息的线程类
    class SendMsg implements Runnable{

        private void sendTextMsg(DataOutputStream out,int msgType,short gameType, String msg,int status) throws Exception {
            byte[] bytes = msg.getBytes();
            int totalLen = 22 + bytes.length;
            out.writeInt(totalLen);//包长
            out.writeInt(msgType);//消息类型
            out.writeInt(status);//状态
            out.writeShort(gameType);//游戏类型
            out.writeInt(0);
            out.writeInt(0);
            out.write(bytes);
            out.flush();
        }

        public void run() {
            Scanner scanner=new Scanner(System.in);
            while (running){
                try {
                    String readMsg=scanner.nextLine();

                    //用问号拆分数组
                    String[] strArray=readMsg.split("\\?");

                    switch (strArray[0]){
                        case "login":
                            HashMap<String, Object> map = new HashMap<String,Object>();
                            map.put("openId", "a1bv2345678900cc");
                            map.put("nickName", "piupiu");
                            map.put("sex", 1);
                            map.put("headIcon", "http://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83eomtGXciaK6d4TZWiaQDDpUIFyJicgR99kr55pmpZwiabOZncicHQiaMiag8PxbJQNOBpFTO51hUyGCAHwUQ/0");
                            map.put("IP", "25.9.9.9");
                            map.put("longitude", 104.5446);
                            map.put("latitude", 28.72096);
                            JSONObject jsonObject = JSONObject.fromObject(map);

                            sendTextMsg(outs,0x000001,(short)0,jsonObject.toString(),1);

                            break;
                        case "createRoom":
                            HashMap<String, Object> room = new HashMap<String,Object>();
                            room.put("roomType", 1);
                            room.put("totalCount", 4);
                            room.put("endPoints", 4);
                            room.put("fanNum", 5);
                            room.put("haiDiPiao", true);
                            HashMap<String, Object> playType = new HashMap<String,Object>();
                            playType.put("tianHu",true);
                            playType.put("diHu",true);
                            playType.put("yaoJiuDui",true);
                            playType.put("jiangDui",true);
                            playType.put("zhuanYi",true);
                            playType.put("queYi",true);
                            playType.put("guoShouGang",true);
                            playType.put("shiBaXueShi",true);
                            room.put("playType", playType);
                            room.put("playerNum", 2);
                            room.put("roomPayment", 1);
                            room.put("jiaDi", 0);

                            JSONObject roomObject = JSONObject.fromObject(room);
                            sendTextMsg(outs,0x00009,(short)1,roomObject.toString(),1);
                            break;
                        case "joinRoom":
                            sendTextMsg(outs,0x000003,(short)1,strArray[1],1);
                            break;
                        case "ready":
                            sendTextMsg(outs,0x010011,(short)1,"",1);
                            break;
                        case "putOut":
                            sendTextMsg(outs,0x100001,(short)1,strArray[1],1);
                            break;
                        case "gang":
                            sendTextMsg(outs,0x100007,(short)1,strArray[1],1);
                            break;
                        case "peng":
                            sendTextMsg(outs,0x100005,(short)1,strArray[1],1);
                            break;
                        case "hu":
                            sendTextMsg(outs,0x100009,(short)1,strArray[1],1);
                            break;
                        case "pass":
                            sendTextMsg(outs,0x100015,(short)1,strArray[1],1);
                            break;
                        case "tui":
                            HashMap<String, Object> tui = new HashMap<String,Object>();
                            int tuiPai[]={9,9};
                            int huPai[]={9};
                            tui.put("tuiPai",tuiPai );
                            tui.put("huPai", huPai);
                            JSONObject tuiObject = JSONObject.fromObject(tui);
                            sendTextMsg(outs,0x100011,(short)1,tuiObject.toString(),1);
                            break;
                        case "mo":
                            sendTextMsg(outs,0x1000b3,(short)1,"",1);
                            break;
                        case "shiBaHu":
                            sendTextMsg(outs,0x200004,(short)1,strArray[1],1);
                            break;
                        case "jiaDi":
                            sendTextMsg(outs,0x200007,(short)1,strArray[1],1);
                            break;
                        case "guoTui":
                            sendTextMsg(outs,0x100011,(short)1,"",2);
                            break;
                        case "exitRoom"://退出房间
                            sendTextMsg(outs,0x10a005,(short)1,"",1);
                            break;
                        case "disbandRoom"://解散房间
                            sendTextMsg(outs,0x10b007,(short)1,"",1);
                            break;
                        case "disbandVote"://解散房间投票 1同意 0不同意
                            sendTextMsg(outs,0x10b009,(short)1,strArray[1],1);
                            break;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Client.this.stop();
                }
            }
        }
    }

    //接收消息的线程类
    class ReceiveMsg implements Runnable{

        public void responseMsg(int headCode,String data){
            switch (headCode){
                case 0x000002:
                    //System.out.println("登录成功!!!");
                    System.out.println(JSONObject.fromObject(data));
                    break;

                default:
                    System.out.println(data);
                    break;
            }
        }

        public void run() {
            while (running){
                try {
                    int totalLen=ins.readInt();//读一个int的数据判断此包有多长
                    int headCode=ins.readInt();//包的执行码
                    int status=ins.readInt();
                    int gameType=ins.readShort();
                    ins.readInt();
                    ins.readInt();

                    byte[] data=new byte[totalLen-22];//创建消息体的空byte数组

                    ins.readFully(data);//读消息体到data数组中

                    String msg=new String(data);

                    responseMsg(headCode,msg);//执行消息分发
                }catch (Exception e){
                    e.printStackTrace();
                    Client.this.stop();
                }
            }
        }
    }

}

实现原理是通过一个线程去循环发数据,用另一个线程去循环接数据,所有的操作都是先去解析数据包,得到自己的操作,最后执行操作。如有不太明白的,可扫码加我微信进行讨论。

发布了23 篇原创文章 · 获赞 26 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览