




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、计算机网络系统实践报告设计题目:网络版小游戏坦克大战学生姓名:学 号: 专业班级:物联网工程12-1班2015年09月基于java的网络版坦克大战游戏设计1、 设计要求1.1设计目的 (1)熟悉开发工具(java)的基本操作; (2)掌握windows/linux应用程序的编写过程; (3)对于socket编程建立初步的概念。1.2设计要求 (1)熟悉socket api 主要函数的使用; (2)掌握相应开发工具对socket api 的封装; (3)设计并实现一对一网络版小游戏,如:tic-tac-toe、五子棋等。 我选择了网络版坦克大战的设计。2、 开发环境与工具 2.1 编程语言:ja
2、va java 语言是一种跨平台,适合于分布式计算环境的面向对象编程语言。java现在主要用在web开发,手机游戏及一些平台游戏的开发,因为它具有很好的跨平台性,在手机等各种电子产品上应用非常广泛。 2.2 运行环境:jdk1.6 2.3 开发工具:my eclipse 10 myeclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于java、java ee以及移动应用的开发。myeclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持相当不错。 2.4 网络建立:socket 网络上的两个程序通过一个双向的通信连接实现数据的交
3、换,这个连接的一端称为一个socket。 socket的英文原义是“孔”或“插座”。作为bsd unix的进程通信机制,取后一种意思。通常也称作"套接字",用于描述ip地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个socket,并绑定到一个端口上,不同的端口对应于不同的服务。socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软
4、件将插头插到不同编号的插座,就可以得到不同的服务。3、 设计原理联机通信机制网络编程,简单地理解就是两台计算机相互通信。其基本模型就是客户机/服务器模型,也就是通信双方中的一方必须提供一个固定的位置,而另一方只需要知道这个固定的位置,并且建立两者之间的联系,然后完成数据交换。这里提供固定位置的一方通常称为服务器,而建立联系的一方称为客户端。socket(中文意思为插座),基于客户机/服务器的soctet通信模式如图3.1所示:创建socket类的对象指定服务器端公认的socket地址和端口在socket上监听客户端的链接请求接收客户端的请求信息解释并处理请求信息向服务器发出请求向服务器端发送链
5、接请求创建socket类对象客户端将处理结果返回给客户端接收服务结果服务请求服务响应服务器端图3.1 基于客户机/服务器的soctet通信模式图当客户程序需要与服务器程序通讯的时候,客户程序在客户机创建一个socket对象,socket类有几个构造函数。两个常用的构造函数是 socket(inetaddress addr, int port) 和 socket(string host, int port),两个构造函数都创建了一个基于socket的连接服务器端流套接字的流套接字。两个函数都通过参数port获得服务器的端口号。假设已经建立连接了,网络api将在客户端基于socket的流套接字中捆
6、绑客户程序的ip地址和任意一个端口号,否则两个函数都会抛出一个ioexception对象。如果创建了一个socket对象,那么它可能通过调用socket的 getinputstream()方法从服务程序获得输入流读传送来的信息,也可能通过调用socket的 getoutputstream()方法获得输出流来发送消息。在读写活动完成之后,客户程序调用close()方法关闭流和流套接字。四、系统功能描述及软件模块划分 4.1 系统功能描述 4.1.1单机版人机对战 a)玩家通过上、下、左、右键来控制坦克的八个方向:上、下、左、右、左上、右上、左下、右下; b)出现十个敌方坦克,自由运动并发射炮弹;
7、 c)玩家通过“control”键发射炮弹; d)打中敌方或被敌方打中,死亡; e)碰撞时死亡。 4.1.2网络对战模式 在人机在人机对战模式中实现功能基础上,增加以下功能实现网络对战功能: a)添加网络功能,使两台或者多台不同计算机的玩家通过一定的网络连接,加入到游戏中; b)能够自动分组选择阵营,一红一篮双方交替进入游戏,填写自己的游戏信息,各个玩家之间实现网络对战功能,并且同是一方的坦克不能相互攻击; c)玩家id是自动分配的,采用递加的模式。 4.1.3总体功能设计坦克大战游戏主要实现玩家参加游戏的整个流程,整个网络版坦克大战游戏流程图如图4.1所示:初 始 化游戏模式单 机对 战产生
8、敌方坦克玩家坦克判断胜负玩家一玩家二玩家一玩家二敌方坦克我方坦克判断胜负结 束随机分配阵营图4.1 网络坦克大战游戏流程 4.2 软件模块划分 4.2.1tankclient类基本功能分析 tankclient类是整个系统的核心部分,它承担整个系统的所有可实现功能的调度工作。 是整个游戏运行的场所。tankclient类设计流程图如图4.2所示:开始初始化坦克对战双方玩家坦克由键盘控制移动发射炮弹碰撞检测(坦克和子弹)不处理同角色坦克产生爆炸不同角 色坦克判断胜负结束图4.2 tankclient类设计流程tankclient类是主类,通过调用其他类中封装的方法来使整个系统运行起来,下面显示t
9、ankclient与各个类之间的关系如图4.3所示:tankclient类(主类)tank类(我方)tank类(敌方)new参数1new参数2调用missile类打中调用explode类产程爆炸判断胜负键盘控制移动键盘控制移动打击图4.3 游戏系统类关联图 4.2.2 tank类基本功能分析 tank类中,封装了一些变量属性,包括坦克自己的大小(width,hright),运动速度(sprrd_x:在x轴方向的速度;speed_y:在y轴方向的速度)、生命值控制(life)、坦克编号(id)、坦克名(name)、方向控制(dir)、生死控制(live)等。tank类中没有main函数,不是主类
10、,它当中只封装一些变量属性和静态方法,被tankclient类调用来实现坦克的一系列动作。tank类中的主要方法罗列如下: (1)getrect()方法public rectangle getrect() return new rectangle(x, y, this.width, this.height); rectangle类是碰撞检测的辅助类,通过得到子弹的x,y坐标和宽高度,检测两个矩形是否碰撞(相交); (2)draw()方法:负责将所有的活动在屏幕上画出来; (3)move()方法:主要负责控制坦克的移动,包括8个方向(左,左上,上,右上,右,右下,下,左下)的控制以及给坦克一个移
11、动的速度; (4)keypressed()方法:设定使用键盘的“”“”“”“”键控制坦克移动; (5)keyreleased()方法:处理按键抬起事件,抬起“ctrl”键时,发射炮弹并加入新炮弹,能够逐一发射每一发炮弹、抬起“a”键可以发射超级炮弹等功能; (6)locationdirection()方法:定义了炮筒方向,可以向八个方向发射炮弹; (7)fire()方法:处理发送子弹的方法; (8)bumpwithwall()方法:主要负责处理坦克撞墙事件; (9)bumpwithtank()方法:主要到负责处理坦克和坦克相撞事件; 4.2.3 missile类基本功能分析 misslile(
12、子弹)类和tank类一样,只封装一些变量属性和静态方法,主要变量包括:子弹自己的大小(width,hright),运动速度(sprrd_x:在x轴方向的速度;speed_y:在y轴方向的速度)、子弹标示(id)、所属坦克的id号(tankid用于网络版)等。misslie类持有一个tankclient类(大管家)的引用tc,tankclient类要执行发射炮弹操作时调用missile类中的方法。misslie类中的主要方法如下:(1) draw()方法:负责画出子弹的所有活动;(2) move()方法:先判断方向再移动,并给它一定的移动速度;(3) getrect()方法:负责取得子弹的外切方
13、形,为碰撞检测做准备;(4) hittan()方法:检测子弹是否撞到坦克,若撞到返回true,否则返回false;(5) hittanks()方法:检测是否撞到一系列坦克中的一个;(6) hitwall()方法:检测子弹和墙是否相撞。 4.2.4 explode类基本功能分析explode(爆炸)类也是一个只封装自己的变量和方法的外部包装类,没有main方法,供tankclient主类需要时调用它的draw()方法,当子弹击中坦克时需要产生爆炸。 4.2.5 服务器类基本功能分析tankserver(服务器)类主要负责在网络对战游戏时维护各个在线玩家的基本信息,并动态的维护玩家列表。联机模式下
14、类关系图如图4.4所示:tankserver类tankclient 1类类tankclient 2类类new参数1new参数2调用missile类调用explode类产程爆炸判断胜负tank类(我方)tank类(敌方)打中打击4.4 联机模式类关联图 4.2.6 信息传送类基本功能分析 信息传送类就是用来封装客户端和服务器端的交互信息。将网络中传递的众多信息封装成可序列化的类,将会使程序有很好的可扩展性。 五、设计步骤5.1 单机版的坦克大战游戏(人机对战) 5.1.1主程序:tankclient 代码如下:public class tankclient extends frame priva
15、te static final long serialversionuid = 5865157849989504064l;public static final int game_width = 800;public static final int game_height = 600;public static int score = 0, 0, 0 ;random r = new random();tank mytank1 = new tank(750, 550, tank.direction.stop, this, 1);tank mytank2 = new tank(50, 550,
16、tank.direction.stop, this, 2);wall w1 = new wall(200, 100, 200, 10, this);wall w2 = new wall(200, 100, 10, 200, this);wall w3 = new wall(200, 300, 200, 10, this);wall w4 = new wall(400, 300, 10, 200, this);wall w5 = new wall(200, 490, 200, 10, this);wall w6 = new wall(500, 100, 10, 400, this);wall w
17、7 = new wall(500, 490, 200, 10, this);blood b = new blood();list<missile> missiles = new arraylist<missile>();list<explode> explodes = new arraylist<explode>();image offscreenimage = null;/ 定义背后的虚拟图片public void paint(graphics g) / g.drawstring("missiles count:" + mi
18、ssiles.size(), 10, 50);/ g.drawstring("explodes count:" + explodes.size(), 10, 70);/ g.drawstring("tanks count:" + tanks.size(), 10, 90);g.setcolor(color.orange);g.drawstring("p1 p2", 10, 40);g.drawstring("l c: 发射一枚普通的子弹。", 10, 60);g.drawstring("k v: 九个方向
19、的超级炮弹。", 10, 80);g.drawstring("j b: 埋下一颗地雷等他踩.", 10, 100);g.drawstring("f2 f3: 购买一辆全新的坦克。", 10, 140);g.drawstring("p1的剩余坦克数 : " + mytank1.getlives(), 600, 50);g.drawstring("p2的剩余坦克数 : " + mytank2.getlives(), 600, 70);g.drawstring("p1的分数 : " + sc
20、ore1, 600, 90);g.drawstring("p2的分数 : " + score2, 600, 110);g.drawstring("剩余的坦克波数 : " + tank.win, 600, 130);mytank1.collideswithwall(w1);mytank2.collideswithwall(w2);mytank1.collideswithwall(w3);mytank2.collideswithwall(w4);mytank1.collideswithwall(w5);mytank2.collideswithwall(w6)
21、;mytank1.collideswithwall(w7);mytank2.collideswithtank(mytank1);mytank1.collideswithtank(mytank2);for (int i = 0; i < missiles.size(); i+) missile m = missiles.get(i);m.hittank(mytank1);m.hittank(mytank2);m.hitwall(w1);m.hitwall(w2);m.hitwall(w3);m.hitwall(w4);m.hitwall(w5);m.hitwall(w6);m.hitwal
22、l(w7);m.draw(g);for (int i = 0; i < explodes.size(); i+) explode e = explodes.get(i);e.draw(g);mytank1.draw(g);mytank2.draw(g);w1.draw(g);w2.draw(g);w3.draw(g);w4.draw(g);w5.draw(g);w6.draw(g);w7.draw(g);if (mytank1.getlife() < 40 | mytank2.getlife() < 40) mytank1.eat(b);mytank2.eat(b);b.dr
23、aw(g);/ 用update截住paintpublic void update(graphics g) if (offscreenimage = null) offscreenimage = this.createimage(game_width, game_height);graphics goffscreen = offscreenimage.getgraphics();color c = goffscreen.getcolor();goffscreen.setcolor(color.black);goffscreen.fillrect(0, 0, game_width, game_he
24、ight);goffscreen.setcolor(c);paint(goffscreen);g.drawimage(offscreenimage, 0, 0, null);public void launchframe() this.setlocation(200, 80);this.setsize(game_width, game_height);this.settitle("tankwar-written by small_light");this.addwindowlistener(new windowadapter() public void windowclos
25、ing(windowevent e) system.exit(0););this.setbackground(color.black);this.setresizable(false);/ 不可以调整窗口大小this.addkeylistener(new keymonitor();this.setvisible(true);new thread(new paintthread().start();/主函数public static void main(string args) tankclient tc = new tankclient();tc.launchframe();/多线程,画图pr
26、ivate class paintthread implements runnable public void run() while (true) repaint();try thread.sleep(40); catch (interruptedexception e) e.printstacktrace(); 5.1.2 信息传输 tanknewmsg(tankmovemsg和tankdeadmsg与此模块基本相同,暂不贴出了) 代码如下:/* * 代表坦克诞生的消息类 author mashibing */public class tanknewmsg implements msg i
27、nt msgtype = msg.tank_new_msg;tank tank;tankclient tc;/* * 根据tank的信息构建消息 * param tank */public tanknewmsg(tank tank) this.tank = tank;/* * 根据消息产生的场所构建新的消息 * param tc */public tanknewmsg(tankclient tc) this.tc = tc;/* * 发送相关的消息 * param ds 通过该socket发送数据 * param ip 数据的目标ip * param udpport 数据的目标端口 */pub
28、lic void send(datagramsocket ds, string ip, int udpport) bytearrayoutputstream baos = new bytearrayoutputstream();dataoutputstream dos = new dataoutputstream(baos);try dos.writeint(msgtype);dos.writeint(tank.id);dos.writeint(tank.x);dos.writeint(tank.y);dos.writeint(tank.dir.ordinal();dos.writeboole
29、an(tank.good); catch (ioexception e) e.printstacktrace();byte buf = baos.tobytearray();try datagrampacket dp = new datagrampacket(buf, buf.length,new inetsocketaddress(ip, udpport);ds.send(dp); catch (socketexception e) e.printstacktrace(); catch (ioexception e) e.printstacktrace();/* * 分析接收到的消息数据 *
30、 param dis 接收到的消息数据的输入流 */public void parse(datainputstream dis) try int id = dis.readint();if (tc.mytank.id = id) return;int x = dis.readint();int y = dis.readint();dir dir = dir.values()dis.readint();boolean good = dis.readboolean();/ system.out.println("id:" + id + "-x:" + x +
31、 "-y:" + y + "-dir:" +/ dir + "-good:" + good);boolean exist = false;for (int i = 0; i < tc.tanks.size(); i+) tank t = tc.tanks.get(i);if (t.id = id) exist = true;break;if (!exist) tanknewmsg tnmsg = new tanknewmsg(tc.mytank);tc.nc.send(tnmsg);tank t = new tank(x, y,
32、 good, dir, tc);t.id = id;tc.tanks.add(t); catch (ioexception e) e.printstacktrace(); 5.1.3爆炸explode 代码如下:public void draw(graphics g) if(!live) tc.explodes.remove(this);return;color c = g.getcolor();g.setcolor(color.orange);g.filloval(x, y, diametersstep, diametersstep);g.setcolor(c);step +;if(step
33、 = diameters.length) live = false;5.2 建立server,建立client并和server连接 tankserver的代码如下:服务端程序 主要代码:public class tankserver private static int id = 100;/* * tcp的监听端口 */public static final int tcp_port = 8888;/* * udp的监听端口 */public static final int udp_port = 6666;list<client> clients = new arraylist&
34、lt;client>();/* * 启动服务器 */public void start() new thread(new udpthread().start();serversocket ss = null;try ss = new serversocket(tcp_port); catch (ioexception e) e.printstacktrace();while (true) socket s = null;try s = ss.accept();datainputstream dis = new datainputstream(s.getinputstream();stri
35、ng ip = s.getinetaddress().gethostaddress();int udpport = dis.readint();client c = new client(ip, udpport);clients.add(c);dataoutputstream dos = new dataoutputstream(s.getoutputstream();dos.writeint(id+);/ s.close();system.out.println("a client connect! addr- "+ s.getinetaddress() + "
36、:" + s.getport()+ "-udp port:" + udpport); catch (ioexception e) e.printstacktrace(); finally if (s != null) try s.close();s = null; catch (ioexception e) e.printstacktrace();public static void main(string args) new tankserver().start();private class client string ip;int udpport;publi
37、c client(string ip, int udpport) this.ip = ip;this.udpport = udpport;private class udpthread implements runnable byte buf = new byte1024;public void run() datagramsocket ds = null;try ds = new datagramsocket(udp_port); catch (socketexception e) e.printstacktrace();system.out.println("udp thread
38、 started at port :" + udp_port);while (ds != null) datagrampacket dp = new datagrampacket(buf, buf.length);try ds.receive(dp);for (int i = 0; i < clients.size(); i+) client c = clients.get(i);dp.setsocketaddress(new inetsocketaddress(c.ip,c.udpport);ds.send(dp);system.out.println("a pac
39、ket received!"); catch (ioexception e) e.printstacktrace();5.3客户端发送udp端口,取得自己的id号 (java.util.uuid) 服务器端保存客户端信息核心代码如下:public void connect(string ip, int port) this.ip = ip;try ds = new datagramsocket(udpport); catch (socketexception e) e.printstacktrace();socket s = null;try s = new socket(ip, p
40、ort);dataoutputstream dos = new dataoutputstream(s.getoutputstream();dos.writeint(udpport);datainputstream dis = new datainputstream(s.getinputstream();int id = dis.readint();tc.mytank.id = id;if (id % 2 = 0)tc.mytank.good = false;elsetc.mytank.good = true;tanknewmsg msg = new tanknewmsg(tc.mytank);
41、send(msg);new thread(new udprecvthread().start();/* * 发送消息 * param msg 待发送的消息 */public void send(msg msg) msg.send(ds, ip, tankserver.udp_port);private class udprecvthread implements runnable byte buf = new byte1024;public void run() while (ds != null) datagrampacket dp = new datagrampacket(buf, buf
42、.length);try ds.receive(dp);parse(dp);system.out.println("a packet received from server!"); catch (ioexception e) e.printstacktrace();private void parse(datagrampacket dp) bytearrayinputstream bais = new bytearrayinputstream(buf, 0, dp.getlength();datainputstream dis = new datainputstream(
43、bais);int msgtype = 0;try msgtype = dis.readint(); catch (ioexception e) e.printstacktrace();5.4 多个客户联网,并发送坦克诞生的消息(tankmovemsg和tankdeadmsg与tanknewmsg基本相同,就不再贴出了) 服务器端建立udp转发线程,客户端接收到后进行处理,用多态进行消息的封装,修正tanknewmsg的处理,让后加入的tank也能看到先加入的坦克 接到tanknewmsg后,也发送一个tanknewmsg 模块tanknewmsg核心代码如下:/* * 代表坦克诞生的消息类
44、* author mashibing */public class tanknewmsg implements msg int msgtype = msg.tank_new_msg;tank tank;tankclient tc;/* * 根据tank的信息构建消息 * param tank */public tanknewmsg(tank tank) this.tank = tank;/* * 根据消息产生的场所构建新的消息 * param tc */public tanknewmsg(tankclient tc) this.tc = tc;/* * 发送相关的消息 * param ds 通
45、过该socket发送数据 param ip 数据的目标ip param udpport 数据的目标端口 */public void send(datagramsocket ds, string ip, int udpport) bytearrayoutputstream baos = new bytearrayoutputstream();dataoutputstream dos = new dataoutputstream(baos);try dos.writeint(msgtype);dos.writeint(tank.id);dos.writeint(tank.x);dos.writei
46、nt(tank.y);dos.writeint(tank.dir.ordinal();dos.writeboolean(tank.good); catch (ioexception e) e.printstacktrace();byte buf = baos.tobytearray();try datagrampacket dp = new datagrampacket(buf, buf.length,new inetsocketaddress(ip, udpport);ds.send(dp); catch (socketexception e) e.printstacktrace(); ca
47、tch (ioexception e) e.printstacktrace();/* * 分析接收到的消息数据 param dis 接收到的消息数据的输入流 */public void parse(datainputstream dis) try int id = dis.readint();if (tc.mytank.id = id) return;int x = dis.readint();int y = dis.readint();dir dir = dir.values()dis.readint();boolean good = dis.readboolean();boolean exist = false;for (int i = 0; i < tc.tanks.size(); i+) tank t = tc.tanks.get(i);if (t.id = id) exist = true;break;if (!exist) tanknewmsg tnmsg = new tanknewmsg(tc.mytank);tc.nc.send(tnmsg);tank t = ne
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025网站会员服务合同样本
- 2025技术咨询服务合同范本3
- 个人买房协议书
- 2025珠海市商业室内装饰装修合同范本
- 2025版机械设备购销合同范本
- 婚内酗酒协议书模板
- 2025年03月新疆吐鲁番市引进各类人才489人笔试历年典型考题(历年真题考点)解题思路附带答案详解
- Unit 11 Rules Matters 第三课时Developing the Topic(含答案)仁爱版2024七下英语日清限时练
- 2025年03月宿城区事业单位统一工作人员5人笔试历年典型考题(历年真题考点)解题思路附带答案详解
- 济宁职业技术学院《语言艺术与写作》2023-2024学年第二学期期末试卷
- 监测与控制节能工程
- 麻醉学课件:多器官功能障碍综合征
- GB/T 16150-1995农药粉剂、可湿性粉剂细度测定方法
- GA/T 1198-2014法庭科学尸体检验照相规范
- 员工自主报告和举报事故隐患奖励汇总表
- 六年级数学期中考试成绩质量分析课件
- KET词汇表(英文中文完整版)
- 新老物业移交表格(全套)
- 东风汽车公司作业成本法实施案例
- 五子棋入门教程ppt
- 病人自杀后的应急预案与流程
评论
0/150
提交评论