做者:陈伟 2011211927 0491101java
王延友 2011211834 0491102
编程
1、整体设计
多线程
1.1 具体设计框架
游戏包括的范围:本游戏包括主类、坦克类、子弹类、爆炸类、墙类、血块类。编程语言
需求函数 |
模块学习 |
产生游戏的屏幕this |
主类模块spa |
将坦克大战的过程呈如今屏幕上线程 |
|
画出坦克 |
坦克类模块 |
控制坦克的移动并让坦克能够攻击 |
|
让坦克不能够穿越墙或别的坦克 |
|
添加坦克的图片 |
|
画出子弹 |
子弹类模块 |
控制子弹的移动 |
|
各类子弹 |
|
让子弹不能够穿墙 |
|
添加子弹的图片 |
|
子弹打墙的爆炸 |
爆炸类模块 |
画出爆炸的过程 |
|
控制坦克的爆炸 |
|
添加爆炸的图片 |
|
画出墙 |
墙类模块 |
实现墙的功能 |
|
画出血块 |
血块类模块 |
让血块围绕着固定的轨迹移动 |
|
实现血块的功能 |
1.2 游戏特色
咱们设计的这款坦克大战和之前的区别我感受挺大的,主要区别以下:
1,在咱们设计的游戏里面坦克的炮筒更接近现实,那就是炮筒能够旋转。炮筒会指向鼠标所指的方向。
2,咱们不止是我一个坦克。咱们有队友,队友都是由电脑控制的坦克。
3,加血道具我方任一坦克都能吃,不仅是玩家控制的坦克能够吃。
4,不论是敌方仍是我方都能发多种子弹。可是特殊子弹的数量有限。
5,咱们新添加了导弹,只有玩家控制的坦克才能够吃导弹。
1.3 类的层次结构图
1.3.1 坦克类的层次结构图
1.3.2 道具类的层次结构图
1.3.3 子弹类层次结构图
1.3.4 爆炸类层次结构图
1.3.5 坦克客户端层次结构图
1.3.6 墙类层次结构图
1.4 系统流程图
2、程序描述
2.1 主类模块
主类是要画出屏幕,而且要将坦克之间打斗的全过程都呈现出来的,因此要先产生一个窗口,窗口产生以后应该要不停的刷新,不然屏幕会定格成画面,用多线程来控制刷新的频率,若是此时屏幕出现闪屏现象,应该用双缓冲机制来画出屏幕。双缓冲机制是经过虚拟出一张图片,将屏幕画在这张虚拟的图片上,再将这张虚拟的图片呈如今屏幕上。
画面重画的类以下:
class RepaintThread implements Runnable // 画面重画线程 { public void run() { while (repaintFlag) { try { repaint(); ut.move(); // Tank定时移动 Shot tcShots = null; for (int i = 0; i < shotsList.size(); i++) // 界面上的子弹定时移动 { tcShots = shotsList.get(i); tcShots.move(); } Thread.sleep(33); } catch (InterruptedException e) { e.printStackTrace(); System.exit(-1); } } } }
2.2 坦克类模块
该类实如今屏幕上画出坦克,并控制坦克的移动,让坦克能够发射炮弹打对方等功能。
画出坦克的方法以下:
public void draw(Graphics g) { if (!init) // 读入炮筒图片 { init = true; this.setTurretDir(new Point(turretDirx + 10, turretDiry + 10)); } if (isLive) { if (this.camp) { switch (tankDir) { case U: case D: { g.drawImage(imgMap1.get(tankDir), x - 18, y - 19, null); } break; case L: case R: { g.drawImage(imgMap1.get(tankDir), x - 19, y - 18, null); } break; default: { } break; } } else { switch (tankDir) { case U: case D: { g.drawImage(imgMap2.get(tankDir), x - 18, y - 19, null); } break; case L: case R: { g.drawImage(imgMap2.get(tankDir), x - 19, y - 18, null); } break; default: { } break; } } g.drawImage(bTurretImg, x - 32, y - 32, null); // 绘制大炮 this.tankHitPoint.draw(g); // 绘制出Tank的血量 } else { if (tankBomb != null) tankBomb.draw(g); // 绘出坦克爆炸 } }
2.3 子弹类模块
该类实如今屏幕上画出子弹和子弹的移动轨迹以及实现了坦克攻击墙壁与攻击敌方坦克的功能,并且咱们设计的是各类各样的子弹,好比我方就有闪弹,敌方除了普通的子弹外还有可以穿墙的子弹。因为代码较长,我就不贴出来了。
2.4 爆炸类模块
该类实现了在屏幕上画出了坦克爆炸的情景,咱们采用了连续播放图片的效果来体现爆炸,咱们的爆炸效果以下:
2.5 墙类模块
游戏里面咱们的墙比较单一,这也能够说是咱们游戏的一点不足。咱们画出的墙的效果以下:
2.6 血类模块
血主要有两种,一种是加血的道具,二是坦克自己的血量。加血道具咱们的设计就是,我方任一坦克吃了以后能回复一点血量。而不一样于之前的是否是只有玩家操做的坦克才能吃加血道具。实现后效果以下:
三,功能演示
3.1 开始画面:
游戏的开始画面咱们展现了玩家将要进入第一关,具体效果以下:
3.2 游戏菜单
咱们的游戏菜单有:开始游戏,暂停游戏,继续游戏,以及对游戏的一些设置。效果以下:
3.3 游戏画面
具体的游戏画面以下:
屏幕左下方的60表明玩家坦克闪弹的剩余数量,上面的五个小圆是导弹的剩余数量。而右下角的爱心是加血道具,下面就是玩家能够吃的两枚导弹。
当咱们胜出后会提示是否进入下一关,效果以下:
4、实现时遇到的问题
在这个程序实现中咱们遇到的困难其实不少,由于程序过大,因此长期是一小点错误就会出现很奇怪的行为。在这其中我列举一下遇到的最大困难。
1:炮筒如何360度旋转,这个问题开始咱们想了好久,到底该如何旋转。转到鼠标所指的方向,多是因为数学功底太差。咱们没有想到用数学的方式解决。最后咱们的解决办法是用三角函数解决的,算出当前的角度就OK了。
2:就是开始菜单的使用,咱们这个开始游戏开始一直不成功。开始时不成功主要是点了没反应,咱们是加了监听的。没点开始游戏就已经开始了。这个问题解决了以后又遇到了新的问题就是一点开始游它就给你弹出一个新的窗口,不是在原来的窗口基础之上开始游戏。之因此出现这样的问题是因为个人界面不是一个panel类,而是一个方法。因此就添加了一个MyStartPanel extends JPanel类。而且实现Runnable接口,实现一闪一闪的界面效果。而后在开始游戏监听函数里面,建立一个坦克客服端对象。调用启动界面函数。就开始游戏了。 这样问题就解决了。
3:坦克之间的碰撞检测。其实这个问题想起来这个问题蛮简单,由于实际的坦克图片是一个矩形框。只要两个矩形框之间不要有交叉就能够了。想法虽好,实现不易啊。开始咱们的方法很繁琐,没有写一个统一的方法来判别。
其实困难重重,常常遇到很奇怪的问题。好比说子弹的发射问题之类的。因此我就列举了主要的问题。
5、心得体会
陈伟心得体会:之因此想作坦克大战是因为我对坦克大战有种感情吧,从小就是这个游戏陪我度过个人童年。之前我都很好奇这个游戏是怎么作的,如今本身学了编程语言。因此有种很强烈的愿望实现一下,而且加进本身的思想。一开始作的时候还很兴奋。但是后来遇到各类问题个人兴趣就会被打击到。可是在这其中我获得了一个对于我来讲很重要的经验。那就是遇到问题是要淡定,不要浮躁。只要你一直坚持研究这个问题的解决方法,到最后它必定会被解决的。其次,我也发现本身作这种大的项目还有不少不足。欠缺编程能力。因此编程能力确实有待提升。在这其中我以为软件工程的思想是很重要的,软件工程学了仍是有很大用处,如今我对软件工程的理解还不够深刻,须要进一步的学习才行。
王延友的心得体会:此次的做业是要求完成一个游戏的改进或者修改为3D的。因为我平时不怎么玩大型游戏,多3D游戏了解得很少,在拿到这个题目时,的确不知道怎么入手,恰好最近在观看韩顺平老师的java视频。他里面有一个案例是编写坦克游戏,因而想到不如我模仿这个游戏吧,没想到个人组员和我想到一块儿去了。他也是计划写这方面的游戏。咱们算是不谋而合。而后就是开始观看视频,按照那些方法开始编写。可是往往都是看着简单,要本身动手的时候就不是那么简单了。因为咱们花了不少时间去设计和编写元素类,因此界面不是很漂亮,并且还有些功能还不能实现。也说明个人能力还欠缺,还得好好努力。同时我也从队友哪里学到了思想的重要性,刚开始的时候不能太注意细节,先要考虑到总体的框架,否则就没法开展工做了。后面才是完善细节的时候。