当前位置:首页 > 免费毕业设计

JAVA泡泡堂网络游戏的设计与实现(源代码+LW)

JAVA泡泡堂网络游戏的设计与实现(源代码+LW)

  • 网站价格: 2
  • 特殊技术: java
  • 作品类型: 免费毕设
  • 售后服务:

联系方式: 微信:biyebang QQ: 629001810

作品详情

   要

网络游戏开发是一项很大的工程,需要很多综合性的知识。这对于刚刚入门的开发者来说很难理解。本论文从研究开发一个模仿泡泡堂网络游戏的例子出发,讲述网络游戏开发中用到的一些最基本的知识和设计思想,使大家清晰的理解游戏开发的过程。

整个设计中利用java中的swing编程,结合游戏的操作流程,对整个游戏进行精心的设计和大量的测试,实现游戏软件服务器端和客户端的开发,为玩家提供一个友好美观的操作界面,并添加聊天等功能以增加玩家之间的互动性,此外实现了可编辑场景地图的功能,使得游戏内容的更加丰富,玩家交互性更好,确保了游戏更具有趣味性、灵活性,以满足玩家对这款网络游戏的要求。

目录

 

系统设计


本设计主要是实现一个类似于“泡泡堂”功能的网络游戏。其操作流程及其主要功能如下介绍

游戏的操作流程

游戏的操作类似于网络游戏QQ堂。其操作流程如图1所示。

1. 首先要先运行服务器端,来处理各个客户端发来的请求。

2. 玩家运行客户端,首先展现一个版权声明的界面,因为游戏中的图片来源于腾迅公司的QQ堂游戏,图片的版权归腾迅公司所有。

3. 几秒后自动跳到登录界面。在这里输入用户名称,密码。因系统中没有对数据库进行操作,并没有保存用户的相关信息,所以没有注册的功能,也没有对密码的正确与否进行验证。输入密码后点击登录进入游戏大厅,退出则关闭程序。

4. 进入大厅后,用户可以选择自己的角色,蓝队或者红队,并可以进行聊天对话。点击准备时将进入准备状态。当所有用户都进入准备状态,游戏自动进入对战场地进行对战游戏。

5. 在对战时,玩家可以用方向键盘控制人物的移动,人物只能在空地中移动,当遇到“箱子”时,可以使用“空格键”放置“泡泡”,利用“泡泡”的爆炸的威力去破坏周围的障碍物(“仙人掌”不能被破坏掉)。同时可以一连串放置多个“泡泡”,放置“泡泡”后,“泡泡”将持续几秒钟才会爆炸,在这段时间玩家可以放置更多的“泡泡”来攻击对手,在运动过程中还要及时躲开“泡泡”的爆炸区域。当玩家被“泡泡”炸中,则该玩家的生命将结束,不能继续进行游戏

6. 当有一个队中的所有玩家都死掉,则该队挑战失败,对方获胜。

 

应该解决的问题

本程序需要解决的主要问题:

1.游戏程序是一项精度要求很高的程序系统,因为其代码利用率很高。一个实时运行的最终作品,每秒都会运行成千上万行程序,绘图事件、键盘事件都会以极高的频率在后台等待响应,若有丝毫的差别都将很容易导致程序在运行不久后可能出现严重错误,甚至死循环。因此,其逻辑设计应当相当严谨,需将所有可能发生的事件及意外情况考虑在设计中。

2.网络计算机之间的数据通讯:用socket进行编程,同时由于对人同时游戏,要尽量减少网络数据的传输量,提高传输效率,防止堵塞。

3.算法的设计:算法是游戏的核心,要设计很好的算法,提高游戏运行的效率,运行速度要高,并且资源占用的要少。

4.线程的控制:由于涉及到对个玩家,并且要即时的将数据进行网络传输,因此可以用多个线程来并发执行这些操作。线程之间的同步和调度上要很好的控制。

5.双缓存:在图片之间相互调用转换时,图像的画面要流畅,不能有停顿和闪烁

6.游戏中为了美观,适用性强,可能需要采用外部文件引入的图片贴图,有关贴图,这里使用了QQ堂游戏里的一些截图来美化界面,同时对解决静态或动态、画面背景、屏幕刷新的双缓冲等都有较好的解决方案。

以上相关技术细节和整体流程将分别在以下小节阐述。

1   系统设计

本游戏开发采用C/S结构,分为服务器端和客户端两部分。

处理流程

服务器端主要处理各个客户端发过来的消息(Message),并根据消息的类型,对消息进行不同的处理,然后将处理后的消息转发或者直接转发消息到所有玩家。

客户端则监听用户的输入动作,包括键盘和鼠标动作,对于不同的动作做不同的处理,并根据玩家动作的类型,把所有信息封装为一个消息的实体(Message),然后发到服务器端。同时要监听服务器端的回复过来的消息当收到一个新的消息,将对消息进行解析,根据消息的类型作不同的处理,从而改变游戏场景或者状态等。处理流程如图2所示。

 

数据流

在整个系统中,客户端和服务器端所有的信息都是通过一个封装的Message来传输的,它们的传输数据流如图3所示(这里以一次通讯为例)

 

当一个客户端把玩家的动作封装为一个的消息,之后发送到服务器端。服务器端接收到该消息,并对该消息进行解析处理。然后将处理过的消息转发给当前的所有客户端,包括消息的发出者。客户端收到该消息,根据消息的类型来解析,然后处理并改变当前的场景。

部署方案


因为游戏为一个网络游戏,要多个玩家同时参加互动。所有程序有服务器端和客户端两部分。它们部署图如图4所示:

 

服务器端部署服务器端程序,负责保存当前玩家的信息,对客户端发过来的消息进行处理并转发等。客户端只需要部署客户端程序,负责发送消息并处理游戏主要逻辑。

1   系统实现

代码结构

 

客户端

首先在程序中定义了几个通用的组件和方法:CenterShowDialog, GameImage.java, ImageButton.java ,ImageLabel.java 和ImagePanel.java

CenterShowDialog:这个类的功能是使显示的图形界面居中。

ImagePanel:定义一个背景为一个image的画板(panel)

GameImage:这里定义了一些对图片操作的类,如创建一个图片等。

ImageButton:定义一个图片按钮(JButton)

ImageLabel:定义一个图片的标签

这些通用的组件和方法供各个模块所公用。一些场景的设置是在它们的基础上进行搭建的。

模块设计

如图7所示,游戏客户端总体分为4个大的模块:游戏入口,登陆,游戏大厅,和对战场地。

以下对具体模块的设计进行详细介绍。

游戏入口模块

主要类:Game.java   

描述:显示一个无标题栏的窗口,提示一些版权信息,如图8所示。

首先在它的构造方法中初始化该JFrame的相关属性。在main方法中,先声明一个Game类,创建声明窗口。之后调用Util方法中的showWindow()方法,显示该窗口的动态展开,产生一个动画的效果。窗口将停顿5秒,以便玩家有足够的时间来阅读相关内容。最后调用Util方法中的closeWindow()方法来动态地收缩关闭该窗口。随后创建一个Login类,并将其显示,进入登录模块,同时隐藏该声明信息窗口。

系统实现

登陆模块

主要类:Login.java

描述:显示登陆界面(效果请参考图9),并处理相关的鼠标动作,输入玩家名称,密码等,登陆后和服务器建立连接,并发送信息到服务器。(因为不设计到数据库,这里并没有对玩家输入的相关信息进行验证,也没有注册玩家信息的功能)

因设计到对一些组件的监听,并对鼠标事件进行监听,该类实现了相关方法:

public class Login extends JFrame implements  ActionListener , mouseMotionListener

构造方法调用init()方法对类进行初始化,这里主要是创建了两个ImageButton : login_bt 和exit_bt,两个文本框:user和password,设置它们被显示的位置和样式,同时为两个ImageButton增加鼠标监听事件。当鼠标点击login_bt时,将触发一个事件,捕捉该事件,并进行处理。

处理过程:从user和password两个文本框得到玩家输入的信息,把这些信息作为属性值赋值给一个新的Message 实体。创建一个和服务器的新的连接,把这个message发送到服务器段。之后创建一个GameHall: new GameHall(msg,in,out);

游戏大厅模块

主要类:GameHall.java

描述:游戏大厅的主界面,同时负责处理玩家一些鼠标事件,并和服务器进行通讯,发送/接受消息。当鼠标触发一些事件时候,对事件的内容进行解析,然后根据不同的事件,创建不同类型的消息,把相关的必要的信息进行封装,最后发给服务器。由服务器进行处理后,服务器发送消息给所有客户端,客户端接收到消息,并对接收到的消息进行处理,来改变大厅场景。

该类中设计到对整个大厅中鼠标和键盘事件的监听,并创建一个主的线程来监听从服务器端发来的消息。因此该类实现了MouseListener,  MouseMotionListener,Runnable,KeyListener等接口。

构造方法中调用了init()方法 。初始化大厅用到的一些组件。整个大厅是一个ImagePanel,一个画布。所有的组件都是在这个画布上增加。并为这些组件增加一个监听器来监听它们的动作。之后程序启动主线程,对服务器发来的消息进行监听,并在解析后作出相应的动作。

thread=new Thread(this);

thread.start();

当受到一个消息时,根据消息的类型,作出不同的动作。最后调用paint()方法来刷新主画布从而改变场景。调用paint()方法时,首先把所要玩家都移除,然后重新画整个场景:

removeAllPlayer()

for(Enumeratione=htPlayer.elements();e.hasMoreElements();){

Message msg=(Message)e.nextElement();

showPlayer(msg);

}

其中的showPlayer()方发中是根据玩家不同的编号(number)和小组(team)来把玩家的图片画到画布的不同位置。并判断该玩家现在的准备情况,如果准备好了就显示准备状态。

游戏大厅中主要实现了小组的选择,聊天功能,准备和取消准备等功能。

Ø 小组的选择:

游戏中的小组分为“蓝队”和“红队”,它们的选择图标都是一个ImageButton。当有鼠标点击它们的动作时,将触发一个鼠标点击事件,这时鼠标监听器将捕捉到该动作。然后创建一个新的消息,把玩家的一些信息赋值给该消息,同时设置消息的类别为“更换小组”,最后发送消息.这里以选择蓝队为例:

Message test=new Message();

test.team=GameKey.TEAM_BLUE;

test.type=GameKey.MESSAGE_TYPE_CHANGE_TEAM;

test.number=meMessage.number;

test.UserName=meMessage.UserName;

Util.printMessage("SelectTeam ",test);

当客户端收到Type为GameKey.MESSAGE_TYPE_CHANGE_TEAM(数值为5)的消息时,从保存的所有玩家的信息中得到状态改变的该玩家,并更换它的TEAM,之后还放到HashTable中。

              for(Enumeration e=htPlayer.elements();e.hasMoreElements();){

                   Message test=(Message)e.nextElement();

                   if(test.number==msg.number){

                       test.team=msg.team;

                       htPlayer.put(Integer.toString(test.number),test);

                   }

                }

最后要调用paint()方法来重新刷新该画布,改变场景,使该玩家的颜色显示和选择小组颜色一致。  

Ø 聊天功能:

原理和小组选择相似,首先玩家在文本框中输入要发送的消息内容,当点击“发送”的图片按钮时,触发一个鼠标动作。监视器拦截该动作,并得到输入文本框中的信息,把它封装到一个消息里面Message。最后发往服务器 。服务器端只是把消息进行转发给所有玩家。玩家的客户端收到消息后,判断该消息的类型,如果是聊天消息,将聊天的内容提取,然后显示在聊天信息板里面。

Ø 准备/取消准备功能:

点击准备图片按钮,触发一个事件,然后封装生成一个消息发送到服务器,服务器转发。客户端收到消息后把该玩家的状态改为“准备”。之后判断是否所有玩家都已经准备好,如果都准备好,把全局变量Ready的数值设置为“OK”,然后在主线程里判断这个值从而得到是否所有玩家都已经准备好。都准备好的话就创建一个新的窗口进入对战区。

对战场地模块

主要类:QQPad.java

描述:这个类为游戏大厅的画布,同时处理对战时的主要逻辑,是整个游戏的核心。负责处理了玩家移动,泡泡的放置及引爆,障碍物的清除和胜负判断等多个功能。

当玩家进入大厅时,程序首先要初始化场景,包括对地图和玩家位置的初始化,并为场景增加监听器监听玩家键盘和鼠标的动作,之后启动一个主线程。该线程负责处理玩家的鼠标和键盘动作,并对从服务器端接收到的消息进行处理,从而改变当前的场景。当有一个小组的全部玩家都被消灭后,就判断胜负并显示结果,这次对战就结束,返回到游戏大厅。整体流程如图10所示。

 

 

以下将对几个主要的流程作详细的介绍。

Ø 地图的生成

地图是每个游戏必需的一个元素,地图主要是生成游戏的场景,然后在画布上显示该场景。在开发很多类型的游戏中,地图系统都需要良好的设计,直观的说,我们需要的地图系统仅仅是一个2D数组,然后用最快的方式将数组影射到屏幕上。

地图的设计方式有很多,大多数2D游戏是通过开发的地图编辑器来实现的。而该游戏的设计是首先定义一个地图文件,这个地图文件是用一些0,1等数字表示一种物体。然后在用流对该文件进行读取,把内容读取到一个数组里面。不同的数字就会在场景中显示出不同的物体。

程序中首先在map文件夹下定义好一个“map1.txt”文件,该文件是由0,1,2三种数字组成:

111110010011111

111000210100111

110012201010011

100010010101001

101121101010100

002011010101011

022010101010220

110101010110200

001010101121101

100101010010001

110010102210011

111001012000111

111110010011111

其中,0在场景中显示的是一个空地,1显示的是一个箱子,2显示为一个植物。之后通过流将数据读取到一个数组里面:

while(true){

            String line=reader.readLine();

            if(line==null){

                reader.close();

                break;

            }

            //过滤掉#开头的行

            if(!line.startsWith("#")){

                line=line.trim();

                lines.add(line);

                width=Math.max(width,line.length());

            }

        }

height=lines.size();

        //对数组赋值

        for(int i=0;i<height;i++){

            String line=(String)lines.get(i);

            for(int j=0;j<line.length();j++){

                int c=(int)line.charAt(j);

                c=c-48;                            //把ASC码转化成数字

                map[j][i]=c;

            }

        }

根据初始化好的数组,对数组中每一个元素的值,将显示不同的物体,从而实现地图的初始化。上例中地图数组最终显示到画布中的场景如图11所示:

 

Ø 初始化场景:

初始化场景主要是初始化场景中使用到的图片,玩家的位置,为场景中的相关组件增加监听器等。对于玩家的位置的初始化,这里先判断玩家的编号,每个编号对应一个不同的位置。而显示玩家时,是通过地图中的数据来显示的。每一个地图代码代表不同的玩家状态。地图中的一个格子是一个数据,拿map[m][n]=1322 为例, 这个数据“1322”它们组成为: 小组编号+当前朝向+X轴方向的格子数+Y轴方向的格子数。其中小组和朝向的代码制定如下:

玩家的小组: 1 -> 蓝队;2 -> 红队

朝向:1 ->朝北; 2 -> 朝东; 3 -> 朝南; 4 -> 朝西

最后根据该数值,来最终决定该玩家的当前的状态,根据状态中的位置朝向等信息,在场景中显示相应的图片来创造当前状态下玩家的实体。

Ø 玩家移动

对战过程处理流程的原理和大厅相似,不过很多是对键盘的监听。当按下键盘的方向键的时候,监听器将捕获该动作,然后将该动作的信息封装为一个消息,在服务器端再对消息进行转发给所有玩家。玩家收到消息,对消息进行解析,得用户的操作,然后改变玩家对应单元格的代码,之后刷新整个画布,玩家的位置将做出变化。其中在移动玩家的时候,要先判断前方是否有障碍物或者是否已经到达了边界,是的话将不能进行移动。

Ø 泡泡处理

泡泡的显示也是用一个数组坐标来表示,不过这个是另外建了一个新的数组map2[][],它的大小和场景坐标一样,但是状态只有两种:放置的泡泡和爆炸中的泡泡。

当玩家按下空格建,将会把玩家当前位置出放置一个泡泡,即把map2中的对应状态改为“8”。放置泡泡的时候,其实建立了一个泡泡的线程,为这个泡泡设置位置,然后就启动该线程,当停顿4妙后,将把这个泡泡给引爆。

pad.setBomb(m,n);

                sleep(sleepTime);//sleepTime=4s

                pad.Bombing(m,n,power);

                sleep(500);

                pad.cleanBomb();

                sleep(1000);

                pad.cleanPlayer();

引爆时调用了Bombing方法。该方法主要是根据泡泡的威力,把在爆炸范围内的箱子或者玩家给清除。也就是改变坐标的代码。首先要显示一个爆炸时候的图片,之后清楚相关的物体。

for(inti=m;i<=m+power;i++){   //向右

            if(i>=15){

                break;

            }

            if(map[i][n]==2){

                break;

            }

            if(map[i][n]==0){

                map[i][n]=88;

            }

            if(map[i][n]==1){

                map[i][n]=88;

                break;

            }

            ……

}

泡泡的爆炸场景显示持续半秒后,将把爆炸范围内的物体(植物除外)的值设置为0,这样在下次刷新场景时将清理被炸掉的物体。

Ø 结束判断:

在每次泡泡爆炸后,都要进行一次判断,首先要判断是否有玩家被炸到,如果有就将该玩家的状态设置为’DEAD’,然后判断整个小组是否所有成员都已经dead掉,如果是,则认定该组失败,而对方获胜。游戏结束。

if(myLive==0 &&blue_team_alive==true && red_team_alive == true){

            g.drawImage(deathImg,84,140,this);

        }

        if(myTeam==1){

            if(!blue_team_alive){

                g.drawImage(lossImg,84,140,this);

            }

            if(!red_team_alive){

                g.drawImage(winImg,84,140,this);

            }

        }

        if(myTeam==-1){

            if(!red_team_alive){

                g.drawImage(lossImg,84,140,this);

            }

            if(!blue_team_alive){

                g.drawImage(winImg,84,140,this);

            }

        }


源文件


帮我毕业网微信

版权所有© 帮我毕业网 并保留所有权利

QQ 1370405256 微信 biyebang

QQ:629001810微信:biyebang

收缩