坦克大战
单机版程序演示
- 能够四处移动
- 能够打击敌人
- 敌人能够移动
- 能够模拟爆炸
- 能够产生障碍
- 能够增长生命
项目的针对对象
³ 初步掌握了J2SE的同学
² 掌握了常用的一些类
² 掌握了常用的一些知识点
² 写过一些学习的程序(toy program)
学习方法
³ 不必太关注细节
² 不必非得把某个类所有的细节全了解清楚再动手
² 不必追求完美
² 关键是要写完,要想方设法让它运行起来
³ 量变引起质变
做这个项目是为了
- 复习J2SE,综合运用J2SE所学的知识
- 初步掌握面向对象编程的基本思想
- 掌握Eclipse开发J2SE程序的基本方法
- 初步掌握Eclipse调试程序的方法
- 掌握编程时一些约定俗成的东西
命名/格式等
- 掌握一些常用的编程方法
- getters setters
- 持有对方引用
- 定义常量
- 保留程序版本
- 学会版本比较
- 激发大家的学习兴趣
做这个项目不是为了
- 不是为掌握软件工程的系统理论
- 瀑布式
- 螺旋递增式
- 不是为了掌握专业游戏的开发方法
- 不应用专门的Game API
- 不是为了掌握专业的设计模式
- 没有刻意去应用设计模式
项目的注意事项
³ 要敲,一定要动手敲,要一行一行跟着敲
³ 看会或者听懂都不算掌握了程序
³ 只有写出来才能证明你真正的掌握
³ 不要照抄,不要记我做程序的步骤
³ 要掌握思路
项目所用的工具
³ eclipse 3.2
³ JDK5.0 或以上
² 泛型在5.0后才得到支持
项目的预备知识
³ J2SE基础知识
² 面向对象
² I/O
² 多线程
² GUI初步
± 事件模型
版本0.1
³ 功能:
² 产生一个窗口
³ 掌握:
² 通过Eclipse建立新的项目
² 为新的项目指定不同的源代码和输出目录
² 指定项目所用的JDK版本
² 通过Eclipse建立新的类
³ 注意:
² 类名和方法名的命名
± 见名知意
± 类名首字母大写
± 方法名、变量名首字母小写
± 应用驼峰标识
版本0.2
³ 功能:
² 添加关闭窗口的事件处理
² 不允许窗口的大小改动
³ 掌握:
² 匿名类的用法
± 思考:匿名类的应用场合?
° 类短小、不涉及将来的扩展、不涉及重要的业务逻辑
² 通过Eclipse重写父类的方法
³ 注意:
² 没掌握匿名类的先照抄,不写也行
± 不影响最后的运行效果
版本0.3
³ 功能:
² 画出代表坦克的实心圆
³ 掌握:
² 如何重写paint方法
³ 注意:
² 不要改变原来的前景色
³ 回顾:
² paint(Graphics g)方法,窗口重画时自动调用
² x轴、y轴的方向
版本0.4
³ 功能:
² 让坦克运动起来
² 步骤:
± 将位置改变为变量
± 启动线程不断重画
° 思考:为什么使用线程重画,而不是每按下一个键进行一次重画?
¯ 线程重画更均匀,更能控制重画的速度。
¯ 按键重画不能解决子弹自动飞行的问题。
± 每次重画改变Tank位置
³ 掌握:
² 内部类的使用
± 思考:内部类有哪些好处?什么时候使用内部类?
° 可以方便的访问包装类的方法。不方便公开的,只为包装类服务的类应当定义为内部类。
³ 注意:
² x, y值得含义,指的是小方块的左上角点
版本0.41
功能
² 使用双缓冲消除闪烁现象
³ 原因
² 刷新重画频率太快,paint方法还没有完成
² 逐条显示
³ 解决办法
² 将所有东西画在虚拟图片上,一次性显示出来
³ 注意
² 如果不能理解透彻就照抄本版本代码,不影响对J2SE的练习功效
思考
³ 把游戏窗口的大小改变为640 X 480?
² 定义常量以应付将来的改动
版本0.5
³ 功能:
² 代码重构
± 将以后可能需要多处改变的量定义为常量
° Frame的宽度和高度
¯ 常量名一般大写
³ 注意:
² 常量一般是public static final的。
版本0.6
³ 功能:
² 让坦克听从我们的指挥
± 添加键盘监听器类KeyMonitor
± TankCient添加键盘监听器
± 针对不同的键改变坦克的位置,与重画线程结合产生不同方向运动
³ 注意:
± switch case语句中break语句的运用
± 写程序要循序渐进
思考
³ 增加100辆坦克到游戏中
版本0.7—重要版本
³ 功能:
² 将坦克单独包装成类
² 步骤:
± 建立Tank类
± 为Tank类添加成员变量x y
± 添加draw方法,使Tank类独立控制自己的画法
± 添加Tank类处理按键的方法
± 根据Tank类修改TankClient类
³ 掌握:
² 面向对象的思考方法
± 细节隐藏、构建单独的类、首先考虑系统中有哪些类
± 合适的方法应该出现在合适的类中
思考
³ 如何让坦克向8个方向行走?
版本0.8
³ 功能:
² 让主战坦克向8个方向行走(1)
² 步骤
± 添加记录按键状态的布尔量
± 添加代表方向的量(使用枚举)
± 根据按键状态确定Tank方向
± 根据方向进行下一步的移动(move)
版本0.9
³ 功能:
² 让主战坦克向8个方向行走(2)
² 步骤
± 处理键抬起的消息
± 修改TankClient相关代码
版本1.0
³ 功能
² 添加子弹类
² 步骤:
± 添加Missile类
± 添加x,y,dir等属性以及常量
° 添加构造方法, draw方法等必要方法
° 根据不同方向,进行不同的运动
° 在TankClient中模拟一颗子弹
¯ new一颗子弹出来
¯ 画出来
³ 注意:
² 不一定一次写到位
² 进行多次试验
² 将步骤分解开来逐一进行调试
版本1.1
³ 功能:
² 根据主战坦克的方向和位置,打出子弹
² 步骤
± 增加对Ctrl键的按键处理
± 根据“坦克打出一发子弹”这句话,来确定Tank中的方法fire,其返回值为Missle
± 根据后返回Tank方向和位置设定子弹的方向和位置并new出来,然(fire方法的实现)
³ 注意:
² 掌握面向对象的思维方式来确定类应该具有的方法
版本1.2
² 为了解决坦克停下也能打出炮弹的问题—画出炮筒
² 步骤
± Tank类增加新的属性ptDir
± 每次move后根据Tank新的方向确定炮筒的方向
± 将炮筒用直线的形式表现出来
版本1.3
³ 功能
² 打出多发炮弹
² 步骤:
± 使用容器装炮弹
± 每当抬起Ctrl键就往容器中加入新的炮弹
± 逐一画出每一发炮弹
³ 注意:
² 泛型的使用
版本1.4
³ 功能
² 解决炮弹不消亡的问题
² 解决坦克出界的问题
² 步骤:
± 加入控制炮弹生死的量bLive(Missle)
± 当炮弹已经死去就不需要对其重画
± 当炮弹飞出边界就死亡
± 当炮弹死亡就从容器中去除
³ 注意:
² 将思维转化为代码
Debug的运用
³ 一步一步跟踪代码
³ 为代码设置断点
³ Step into 和 step over的概念
³ 学会在运行过程中观测变量的值
版本1.5
³ 功能
² 画一辆敌人的坦克
² 步骤:
± 加入区别敌我的量good
± 根据敌我的不同设置不同的颜色
± 更新Tank的构造函数,加入good
± TankClient中new 出敌人的坦克并画出
版本1.6
³ 功能:
² 将敌人坦克击毙
² 分析:一颗子弹击中敌人坦克
² 步骤:
± Missle中加入hitTank(Tank)方法,返回布尔类型
± 碰撞检测的辅助类Rectangle
± 为Tank和Missle都加入getRect方法
± 当击中敌人坦克时,坦克被打死,子弹也死去
± 增加控制Tank生死的量live
± 如果死去就不画了
³ 注意:
± 不要照抄代码
± 沿着思路往里加入代码
版本1.7
² 加入爆炸
² 步骤:
° 添加爆炸类
¯ 用不同直径的圆模拟爆炸
¯ 加入live
¯ 加入位置属性
¯ 加入draw方法
° 爆炸应该存在于集合类中
¯ TankClient加入集合
¯ 将集合中的爆炸逐一画出(如果死去就去除)
° 击毙一辆坦克后应产生爆炸
¯ hitTank时应产生爆炸
版本1.8
³ 功能:
² 添加多辆坦克
² 步骤:
± 用容器来装敌人的Tank
± 向容器中装入多辆敌人Tank
± 画出来
± 运行,不能打掉
° 添加hitTanks方法,打一系列Tank
° TankClient里面每发子弹都打tanks
版本1.9
³ 功能:
² 让敌军坦克更加智能
² 步骤:
± 让敌军坦克动起来
° 构造函数中可以指定方向
° new敌军坦克的时候指定敌军坦克的方向
± 让敌军坦克向随机方向移动
° (Tank)静态的,添加随机数产生器 java.util.Random
° move完成后,如果是敌军坦克的,随机产生一个数,来设定坦克下一个方向
° Direction.values()
± 让敌军坦克向随机方向移动随机的步骤
° 添加变量,记录随机步骤
° 当==0时,改变方向,否则,只是随机步骤递减
± 让敌军坦克发射炮弹
° 本军炮弹不打本军
° 炮弹添加好坏bGood,根据好坏画不同颜色
° 修改炮弹的构造方法
° 修改Tank的fire方法
° 修改hitTank方法,好不能打好,坏不能打坏
± 敌军炮火不能太猛烈
版本2.0
³ 功能:
² 添加两堵墙
² 步骤:
± 建Wall类、建立Wall对象、画出来
± 让每一颗子弹打击每一堵墙
° hitWall()方法
° 注意:
¯ 子弹速度不能太快,否则很容易穿过墙
± 让坦克不能穿过墙
° 记录上一次的位置oldX, oldY
° 修改构造函数
° 每次move之前纪录上一次位置
° 添加stay方法
° 记录移动前的位置
° 当撞到时回到移动前的位置
° 当碰到墙的时候stay