基于Linux的坦克大战游戏程序的开发学生姓名:王浩指导老师:侯利娟摘要本课程设计主要是在linux操作系统上用java语言和Eclipse开发小游戏,并设置Linux为游戏服务器为游戏服务。
关键字 Java;Eclipse;游戏服务器;命令行本设计采用分层思想,分为客户端,服务端,其中客户端分为网络连接,消息处理,具体传输底层交给Netclient.java实现。
窗口画面的显示,是以线程每隔0.1s刷新画面上的信息,所以坦克客服端只要改变坦克相关信息的坐标,就能实现动态画面。
客户端保存所有其他客服端的坦克信息,子弹信息,当接收到消息时及时更新自己本地保存的信息,并发送相应的匹配结果信息。
服务端得到客户端的tcp连接后,分配给客户一个ID后,并保存客户端信息,当再次收到客户端的udp数据包后,服务端就转发给其他所有客户端,从而实现网络对战。
Tank每产生一个数据包经过自己的客户端的NetClient转换成数据包发给服务器,同时,NetClient收到数据包后,读取数据包第一个字段,从而辨别数据包是6种tank 信息的其中一种,交给客服端更新信息。
游戏中的墙壁实现原理:定义一个小方块,在不同的坐标画出小方块,这样就可以利用小方块,画出各种图案,每个方块有个存活状态控制信息,只有为活着时,才可以被画笔(paint())调用。
目录1 课程设计目的与要求 (1)1.1 课程设计的意义 (1)1.2 课程设计的目的 (1)1.3 Linux游戏服务器简介 (1)2 部署Linux开发游戏的资源 (2)2.1 启动vsftp服务器 (2)2.2 上传资源 (3)2.3 安装资源 (4)3 游戏开发与调试 (5)3.1 TankWar客服端开发 (5)3.2 TankWar服务器端开发 (8)3.3 TankWar负责网络传输分析 (10)3.4 TankWar传递消息分析 (11)3.5 TankWar运行和调试 (14)5 结束语 (18)参考文献 (19)附录:源程序清单 (20)1 课程设计目的与要求1.1 课程设计的意义Linux操作系统近几年有了蓬勃的发展,在整个世界范围内得到了越来越多公司和团体的支持,尤其是最近IBM公司的鼎力支持,更是使Linux服务器如虎添翼,更上一层楼。
而在国内,Linux的应用也是方兴未艾,众多公司已经投入到Linux系统的研发和推广工作中。
一些优秀的Linux操作系统相继出现,比如红旗Linux等。
Linux服务器已每年惊人的数字增长。
据科学调查Linux服务器在全球所占的比例达到98%。
1.2 课程设计的目的巩固和运用所学课程,理论联系实际,提高分析、解决计算机技术实际问题的独立工作能力。
通过该课程设计的学习,总结Linux网络系统课程的学习内容,利用Eclipse 开发Java游戏,从而巩固课堂知识、深化学习内容、完成教学大纲要求,学好计算机科学与技术专业的专业基础课,从而更深刻的理解网络操作系统。
1.3 Linux游戏服务器简介在高端服务器操作系统领域,随着开源软件在世界范围内影响力日益增强,Linux 服务器操作系统在整个服务器操作系统市场格局中占据了越来越多的市场份额,并且形成了大规模市场应用的局面。
Linux引起了全球IT产业的高度关注,并以强劲的势头成为服务器操作系统领域中的中坚力量。
目前国外服务器厂商使用的服务器操作系统主要包括SUN的SOLARIS、IBM的AIX、HP的HP-UX,其中UNIX系列的产品几乎占据了大部分服务器高端市场和部分服务器中低端市场,WINDOWS 系列占据了较大部分服务器中低端市场,LINUX由于其成本优势在中低端市场也有良好的表现,并且市场份额上升幅度很大。
目前国内的服务器操作系统情况基本类似于国外,高端服务器操作系统市场基本为UNIX平台所占据,由于国内中低端服务器的市场保有量较大,所以WINDOWS系列产品的实际市场占有率相对较国外高,约占40%,LINUX由于低成本的特点,也取得了大约35%的市场份额。
2 部署Linux开发游戏的资源2.1 启动vsftp服务器配置vsftp如图2.1),启动Linux下vsftp服务器(如图2.2)。
图2.1 修改vsftp 服务器配置文件图2.2 vsftp 服务器启动图2.3 设置vsftp 服务器自动启动2.2 上传资源向linux服务器上传资源,和及时更新服务器资源(如图2.5)。
图2.4连接vsftp服务器图2.5向linux服务器传输资源2.3 安装资源安装java虚拟机,使java程序能够正常运行(如图2.5)。
图2.5安装java虚拟机图2.5 java虚拟机安装完毕3 游戏开发与调试3.1 TankWar客服端开发客服端运行开始时,先以TCP传输方式向服务器请求建立连接。
得到服务器确认后,确认自己从服务器分配的ID。
然后以UDP传输方式传输坦克的各信息。
客服端利用容器List保存服务器发来的其他坦克客服端信息。
再从List中取出各信息来和自己比较。
比向服务器传递比较消息。
这里采用分层思想,具体传输底层交给Netclient.java实现。
窗口画面的显示,是以线程每隔0.1s刷新画面上的信息,所以坦克客服端只要改变坦克相关信息的坐标,就能实现动态画面。
图3.1 客户端数据流①坦克建立消息②坦克产生一个子弹消息③子弹死去消息④坦克死去消息⑤坦克移动消息⑥墙壁死去消息当服务端NetClient接收到数据包时会读取数据包第一个字段,从而知道消息类型,交给相应实现消息接口的消息解析器。
得到消息所有信息后,更新本地内容,从而画笔(paint())刷新画面时,内容已改变。
public void paint(Graphics g){//每当刷新一次运行下面内容Color c = g.getColor();g.setColor(Color.red);g.drawString("炮弹数目: "+missiles.size(), 20, 55);g.drawString("爆炸数目: "+baozaos.size(), 20, 70);g.drawString("LINUX课程设计",20,40);g.drawString("感谢侯利娟老师2年来的无私奉献!!",300,40);g.setColor(c);for(int i =0;i<baozaos.size();i++){//监听坦克死去发生爆炸Explode baozao = baozaos.get(i);baozao.drawExplode(g);}myTank.DrawTank(g);//画主机坦克for(int i = 0; i < enemyTank.size();i++){//画敌人坦克this.enemyTank.get(i).DrawTank(g);}for(int i = 0; i < missiles.size();i++){//画所有子弹Missile m = missiles.get(i);m.hitTanks(enemyTank);if(m.tankId != myTank.ID){if(m.hitTank(myTank)){//判断子弹是不是击中坦克Msg tankdead = new TankDeadMsg(this.myTank.ID);//产生一个坦克死去消息Msg Missiledead = new MissileDeadMsg(m.tankId,m.ID);//产生一个子弹死去消息this.nc.send(Missiledead);//发送子弹死去消息this.nc.send(tankdead);//发送坦克死去消息}}m.drawMissile(g);//调用画子弹方法}for(int i = 0;i<linuxs.size();i++){//判断子弹击中墙壁并出现墙壁损失Linux l = linuxs.get(i);for(int j = 0;j<this.missiles.size();j++)if(l.hitMissile(missiles.get(j))){//判断子弹击中墙壁Msg Missiledead = new MissileDeadMsg(this.myTank.ID,missiles.get(j).ID);Msg lm = new LinuxMsg(l.id,l.x,l.y,l.live);this.nc.send(Missiledead);//发生子弹死去消息this.nc.send(lm);//发生墙壁损失}if(l.live){l.drawLinux(g);//画出还剩下墙壁}}}3.2 TankWar服务器端开发TankWar服务器端接受客服端以TCP传输方式传来的建立请求,分配给客服端一个ID号,保存客服端的信息。
当服务端以线程方式接受到从客服端以UDP方式发来的数据包时,服务端就转发给各客服端。
服务器只转发数据包,不做任何修改。
图3.2 tcp和udp连接①建立tcp请求连接②分配客户ID③客户向服务器发送UDP数据包④服务器转发数据包图3.3 服务器数据流图List<Client> udp_clients = new ArrayList<Client>();//存储客户private class UDPRecvThread implements Runnable{//接收客户的UDP 数据包,并转发进程byte[] buf = new byte[1024];public void run() {DatagramSocket dgs = null;//UDP服务端try {dgs = new DatagramSocket(UDP_PORT);} catch (SocketException e) {e.printStackTrace();}while(dgs != null){DatagramPacket dp = new DatagramPacket(buf,buf.length);try {dgs.receive(dp);System.out.println("数据包字符长度为:"+buf.length);System.out.println("一个数据包接受成功"+" potr:"+UDP_PORT);for(int i = 0; i < udp_clients.size();i++){dp.setSocketAddress(newInetSocketAddress(udp_clients.get(i).IP,udp_clients.get(i).udp_ port));dgs.send(dp);System.out.println("数据包转发成功"+ i+"号"+udp_clients.size());}} catch (IOException e) {e.printStackTrace();}}}}}3.3 TankWar负责网络传输分析NetClient.java实现网络底层的传输,定义TCP,UDP传输,客服端经过这里封装和发出数据包(数据包的封装交给实现msg.java接口给消息类),当服务器发来消息是,先在这里经过处理再交给客服端。