- 零基础学Java项目开发
- 聚慕课教育研发中心编著
- 3014字
- 2022-07-28 18:41:36
4.3 系统功能技术实现
本节根据对系统的需求分析,对坦克大战游戏的各功能界面进行详细的描述与实现。
4.3.1 面板功能设计
面板功能的设计包括对基地、敌方坦克、河道和草坪、普通墙与钢墙的设计及对界面窗口的创建。
1.基地的设计
Base类定义了几个变量,通过构造器初始化基地的变量参数,使用g.drawImage( )方法设置一幅图片来代表基地,通过public void move( )来处理基地受到钢墙防护时的变化,使用if条件语句判断钢墙的保护时间。该游戏的核心重点自然就是基地,一旦基地被毁,则玩家失败,游戏结束。游戏面板是游戏程序的关键,这里使用了方法paintComponent(Graphics g)来进行建立并设置其属性。具体实现代码如下:
2.敌方坦克的设计
Enemy类设置了敌方坦克的共同属性,并根据不同外形的坦克设置了不同的属性,如椭圆形坦克的移动速度会比较快,拥有多层颜色坦克的生命力与其拥有的颜色数量相吻合。利用随机函数Math.random( )*4随机生成一个随机值,并转换成整型数值,将此值赋予变量direction作为敌方坦克生成时的方向,再将Math.random( )*200生成的随机值转换成整型数值,赋予变量interval作为生成时的时间间隔,并且设置了敌方坦克的移动周期,在一个周期内将会朝着相同的方向继续移动,还设置了其发射弹药的时间间隔。而在特殊属性中,分别设置敌方坦克的火力、速度、图标等属性,再使用方法draw(Graphics g)向地图中加入敌方坦克。具体实现代码如下:
3.河道和草坪的设计
Grass类继承了Actor接口,通过Grass类构造器定义草坪的x轴、y轴坐标和矩形边界及图标,并通过public void draw(Graphics g)方法绘制草坪。游戏双方坦克及其弹药可以自由通过草坪。具体实现代码如下:
River类继承了Actor接口,用River类构造器定义河道的x轴、y轴坐标和矩形边界及图标,用g.drawImage(Image,int,int,ImageObserver)方法设置一幅图片来代表河道。以前各个经典版本的坦克大战游戏都将河道设置为不允许坦克经过,但弹药可以自由通过,本程序为了遵循经典,也如此设计。具体实现代码如下:
4.普通墙与钢墙的设计
该模块通过new Rectangle(int x,int y,int width,int height)完成了一个矩形的创建,然后将其具体值赋予变量数组border[数组索引]生成墙。坐标x和y为绘制矩形时的起始点,width和height分别为矩形的宽和高。通过构造器定义普通墙和钢墙的矩形边界及图标。具体实现代码如下:
5.界面窗口的创建
在该模块中,在ServerView类的构造器中用super( )方法调用父类构造器设置窗口标题为“坦克大战”,使用JButton(String)定义退出、帮助、发送、暂停/继续、建立主机和隐藏6个鼠标单击事件(即所谓的按钮),用JTextField定义文本框并将其设置为不可编辑。使用new drawingPanel( )和setBackground(Color c)创建一个面板并设置背景颜色,再通过setBounds( )和setLayout( )方法定义界面的大小并将界面布局定义为空,并通过add( )方法向界面添加按钮和文本框。使用setColor(Color c)方法设置面板颜色为指定颜色,再通过继承自java.awt.Graphics类中的drawString(String,int,int)方法向面板添加并输出当前关数及剩余敌人数,通过if条件语句进行判断,如果消灭坦克数量大于敌方坦克数量则输出胜利场景。
4.3.2 弹药功能设计
该模块用setColor( )方法设置弹药颜色为浅灰色,使用g.fillRect(int,int,int,int)方法设置弹药水平或垂直发射时的形状,弹药与什么物体相交通过if条件语句和equals( )方法来鉴定,然后处理相交时弹药和其他对象的属性变化。具体实现代码如下:
4.3.3 坦克功能设计
坦克销毁了什么特殊武器图标通过if语句和equals( )方法来鉴定,如果销毁TNT图标,则已经出现的敌方坦克全部被炸毁;如果销毁掉坦克图标,玩家坦克加一条生命;如果销毁掉五角星图标,则提升玩家坦克弹药火力并且速度加快,可以打破钢墙;若是头盔图标,则玩家坦克获得防护盾并且“免疫”敌方弹药;如果销毁掉钢墙图标,则基地由普通墙变为钢墙,如果销毁掉钟表图标,则时间停止,所有敌方坦克静止。具体实现代码如下:
4.3.4 服务器设计
服务器的设计包括对ServerModel类、FeedbackHandler类及其他各类的设计。
1.ServerModel类的设计
在ServerModel类中实现了ActionListener接口,具备监听功能,然后创建一些连接变量和游戏变量的方法,设置布尔类型的服务器状态变量,使用构造器完成消息队列信息的设置;使用createServer( )方法建立主机,当布尔变量serverCreated的值为true时,主机创建成功,还设置了一个端口号,用try…catch语句处理代码执行时发生的异常,并给出错误提示;服务器通过accept( )方法与客户端建立连接,当端口号没有被其他应用程序占用且IP地址正确时,则成功完成连接,载入游戏,否则就会显示相应的错误提示。使用addMessage( )方法在屏幕上显示消息,使用removeMessage( )方法删除屏幕上的消息,通过addActor( )方法和remove( )方法完成了向地图中增添新的物体对象和清除已经不存在物体对象的操作。具体实现代码如下:
2.FeedbackHandler类的设计
FeedbackHandler类从客户端程序解码指令字符串,然后将字符串转换为真正的指令。通过while(!instruction.substring(i,i+1).equals("?"))语句判断其指令,并根据其指令来完成相对性的操作。
3.其他各类的设计
Lever类设置了不同的关卡,通过if(1+ (currentLevel-1)%8 == num)判断语句来加入关卡。在进入下一关卡时,上一个关卡的所有东西都会被系统清理,并且增加了游戏难度,同时还设置了胜利场景。
Player类通过构造器设置了玩家坦克的生命数量、生成时的方向和无敌时间,以及健康状态、弹药数量等。通过if(type.equals("1P"))语句来判断两个玩家并设置其坦克的初始位置,用drawImage( )方法绘制玩家坦克。当玩家敲击开火键时,会用if语句判断是否满足条件,若满足就会生成一包弹药,并且弹药的位置、速度等属性参数都会被设置好,再通过add( )方法添加弹药。在坦克的下一个移动有效的前提下,根据玩家坦克的移动定义玩家坦克的下一个边界,并判断是否与地图边界和其他物体对象相交,设置相交时坦克与物体对象会发生的变化情况。当玩家坦克被击毁时,其生命减少。使用reset( )方法将玩家坦克路径重置为空,遗弃所有坐标和点类型,设置其位置为游戏开始时的位置。
在powerUp类中实现了对玩家坦克弹药火力的增加。Ticker类运用构造器建立时间发生器,实现了runnable接口,并调用了其run( )方法。
ServerControler类处理来自服务器端视图框架的输入,实现了玩家消息互通功能。使用构造器view.buttonName.addActionListener( )方法完成按钮功能的设计。使用addKeyListener (new KeyAdapter( ))方法增加键盘输入的操作,再通过keyPressed(KeyEvent e)方法来实现,通过if(e.getKeyCode( ) == KeyEvent.VK_UP)语句来判断并执行相应的方向移动操作,通过if(e.getKeyChar( ) == 's')判断并执行“s”键的操作,if(e.getKeyCode( )==e.VK_ENTER)判断是否单击Enter键,再通过if(e.getKeyChar( ) ==?)来判断输入什么键并执行相应的操作。通过keyReleased(KeyEvent e)方法来释放给定的键。具体实现代码如下:
4.3.5 客户端设计
客户端的设计包括对ClientModel类、InstructionHandler类及其他各类的设计。
1.ClientModel类的设计
在ClientModel类中实现了ActionListener接口,具备监听功能,然后创建一些连接变量和游戏变量,并设置布尔类型的客户端状态变量,使用构造器完成消息队列信息的设置,用try…catch语句处理代码执行时发生的异常,给出错误提示;使用add( )方法向地图中添加对象。客户端程序实际上不执行任何逻辑计算,它只接收指令,将指令字符串做出的反馈告知客户端。具体实现代码如下:
public void connectServer(){ addMessage("正在连接主机"); try{ serverIP = view.IPfield.getText(); InetAddress addr = InetAddress.getByName(serverIP); clientSocket = new Socket(addr, 4321); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); }catch(Exceptione){ t.stop(); System.out.println(e); addMessage("连接出现错误,请确认1.输入的IP是否正确 2.主机端已存在"); return; }
2.InstructionHandler类的设计
InstructionHandler类只有客户端可读,它对从服务器程序反馈的指令字符串进行解码,然后将字符串转换为真正的指令,通过for循环语句和if判断语句等来判断指令,并执行相应的指令动作。具体实现代码如下:
3.其他各类的设计
在Shield类中使用构造器,并实现玩家坦克销毁掉头盔图标后获得防护盾功能,通过draw(Graphics g)方法绘制防护盾,用方法setColor(Color c)设置其颜色,用drawRect( )设置防护盾的x轴、y轴坐标和高度、宽度。当防护盾时间结束时,通过removeActor( )方法去除防护盾。在Level类中,定义游戏正在玩的关数,设置不同的关卡,通过if(1+(levelIndex-1)%8 == num)判断语句来加入关卡。在进入下一关卡时,上一个关卡的所有东西都会被系统清理,并且增加了游戏难度。此类只有一层对象,所以是一个静态变量。NormalObject类代表所有其他对象。ClientControler类功能与ServerControler类相同,都是实现按钮的功能和处理键盘输入的操作。