C#坦克大戰網路版代碼

來源:互聯網
上載者:User

 

簡單C#坦克大戰網路版代碼

 

 

寫完單機版  http://blog.csdn.net/xiaoxiao108/archive/2010/12/18/6084473.aspx 遊戲後

再寫個網路版玩玩。

開發工具vs2008

 

 

網路版實現方法很簡單

1.一個服務端,多個用戶端

2.服務端開個連接埠監聽,當一個用戶端程式後串連到服務端後,服務端分配個編號給用戶端作為他的坦克編號

3.當有新坦克建立,坦克移動,等操作時,用戶端發送資料到服務端,服務端再把資料發送到所有的用戶端來實現網路遊戲的同步

 

 

具體實現代碼

1.服務端開啟服務代碼

        public void Start()

        {

            //開啟udp線程

            Thread t = new Thread(UDPThread);

            t.IsBackground = true;

            t.Start();

            //開啟tcp服務

            TcpListener tl = new TcpListener(TCP_PORT);

            tl.Start();

            while (true)

            {

                TcpClient tc = tl.AcceptTcpClient();

                Stream ns = tc.GetStream();

                BinaryReader br = new BinaryReader(ns);

                int udpPort = br.ReadInt32();//br.Close();不能關閉br

                BinaryWriter bw = new BinaryWriter(ns);

                bw.Write(ID++);

                IPEndPoint rep = (IPEndPoint)tc.Client.RemoteEndPoint;

                Client c = new Client(rep.Address.ToString(), udpPort);

                clients.Add(c);

                Console.WriteLine("A Client TCP Connect! Addr- " + rep.Address.ToString() + ":" + rep.Port);

            }

        }

2.服務端udp資料接收轉寄代碼

       private void UDPThread()

        {

            Console.WriteLine("UDP thread started at port :" + UDP_PORT);

            byte[] buf = new byte[1024];

            UdpClient uc = new UdpClient(UDP_PORT);//// 跟java有區別 如果這句話放到while外面  就不能接受第二個坦克連入

            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);

            while (true)

            {

                buf = uc.Receive(ref ipep);

                Console.WriteLine("a udp packet received! from " + ipep.Address + ":" + ipep.Port);

                //把收到的資料轉寄給每一個用戶端

                for (int i = 0; i < clients.Count; i++)

                {

                    Client c = clients[i];

                    UdpClient _uc = new UdpClient();

                    _uc.Connect(c.ip, c.udpPort);

                    _uc.Send(buf, buf.Length);

                }

            }

        }

3.用戶端串連代碼

       public void Connect(string ip, int port)

        {

            this.ip = ip;

            TcpClient client = new TcpClient();

            client.Connect(ip, port);

            Stream ns = client.GetStream();

            BinaryWriter bw = new BinaryWriter(ns);

            bw.Write(udpPort);

            BinaryReader br = new BinaryReader(ns);             //bw.Close();不能關閉bw

            //從伺服器端取到伺服器分配的坦克編號

            int id = br.ReadInt32();

            tc.myTank.ID = id;

            //編號為偶數的設定為壞蛋

            if (id % 2 == 0)

                tc.myTank.Good = false;

            else

                tc.myTank.Good = true;

            //可以在“輸出視窗”看到下面的調試代碼

            Debug.WriteLine("Connected to server! and server give me a ID:" + id);

            br.Close();

            ns.Close();

            client.Close();

            TankNewMsg msg = new TankNewMsg(tc.myTank);

            Send(msg);

            //開啟接收線程

            Thread t = new Thread(UDPRecvThread);

            t.IsBackground = true;

            t.Start();

        }

4.坦克加入訊息代碼發送代碼

 

        public void Send(UdpClient uc, string ip, int udpPort)

        {

            uc.Connect(ip, udpPort);

            //程式中用 | 來分割發送的內容

            string str = msgType + "|" + tank.ID + "|" + tank.x + "|" + tank.y + "|" + (int)tank.dir + "|" + tank.Good;

            uc.Send(Encoding.UTF32.GetBytes(str), Encoding.UTF32.GetBytes(str).Length);

        }

5.坦克加入訊息解析代碼

       public void Parse(byte[] b)

        {

            string str = Encoding.UTF32.GetString(b);

            string[] strs = str.Split('|');

            int id = Convert.ToInt32(strs[1]);

            //如果資料包裡是自己的坦克不處理

            if (id == tc.myTank.ID)

            {

                return;

            }

            int x = Convert.ToInt32(strs[2]);

            int y = Convert.ToInt32(strs[3]);

            Direction dir = (Direction)Convert.ToInt32(strs[4]);

            bool good = Convert.ToBoolean(strs[5]);

            Boolean exist = false;

            for (int i = 0; i < tc.tanks.Count; i++)

            {

                Tank t = tc.tanks[i];

                if (t.ID == id)

                {

                    exist = true;

                    break;

                }

            }

            //如果坦克不存在就建立出來

            if (!exist)

            {

                TankNewMsg msg = new TankNewMsg(tc.myTank);

                tc.nc.Send(msg);

                //Tank t = new Tank(x, y, good, tc);//java中是這樣寫得Tank t = new Tank(x,y,good,dir,tc)

                Tank t = new Tank(x, y, good, dir, tc);  //有可能是老坦克 給新坦克發包 所以要家dir參數

                t.ID = id;

                tc.tanks.Add(t);

            }

        }

6.坦克移動訊息

        public void Send(UdpClient uc, string ip, int udpPort)

        {

            uc.Connect(ip, udpPort);

            //程式中用 | 來分割發送的內容

            string str = msgType + "|" + id + "|" + x + "|" + y + "|" + Convert.ToInt32(dir);

            uc.Send(Encoding.UTF32.GetBytes(str), Encoding.UTF32.GetBytes(str).Length);

        }

 

        public void Parse(byte[] b)

        {

            string str = Encoding.UTF32.GetString(b);

            string[] strs = str.Split('|');

            int id = Convert.ToInt32(strs[1]);

            //如果資料包裡是自己的坦克不處理

            if (id == tc.myTank.ID)

            {

                return;

            }

            int x = Convert.ToInt32(strs[2]);

            int y = Convert.ToInt32(strs[3]);

            Direction dir = (Direction)Convert.ToInt32(strs[4]);

            for (int i = 0; i < tc.tanks.Count; i++)

            {

                Tank t = tc.tanks[i];

                if (t.ID == id)

                {

                    t.dir = dir;

                    t.x = x;

                    t.y = y;

                    break;

                }

            }

        }

7.子彈訊息處理代碼

        public void Send(UdpClient uc, string ip, int udpPort)

        {

            uc.Connect(ip, udpPort);

            //程式中用 | 來分割發送的內容

            string str = msgType + "|" + m.tankID + "|" + m.x + "|" + m.y + "|" + (int)m.dir + "|" + m.good;

            uc.Send(Encoding.UTF32.GetBytes(str), Encoding.UTF32.GetBytes(str).Length);

        }

 

        public void Parse(byte[] b)

        {

            string str = Encoding.UTF32.GetString(b);

            string[] strs = str.Split('|');

            int tankID = Convert.ToInt32(strs[1]);

            if (tankID == tc.myTank.ID)

            {

                return;

            }

            int x = Convert.ToInt32(strs[2]);

            int y = Convert.ToInt32(strs[3]);

            Direction dir = (Direction)Convert.ToInt32(strs[4]);

            bool good = Convert.ToBoolean(strs[5]);

            Missile m = new Missile(tankID, x, y, good, dir, tc);

            tc.missiles.Add(m);

        }

 

 

 

 

單機測試時 先運行服務端  再運行多個用戶端就ok

多機連網遊戲時修改下 nc.Connect("127.0.0.1", 8888);中的ip地址就可以在區域網路內玩了

        private void Form1_Load(object sender, EventArgs e)

        {

            myTank = new Tank(50, 20, true, this);//放到前面 this不能用  //y軸比java的減少了30

            nc = new NetClient(this);

            nc.Connect("127.0.0.1", 8888);

            //nc.connect("192.168.1.168",8888);

            //nc.connect("10.10.10.1",8888);

        }

 

如果你發現有什麼不合理的,需要改進的地方,郵件聯絡328452421@qq.com(qq常年不線上,郵件聯絡)  朱曉 (泰山學院)。相互交流 謝謝

 

 

  http://download.csdn.net/source/2986606

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.