课程设计小组报告——基于ARM实验箱的捕鱼游戏的设计与实现

课程设计小组报告——基于ARM实验箱的捕鱼游戏的设计与实现

一、任务简介

1.1 任务内容

捕鱼游戏这个项目是一个娱乐性的游戏开发,该游戏可以给人们带来娱乐的同时还可以给人感官上的享受,所以很受人们的欢迎。本次游戏的程序设计包含,java swing组件的合理运用,还有图像的变动达到一个动态的动画效果,线程的运用,游戏的异常处理,等方面的知识。培养学生运用所学知识的基础理论、基本知识和基本技能,分析解决实际问题能力的一个重要环节。它与课堂教学环节彼此配合,相辅相成,在某种程度上是课堂学习的继续、深化和检验。它的实践性和综合性是其它教学环节所不能代替的。课程设计能使学生受到必需的综合训练,在不同程度上提高各种能力。
通过课程设计,使学生熟练掌握Java语言课程中所学的理论知识,通过综合Java语言的基本知识来解决实际问题,加强学生分析和解决问题的能力。

1.2 任务要求

  • 游戏能够通过ARM实验箱实现相应的功能。
  • 具体要求:
    (1) 调整大炮:根据上下按钮来调整大炮的等级;
    (2) 发射炮弹:点击屏幕,来发射一枚炮弹,每发射一枚炮弹会扣除和大炮等级相应的金币数;
    (3) 捕鱼:当炮弹打中一条鱼的时候张网捕鱼;
    (4) 捞金:每当捕捉到一条鱼时,可以获得相应的金币;
    (5) 金币补偿:当金币没有时,每隔3分钟会补充到100金币;
    (6) 在线更新:可以在网上更新下载新的内容。

二、系统设计

2.1游戏设计流程分析

游戏启动后,加载游戏,游戏界面成功打开后可以点击鼠标,控制炮台发射的方向,消耗金币发射子弹,子弹碰到鱼之后会变成渔网,根据代码中设计的算法通过鱼的可击落概率和子弹的威力判断鱼是否被击落(当然,这是随机的),如果没有击杀鱼,鱼继续游动,如果击杀了鱼,会触发被击落程序,鱼会抽到并消失,返回这条鱼该回报的金币。当计时器为0时,如果金币数小于100了,就会将玩家的金币数补到100。只要有足够的金币可以发射炮弹,玩家可以不停的发射炮弹。游戏流程如图:

2.2所有功能实现类(接口)的简介

  • 如下类:
    • main方法在类AwtMainComponet里面,main方法里设置了窗口参数和鼠标监听器。
    • Constant:常量类,里面有游戏中运用到的常量。
    • MainSurface:绘制图层类,图层的绘制就是在该类中实现的。
    • CannonManager:大炮管理器类,大炮的所有属性以及该有的方法。
    • CatchFishManager:捕捉管理器类,类中是鱼的捕捉方法。
    • FishManager:鱼管理器类,类中解析了鱼的配置信息,管理着鱼的动作等信息。
    • GameInitManager:游戏初始化管理器类,类中有游戏的初始化方法。
    • HeadFish:领头鱼类,领头鱼是一种虚拟的鱼,其实就是把一群鱼模拟成一个对象。
    • ImageConfig:图片的配置信息类,类中有图片的细节信息。
    • ImageManager:图片管理器类,根据解析文件获取图片。
    • Bitmap:图片信息类。
    • LayoutManager:布局管理器,在类中有大炮底座类,提高降低大炮按钮,计分板计时板的设计。
    • MusicManager:音乐管理器,管理游戏的背景音乐。
    • ParticleEffectManager:粒子管理器,类中管理游戏的粒子效果。
    • PathManager:鱼路径管理器,类中管理鱼的路径。
    • ScoreManager:得分管理器,类中管理如何得分。
    • ShoalManager:鱼群管理器类,类中管理鱼群的方法。
    • SoundManager:音效管理器,类中管理游戏的音效。
    • Ammo:子弹类,类中管理子弹的属性。
    • AmmoParticleEffect:子弹粒子效果,类中写了子弹粒子效果的实现。
    • BackGround:背景类,类中设计了游戏的背景。
    • FishGold:显示捕捉到鱼后显示的金币数量。
    • FishInfo:某一种鱼的细节配置信息类。
    • FishingNet:鱼网类,类中是渔网的属性和方法。
    • GamingInfo:游戏进行中需要共同用到的一些变量。
    • Gold:金币类,类中是金币的属性和方法。
    • GoldParticleEffect:金币粒子效果,类中是金币的粒子效果属性。
    • HighPoint:高分显示类,当获取高分时游戏的显示。
    • HundredPoint:百分显示,当获取百分时游戏的显示。
    • LoadProgress:加载进度条,类中设计了加载进度条。
    • NetParticleEffect:渔网粒子效果,类中配置渔网粒子效果。
    • WaterRipple:水波纹类,水波纹的属性方法。
    • Bottom:大炮底座类,类中设计大炮的底座。
    • BottomGold:金币显示组件,显示金币。
    • BottomTime:时间显示组件,显示时间。
    • ButtonAdapter:按钮,大炮的按钮属性及方法。
    • Cannon:定义所有大炮的模拟类,设计了发射大炮的动作。
    • ChangeCannonEffect:设计了更换大炮时的变换效果。
    • Componet:组件的父类,有设计组件的坐标的方法。
    • DownCannonButtonListener:降低大炮质量的按钮逻辑。
    • UpCannonButtonListener:提升大炮质量的按钮逻辑。
    • Fish:鱼类,设计鱼的所有属性和方法,如鱼的动作和捕捉方法。
    • Button:按钮的接口,有是否可用和当按钮被点击的方法。
    • Drawable:图片的接口,可获取图片的宽高的方法。
    • OnClickListener:单机事件的接口,单机时的方法。
    • FishRunThread:鱼游动进程,设计了鱼游动的方法。
    • PicActThread:控制鱼的动作的进程,设计了播放了鱼所有动作的方法。
    • ShotThread:射击进程,设计了发射子弹的方法。
    • CircleRectangleIntersect:圆与矩形碰撞检测类(鱼是矩形,网是圆)。
    • Tool:获取目标与源之间的角度,判断击落与否。
      上述的所有类的共同合作才完成了捕鱼达人游戏的开发。

      2.3 功能模块

  • 分别有:鱼的模块,渔网的模块,鱼池的模块,游戏的模块,每一个模块相当于一个类。
    • 鱼模块:主要实现鱼图片的加载,鱼游动效果,鱼游动,还有鱼的一些基本属性,比如鱼的坐标,大小,还有血量值。一些基本方法,鱼的构造方法。
    • 渔网模块:主要实现渔网图片的加载,渔网的属性有坐标,大小的宽和高,还有渔网的power值,渔网中还有一个改变渔网大小的方法。
    • 鱼池模块:将鱼类的对象,网类的对象都在本类中进行调用,并将相应对象的图片显示出来,并将游戏的背景‘画’出来。
    • 游戏启动模块:将游戏图片加载进来。

2.3.1 Fish类

2.3.2 FishNet类

2.3.3 FishPanel类

三、游戏功能的具体实现

3.1 游戏的初始化

3.1.1 游戏启动界面的设计和各类的初始化

  • GameInitManager类中,对游戏的初始化进行了管理,首先判断游戏是否已经初始化过,若没有,则进行初始化。然后初始化进度条画面,实际上就是加载完进度条和背景图片,最后完成了游戏启动界面的初始化。其次,在该类中也对其他组件进行了初始化(界面组件,得分管理器,粒子管理器,大炮管理器,鱼管理器,所有音效,大炮),一个个进行加载。关键代码如下:

    /* 初始化游戏*/
    private void initGame(){
            //初始化界面组件
            this.initComponents();
            //初始化得分管理器
            ScoreManager.getScoreManager().init();
            //初始化粒子管理器
            ParticleEffectManager.getParticleEffectManager();
            LoadProgress.getLoadProgress().setProgress(10);
            //初始化大炮管理器
            CannonManager.getCannonManager().init();
            LoadProgress.getLoadProgress().setProgress(20);
            //初始化鱼管理器
            FishManager.getFishMananger().initFish();
            LoadProgress.getLoadProgress().setProgress(40);     
        …… 
            //初始化音效
            initSound();
            LoadProgress.getLoadProgress().setProgress(90);     
            //初始化大炮
            CannonManager.getCannonManager().initCannon();
            LoadProgress.getLoadProgress().setProgress(100);
    }
  • 其中在加载进度条中,需要一个类LoadProgress的支持,该类对进度条位置、图片、进度条背景和进度值的管理都起到了决定性的作用。
  • 游戏启动界面如图:

3.1.2 游戏的画面及音效

  • 游戏画面的设计:
    • ImageConfig是图片的配置信息类,图片的信息需要调用该类中的ActConfig内部类来对图片进行初始化赋初属性。
    • ImageManager类是加载图片最重要的一个类,其中方法createImageConfigByPlist能根据给定的配置文件,创建相关的配置信息类,传入带路径的文件返回一个ImageManager对象。方法setScaleInfo设置了图片的缩放信息。方法scaledSrcBitmap真正做到了缩放图片,传入图片的配置信息,返回缩放后的图片,使得图片大小适应游戏界面,画面的协调感能强烈,取得图片代码:

      this.baseImageCache = getBitmapByAssets(config.getSrcImageFileName() + ".png");
              this.baseImageString = config.getSrcImageFileName();
    • getActConfig方法解析图片配置信息,该类严格按照顺序解析,不忽略属性顺序问题,所以xml那边的配置的顺序需要做到严格,返回每一张图的细节信息。
    • getImage方法则是根据图片的配置信息获取图片,根据图片的配置文件和源图返回一个裁出来的图。
    • getImagesByActConfigs这个方法能返回一组而不是一个给定配置信息的图片。
    • getImagesMapByImageConfig方法则能根据图片配置对象信息返回一组图片的HashMap对象。
    • rotateImage方法实现了图片的旋转。
    • scaleImageByScreescaleImageByProportionsacleImageByWidthAndHeight这三个方法会根据需要完成根据屏幕尺寸,比例以及给定尺寸缩放图片。
    • Bitmap类是图片信息类,类中写了获取图片的方法给接下来的程序设计调用,如获取图片的宽度和高度,缩放图片和复制图片,返回、设置图片的像素颜色。
    • 项目中有一个接口Drawable,其中定义了获取图片旋转的矩阵表示,获取当前动作图片的资源,图片的高度和宽度,绘制的回调方法。该接口可供fish类,cannon类,ChangeCannonEffect等类实现其不同的功能。
      这些方法使得游戏里的死的图片仿佛一下子变活了,且相处的那么融洽,不仅加载了图片这么简单,还使游戏给人感官上的体验上了也提升了一个档次。玩家对一款游戏的第一印象本来就是一款游戏的画面感而决定的,所以游戏图片的选择首先要精美,颜色要鲜艳,且不能太僵硬,所以在这个类中有这么大量的方法的分工合作,才完成了游戏画面的设计。

  • 播放音乐:
    MusicManager类是音乐管理器类,其中属性有文件流,文件格式,输出设备
    方法playMusicByR可以根据传入文件中对应的ID属性名来播放音效,关键代码如下:
    /**
    • 根据R文件中对应的ID属性名来播放音效
    • @param resId
      */
      public void playMusicByR(String resId,boolean isLoop){
      try {
      File file = new File("bgm"+File.separator+resId);
      Thread playThread = new Thread(new PlayThread(file,true));
      playThread.start();
      } catch (Exception e) {
      e.printStackTrace();
      }
      }
      内部类PlayThread是播放音乐线程,实现了取得文件输出流以后转为MP3文件编码的操作,且实现了打开输出设备,读取数据到缓存数据,并写入缓存数据的操作。
      SoundManager则是音效管理器,定义了一些播放音效为常量,方便方法的调用:
      /**
    • 音效常量定义
      */
      public static final int SOUND_BGM_FIRE = 1; //开火音效
      public static final int SOUND_BGM_NET = SOUND_BGM_FIRE + 1; //张网音效
      public static final int SOUND_BGM_CHANGE_CANNON = SOUND_BGM_NET+1; //更换大炮
      public static final int SOUND_BGM_GOLD = SOUND_BGM_CHANGE_CANNON+1; //获得金币
      public static final int SOUND_BGM_HIGH_POINT = SOUND_BGM_GOLD+1; //获得高分
      public static final int SOUND_BGM_HUNDRED_POINT = SOUND_BGM_HIGH_POINT+1; //获得百分
      public static final int SOUND_BGM_NO_GOLD = SOUND_BGM_HUNDRED_POINT+1; //没有金币
      soundMap = new HashMap

             图 3-2 游戏的图层的设计

      3.1.4 布局的管理
      LayoutManager类是布局管理器类,该类对游戏的布局产生了至关重要的作用,内部属性有调节子弹的按钮,有计分板,有计时板,有当前使用的大炮。addButton方法实现了在大炮两边添加按钮的功能,在屏幕上点击会发射子弹的原因正是因为有了onClick这个方法,功能才得以实现。Init方法初始化布局,这里会初始化大炮底座,提高大炮质量的按钮,降低大炮质量的按钮,计分板以及计时板,比如计分板在提升大炮质量按钮右边屏幕宽度1/30,1/3按钮高度的位置,计时板在降低大炮质量按钮左边边屏幕宽度1/30加组件宽度,1/3按钮高度的位置。大炮、时间和金币的布局如图3.3:

           图 3-3 大炮、时间和金币的布局

      3.1.5 粒子效果的设计
      为了增加游戏画面的丰富性,我在游戏中还增添了粒子效果,分别有渔网粒子效果,子弹粒子效果和金币粒子效果,这样会使玩家产生眼前一亮的感觉。 ParticleEffectManager类是粒子管理器类,属性有金色星星粒子图片,星星粒子图片,星星粒子彩色图。createColorfulParticleImgs方法在循环中调用getColor方法随机产生几个颜色的粒子,createColorfulParticleImg是随机产生一个颜色的粒子方法,类中当然也获取了渔网,子弹,金币粒子的效果实例。 GoldParticleEffect类是金币粒子效果类,playEffect方法可以根据粒子产生的位置以及偏移量播放一次粒子效果的方法,setEffectMatrix方法设置了粒子位置。
      NetParticleEffect是渔网粒子效果类,playEffect方法可以根据粒子产生的位置以及偏移量播放一次粒子效果的方法,setEffectMatrix方法设置了粒子位置。
      AmmoParticleEffect是子弹粒子效果类,playEffect方法可以根据粒子产生的位置以及偏移量播放一次粒子效果的方法,setEffectMatrix方法设置了粒子位置。
      比如子弹粒子效果如图4-4:

           图3-4 子弹粒子效果

      3.2 鱼类的设计与功能详细说明
      3.2.1 领头鱼
      首先要设计一个对鱼类来说一个必须的类--领头鱼类HeadFish,这个类并不是实质的鱼,而是一个点,这个点带领着所有鱼群游动。该类决定了鱼群的X,Y坐标,游动方向,旋转角度和旋转方向。
      关键代码:
      public class HeadFish {
      private int[] fishOutlinePoint = new int[4]; //鱼的外接矩形,x的最小值,最大值,Y的最小值,最大值
      //控制鱼移动的线程
      private FishRunThread fishRunThread;
      private boolean isNew = true; //是否刚生成的鱼 这个参数决定着进入屏幕时候的路线
      private float fish_x; //鱼当前的X坐标
      private float fish_y; //鱼当前的Y坐标
      private int currentRotate; //鱼当前已旋转的角度
      private float lastX; //最后一次旋转后的X增量 这组XY的作用是旋转后若走直线,就以这两个值
      private float lastY; //最后一次旋转后的Y增量 递增就可以了
      private int rotateDirection; //左转还是右转 这个值的用途在于,鱼在旋转后走直线时,要计算最后一次旋转后的增量,而这个记录了上次是左转还是右转用于计算角度得知直线时的增量
      //当前鱼群的鱼,鱼群的鱼都已它为参照,同样这个鱼也在鱼群集合里
      private Fish fish;
      //鱼群
      private ArrayList

                    图 3-5 丰富多彩的鱼类
      FishManager类是管理鱼的类,该类是通过给不同的鱼起的不同的名字来进行管理的,会根据名字保存所有鱼的捕获动作配置信息,根据名字缓存的鱼的动作图片,根据名字缓存的鱼的捕获动作的图片,还包括所有鱼的种类。Createable属性是一个判断是否可以创建新的鱼的属性,每当调用updateFish方法时,这个值会被设置成false,updateFish方法执行完毕后,这个值会改变成true。initFish方法会初始化管理器,会读取fish文件夹下的FishConfig.plist文件,来加载鱼的所有配置信息,文件配置如下:



      类中方法birthFishByFishName方法可以根据鱼的名字获取一条鱼的实例,updateFish就是更新加载的鱼,getAllFishName方法来获取所有鱼的名字,getFishByName方法根据鱼的名字和鱼的动作信息实现了设置鱼的动作到管理器鱼动作结构中,成功返回true,失败返回false。getFishActByFishName方法可以获取鱼的游动图片集,getFishCatch- ActsByFishName方法则是可以获取鱼的被捕获图片集。initFishInfo方法初始化了鱼的配置信息,如鱼的图层ID,鱼的动作速度,鱼的价值,鱼的捕捉概率等,关键代码如下:
      private void initFishInfo(String config){
      try{
      //如果配置信息没有找到,抛出异常
      if(config==null){
      throw new Exception("FishManager:读取配置文件出错,没有找到fishInfoConfig信息");
      }
      //加载鱼的基本信息配置文件
      XmlPullParser xml = XmlManager.getXmlParser(config, "UTF-8");
      //解析所有的鱼的基本信息
      while(GamingInfo.getGamingInfo().isGaming()&&XmlManager.gotoTagByTagName(xml, "key")){
      XmlManager.gotoTagByTagName(xml, "string");
      String fishName = XmlManager.getValueByCurrentTag(xml);
      FishInfo fishInfo = new FishInfo();
      //设置最大旋转角度
      XmlManager.gotoTagByTagName(xml, "integer"); fishInfo.setMaxRotate(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置移动速度
      XmlManager.gotoTagByTagName(xml, "integer"); fishInfo.setFishRunSpeed(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置动作速度
      XmlManager.gotoTagByTagName(xml, "integer");
      fishInfo.setActSpeed(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置鱼群最大数量
      XmlManager.gotoTagByTagName(xml, "integer"); fishInfo.setFishShoalMax(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置鱼的图层ID
      XmlManager.gotoTagByTagName(xml, "integer");
      fishInfo.setFishInLayer(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置鱼的价值
      XmlManager.gotoTagByTagName(xml, "integer");
      fishInfo.setWorth(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)));
      //设置鱼的捕捉概率
      XmlManager.gotoTagByTagName(xml, "integer"); fishInfo.setCatchProbability(Integer.parseInt(XmlManager.getValueByCurrentTag(xml)))
      allFishConfig.put(fishName, fishInfo);
      }
      }catch(Exception e){
      e.printStackTrace();
      }
      }
      FishRunThread类是鱼游动的线程,该线程决定了鱼是否可以游动,确定了当前线程需要控制额度领头鱼,鱼是否处于屏幕外,鱼的绘制速度(这个应与屏幕刷新速度一样)以及鱼的旋转长度。改进程中的run方法还很好的处理了鱼的旋转模式,鱼在屏幕的不同象限和鱼头的朝向都会使鱼进行不同的旋转路线,关键代码如下:
      // 如果路径为旋转模式
      if (pathMode[0] == PathManager.PATH_MODE_ROTATE) {
      /**
  • 这里做了一个处理,就是分析鱼头朝向和所在位置让鱼进行不同的旋转路线
    */
    // 如果鱼处于第1或第2象限
    if (fish.getFish_X() <= GamingInfo.getGamingInfo().getScreenWidth() / 2
    && fish.getFish_Y() <= GamingInfo.getGamingInfo().getScreenHeight() / 2
    || fish.getFish_X() > GamingInfo.getGamingInfo().getScreenWidth() / 2
    && fish.getFish_Y() <= GamingInfo.getGamingInfo().getScreenHeight() / 2) {
    // 如果鱼头是朝向x的负坐标方向
    if (fish.getCurrentRotate() >= 90
    && fish.getCurrentRotate() <= 270
    || fish.getCurrentRotate() <= -90
    && fish.getCurrentRotate() >= -270) {
    rotateLeftFish(pathMode[1]);
    } else {
    rotateRightFish(pathMode[1]);
    }
    // 如果鱼处于第3或第4象限
    } else {
    // 如果鱼头是朝向x的负坐标方向
    if (fish.getCurrentRotate() >= 90
    && fish.getCurrentRotate() <= 270
    || fish.getCurrentRotate() <= -90
    && fish.getCurrentRotate() >= -270) {
    rotateRightFish(pathMode[1]);
    } else {
    rotateLeftFish(pathMode[1]);
    }
    }
    // 如果路径为直行模式
    } else {
    goStraight(pathMode[1]);
    }
    类中goStraight方法是让鱼根据给定长度走直线的方法,比如新出来的鱼就会走直线,不会一出现在屏幕里就旋转,我们这里给定的是100个单位。当然鱼的左转右转方法也在该进程内,分别是rotateLeftFish和rotateRightFish方法。fishRun方法是控制鱼的行动方法的类,其中我们传入的移动模式定义为int类型,分别是1:左转,-1:右转,0:直走。setFishOutlintPoint方法根据传入的旋转的角度得到鱼所对应的X,Y值来设置鱼的外接矩形(鱼是不规则的,所以我们把所有的鱼都看做一个矩形)。isAtOut方法可以检查鱼是否已经处于屏幕外, 如果鱼的外接矩形的上边缘大于屏幕高度或者下边缘小于0则认定鱼处于屏幕下或上边缘外,true:处于屏幕外,false:在屏幕内。setFishAtOut方法处理了出了边界后的鱼,让鱼群移动线程停掉,并且通知鱼群管理器,这条鱼已经离开屏幕,触发notifyFishIsOutOfScreen方法。
    PicActThread线程是控制鱼的动作的线程。需要设置的属性有:被控制的鱼,鱼是否需要暂停动作,是否需要动作,获取鱼的所有动作,线程是否已经暂停。
    其中run方法可以设置一个循环放置一个动作给鱼的当前动作的循环,比如游动时循环摆动尾巴的动作。并且线程中有鱼动作的重置,播放,暂停播放,停止播放方法,为鱼类调用。
    3.3 炮台及子弹的设计与详细说明
    3.3.1 炮台的详细设计
    CannonManager是大炮管理器类,设置的属性有:是否可以更换大炮,所有子弹的HashMap(key:大炮质量ID,value:子弹图片数组),所有大炮的HashMap(key:大炮质量ID,value:子弹图片数组),所有渔网图片,水波纹下效果图片,变换大炮的效果图,是否可以发射炮弹,当前使用的大炮ID。首先,管理器类都需要初始化所需要的功能,该类初始化了大炮管理器,金币数字,更换大炮的效果图,所有大炮图片,大炮,渔网,所有子弹图片。所有子弹的初始化关键代码如下:
    private void initAmmo(HashMap

        ……
    
        case 100:
            showHundredPoint(100,showX,showY);
            break;
        case 120:
            showHundredPoint(120,showX,showY);
            break;
        case 150:
            showHundredPoint(150,showX,showY);
            break;
        default:
            showGoldNum(value,showX,showY);
            goldRun(showX,showY);
    }

    类中方法showGoldNum是根据得分显示获得金币数的方法,根据不同的鱼不同的分以及鱼被击落的位置在该位置显示对应的分数。goldRun方法使得产生的金币移动到底部位置,使游戏体验性增强,通过计算目标和始发点之间的距离,计算目标与始发地之间需要行走的帧数,计算子弹沿X轴进行的增量来确定金币的移动方式。
    调用SoundManager的playSound方法播放金币音效。showHighPoint方法是显示高分的方法,根据鱼类别获取该显示的高分图片,显示在指定位置。同理,showHundredPoint方法也是将百分图标显示在指定位置。getGold是获取一个金币的方法。Init方法初始化了金币,高分,百分,这三个初始化方法也在得分管理器类ScoreManager中完成了实现。setGoldNum方法则是设置了金币对应的数字图片,是之前击落鱼显示金币的基础。
    3.4.2 定时自动补充金币的设计
    这里大家一定会发现游戏有一个计时器吧,这个计时器的作用是为了防止玩家所持有的金币不够而影响游戏的体验。当计时器记时结束且金币数小于100时,将会调用GamePartManager的startGiveGoldThrad方法启动定时给金币线程,内部有对于计时器数字为0时调用的逻辑。关键代码如下:
    try {
    int time = Constant.GIVE_GOLD_TIME;
    BottomTime bt = LayoutManager.getLayoutManager().getBottomTime();
    while(GamingInfo.getGamingInfo().isGaming()){
    while(!GamingInfo.getGamingInfo().isPause()){
    if(time==0){
    giveGold();
    time = Constant.GIVE_GOLD_TIME;
    }
    bt.updateNumIndex(time);
    time--;
    Thread.sleep(1000);
    }
    break;
    }
    }

4 系统测试
在Eclipse中通过安装的安卓模拟器程序可以成功运行,但是在ARM开发板上就很费劲了。在长时间的游戏过程中,游戏能顺利满足之前所提出的所有需求,游戏运行起来也很流畅,鱼的出现概率也符合设计,鱼的种类也是多种多样的,鱼能顺利的直走拐弯,鱼的被击落概率也符合逻辑,鱼被击落的动作也很生动,不同的子弹有不同的火力,各式各样的粒子效果也让人满意,不同的金币动画也很丰富多彩,游戏的音效和音乐都很流畅动听,自动给金币也能顺利实现,游戏的难度比较适中,因为游戏的整个画面很生动靓丽,所以使得游戏玩起来舒适度和休闲度很高,玩家的体验感也很强,这又是吸引玩家的一大理由。在游戏的配置文件中也可以在网上选取其他的地图图片或者鱼的图片修改游戏的信息,且整个游戏在长时间的游戏过程中没有出现BUG。

5 课程设计总结
该款捕鱼游戏主要实现了通过鼠标点击屏幕在该位置发射子弹击打小鱼的功能,并且可以调节子弹威力,子弹所消耗金币越多则威力越大,鱼的种类不同击杀的概率也不同,获取的金币也不同,这样也很符合游戏的逻辑性,也更加吸引玩家。这样一款老少皆宜、操作简单、画面生动的休闲游戏,无疑给朋友们在忙碌的工作学习之余,能够通过玩我的捕鱼达人得到一些身体心理上的放松。
游戏还有一些不足,现在我的游戏只能在一张地图上玩起来,而且只有玩家想结束游戏才能结束游戏,游戏如果能够加入不同的关卡或者地图的话,游戏的体验也会提高一个档次,游戏的玩法也会变的新鲜多样,使游戏的挑战性更强一些,游戏的趣味性也会更高。
在试验过程中我们对与java的swing组建的应用更是如鱼得水,游戏的各个板块都与之相关,比如JFrame类创建游戏运行的视窗也是相当于画板,将游戏的效果显示出来,Pannel类画出背景,鱼,网等。还有,我对于面向对象的理念更加的清晰,以前对于面向过程,面向对象的概念还不是很懂,如今明白,面向对象,简而言之是万物皆对象,在我编程的过程中,鱼是一个对象,渔网也是一个对象,还有里面的鱼池也是一个对象,甚至是游戏运行的视窗也是JFrame的一个对象。每个对象都有自己的属性,方法,单斐然还有构造器,对对象进行初始化。
在我的程序设计过程中,我充分的体会到了“实践出真知”这一点,书本上的知识是不够的,只有把理论与实践相结合才能够真正的学到知识。一个游戏的设计,不可能一步到位,还需要不断的完善和补充。同时,游戏中还存在许多问题,有待在日后的使用中发现和解决。编程前的深思熟虑是减少程序调试工作量的重要方法,只有进行充分考虑,才会减少调试过程中的工作量。虽然在开始写程序之前我们做了多的准备工作,但在真正的写程序时仍然发现许多问题,有些问题是分析时的疏漏,有些则是如果不做无论如何也想不到的。

猜你喜欢

转载自www.cnblogs.com/feng886779/p/9126275.html