开发工具:
文件大小: 92kb
下载次数: 0
上传时间: 2011-01-16
详细说明: 写完单机版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旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.