- 浏览: 23992 次
- 性别:
线程项目——坦克大战总结
一.预计游戏实现功能
1)两方坦克,电脑控制敌方坦克,由线程控制。玩家控制自己的坦克,通过添加键盘监听器实现。
2)坦克发射子弹,并能判断敌我,判断输赢。通过建立子弹线程实现。
3)坦克之间不能互撞。
3)添加背景,有普通强(普通子弹课打破),白色墙(普通子弹无法打破),水(子弹可通过,坦克不能),草(子弹,坦克均能通过)。
4)实现子弹,坦克碰到不同障碍物的不同执行方法。
5)优化界面,添加音乐,判断输赢,实现重玩,升级等其他功能。
二.碰到的技术问题
其实,整个过程我们碰到了无数大大小小,奇奇怪怪的问题,以下只罗列出几个关键性问题供大家参考。
1)两方坦克,两方子弹图片,走法均不同,如何设计既能减少代码,又能实现该功能。 虽说玩家自己的坦克不是线程,但和其他坦克只是图片不同,创建一个坦克类,写一个设置名字的方法,在创建坦克对象时,区别敌我。此类中,写坦克行走,转向,碰到其他坦克和障碍物的方法。再单独写一个坦克线程类,利用人机算法,在run方法中,操作坦克运动。
大致如下:
坦克类
public class Tank {
//构造器,传入初始坦克的位置
public Tank(Graphics g, int x, int y) {}
//设置不同方向坦克的图片对象
public void setImage() {}
// 坦克前进的方法
public int forward() {}
//坦克攻击的方法
public void attack() {}
//得到坦克运动时方向的方法
public String getDirection() {}
//判断坦克是否和其他会坦克相撞
public int isSeparate() {}
//设置坦克名字的方法
public void setName(String name) {}
}
坦克线程类
public class TankRunnable implements Runnable{
//构造器,传入坦克对象
public TankRunnable(Tank tank, Graphics g) {}
//重写run方法
public void run() {}
}
而子弹类则直接写成一个线程类,重写run方法时直接调用发射的方法。此类中,也有诸如根据坦克名字设置图片,判断敌我的方法。
大致如下:
子弹线程类
public class Bullet extends Thread{
//构造器,传入此时要发射坦克的坐标和坦克对象
public Bullet(Graphics g, int x, int y, String direction, String name,
Tank tank) {}
//发射子弹的方法
public void shot() {}
//判断是否撞到墙
private void isHitWall() {}
//设置子弹图片的方法
public void setImage() {}
//判断是否打到坦克
public void isHitTank() {}
//重写run方法
public void run() { shot();}
}
此外,判断子弹打中坦克方法中,要把子弹和对方坦克一一进行判断,此时,可以用集合分别存储这些坦克对象,写在一个借口里,让子弹类实现接口即可。
2)墙的画法
由于墙被子弹打到后,要爆炸消失,所有墙肯定不能用一张背景图代替,必须一块一块的画在画布上。在这个问题上,我们先用坐标循环画出墙,并把每个墙的对象都存入一个集合里,而此时却出现了很大的一个问题,子弹线程中,有判断子弹是否打到墙的方法,我们是让子弹与画面上所有墙进行比较判断,这无疑加大了子弹的压力。画面上一次会出现多个子弹,而每颗子弹没走一步就要执行这么多次,主程序就出现了最讨厌的问题——卡!
最后,我们决定像五子棋那样,用一个二维数组存储这些墙,子弹判断时只需要根据坐标判断与之相邻的一块砖即可,大大减少代码的执行。
3)边界
这个问题,我们暂时还没有解决。
由于在坦克类中,我们写了一个碰到边界即反向的方法,而此方法却不适合玩家自己的坦克,进而出现了玩家到边界自动转向,图片却没有转换过来,且还能继续走,甚至出边界。
4)卡
这本属于项目优化,我们写的子弹线程中太多方法,子弹每走一步,要判断执行很多代码,必然导致运行速度慢,甚至卡,死机等问题。
对此,我们先是用数组存储墙缓解这个问题,也进一步限制子弹颗数,即一颗子弹要么出边界,要么打到墙或坦克,才能发射另一颗子弹。
5)人机算法
若是智能的算法,电脑的坦克应该追随玩家的坦克,并在合适时机发射子弹,像五子棋一样,既要有防守,也要有进攻。而我们写的算法很简单,坦克其实在无序的行走,这个将慢慢完善。
三.几个重点技术实现方法
1)坦克运动方向和图片的匹配
public int forward() {
// 坦克初始位置
g.drawImage(image, x, y, High, Wide, null);
// 设置一个黑色矩形
g.setColor(Color.BLACK);
try {
// 如果是自己的坦克,线程不休眠,阻止键盘延迟
if (name.equals("Mytank")) {
sleep = 0;
}
Thread.sleep(sleep);// 线程休眠
g.fillRect(x, y, High, Wide);// 覆盖原先坦克的图片
// 判断方向,改变相应坐标值
if (direction.equals("Right")) {
x += speed;
setDirection("Right");
}
if (direction.equals("Left")) {
x -= speed;
setDirection("Left");
}
if (direction.equals("Up")) {
y -= speed;
setDirection("Up");
}
if (direction.equals("Down")) {
y += speed;
setDirection("Down");
}
// 画出新位置,走一步
g.drawImage(image, x, y, High, Wide, null);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
2)坦克,子弹行走的动态效果
上述代码已有介绍,即根据起始坐标先画出图,用黑色矩形框盖住原先图片,再画出新位置的图。这和画布重绘其实是一样的。
当然也可以在重绘方法中实现。
此外,重要的是要利用双缓冲清楚闪屏的情况。
3)判断子弹或坦克是否碰到障碍物
这是一个技术难点,即使得到两者坐标,又如何判断。
此刻,我们利用Rectangle中的intersect(Rectangle R)方法判断两者是否相撞。
即,根据两者坐标创建两个矩形对象,用上述方法即可。
4)声效
File file = new File("music\\fire.wav");
URL rul;
try {
rul = file.toURL();
AudioClip ac = Applet.newAudioClip(rul);
ac.play();
} catch (MalformedURLException e) {
e.printStackTrace();
}
四.自我体会
这是第一个我们做的比较复杂的项目,加之我们选的题目复杂程度也高,中间碰到了很多问题,刚开始还比较积极,但后来些许有些烦躁。好在我们都坚持下来了,这里,我最想说的是以下几点;
1)团队合作很重要
刚开始,想要一个人独立完成一个项目的确有点困难,而团队合作不仅在节省了时间,也保证了项目的质量性。三个人有三种想法,只要交流的好,面对问题,总能找出比较好的解决办法。当然,在找错时也很有帮助。
2)做项目要有全局思维
一个完整的项目前前后后的联系是很紧密的,在初始做时,要对整个游戏,每个步骤有宏观的把握,即要想到后面的步骤。不然,很容易出现前面一直解决问题,最后发现思路完全错,最大的致命性问题无法解决。
3)遇到问题要积极及时与他人交流
发表评论
-
java基础整理
2013-05-13 22:22 0Java基础整理 从武汉回来有好几周的时间了 ... -
线程同步
2013-01-18 23:49 821窗外狂风大作,实在不想在睡觉时刻本着不完成誓不罢休不 ... -
线程同步
2013-01-18 23:19 0窗外狂风大作,实在不 ... -
数据结构-----Hash
2012-11-23 10:14 860数据结构之Hash表 一.数据结构概念 数据结 ... -
通信基础小结
2012-10-29 00:14 748通信基础小结 通信 ... -
线程基础
2012-08-01 22:32 601线程基础 一.进程和线程 ... -
数据结构之链表
2012-08-01 22:23 634数据结构之链表 链表的基本概念 ... -
哈弗曼树解压缩
2012-07-30 15:06 786... -
IO总结
2012-07-16 21:05 642Java IO 总结 第一部分 ... -
Java集合机制
2012-07-15 20:01 985Java 集合框架 一.关于集合 ... -
异常机制
2012-07-11 14:30 734JAVA异常机制总结 ... -
画图板小结
2012-07-05 10:05 704项目总结——画板 一.整体思路 ... -
关键字
2012-05-25 16:28 598关键字总结 一.关键字分类 1.常用关键字 ... -
继承,转型,重写,多态性
2012-05-13 15:11 667Java实战入门小结——02 一:继承 1 ... -
类,对象,构造函数,this关键字等
2012-04-15 22:48 1117Java实战入门小结--01 一:类与对象的关系 类 ...
相关推荐
这个东西很不错,真心值你你们下载吗,我用了2年时间,全身心的去研究多线程,希望对大家有帮助
文档里描述了java多线程开发的具体说明和实例
MSMQ项目总结示例代码 MSMQ项目总结\MSMQ数据库数据传输.rar ...MSMQ项目总结\MSMQ单线程监控.rar MSMQ项目总结\MSMQ文件发送接收.rar MSMQ项目总结\MSMQ远程信息交互.rar MSMQ项目总结\MSMQ应用文档.doc MSMQ项目总结
这是我研究生两年来,学习C++和做项目中遇到问题,然后总结出来的一些文件 包含c++ 线程 指针 调试 编码等方面 。rar中包含30个word文档文件。
我们知道,多线程是Android开发中必现的场景,很多原生API和开源项目都有多线程的内容,这里简单总结和探讨一下常见的多线程切换方式。 我们先回顾一下Java多线程的几个基础内容,然后再分析总结一些经典代码中对于...
http://blog.csdn.net/stvel/article/details/52795631 对应文章更有效果哦
c# 线程学习资料 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
c#多线程编程 这个都是本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
这个基于TCP协议的网上考试系统采用 C/S结构,是对学习j2se的一个检验,基本涉及到j2se的所有方面:多线程,IO,GUI,网络编程,JDBC等等。 开发平台:eclipse3.1 数据库:Oracle 9i 总结中包括: 一、...
Java总结,关于黑马现场面试的总结,IO流,线程,File,集合,反射
最近做项目时在多线程读写数据库时抛出了异常,这自然是我对SQlite3有理解不到位的地方,所以事后仔细探究了一番。 1.关于getWriteableDataBase()和getReadableDatabase()的真正作用 getWriteableDataBase()其实是...
java web项目技术总结,从架构到技术分解,以及技术的使用,还有关键性业务设计与实现(在线聊天设计、订单多线程技术、多线程查询数据库技术、风格切换技术等)
c#+多线程学习 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
c# Socket 多线程聊天 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
看B站视频项目总结的系列文档,仅供个人学习使用
总结试验了23各C#中用到的线程,简单的做成了实例,可单独运行看每一种效果,有需要的朋友可下载,运行+断点看效果,研究明白后可运用到项目中
2.7归纳与总结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 51 2.8借shared_ptr 实现copy-on-write. . . . . . . . . . . . . . . . . . . . . . 52 第3章多线程服务器的适用场合与常用...
自己学习Java的心得体会,以自己的方式总结 适合新手 快速操作新项目知识
当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。 QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...