知识回顾:前一篇讲解了窗口里面绘制的正方形已经可以跟随着键盘的上下左右键移动了

如果按键改变的不是每次+10或者减10,这时候又要改变源码,所以优化代码

思路:使用枚举定义坦克的方向:

新建一个枚举类(Dir.class):定义坦克的方向,然后在TankFrame中调用

1.定义坦克方向的enum,根据按键状态确定坦克方向,根据坦克方向确定坦克位移

public enum Dir {//方向向左LEFT,//方向向上UP,//方向向右RIGHT,//方向向下DOWN
}

2.修改TankFrame的方法让Tank运动起来:

public class TankFrame extends Frame {private static  int x = 200;private static  int y = 200;//默认方向向下Dir dir = Dir.DOWN;//默认坦克的速度为10private static  int SPEED = 3;public TankFrame(){//设置窗口的尺寸this.setSize(800,600);//设置窗口位置this.setLocation(500,200);//参数设置为true,当程序运行时,窗口显示this.setVisible(true);//设置窗口标题this.setTitle("Tank war");//添加键盘监听事件this.addKeyListener(new MyKeyListener());//点击窗口X关闭窗口,添加监听事件this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}/*** 重写paint方法,然后在窗口中指定位置画出一个矩形* @param g*/@Overridepublic void paint(Graphics g){g.fillRect(x,y,25,25);switch (dir){case LEFT:x-=SPEED;break;case UP:y-=SPEED;case RIGHT:x+=SPEED;break;case DOWN:y+=SPEED;break;default:break;}}/*** 键盘监听处理类*/class MyKeyListener extends KeyAdapter{//定义几个默认的方向boolean bL = false;boolean bU = false;boolean bR = false;boolean bD = false;//按下一个键的时候@Overridepublic void keyPressed(KeyEvent e) {int key = e.getKeyCode();switch (key){case KeyEvent.VK_LEFT:bL = true;x-=SPEED;break;case KeyEvent.VK_UP:bU = true;y-=SPEED;break;case KeyEvent.VK_RIGHT:bR = true;x+=SPEED;break;case KeyEvent.VK_DOWN:bD = true;y+=SPEED;break;default:break;}setTankDir();}//按键抬起的时候@Overridepublic void keyReleased(KeyEvent e) {int key = e.getKeyCode();switch (key){case KeyEvent.VK_LEFT:bL = false;break;case KeyEvent.VK_UP:bU = false;break;case KeyEvent.VK_RIGHT:bR = false;break;case KeyEvent.VK_DOWN:bD = false;break;default:break;}setTankDir();}private void setTankDir(){if (bL)  dir=Dir.LEFT;if (bU)  dir=Dir.UP;if (bR)  dir=Dir.RIGHT;if (bD)  dir=Dir.DOWN;}}}

3.现在我们都在TankFrame里面做的一系列操作,现在我们是否需要抽象一个Tank的类,封装相应的属性和方法

抽象出坦克类,封装相应的属性和方法,在tankFrame中直接调用

package com.tank;import java.awt.*;/*** @author litao* @date 2020-05-25* Tank封装类*/
public class Tank {//定义初始位置private int x,y;//定义初始速度private static final  int SPEED = 10;//默认方向private Dir dir = Dir.DOWN;public Dir getDir() {return dir;}public void setDir(Dir dir) {this.dir = dir;}//定义坦克的构造方法public  Tank(int x,int y ,Dir dir){this.x = x;this.y = y;this.dir = dir;}/*** tank里面封装画坦克的方法,直接在TankFrame里面调用* @param g*/public void paint(Graphics g){g.fillRect(x,y,50,50);switch (dir){case LEFT:x-=SPEED;break;case UP:y-=SPEED;case RIGHT:x+=SPEED;break;case DOWN:y+=SPEED;break;default:break;}}}

4.怎样处理坦克静止的状态,因为现在我们的坦克默认是运动状态的:moving = false;

思路:在tank类里面添加一个boolean moving标识,如果上下左右键有按下,moving为true,反之为false;(在tankFrame里面设置是否为true或者false)

//TankFrame类里面的方法,具体源码看gitHub
private void setMainTankDir(){//上下左右键都没有按下时,设置moving为falseif(!bL && !bU && !bR && !bD){myTank.setMoving(false);}else {myTank.setMoving(true);if (bL) {myTank.setDir(Dir.LEFT);}if (bU) {myTank.setDir(Dir.UP);}if (bR) {myTank.setDir(Dir.RIGHT);}if (bD) {myTank.setDir(Dir.DOWN);}}}

5.按下Ctrl键,主站坦克打出一个子弹,用面向对象的思想考虑

思路:5.1封装一个子弹,新建一个Bullect类

package com.tank;import java.awt.*;/*** @author litao* @date 2020-05-25* 子弹封装类*/
public class Bullet {//定义子弹的宽度和高度private  static  final int BULLET_WIDTH = 30,BULLET_HEIGHT = 30;private static  final  int SPEED = 10;//定义初始位置private  int x,y;//定义方向private  Dir dir;//子弹的构造方法public Bullet(int x,int y,Dir dir){this.x = x;this.y = y;this.dir = dir;}public void paint(Graphics g){Color color =g.getColor();g.setColor(Color.RED);g.fillOval(x,y,BULLET_WIDTH,BULLET_HEIGHT);g.setColor(color);move();}private void move() {switch (dir){case LEFT:x-=SPEED;break;case UP:y-=SPEED;case RIGHT:x+=SPEED;break;case DOWN:y+=SPEED;break;default:break;}}}

5.2按下ctrl键,tank会fire出一颗子弹,必须持有tankframe的引用,把子弹传递给窗口,画出来

在Tank类里面写一个fire的方法:

按下ctrl键,tank会fire出一颗子弹,必须持有tankframe的引用,把子弹传递给窗口,画出来

//坦克发射子弹public void fire() {tf.bullet = new Bullet(this.x,this.y,this.dir);}

6.连续按Ctrl可以打出许多的子弹,讲子弹装在一个容器里就可以了。

List<Bullet> bullets = new ArrayList<>();

7.当我们打出的子弹数量超出我们画的边框的时候,子弹的数量还是在无限增加,所以当子弹飞出窗口以后,就把子弹remove掉。

消除子弹列表的内存泄漏问题,小心处理迭代器中的删除问题,1:使用普通方式迭代 2:在迭代过程中删除(iterator.remove)

和判断静止还是移动是一个道理,当超出边界范围的时候,直接remove掉bullets里面的子弹数量

if(x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false;

设计模式之Tank大战02相关推荐

  1. java程序 联机方法_Java实现Tank大战联机版

    前言 在前面对于Java初学者开发简单的桌面游戏的碰撞检测的总结中,笔者特意去翻了翻U盘里面 的东西.发现以前用Java做的Tank大战游戏还静静的躺在那个角落.现在将其分享出来.陆续的 也会将以前做 ...

  2. 设计模式3:飞机大战源码PPT演示录像

    1.功能介绍: java做的飞机大战,包括4个关卡,每一关有BOSS, BOSS的移动方式有三角形.抛物线等方式,敌机子弹分散发射,有道具可回血,玩家和BOSS显示生命值,每一关有胜利画面.PPT介绍 ...

  3. Tank大战游戏模拟(java版)

    Java小项目 – 坦克大战 1.任务分析 玩家进入游戏,通过操纵坦克来守卫基地,摧毁全部敌方坦克来取得胜利,如果基地被摧毁,或者玩家坦克被摧毁,则判定游戏失败 2.具体分析 图形用户界面使用GUI技 ...

  4. JavaScript设计模式与开发实践 | 02 - this、call和apply

    this JavaScript的this总是指向一个对象,至于指向哪个对象,是在运行时基于函数的执行环境的动态绑定的,而非函数被声明时的环境. this的指向 this的指向大致可以分为以下4类: 作 ...

  5. 1.基础完成版本-设计模式之坦克大战

    1.版本地址 https://github.com/phs999/DesignPatterns/tree/9af503c47d25dfea6a0a848438725afbc3e4a424 2.实现效果 ...

  6. 【设计模式】行为型02模板方法模式(Template Method Patten)

    五一长假,没有出去,不喜欢嘈杂的人群,玩了会游戏发泄了下憋在心底的戾气,手旁大马克杯里是母亲泡的绿茶.点开自己的播放列表,耳机里传来的是理查德克莱德曼的致爱丽丝.自己是个凡人,卑微渺小的活着.不说废话 ...

  7. 坦克大战java_清华毕业大佬用一个坦克大战项目讲完了23种设计模式

    先给大家讲述一下坦克大战是怎么进行运行的. 坦克大战第一节: new 出一个窗口: 设定标题栏内容: TankFrame从Frame继承+显示: 认识paint方法,重写: 坦克大战第二节 学习gra ...

  8. Java设计模式(二)创建型设计模式

    文章目录 三 创建型设计模式 3.1 单例设计模式 3.1.1 饿汉式(线程安全) 3.1.2 懒汉式(线程不安全) 3.1.3 优缺点 3.1.4 补充 3.1.5 框架中的使用 3.1.4.1 S ...

  9. JavaStudy5(坦克大战)—B站韩顺平

    JavaStudy5(坦克大战01)-B站韩顺平 跳转坦克大战02: 跳转坦克大战03: 1. 坦克大战 1.1坦克大战游戏演示 1.1.1游戏演示 1.1.2 为什么写这个项目 1.1.3 写项目前 ...

最新文章

  1. 剑指offer-面试题20.顺时针打印矩阵
  2. mysql提取数字_Mysql中实现提取字符串中的数字的自定义函数分享
  3. 01背包初始化的细节问题与循环下限的改进
  4. java推送Comet_使用Comet4j实现消息推送
  5. android 克隆对象,克隆会破坏单例对象吗?
  6. 抢疯了!字节、美团《人人都要学的架构思维》完整版PDF开放下载!
  7. 技术社区_如何加入技术社区
  8. memcache/redis 缓存学习笔记
  9. Flex+BlazeDs+Java的教程及Demo
  10. springboot 基于Vue旅游景区商城网站java项目源码
  11. CMPP网关协议核心代码 java版本
  12. 国家信息安全水平考试NISP一级官方视频知识点整理
  13. 软件测试面试自我介绍
  14. 图像处理的边缘和纹理的区别
  15. Open Distro 初探
  16. 加拿大计算机专业前八大学,加拿大留学:计算机工程专业排名前八的名校详情...
  17. 如何打造短期爆发式增长的爆款文章
  18. Word里面怎么才能输入平方
  19. C++函数模板与类模板的区别
  20. python图片目标检测_python+opencv实现目标检测中图片怎么插入

热门文章

  1. 沧海一粟第五次团队博客
  2. 在n个硬币中找出假币
  3. 映客都是互刷礼物吗_仿映客刷礼物效果---代码优化
  4. 2016hctf Writeup.md
  5. pytorch使用过程中的错误处理之内存溢出
  6. centos7 nginx安装
  7. 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
  8. Linaro ubuntu for arndale octa烧写步骤
  9. Spanky - beloved ~桜の彼方へ~ -full ver
  10. Pycharm完整中文教程