这个版本,只能算是一个雏形,把最基本的东西给完成了,不过,后面可添加的也不多。有一点,还是想去实现,那就是敌方坦克自己寻找对手!也就是游戏AI.

emmm, 什么时候可以了解一下这个AI。顺便学学python。

这个帖子只是为了贴上代码,对后续的代码作为优化和添加游戏AI做准备的。


1. 各类接口

  1. package Event;
  2. /*
  3. *具有攻击力的接口
  4. */
  5. public interface Attackable {
  6. /*
  7. * 校验具有攻击力的实物, 和, 具有被攻击的实物,是否能撞在一起
  8. *
  9. */
  10. boolean checkAttack(Hitable hit);
  11. }
  1. package Event;
  2. /*
  3. * 具有阻挡功能的实物
  4. */
  5. public interface Blockable {
  6.  
  7. }
  1. package Event;
  2. /*
  3. * 能被销毁的类
  4. */
  5. import domain.Blast;
  6. /*
  7. * 销毁接口
  8. */
  9. public interface Destoryable {
  10. /*
  11. * 判断是否需要销毁
  12. */
  13. boolean isDestoryable();
  14.  
  15. /*
  16. * 销毁时,绘制爆炸物
  17. */
  18. Blast showDestory();
  19. }
  1. package Event;
  2.  
  3. import domain.Blast;
  4. /*
  5. * 能被攻击的类
  6. */
  7. public interface Hitable {
  8. Blast showAttack();
  9. }
  1. package Event;
  2. /*
  3. * 具有移动功能的事物
  4. *
  5. */
  6. public interface Moveable {
  7. boolean checkHit(Blockable blockable);
  8. }

2.各类游戏元素的父类

  1. package domain;
  2.  
  3. /*
  4. * 父类:
  5. * 是砖墙,坦克,水墙等所有元素的抽象出来的抽象类
  6. */
  7. public abstract class Element {
  8. /*
  9. * 属性
  10. * 坐标
  11. */
  12. protected int x;
  13. protected int y;
  14. //宽高
  15. protected int width;
  16. protected int hight;
  17.  
  18. //构造函数
  19. //空参构造函数
  20. public Element() {super();} //可以不写super(),java会自己调用,也就是调用抽象类的父类
  21.  
  22. public Element(int x, int y) {
  23. this.x=x; this.y=y;
  24. }
  25.  
  26. /*
  27. * 绘制元素
  28. */
  29. public abstract void draw();
  30.  
  31. /*
  32. * 设置元素的渲染级别,数字越高,渲染级别越高
  33. */
  34. public int getOrder() {return 0;}
  35. }

坦克的父类

  1. package domain;
  2.  
  3. import org.itheima.game.utils.CollisionUtils;
  4.  
  5. import Event.Blockable;
  6. import Event.Destoryable;
  7. import Event.Hitable;
  8. import Event.Moveable;
  9. /*
  10. * 所有坦克的父类\
  11. * 坦克具有移动,阻挡,被攻击,被销毁的功能
  12. *
  13. */
  14. public abstract class Tank extends Element implements Moveable, Blockable, Hitable,Destoryable{
  15. /*
  16. * 属性
  17. */
  18. //攻击力
  19. protected int power=1;
  20. //血量
  21. protected int blood=5;
  22.  
  23. //坦克的移动方向
  24. protected Direction direction=Direction.UP;
  25.  
  26. //每次移动的速度
  27. protected int speed=3;
  28.  
  29. //记录最后一颗子弹的发射时间
  30. protected long lastTime;
  31.  
  32. //记录坦克不能移动的方向
  33. protected Direction badDirection;
  34.  
  35. //记录坦克碰撞的最小移动距离
  36. protected int badSpeed;
  37.  
  38. /*
  39. * 构造函数
  40. */
  41. public Tank() {super();}
  42. public Tank(int x, int y) {super(x, y);}
  43.  
  44. /*
  45. * 绘制坦克
  46. */
  47. public abstract void draw();
  48.  
  49. /*
  50. * 发射子弹
  51. */
  52. public Bullet shot() {
  53. //思路:如歌最后一颗子弹 - 当前发射的时间 > 650ms 就发射子弹
  54. //获取当前时间
  55. long newTime=System.currentTimeMillis();
  56. if(newTime-lastTime<650) {
  57. return null; //不发射子弹
  58. }else {
  59. lastTime=newTime;
  60. return new Bullet(this); //谁调用了就是谁的子弹
  61. }
  62. }
  63.  
  64. /*
  65. * 获取坦克的移动方向
  66. */
  67. public Direction getDirection() {return direction;}
  68.  
  69. /*
  70. * 校验:移动物(坦克)是否与障碍物是否撞上
  71. */
  72. public boolean checkHit(Blockable block){
  73. Element e=(Element)block;
  74. int x1=e.x;
  75. int y1=e.y;
  76. int w1=e.width;
  77. int h1=e.hight;
  78.  
  79. //预判坦克的坐标
  80. int x2=x;
  81. int y2=y;
  82. switch (direction) {
  83. case UP:
  84. y2-=speed;
  85. break;
  86. case DOWN:
  87. y2+=speed;
  88. break;
  89. case LEFT:
  90. x2-=speed;
  91. break;
  92. case RIGHT:
  93. x2+=speed;
  94. break;
  95. default:
  96. break;
  97. }
  98. boolean flag=CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x2, y2, width, hight);
  99. if(flag) {
  100. //说明预判可以撞上,不仅要记录不能移动的方向,还要记录最小间隙
  101. badDirection=direction;
  102. switch (direction) {
  103. case UP:
  104. badSpeed=y-y1-h1;
  105. break;
  106. case DOWN:
  107. badSpeed = y1 - y - hight;
  108. break;
  109. case LEFT:
  110. badSpeed = x - x1 - w1;
  111. break;
  112. case RIGHT:
  113. badSpeed = x1 - w1 - width;
  114. break;
  115. default:
  116. break;
  117. }
  118. }else {
  119. badDirection=null; //没有撞上的话,就没有坏的方向
  120. }
  121. return flag;
  122. }
  123.  
  124. /*
  125. * 销毁的方法
  126. */
  127. public boolean isDestory() {return blood<=0;}
  128.  
  129. /*
  130. * 被销毁物,在被销毁时的表现。
  131. */
  132. public Blast showDestory() {return new Blast(this);}
  133.  
  134. }

各种游戏元素

  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.DrawUtils;
  6. import org.itheima.game.utils.SoundUtils;
  7.  
  8. import Event.Blockable;
  9. import Event.Destoryable;
  10. import Event.Hitable;
  11.  
  12. /*
  13. *
  14. * 爆炸物类
  15. *
  16. */
  17. public class Blast extends Element implements Destoryable{
  18. /*
  19. * 属性
  20. */
  21. //1.图片
  22. private String[]arr= {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif",
  23. "res/img/blast_5.gif", "res/img/blast_6.gif", "res/img/blast_7.gif", "res/img/blast_8.gif"};
  24. //2.定义变量,记录要绘制的图片索引
  25. private int index;
  26.  
  27. //3.定义变量,记录是否需要销毁该爆炸物
  28. //true:销毁, false :不销毁
  29. private boolean isDestory;
  30.  
  31. /*
  32. * 构造方法
  33. * 爆炸物的坐标依赖墙的坐标
  34. */
  35. public Blast(Hitable hit) {
  36. this(hit, false);
  37. try {
  38. SoundUtils.play("res/snd/blast.wav");
  39. } catch (IOException e) {
  40. // TODO Auto-generated catch block
  41. e.printStackTrace();
  42. }
  43. }
  44. /*
  45. * flag :true表示挨打,绘制1~4的图片
  46. * false 说明是销毁,绘制1~8的图片
  47. */
  48. public Blast(Hitable hit, boolean flag) {
  49. Element element=(Element)hit;
  50. //计算爆炸物的位置
  51. //获取墙的坐标和宽高
  52. int x1=element.x;
  53. int y1=element.y;
  54. int w1=element.width;
  55. int h1=element.hight;
  56. //获取爆炸物的宽度
  57. try {
  58. int size[]=DrawUtils.getSize("res/img/blast_1.gif");
  59. width=size[0]; hight=size[1];
  60.  
  61. //计算爆炸物的坐标
  62. x=x1+(w1-width)/2;
  63. y=y1+(h1-hight)/2;
  64. } catch (IOException e) {
  65. // TODO Auto-generated catch block
  66. e.printStackTrace();
  67. }
  68.  
  69. if(flag) {
  70. arr=new String[] {"res/img/blast_1.gif", "res/img/blast_2.gif", "res/img/blast_3.gif", "res/img/blast_4.gif"};
  71. try {
  72. SoundUtils.play("res/snd/hit.wav");
  73. } catch (IOException e) {
  74. // TODO Auto-generated catch block
  75. e.printStackTrace();
  76. }
  77. }
  78. }
  79. @Override
  80. public void draw() {
  81. // TODO Auto-generated method stub
  82. //定义变量,记录要绘制的图片的路径
  83. String res=arr[index++];
  84. if(index>=arr.length) {
  85. index=0;
  86. //说明爆炸物已经绘制过一次了可以销毁
  87. isDestory=true;
  88. }
  89. try {
  90. DrawUtils.draw(res, x, y);
  91. } catch (IOException e) {
  92. // TODO Auto-generated catch block
  93. e.printStackTrace();
  94. }
  95. }
  96.  
  97. /*
  98. * 获取爆炸物的状态
  99. */
  100. public boolean isDestoryable() {
  101. // TODO Auto-generated method stub
  102. return isDestory;
  103. }
  104. /*
  105. * 销毁时,绘制销毁的爆炸物
  106. */
  107. public Blast showDestory() {return null;}
  108.  
  109. }
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.CollisionUtils;
  6. import org.itheima.game.utils.DrawUtils;
  7. import org.itheima.game.utils.SoundUtils;
  8.  
  9. import Event.Attackable;
  10. import Event.Destoryable;
  11. import Event.Hitable;
  12. import Grame.config;
  13.  
  14. /*
  15. * 子弹类,具有攻击能力,被销毁的能力
  16. */
  17. public class Bullet extends Element implements Attackable, Destoryable {
  18.  
  19. //记录子弹移动的方向
  20. private Direction direction;
  21. //记录子弹的速度
  22. private int speed=7;
  23. //定义变量,记录子弹所属的坦克
  24. private Tank tank;
  25.  
  26. /*
  27. * 构造函数(non-Javadoc)
  28. * @see Event.Destoryable#isDestoryable()
  29. */
  30. //子弹的坐标依赖坦克
  31. public Bullet(Tank tank) {
  32. // TODO Auto-generated constructor stub
  33. super();
  34. //用变量tank记录,子弹所属的坦克
  35. this.tank=tank;
  36.  
  37. //获取坦克的坐标,宽高,方向
  38. int tankX=tank.x;
  39. int tankY=tank.y;
  40. int tankWidth=tank.width;
  41. int tankHight=tank.hight;
  42. direction=tank.getDirection();
  43.  
  44. //获取子弹的宽高
  45. try {
  46. int size[]=DrawUtils.getSize("res/img/bullet_u.gif");
  47. width=size[0]; hight=size[1];
  48. } catch (IOException e) {
  49. // TODO Auto-generated catch block
  50. e.printStackTrace();
  51. }
  52.  
  53. //计算子弹的坐标
  54. switch (direction) {
  55. case UP:
  56. x = tankX + (tankWidth - width)/2;
  57. y = tankY - hight / 2;
  58. break;
  59. case DOWN:
  60. x = tankX + (tankWidth - width)/2;
  61. y = tankY + tankHight - hight /2;
  62. break;
  63. case LEFT:
  64. x=tankX-width;
  65. y=tankY+(tankHight-hight)/2;
  66. break;
  67. case RIGHT:
  68. x = tankX + tankWidth - width / 2;
  69. y = tankY + (tankHight - hight)/2;
  70. break;
  71. default:
  72. break;
  73. }
  74.  
  75. try {
  76. SoundUtils.play("res/snd/fire.wav");
  77. } catch (IOException e) {
  78. // TODO Auto-generated catch block
  79. e.printStackTrace();
  80. }
  81. }
  82.  
  83. /* 出边界
  84. * 销毁子弹 true:销毁,false:不销毁(non-Javadoc)
  85. * @see Event.Destoryable#isDestoryable()
  86. */
  87. @Override
  88. public boolean isDestoryable() {
  89. // TODO Auto-generated method stub
  90. if(x<0||x>config.WIDTH||y<0||y>config.HIGHT) return true;
  91. return false;
  92. }
  93.  
  94. /*
  95. * 子弹销毁时的反映(non-Javadoc)
  96. * @see Event.Destoryable#showDestory()
  97. */
  98. @Override
  99. public Blast showDestory() {
  100. // TODO Auto-generated method stub
  101. return null;
  102. }
  103. /*校验是否与阻碍物碰上
  104. * (non-Javadoc)
  105. * @see Event.Attackable#checkAttack(Event.Hitable)
  106. */
  107. @Override
  108. public boolean checkAttack(Hitable hit) {
  109. // TODO Auto-generated method stub
  110. Element e=(Element)hit;
  111. int x1=e.x;
  112. int y1=e.y;
  113. int w1=e.width;
  114. int h1=e.hight;
  115. //第一个矩形:障碍物,第二个撞击物:子弹
  116. return CollisionUtils.isCollsionWithRect(x1, y1, w1, h1, x, y, width, hight);
  117. }
  118.  
  119. /*
  120. * 绘制子弹(non-Javadoc)
  121. * @see domain.Element#draw()
  122. */
  123. @Override
  124. public void draw() {
  125. // TODO Auto-generated method stub
  126. String res="";
  127. //判断坦克方向
  128. switch (direction) {
  129. case UP:
  130. res = "res/img/bullet_u.gif";
  131. y-=speed;
  132. break;
  133. case DOWN:
  134. res = "res/img/bullet_d.gif";
  135. y += speed;
  136. break;
  137. case LEFT:
  138. res = "res/img/bullet_l.gif";
  139. x -= speed;
  140. break;
  141. case RIGHT:
  142. res = "res/img/bullet_r.gif";
  143. x += speed;
  144. break;
  145. default:
  146. break;
  147. }
  148.  
  149. try {
  150. DrawUtils.draw(res, x, y);
  151. } catch (IOException e) {
  152. // TODO Auto-generated catch block
  153. e.printStackTrace();
  154. }
  155. }
  156.  
  157. /*
  158. * 获取子弹所属坦克
  159. */
  160. public Tank getTank() {
  161. return tank;
  162. }
  163. }
  1. package domain;
  2. /*
  3. * 枚举四个方向
  4. */
  5. public enum Direction {
  6. UP,DOWN,LEFT,RIGHT;
  7. }
  1.  
  1. package domain;
  2.  
  3. import java.io.IOException;
  4. import java.util.Random;
  5.  
  6. import org.itheima.game.utils.DrawUtils;
  7.  
  8. import Grame.config;
  9.  
  10. public class EnemyTank extends Tank{
  11.  
  12. /*
  13. * 属性(non-Javadoc)
  14. * @see Event.Hitable#showAttack()
  15. */
  16. public EnemyTank(int x, int y) {
  17. super(x, y);
  18. try {
  19. int size[]=DrawUtils.getSize("res/img/enemy_u.gif");
  20. width=size[0]; hight=size[1];
  21. } catch (IOException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26. public EnemyTank() {super();}
  27.  
  28. @Override
  29. public Blast showAttack() {
  30. // TODO Auto-generated method stub
  31. //扣血
  32. blood-=new Mytank().power;
  33. return new Blast(this, true);
  34. }
  35.  
  36. @Override
  37. public boolean isDestoryable() {
  38. // TODO Auto-generated method stub
  39. return blood<=0;
  40. }
  41.  
  42. /*
  43. * 坦克的绘制(non-Javadoc)
  44. * @see domain.Tank#draw()
  45. */
  46. @Override
  47. public void draw() {
  48. // TODO Auto-generated method stub
  49. String res="";
  50. //判断坦克的方向
  51. switch (direction) {
  52. case UP:
  53. res = "res/img/enemy_u.gif";
  54. break;
  55. case DOWN:
  56. res = "res/img/enemy_d.gif";
  57. break;
  58. case LEFT:
  59. res = "res/img/enemy_l.gif";
  60. break;
  61. case RIGHT:
  62. res = "res/img/enemy_r.gif";
  63. break;
  64. default:
  65. break;
  66. }
  67.  
  68. try {
  69. DrawUtils.draw(res, x, y);
  70. } catch (IOException e) {
  71. // TODO Auto-generated catch block
  72. e.printStackTrace();
  73. }
  74. }
  75.  
  76. /*
  77. * 随机获取敌方坦克的方向
  78. */
  79. public Direction getRandDirection() {
  80. int num=new Random().nextInt(4);
  81. switch (num) {
  82. case 0:
  83. return Direction.UP;
  84. case 1:
  85. return Direction.DOWN;
  86. case 2:
  87. return Direction.LEFT;
  88. case 3:
  89. return Direction.RIGHT;
  90. default:
  91. break;
  92. }
  93. return Direction.UP;
  94. }
  95.  
  96. /*
  97. * 移动
  98. */
  99. public void move() {
  100. //如果传过来的方向,与坦克不能移动的方向相同,则移动最小距离
  101. if(direction==badDirection) {
  102. switch (direction) {
  103. case UP:
  104. y-=badSpeed;
  105. break;
  106. case DOWN:
  107. y+=badSpeed;
  108. break;
  109. case LEFT:
  110. x-=badSpeed;
  111. break;
  112. case RIGHT:
  113. x+=badSpeed;
  114. break;
  115. default:
  116. break;
  117. }
  118. //不能移动就随机换一下方向
  119. direction=getRandDirection();
  120. return ;
  121. }
  122.  
  123. switch (direction) {
  124. case UP:
  125. y-=speed;
  126. break;
  127. case DOWN:
  128. y+=speed;
  129. break;
  130. case LEFT:
  131. x-=speed;
  132. break;
  133. case RIGHT:
  134. x+=speed;
  135. break;
  136. default:
  137. break;
  138. }
  139.  
  140. //边界处理
  141. if(x<0) {
  142. x=0;
  143. direction=getRandDirection();
  144. }
  145. if(x>config.WIDTH-64) {
  146. x=config.WIDTH-64;
  147. direction=getRandDirection();
  148. }
  149. if(y<0) {
  150. y=0;
  151. direction=getRandDirection();
  152. }
  153. if(y>config.HIGHT-64) {
  154. y=config.HIGHT-64;
  155. direction=getRandDirection();
  156. }
  157. }
  158. }
 
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.DrawUtils;
  6. /*
  7. * 草坪
  8. */
  9. public class Grass extends Element{
  10.  
  11. public Grass(int x, int y) {
  12. // TODO Auto-generated constructor stub
  13. super(x, y);
  14. //获取宽高
  15. try {
  16. int size[]=DrawUtils.getSize("res/img/grass.gif");
  17. width=size[0]; hight=size[1];
  18. } catch (IOException e) {
  19. // TODO Auto-generated catch block
  20. e.printStackTrace();
  21. }
  22. }
  23. @Override
  24. public void draw() {
  25. // TODO Auto-generated method stub
  26. try {
  27. DrawUtils.draw("res/img/grass.gif", x, y);
  28. } catch (IOException e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. }
  32. }
  33.  
  34. /*
  35. * 修改草坪的渲染级别
  36. */
  37. public int getOrder() {return 1;}
  38. }
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.swing.plaf.DimensionUIResource;
  6.  
  7. import org.itheima.game.utils.DrawUtils;
  8.  
  9. import Grame.config;
  10.  
  11. public class Mytank extends Tank{
  12. public Mytank(int x, int y) {
  13. // TODO Auto-generated constructor stub
  14. super(x, y);
  15. //初始化速度
  16. speed=30; power=2; blood=10;
  17.  
  18. //获取坦克的宽高
  19. try {
  20. int size[] = DrawUtils.getSize("res/img/tank_u.gif");
  21. width=size[0];
  22. hight=size[1];
  23. } catch (IOException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. }
  28.  
  29. public Mytank() {
  30. // TODO Auto-generated constructor stub
  31. super();
  32. power=2;
  33. }
  34.  
  35. /*
  36. * 挨打方法(non-Javadoc)
  37. * @see Event.Hitable#showAttack()
  38. */
  39. @Override
  40. public Blast showAttack() {
  41. // TODO Auto-generated method stub
  42. //扣血
  43. blood-=new EnemyTank().power;
  44. return new Blast(this, true);
  45. }
  46.  
  47. @Override
  48. public boolean isDestoryable() {
  49. // TODO Auto-generated method stub
  50. return blood<=0;
  51. }
  52.  
  53. @Override
  54. public void draw() {
  55. // TODO Auto-generated method stub
  56. String res="";
  57. switch (direction) {
  58. case UP:
  59. res = "res/img/tank_u.gif";
  60. break;
  61. case DOWN:
  62. res = "res/img/tank_d.gif";
  63. break;
  64. case LEFT:
  65. res = "res/img/tank_l.gif";
  66. break;
  67. case RIGHT:
  68. res = "res/img/tank_r.gif";
  69. break;
  70. default:
  71. break;
  72. }
  73. try {
  74. DrawUtils.draw(res, x, y);
  75. } catch (IOException e) {
  76. // TODO Auto-generated catch block
  77. e.printStackTrace();
  78. }
  79. }
  80.  
  81. /*
  82. * 坦克的移动
  83. */
  84. public void move(Direction direction) {
  85. //如果传过来的方向和坦克不能动的方向一致,则移动最小
  86. if(badDirection==direction) {
  87. //移动最小间距
  88. switch (direction) {
  89. case UP:
  90. y -= badSpeed;
  91. break;
  92. case DOWN:
  93. y += badSpeed;
  94. break;
  95. case LEFT:
  96. x -= badSpeed;
  97. break;
  98. case RIGHT:
  99. x += badSpeed;
  100. break;
  101. default:
  102. break;
  103. }
  104. return ;
  105. }
  106.  
  107. //刷新方向,用户按下的方向传给坦克:坦克的方向
  108. if(this.direction!=direction)
  109. {
  110. this.direction=direction;
  111. return ;
  112. }
  113.  
  114. switch (direction) {
  115. case UP:
  116. y -= speed;
  117. break;
  118. case DOWN:
  119. y += speed;
  120. break;
  121. case LEFT:
  122. x -= speed;
  123. break;
  124. case RIGHT:
  125. x += speed;
  126. break;
  127. default:
  128. break;
  129. }
  130.  
  131. /*
  132. * 边界处理
  133. */
  134. if(x<0) {x=0;}
  135. if(x>config.WIDTH-64) {x=config.WIDTH-64;}
  136. if(y<0) {y=0;}
  137. if(y>config.HIGHT-64) {y=config.HIGHT-64;}
  138. }
  139.  
  140. }
  1.  
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.DrawUtils;
  6.  
  7. import Event.Blockable;
  8. import Event.Destoryable;
  9. import Event.Hitable;
  10.  
  11. public class Steel extends Element implements Blockable, Hitable, Destoryable{
  12. /*
  13. * 属性:
  14. */
  15. //1.血量
  16. private int blood=5;
  17.  
  18. public Steel(int x, int y) {
  19. super(x, y);
  20.  
  21. //获取铁墙的宽高
  22. try {
  23. int size[]=DrawUtils.getSize("res/img/steel.gif");
  24. width=size[0];
  25. hight=size[1];
  26. } catch (IOException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  31.  
  32. @Override
  33. public void draw() {
  34. // TODO Auto-generated method stub
  35. try {
  36. DrawUtils.draw("res/img/steel.gif", x, y);
  37. } catch (IOException e) {
  38. // TODO Auto-generated catch block
  39. e.printStackTrace();
  40. }
  41. }
  42.  
  43. /*
  44. * 挨打后的反映(non-Javadoc)
  45. * @see Event.Hitable#showAttack()
  46. */
  47. @Override
  48. public Blast showAttack() {
  49. // TODO Auto-generated method stub
  50. blood--;
  51. return new Blast(this,true);
  52. }
  53.  
  54. /*
  55. * 销毁时响应的动作(non-Javadoc)
  56. * @see Event.Destoryable#showDestory()
  57. */
  58. @Override
  59. public Blast showDestory() {
  60. // TODO Auto-generated method stub
  61. return new Blast(this);
  62. }
  63.  
  64. /*
  65. * 销毁铁墙(non-Javadoc)
  66. * @see Event.Destoryable#isDestoryable()
  67. */
  68. @Override
  69. public boolean isDestoryable() {
  70. // TODO Auto-generated method stub
  71. return blood<=0;
  72. }
  73. }
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.DrawUtils;
  6.  
  7. import Event.Blockable;
  8. import Event.Destoryable;
  9. import Event.Hitable;
  10.  
  11. public class Wall extends Element implements Hitable, Blockable, Destoryable{
  12.  
  13. //血量
  14. private int blood=3;
  15.  
  16. /*
  17. * 含参数的构造函数
  18. */
  19. public Wall(int x, int y) {
  20. // TODO Auto-generated constructor stub
  21. super(x, y);
  22.  
  23. //获取宽度,长度
  24. try {
  25. int size[]=DrawUtils.getSize("res/img/wall.gif");
  26. width=size[0];
  27. hight=size[1];
  28. } catch (IOException e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. }
  32.  
  33. }
  34. /*
  35. *绘制
  36. * @see domain.Element#draw()
  37. */
  38. @Override
  39. public void draw() {
  40. try {
  41. DrawUtils.draw("res/img/wall.gif", x, y);
  42. } catch (IOException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. }
  47.  
  48. /*
  49. * 挨打
  50. * Blast爆炸类
  51. */
  52. public Blast showAttack() {
  53. blood--; //挨打一次血量减少
  54. return new Blast(this, true);
  55. }
  56.  
  57. /*
  58. * 销毁判断,血量小于等于0时,就销毁
  59. */
  60. public boolean isDestoryable() {return blood<=0;}
  61.  
  62. /*
  63. * 销毁响应动作
  64. */
  65. public Blast showDestory() {return new Blast(this);}
  66.  
  67. }
  1. package domain;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.itheima.game.utils.DrawUtils;
  6.  
  7. import Event.Blockable;
  8.  
  9. public class Water extends Element implements Blockable{
  10.  
  11. public Water(int x, int y) {
  12. super(x, y);
  13. try {
  14. int size[]=DrawUtils.getSize("res/img/water.gif");
  15. width=size[0]; hight=size[1];
  16. } catch (IOException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. }
  20.  
  21. }
  22. @Override
  23. public void draw() {
  24. try {
  25. DrawUtils.draw("res/img/water.gif", x, y);
  26. } catch (IOException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  1. package Grame;
  2.  
  3. public class APP {
  4. /*
  5. * 游戏的主入口,所有代码的主入口
  6. */
  7. public static void main(String[] args) {
  8. //绘制窗口
  9. MyWindows gr=new MyWindows(config.TITLE, config.WIDTH, config.HIGHT, config.PFS);
  10.  
  11. //开始游戏
  12. gr.start();
  13.  
  14. }
  15.  
  16. }
  1.  
  1. package Grame;
  2.  
  3. public interface config {
  4. String TITLE="坦克大战";
  5. int WIDTH=64*15;
  6. int HIGHT=64*10;
  7. int PFS=50;
  8. }
  1. package Grame;
  2.  
  3. import java.awt.HeadlessException;
  4. import java.awt.Window;
  5. import java.io.IOException;
  6. import java.nio.file.Watchable;
  7. import java.util.Comparator;
  8. import java.util.concurrent.CopyOnWriteArrayList;
  9.  
  10. import org.itheima.game.utils.DrawUtils;
  11. import org.itheima.game.utils.SoundUtils;
  12. import org.lwjgl.input.Keyboard;
  13. import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID;
  14.  
  15. import Event.Attackable;
  16. import Event.Blockable;
  17. import Event.Destoryable;
  18. import Event.Hitable;
  19. import Event.Moveable;
  20. import domain.Blast;
  21. import domain.Bullet;
  22. import domain.Direction;
  23. import domain.Element;
  24. import domain.EnemyTank;
  25. import domain.Grass;
  26. import domain.Mytank;
  27. import domain.Steel;
  28. import domain.Tank;
  29. import domain.Wall;
  30. import domain.Water;
  31.  
  32. /*
  33. * 游戏窗口类
  34. *
  35. */
  36. public class MyWindows extends org.itheima.game.Window{
  37.  
  38. //定义:集合,存储元素
  39. //CopyOnWeiteArrayList 可以解决并发修改异常的集合
  40. CopyOnWriteArrayList<Element>list=new CopyOnWriteArrayList<>();
  41. //创建坦克对象
  42. Mytank mt;
  43. //创建敌方坦克
  44. EnemyTank et1;
  45. EnemyTank et2;
  46.  
  47. public MyWindows(String title, int width, int height, int fps) {super(title, width, height, fps);}
  48.  
  49. /*
  50. * 绘制窗口时运行
  51. */
  52. @Override
  53. protected void onCreate() {
  54. //播放开始音乐
  55. try {
  56. SoundUtils.play("res/snd/start.wav");
  57. } catch (IOException e) {
  58. // TODO Auto-generated catch block
  59. e.printStackTrace();
  60. }
  61.  
  62. //创建砖墙
  63. for(int i=0;i<config.WIDTH/64-1;++i) {
  64. Wall wall=new Wall(i*64, 64);
  65. addElement(wall);
  66. }
  67. //创建水墙
  68. for(int i=1;i<config.WIDTH/64;++i) {
  69. Water water=new Water(i*64, 64*3);
  70. addElement(water);
  71. }
  72. //绘制铁墙
  73. for(int i=0;i<config.WIDTH/64-1;++i) {
  74. Steel steel=new Steel(i*64, 64*5);
  75. addElement(steel);
  76. }
  77. //创造草坪
  78. for(int i=1;i<config.WIDTH/64;++i) {
  79. Grass grass=new Grass(i*64, 64*7);
  80. addElement(grass);
  81. }
  82.  
  83. //创造己方坦克
  84. mt=new Mytank(config.WIDTH/2-32, config.HIGHT-64);
  85. addElement(mt);
  86. //创建敌方坦克
  87. et1=new EnemyTank(0, 0);
  88. et2=new EnemyTank(config.WIDTH-64, 0);
  89. addElement(et1);
  90. addElement(et2);
  91. }
  92.  
  93. //鼠标事件
  94. @Override
  95. protected void onMouseEvent(int key, int x, int y) {
  96. // TODO Auto-generated method stub
  97.  
  98. }
  99.  
  100. //键盘事件
  101. @Override
  102. protected void onKeyEvent(int key) {
  103. // TODO Auto-generated method stub
  104. switch (key) {
  105. case Keyboard.KEY_UP:
  106. mt.move(Direction.UP);
  107. break;
  108. case Keyboard.KEY_DOWN:
  109. mt.move(Direction.DOWN);
  110. break;
  111. case Keyboard.KEY_LEFT:
  112. mt.move(Direction.LEFT);
  113. break;
  114. case Keyboard.KEY_RIGHT:
  115. mt.move(Direction.RIGHT);
  116. break;
  117. case Keyboard.KEY_SPACE: //回车键
  118. Bullet shot=mt.shot(); //发射子弹
  119. //对子弹进行非空校验
  120. if(shot!=null) {
  121. addElement(shot);
  122. }
  123. break;
  124. default:
  125. break;
  126. }
  127. }
  128.  
  129. //事实刷新
  130. @Override
  131. protected void onDisplayUpdate() {
  132. // TODO Auto-generated method stub
  133. //如果己方坦克已经销毁,或者敌方坦克都销毁,则游戏结束
  134. if(mt.isDestory()||(et1.isDestory()&&et2.isDestory())) {
  135. list.clear();
  136. //绘制结束图片
  137. try {
  138. DrawUtils.draw("res/img/gameover.gif", (config.WIDTH-96)/2, (config.HIGHT-96)/2);
  139. } catch (IOException e1) {
  140. // TODO Auto-generated catch block
  141. e1.printStackTrace();
  142. }
  143. //停止所有音乐
  144. SoundUtils.stop("res/snd/fire.wav");
  145.  
  146. return;
  147. }
  148.  
  149. //绘制元素
  150. for(Element e:list) {
  151. e.draw();
  152. }
  153.  
  154. //调用敌方坦克的随机移动的功能
  155. for(Element e:list) {
  156. if(e instanceof EnemyTank) {
  157. //如果是敌方坦克,就随机移动
  158. ((EnemyTank)e).move();
  159.  
  160. //如果是敌方坦克,就调用其发射子弹的能力
  161. Bullet shot=((EnemyTank)e).shot();
  162. if(shot!=null) {
  163. addElement(shot);
  164. }
  165. }
  166. }
  167.  
  168. //销毁出界子弹
  169. for(Element e:list) {
  170. //如果是子弹
  171. if(e instanceof Bullet) {
  172. //判断子弹是否出界
  173. boolean flag=((Bullet)e).isDestoryable();
  174. if(flag) {
  175. list.remove(e);
  176. }
  177. }
  178. }
  179.  
  180. //销毁所有需要销毁的实物
  181. for(Element e:list) {
  182. //判断事物是否需要销毁
  183. if( e instanceof Destoryable) {
  184. boolean blast=((Destoryable)e).isDestoryable();
  185. if(blast) {
  186. //说明事物需要销毁
  187. //1.绘制销毁时的爆炸物
  188. Blast blast2=((Destoryable)e).showDestory();
  189. if(blast2!=null) {
  190. addElement(blast2);
  191. }
  192.  
  193. //消除该事物
  194. list.remove(e);
  195. }
  196. }
  197. }
  198.  
  199. /*
  200. * 校验:运动物体 与 障碍物 的碰撞
  201. */
  202. for(Element e1:list) {
  203. for(Element e2:list) {
  204. if(e1!=e2&&e1 instanceof Moveable&&e2 instanceof Blockable) {
  205. //说明 e1运动物 与 e2 障碍物
  206. boolean flag=((Moveable)e1).checkHit((Blockable)e2);
  207. if(flag) { //说明碰撞了
  208. break;
  209. }
  210. }
  211. }
  212. }
  213.  
  214. /*
  215. * 攻击者 与 被攻击者 是否碰撞
  216. */
  217. for(Element e1: list) {
  218. for(Element e2: list) {
  219. if(e1 instanceof Attackable&&e2 instanceof Hitable) {
  220. //说明 e1 攻击者 e2 被攻击者
  221. boolean flag=((Attackable)e1).checkAttack((Hitable)e2);
  222. if(flag) {
  223. //校验:是己方坦克发过来的子弹,是则不能攻击,否则能产生攻击
  224. if(((Bullet)e1).getTank().getClass()==e2.getClass()) {
  225. continue;
  226. }
  227.  
  228. //校验:能不能攻击敌军
  229. //子弹销毁
  230. list.remove(e1);
  231. //被攻击者受到攻击,绘制出爆炸物
  232. Blast blast=((Hitable)e2).showAttack();
  233. addElement(blast);
  234. }
  235. }
  236. }
  237. }
  238.  
  239. }
  240.  
  241. /*
  242. * 添加元素
  243. */
  244. public void addElement(Element e) {
  245. list.add(e);
  246.  
  247. //对集合按照渲染级别进行排序
  248. list.sort(new Comparator<Element>() {
  249.  
  250. @Override
  251. public int compare(Element o1, Element o2) {
  252. // TODO Auto-generated method stub
  253. return o1.getOrder()-o2.getOrder();
  254. }
  255. });
  256. }
  257.  
  258. }
  1.  

(java项目)坦克大战 2.0的更多相关文章

  1. Java小项目--坦克大战(version1.0)

    Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...

  2. Java实例-坦克大战

    Java实例-坦克大战 一.样例图片 二.类图结构 坦克大战中的所有类 类的关系图 我的坦克类 三.说明 1.每一个新的独立运行的东西就是一个线程,像我方坦克,像敌方坦克,像所有的子弹 2.每一个线程 ...

  3. 【java版坦克大战---准备篇】 java 绘图

    要写坦克大战当然要先画出坦克.java画图是基础. package com.game; import java.awt.*; import javax.swing.*; public class Pr ...

  4. 例子:web版坦克大战1.0

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Unity项目 - 坦克大战3D TankBattle

    目录 游戏原型 项目演示 绘图资源 代码实现 技术探讨 参考来源 游戏原型 游戏玩法:在有界的战场上,玩家将驾驶坦克,代表绿色阵营,与你的队友一起击溃红蓝阵营的敌人,在这场三方大战中夺得胜利! 操作指 ...

  6. java的坦克大战

    一个渣渣写坦克大战的步骤: 1.首先创造好一个坦克和一个GAME框架,并且坦克能够跟着键盘键位移动 案例:在我的博客文件中保存,它的名字是:tankwar0100.rar 主要解决了:1.坦克背景框 ...

  7. 【 java版坦克大战--事件处理】 坦克动起来了

    折腾了这么久,坦克总算能动了.只贴代码编辑不给上首页,花了半个小时的时间写了n多注释. 再顺便把绘图的原理发在这里: 绘图原理 Component类提供了两个和绘图有关的重要方法: ①   paint ...

  8. 【 java版坦克大战--绘图技术】 绘制坦克

    通过上一节,我们学会的用java绘图.那现在就用java绘制自己坦克. 首先通过分析坦克由这几部分组成.如图 各个部件的长宽如图.15,10为圆心. /** * 坦克游戏的1.0版 * 1.画出坦克 ...

  9. 【 java版坦克大战--事件处理】 键盘控制小球上下左右移动

    上一节已经学习了事件处理,这一节需要完成通过键盘的上下左右键控制小球移动. 然后再通过应用到我们绘制的坦克上. /** * 加深对事件处理机制的理解 * 通过光标的上下左右键,控制小球的左右上下移动. ...

随机推荐

  1. Struts2之ValueStack、ActionContext

    今天在看Action获取Resquest.Response时,发现了一个词:值栈.于是今天一天都在看,了解了值栈不仅能知道Action怎么获取request.response等这些,还会了解OGNL语 ...

  2. 探秘 Java 热部署二(Java agent premain)

    # 前言 在前文 探秘 Java 热部署 中,我们通过在死循环中重复加载 ClassLoader 和 Class 文件实现了热部署的功能,但我们也指出了缺点-----不够灵活.需要手动修改文件等操作. ...

  3. Linux常用基本命令:三剑客命令之-awk 三元表达式

    awk 3元表达式,if...else结构都可以用3元表达式改写 ghostwu@dev:~/linux/awk$ awk -v FS=":" '{ type=$3>=100 ...

  4. CSS-高度塌陷问题

    目录 CSS-高度塌陷问题 表现 产生的原因 高度塌陷的解决办法: BFC相关 CSS-高度塌陷问题 表现 例如: HTML: <div class="first"> ...

  5. UED与UCD

    UED User Experience Design(用户体验设计),简称UED.UED是以用户为中心的一种设计手段,以用户需求为目标而进行的设计.设计过程注重以用户为中心,用户体验的概念从开发的最早 ...

  6. 【代码笔记】Web-HTML-标题

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  7. css选择器:基本选择器

    基本选择器 1.通用元素选择器 *表示应用到所有的标签. *{ padding:0px; margin:0px; } 2.元素/标签选择器 匹配所有p标签的元素 p{ color:red; backg ...

  8. JS笔记(二):对象

    (一) 对象 对象是JS的基本数据类型,类似于python的字典.然而对象不仅仅是键值对的映射,除了可以保持自有的属性,JS对象还可以从一个称为原型的对象继承属性,对象的方法通常是继承的属性.(这种对 ...

  9. exception is feign.RetryableException: Connection refused (Connection refused) executing GET http://......

    2018-03-23 10:00:58.430 ERROR 31889 --- [nio-4321-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Se ...

  10. [20171107]dbms_shared_pool.pin补充.txt

    [20171107]dbms_shared_pool.pin补充.txt --//上午的测试,做一些补充,主要还是一些理解问题. 1.环境:SCOTT@book> @ &r/ver1 P ...