Java坦克大战 (七) 之图片版
本文来自:小易博客专栏。转载请注明出处:http://blog.csdn.net/oldinaction
在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学完J2SE的小伙伴们一点启示!
坦克大战效果图:
坦克大战V0.7图片版实现功能:
1、将方向定义为一个Enum类写在一个文件里,修正坦克子弹的颜色
2、加入坦克、子弹、爆炸的图片
3、添加配置文件,并导出可运行的jar包
注意事项:
1、ProperMrg类中props.load(ProperMgr.class.getClassLoader().getResourceAsStream("config/tank.properties"));的解释:
(1)得到ProperMgr这个类编译后的class文件(ProperMgr.class)
(2)得到类装载器(getClassLoader())
(3)通过装载器得到源文件("config/tank.properties")的Stream(getResourceAsStream())
(4)加载(load)源文件
2、Tank类中获取图片tk.getImage(Tank.class.getClassLoader().getResource("images/tankL.gif"))的解释:
(1)Tank.class.getClassLoader()得到某个类(Tank)的装载器
(2)再获取文件getResource("文件路径")
(3)这样既不是绝对路径也不是相对路径,文件路径是根据装载器来获取相应的路径的。不用担心文件被移动后的路径问题(所有的文件最终会被编译到bin目录下)
坦克大战V0.7图片版源代码:
包com.exjava.tankWar中含有的类
TankClient类:
- package com.exjava.tankWar;
- import java.awt.*;
- import java.awt.event.*;
- import java.io.IOException;
- import java.util.List; //java.awt包中也有个List,所以此处要导包明确
- import java.util.ArrayList;
- import java.util.Properties;
- /**
- * 主要的类
- * @ClassName: TankClient
- * @Description: 坦克,子弹,爆炸,血块都在这里实例化
- * @author oldinaction
- * @date 2014年9月2日 下午4:15:44
- */
- public class TankClient extends Frame {
- public static final int GAME_WIDTH = 800;
- public static final int GAME_HEIGHT = 600;
- Tank myTank = new Tank(350, 520, true, Direction.STOP, this); //我方坦克
- Wall w1 = new Wall(100, 300, 20, 100, this), w2 = new Wall(300, 250, 150, 20, this);
- Blood b = new Blood(this);
- List<Missile> missiles = new ArrayList<Missile>(); //定义一个集合来装子弹
- List<Explode> explodes = new ArrayList<Explode>();
- List<Tank> tanks = new ArrayList<Tank>();
- Image offScreenImage = null; //定义一个屏幕后的虚拟图片
- @Override
- public void paint(Graphics g) {
- if (tanks.size() <= 0) {
- for(int i = 0; i < Integer.parseInt(ProperMgr.getProperty("reProduceTank")); i++) {
- tanks.add(new Tank(50 + 40*(i+1), 50, false, Direction.D, this));
- }
- }
- g.drawString("missiles Count: " + missiles.size(), 10, 50); //用来记录missiles中子弹的个数
- g.drawString("explodes Count: " + explodes.size(), 10, 70);
- g.drawString("tanks Count: " + tanks.size(), 10, 90);
- g.drawString("myTank life: " + myTank.getLife(), 10, 110);
- for (int i = 0; i < missiles.size(); i++) { //遍历集合,把其中的子弹画出来
- Missile m = missiles.get(i);
- m.hitTanks(tanks);
- m.hitTank(myTank);
- m.hitWall(w1); //检测子弹是否撞墙
- m.hitWall(w2);
- m.drawMissile(g);
- }
- for (int i = 0; i < explodes.size(); i++) {
- Explode e = explodes.get(i);
- e.draw(g);
- }
- for (int i = 0; i < tanks.size(); i++) {
- Tank t = tanks.get(i);
- t.collidesWithWall(w1); //检测敌方坦克是否撞墙
- t.collidesWithWall(w2);
- t.collidesWithTanks(tanks);
- t.drawTank(g);
- }
- myTank.drawTank(g);
- myTank.eat(b);
- w1.draw(g);
- w2.draw(g);
- b.draw(g);
- }
- //利用双缓冲消除圆圈移动时屏幕的闪动
- @Override
- public void update(Graphics g) {
- if (offScreenImage == null) {
- offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); //判断是为了避免每次重画时都给offScreenImage赋值
- }
- Graphics gOffScreen = offScreenImage.getGraphics(); //定义虚拟图片上的画笔gOffScreen
- Color c = gOffScreen.getColor();
- gOffScreen.setColor(Color.BLACK);
- gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); //重画背景,如果没有这句则在屏幕上会保留圆圈的移动路径
- gOffScreen.setColor(c);
- paint(gOffScreen); //把圆圈画到虚拟图片上
- g.drawImage(offScreenImage, 0, 0, null); //再一次性把虚拟图片画到真实屏幕上,在真实屏幕上画则要用真实屏幕的画笔g
- }
- public void luanchFrame() {
- int initTankCount = Integer.parseInt(ProperMgr.getProperty("initTankCount"));
- for(int i = 0; i < initTankCount; i++) {
- tanks.add(new Tank(50 + 40*(i+1), 50, false, Direction.D, this));
- }
- this.setLocation(300, 50);
- this.setSize(GAME_WIDTH, GAME_HEIGHT);
- this.setTitle("坦克大战 - 游戏还存在Bug,欢迎大家试玩! - 帮助(复活:F2;放弹:1键;超级炮弹:空格) - By:小易 - QQ:381740148");
- this.setResizable(false); //不允许改变窗口大小
- this.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- System.exit(0);
- }
- }); //添加关闭功能,此处使用匿名类比较合适
- this.setBackground(Color.BLACK);
- this.addKeyListener(new KeyMonitor());
- setVisible(true);
- new Thread(new PaintThread()).start(); //启动线程,实例化线程对象时不要忘了new Thread(Runnable对象);
- }
- public static void main(String[] args) {
- TankClient tc = new TankClient();
- tc.luanchFrame();
- }
- //PaintThread只为TankClient服务,所以写成内部类好些
- public class PaintThread implements Runnable {
- public void run() {
- while (true) {
- repaint(); //repaint()是TankClient或者他的父类的方法,内部类可以访问外部包装类的成员,这也是内部类的好处
- try {
- Thread.sleep(50); //每隔50毫秒重画一次
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public class KeyMonitor extends KeyAdapter {
- @Override
- public void keyReleased(KeyEvent e) {
- myTank.keyReleased(e);
- }
- @Override
- public void keyPressed(KeyEvent e) {
- myTank.keyPressed(e);
- }
- }
- }
Tank类:
- package com.exjava.tankWar;
- import java.awt.*;
- import java.awt.event.*;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Random;
- public class Tank {
- public static final int XSPEED = 5; //定义常量X轴速度
- public static final int YSPEED = 5;
- public static final int WIDTH = 30;
- public static final int HEIGHT = 30;
- public static final int LIFE = 100;
- //定义一个随机数产生器,此时的Random类是java.util.Random,不同于Math中的
- private static Random r = new Random(); //随机数产生器只需要一个,所以定义成静态,防止每次new一个坦克是都会产生一个随机数产生器
- private BloodBar bb = new BloodBar();
- private boolean good; //定义变量说明是我方还是敌方坦克,为true表示我方坦克
- private boolean live = true; //定义变量说明是坦克是否存活
- private int life = LIFE; //设置坦克的生命值为100
- TankClient tc;
- private int x , y; //定义变量画圆圈(坦克)时四边形左上点的x、y左边
- private int oldX , oldY; //定义坦克上个位置的坐标
- private boolean bL = false, bU = false, bR = false, bD = false; //定义变量左上右下的按键是否被按下
- private Direction dir = Direction.STOP; //定义变量坦克的方向
- private Direction ptDir = Direction.U; //定义变量坦克炮筒的方向,起初向上
- private int step = r.nextInt(12) + 3; //定义坦克朝着一个方向移动几步
- private static Toolkit tk = Toolkit.getDefaultToolkit();
- private static Image[] TankImages = null;
- private static Map<String, Image> imgs = new HashMap<String, Image>();
- //静态代码区,这样这个类的class文件被加载,首先执行这里的代码;一条语句也可以写在里面,最适合给一些变量做初始化
- static{
- TankImages = new Image[] {
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankL.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankLU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankRU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankR.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankRD.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankD.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/tankLD.gif"))
- };
- imgs.put("L", TankImages[0]);
- imgs.put("LU", TankImages[1]);
- imgs.put("U", TankImages[2]);
- imgs.put("RU", TankImages[3]);
- imgs.put("R", TankImages[4]);
- imgs.put("RD", TankImages[5]);
- imgs.put("D", TankImages[6]);
- imgs.put("LD", TankImages[7]);
- }
- public Tank(int x, int y, boolean good) {
- this.x = x;
- this.y = y;
- this.good = good;
- this.oldX = x;
- this.oldY =y;
- }
- public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {
- this(x, y, good); //相当于调用上面的构造方法
- this.dir = dir;
- this.tc = tc;
- }
- public void drawTank(Graphics g) {
- if(!live) {
- if(!good) {
- tc.tanks.remove(this);
- }
- return; //如果坦克没有存活就直接返回,不用画坦克了
- }
- if (good) bb.draw(g);
- //根据炮筒的方向,画直线代表炮筒
- switch (ptDir) {
- case L:
- g.drawImage(imgs.get("L"), x, y, null);
- break;
- case LU:
- g.drawImage(imgs.get("LU"), x, y, null);
- break;
- case U:
- g.drawImage(imgs.get("U"), x, y, null);
- break;
- case RU:
- g.drawImage(imgs.get("RU"), x, y, null);
- break;
- case R:
- g.drawImage(imgs.get("R"), x, y, null);
- break;
- case RD:
- g.drawImage(imgs.get("RD"), x, y, null);
- break;
- case D:
- g.drawImage(imgs.get("D"), x, y, null);
- break;
- case LD:
- g.drawImage(imgs.get("LD"), x, y, null);
- break;
- }
- move(); //每次按键都会重画,就会调用drawTank,在这里重画坦克的此时位置
- }
- public void keyPressed(KeyEvent e) {
- int key = e.getKeyCode(); //得到按键的虚拟码,再和下面的KeyEvent.VK_LEFT等虚拟码比较看是否是某按键
- switch (key) {
- case KeyEvent.VK_F2:
- if (!this.live) {
- this.live = true;
- this.life = LIFE;
- }
- break;
- case KeyEvent.VK_LEFT:
- bL = true;
- break;
- case KeyEvent.VK_UP:
- bU = true;
- break;
- case KeyEvent.VK_RIGHT:
- bR = true;
- break;
- case KeyEvent.VK_DOWN:
- bD = true;
- break;
- }
- locateDraction();
- }
- public void keyReleased(KeyEvent e) {
- int key = e.getKeyCode();
- switch (key) {
- case KeyEvent.VK_1: //按1就发射子弹调用fire方法
- fire(); //只有松开1才能发出子弹
- break;
- 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;
- case KeyEvent.VK_SPACE: //按SPACE就发射子弹调用fire方法
- superFire();
- break;
- }
- locateDraction();
- }
- //通过上右下的按键是否被按下判断坦克要运动的方向
- void locateDraction() {
- if(bL && !bU && !bR && !bD) dir =Direction.L;
- else if(bL && bU && !bR && !bD) dir =Direction.LU;
- else if(!bL && bU && !bR && !bD) dir =Direction.U;
- else if(!bL && bU && bR && !bD) dir =Direction.RU;
- else if(!bL && !bU && bR && !bD) dir =Direction.R;
- else if(!bL && !bU && bR && bD) dir =Direction.RD;
- else if(!bL && !bU && !bR && bD) dir =Direction.D;
- else if(bL && !bU && !bR && bD) dir =Direction.LD;
- else if(!bL && !bU && !bR && !bD) dir =Direction.STOP;
- }
- public void move() {
- oldX = x;
- oldY = y;
- switch (dir) {
- case L:
- x -= XSPEED;
- break;
- case LU:
- x -= XSPEED;
- y -= YSPEED;
- break;
- case U:
- y -= YSPEED;
- break;
- case RU:
- x += XSPEED;
- y -= YSPEED;
- break;
- case R:
- x += XSPEED;
- break;
- case RD:
- x += XSPEED;
- y += YSPEED;
- break;
- case D:
- y += YSPEED;
- break;
- case LD:
- x -= XSPEED;
- y += YSPEED;
- break;
- case STOP:
- break;
- }
- if(this.dir != Direction.STOP) {
- this.ptDir = this.dir;
- }
- //防止坦克出界
- if (x < 0) x = 0;
- if (y < 25) y = 25; //考虑了标题栏的高度
- if (x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
- if (y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
- if (!good) {
- Direction[] dirs = Direction.values(); //把枚举转换成数组
- if (step == 0) {
- int rn = r.nextInt(dirs.length);
- dir = dirs[rn]; //如果移动步数为0就改变方向
- step = r.nextInt(12) + 3;
- }
- step --;
- if(r.nextInt(40) > 37) this.fire();
- }
- }
- public void stay() {
- x = oldX;
- y = oldY;
- }
- //坦克开火,就new一个子弹出来
- private Missile fire() {
- if(!live) return null;
- int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2; //让子弹从坦克中心打出
- int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
- Missile m = new Missile(x, y, good, ptDir , this.tc);
- tc.missiles.add(m); //每new一个Missile对象就把他装到集合中
- return m; //返回的m,其他地方可调用可不调用
- }
- private Missile fire(Direction dir) {
- if(!live) return null;
- int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2; //让子弹从坦克中心打出
- int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
- Missile m = new Missile(x, y, good, dir , this.tc);
- tc.missiles.add(m); //每new一个Missile对象就把他装到集合中
- return m; //返回的m,其他地方可调用可不调用
- }
- public Rectangle getRect() {
- return new Rectangle(x, y, WIDTH, HEIGHT); //得到坦克的探测方块,Rectangle是java.awt包中专门用于游戏碰撞的类
- }
- public boolean isLive() {
- return live;
- }
- //Tank类的成员方法可生成对应的get和set方法,那么在其他类中就可以访问了
- public void setLive(boolean live) {
- this.live = live;
- }
- public boolean isGood() {
- return good;
- }
- //检测坦克是否撞墙
- public boolean collidesWithWall(Wall w) {
- if(this.live && this.getRect().intersects(w.getRect())) {
- this.stay(); //如果坦克撞到墙就让他回到上一个位置
- return true;
- }
- return false;
- }
- //检测坦克是否相撞,java.util.List<E>接口或者类的另一种写法,java.awt中也有List,所以要写明确
- public boolean collidesWithTanks(java.util.List<Tank> tanks) {
- for (int i = 0; i < tanks.size(); i++) {
- Tank t = tanks.get(i);
- if (this != t) {
- if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) {
- this.stay();
- t.stay();
- return true;
- }
- }
- }
- return false;
- }
- //超级炮弹:朝8个方向各发一发炮弹
- private void superFire() {
- Direction[] dirs = Direction.values();
- for (int i = 0; i < 8; i++) { //dirs[8]是STOP
- fire(dirs[i]);
- }
- }
- public int getLife() {
- return life;
- }
- public void setLife(int life) {
- this.life = life;
- }
- public class BloodBar {
- public void draw(Graphics g) {
- Color c = g.getColor();
- g.setColor(Color.RED);
- g.drawRect(x, y - 10, WIDTH, 10);
- int w = WIDTH * life/LIFE ;
- g.fillRect(x, y - 10, w, 10);
- g.setColor(c);
- }
- }
- //吃血块
- public boolean eat(Blood b) {
- if(this.live && b.isLive() && this.getRect().intersects(b.getRect())) {
- b.setLive(false);
- life = LIFE;
- return true;
- }
- return false;
- }
- }
Missile类:
- package com.exjava.tankWar;
- import java.awt.*;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class Missile {
- public static final int XSPEED = 10;
- public static final int YSPEED = 10;
- public static final int WIDTH = 10;
- public static final int HEIGHT = 10;
- int x, y;
- Direction dir;
- private boolean good; //定义变量表示是否是我方子弹
- private boolean live = true; //定义一个判断子弹是否出界的变量
- private TankClient tc;
- private static Toolkit tk = Toolkit.getDefaultToolkit();
- private static Image[] MissileImages = null;
- private static Map<String, Image> imgs = new HashMap<String, Image>();
- static{
- MissileImages = new Image[] {
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileL.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileLU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileRU.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileR.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileRD.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileD.gif")),
- tk.getImage(Tank.class.getClassLoader().getResource("images/missileLD.gif"))
- };
- imgs.put("L", MissileImages[0]);
- imgs.put("LU", MissileImages[1]);
- imgs.put("U", MissileImages[2]);
- imgs.put("RU", MissileImages[3]);
- imgs.put("R", MissileImages[4]);
- imgs.put("RD", MissileImages[5]);
- imgs.put("D", MissileImages[6]);
- imgs.put("LD", MissileImages[7]);
- }
- public Missile(int x, int y, Direction dir) {
- this.x = x;
- this.y = y;
- this.dir = dir;
- }
- public Missile(int x, int y,boolean good, Direction dir, TankClient tc) {
- this(x, y, dir);
- this.good = good;
- this.tc = tc;
- }
- public void drawMissile(Graphics g) {
- if(!live) {
- tc.missiles.remove(this);
- return;
- }
- switch (dir) {
- case L:
- g.drawImage(imgs.get("L"), x, y, null);
- break;
- case LU:
- g.drawImage(imgs.get("LU"), x, y, null);
- break;
- case U:
- g.drawImage(imgs.get("U"), x, y, null);
- break;
- case RU:
- g.drawImage(imgs.get("RU"), x, y, null);
- break;
- case R:
- g.drawImage(imgs.get("R"), x, y, null);
- break;
- case RD:
- g.drawImage(imgs.get("RD"), x, y, null);
- break;
- case D:
- g.drawImage(imgs.get("D"), x, y, null);
- break;
- case LD:
- g.drawImage(imgs.get("LD"), x, y, null);
- break;
- }
- move();
- }
- private void move() {
- switch (dir) {
- case L:
- x -= XSPEED;
- break;
- case LU:
- x -= XSPEED;
- y -= YSPEED;
- break;
- case U:
- y -= YSPEED;
- break;
- case RU:
- x += XSPEED;
- y -= YSPEED;
- break;
- case R:
- x += XSPEED;
- break;
- case RD:
- x += XSPEED;
- y += YSPEED;
- break;
- case D:
- y += YSPEED;
- break;
- case LD:
- x -= XSPEED;
- y += YSPEED;
- break;
- }
- if (x < 0 || y < 0 || x > tc.GAME_WIDTH || y > tc.GAME_HEIGHT) {
- live = false;
- }
- }
- public boolean isLive() {
- return live;
- }
- public Rectangle getRect() {
- return new Rectangle(x, y, WIDTH, HEIGHT); //得到子弹的探测方块,Rectangle是java.awt包中专门用于游戏碰撞的类
- }
- //判断子弹是否打到了坦克
- public boolean hitTank(Tank t) {
- //intersects是Rectangle的一个方法;t.isLive()是为了判断坦克是否存活,如果没有则打掉这个坦克后,之后的子弹到达原来这个坦克的位置就会消失
- if (this.live && this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()) {
- if (t.isGood()) {
- t.setLife(t.getLife() - 20);
- if (t.getLife() <= 0) {
- t.setLive(false);
- }
- } else {
- t.setLive(false);
- }
- this.live = false;
- Explode e = new Explode(x, y, tc);
- tc.explodes.add(e);
- return true;
- }
- return false;
- }
- public boolean hitTanks(List<Tank> tanks) {
- for (int i = 0; i < tanks.size(); i++) {
- if (hitTank(tanks.get(i))) {
- return true;
- }
- }
- return false;
- }
- public boolean hitWall(Wall w) {
- if(this.live && this.getRect().intersects(w.getRect())) {
- this.live = false;
- return true;
- }
- return false;
- }
- }
Explode类:
- package com.exjava.tankWar;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.Toolkit;
- //爆炸类(爆炸的英文:explode)
- public class Explode {
- int x, y;
- private TankClient tc;
- private boolean live = true;
- private boolean init = false; //定义变量表示图片是否已经被加载到内存了
- private static Toolkit tk = Toolkit.getDefaultToolkit(); //Toolkit是java.awt中的工具包类,这样就可以方便的拿到硬盘的信息
- private static Image[] imgs = { //每次只需加载一次,所以写出static
- //下面用到了反射的概念,Explode.class.getClassLoader()是得到最终生成class文件的装载器,getResource()得到装载器的目录
- //此时加载的图片路径绝对和相对都不合适,用这个方法最合适,这个方法比较常用
- tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/2.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/6.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/7.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/8.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/9.gif")),
- tk.getImage(Explode.class.getClassLoader().getResource("images/10.gif"))
- };
- int step = 0; //定义变量代表画爆炸的圆画到第几个了
- public Explode(int x, int y, TankClient tc) {
- this.x = x;
- this.y = y;
- this.tc = tc;
- }
- public void draw(Graphics g) {
- if(!init) {
- for (int i = 0; i < imgs.length; i++) {
- g.drawImage(imgs[i], -100, -100, null); //把图片画在看不到的地方
- }
- init = true;
- }
- if(!live) {
- tc.explodes.remove(this);
- return;
- }
- if (step == imgs.length) {
- live = false;
- step = 0;
- return;
- }
- g.drawImage(imgs[step], x, y, null);
- step ++ ;
- }
- }
Wall类:
- package com.exjava.tankWar;
- import java.awt.*;
- public class Wall {
- private int x, y, w, h;
- private TankClient tc;
- public Wall(int x, int y, int w, int h, TankClient tc) {
- this.x = x;
- this.y = y;
- this.w = w;
- this.h = h;
- this.tc = tc;
- }
- public void draw(Graphics g) {
- Color c = g.getColor();
- g.setColor(Color.WHITE);
- g.fillRect(x, y, w, h);
- g.setColor(c);
- }
- public Rectangle getRect() {
- return new Rectangle(x, y, w, h);
- }
- }
Blood类:
- package com.exjava.tankWar;
- import java.awt.*;
- public class Blood {
- private int x, y, w, h;
- private TankClient tc;
- private boolean live = true;
- private int step = 0;
- int[][] pos = {
- {400,400}, {420,400}, {440,400}, {440,420}, {440,440}, {420,440}, {400,440}, {400,420}
- };
- public Blood(TankClient tc) {
- this.x = pos[0][0];
- this.y = pos[0][1];
- this.w = h = 10;
- this.tc = tc;
- }
- public void draw(Graphics g) {
- if (!live) return;
- Color c = g.getColor();
- g.setColor(Color.MAGENTA);
- g.fillRect(x, y, w, h);
- g.setColor(c);
- move();
- }
- private void move() {
- step ++;
- if(step == pos.length) {
- step = 0;
- }
- x = pos[step][0];
- y = pos[step][1];
- }
- public Rectangle getRect() {
- return new Rectangle(x, y, w, h);
- }
- public boolean isLive() {
- return live;
- }
- public void setLive(boolean live) {
- this.live = live;
- }
- }
Direction类:
- package com.exjava.tankWar;
- public enum Direction {
- L,LU,U,RU,R,RD,D,LD,STOP; //定义枚举类型,值为左、左上、上、右上、右、右下、下、左下、停止
- }
ProperMgr类:
- package com.exjava.tankWar;
- import java.io.IOException;
- import java.util.Properties;
- public class ProperMgr {
- //Singleton模式,只实例化一个对象
- //读配置文件用的对象,这个对象只需要把配置文件加载到内存就行,之后就和他没关系,所以只需实例化一次
- static Properties props = new Properties();
- static {
- try {
- props.load(ProperMgr.class.getClassLoader().getResourceAsStream("config/tank.properties"));
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- private ProperMgr() {} //构造方法定义成静态的,就是不准别的类new这种对象
- public static String getProperty(String key) {
- return props.getProperty(key);
- }
- }
包config中含有的文件
tank.properties源码:
- initTankCount=20
- reProduceTank=10
包images中含有的文件上述图片
坦克大战图片下载地址:点击下载
Java坦克大战 (七) 之图片版的更多相关文章
- Java坦克大战(四)
这是我的坦克游戏大战的最后一版,里面添加很多新的功能.这个坦克大战的有很多不足之处,但是对于初学者来说依然是一个很好的练习项目,从中我们可以学习Java基础知识,将知识与项目结合,学习面向对象编程思想 ...
- Java坦克大战(三)
关于这个坦克大战的项目是在学习Java基础的时候,拿来练习的最近看到这些代码,感觉很亲切,就把他们都复制下来,编辑成博客.回首看去,Java基础的学习确实应该建立在找项目练习上,这样才能将学到的基础知 ...
- Java坦克大战(二)
本文紧接上一篇讲解坦克大战这个项目,因为当初在学习的时候,是以这个案例逐步学习Java基础的,过程是先讲知识点,再将知识点逐步的融入到项目中,即给坦克添加新的功能.之前的Demo练习,想都记录下来.这 ...
- Java坦克大战 (六) 之增加可玩性
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Java坦克大战 (五) 之产生敌方坦克和爆炸效果
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Java坦克大战 (四) 之子弹的产生
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Java坦克大战 (三) 之可完全控制坦克朝八个方向运动
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Java坦克大战 (二) 之画一个能动的圆圈代表坦克
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Java坦克大战(一)
接下来的几篇博客,想记录一下通过学习坦克大战项目来循序渐进的学习Java基础.主要是为了巩固基础知识,当然学习编程重要的还是多敲,问题通常是在敲代码的过程中发现的,积累也是在敲代码中寻求的经验.这个坦 ...
随机推荐
- 3.爬虫 urlib库讲解 总结
urllib库的总结: 用ProcessOn(安利这个软件,够用了)根据前面的几节内容做了个思维导图. urllib库一共有四个模块: request:它是最基本的模块,可以用来模拟发送请求 erro ...
- 九度OJ--1165(C++)
#include <iostream>#include <string>#include <vector> using namespace std; int mai ...
- oracle补充
索引 索引是若干数据行的关键字的列表,查询数据时,通过索引中的关键字可以快速定位到要访问的记录所在的数据块,从而大大减少读取数据的I/O次数,因此可以显著的提高性能 创建索引的SQL 把下面表中的na ...
- 【bzoj1455】罗马游戏 可并堆+并查集
题目描述 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻.他决定玩这样 ...
- [SCOI2010]序列操作 线段树
---题面--- 题解: 在考场上打的这道题,出人意料的很快就打完了?! 直接用线段树,维护几个东西: 1,lazy标记 : 表示区间赋值 2,mark标记:表示区间翻转 3,l1:前缀最长连续的1的 ...
- nfs 和samba
NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文件.通过使用N ...
- 第116讲 boost::algorithm::string之替换和删除
http://www.360doc.com/content/16/0523/18/29304643_561672752.shtml
- 洛谷P2568 GCD (欧拉函数/莫比乌斯反演)
P2568 GCD 题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入输出样例 输入 ...
- POJ1459:Power Network(多源点多汇点的最大流)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 31086 Accepted: 15986 题 ...
- POJ2912:Rochambeau(带权并查集)
Rochambeau Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5208 Accepted: 1778 题目链接:h ...