• Java游戏制作——王者荣耀


    一.准备工作

    首先创建一个新的Java项目命名为“王者荣耀”,并在src下创建两个包为“com.sxt"、”com.stx.beast",在相应的包中创建所需的类。

    创建一个名为“img”文件夹来储存所需的图片素材。

    二.代码呈现

    1. package com.sxt;
    2. import javax.swing.*;
    3. import java.awt.*;
    4. public class Background extends GameObject {
    5. public Background(GameFrame gameFrame) {
    6. super(gameFrame);
    7. // TODO Auto-generated constructor stub
    8. }
    9. Image bg = Toolkit.getDefaultToolkit().getImage("img/Map.jpg");
    10. public void paintSelf(Graphics g){
    11. g.drawImage(bg,0,0,null);
    12. }
    13. @Override
    14. public Rectangle getRec() {
    15. // TODO Auto-generated method stub
    16. return null;
    17. }
    18. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Image;
    5. import java.awt.Rectangle;
    6. import java.awt.event.ActionEvent;
    7. import java.awt.event.ActionListener;
    8. import java.awt.event.KeyEvent;
    9. import java.util.ArrayList;
    10. import javax.swing.JButton;
    11. public abstract class Champion extends GameObject {
    12. // 移动
    13. public boolean up, down, left, right;
    14. // 移动图集
    15. static String[] imgs = new String[8];
    16. // 第几张图片
    17. int moveCount = 1;
    18. //技能图片
    19. Image abilityOne;
    20. Image abilityTwo;
    21. Image abilityThree;
    22. //英雄头像
    23. Image classical;
    24. //技能冷却时间
    25. int coolDownTimeOne;
    26. int coolDownTimeTwo;
    27. int coolDownTimeThree;
    28. //三个技能是否处于冷却状态
    29. boolean coolDownOne = true;
    30. boolean coolDownTwo = true;
    31. boolean coolDownThree = true;
    32. //英雄列表
    33. ArrayList championList = new ArrayList();
    34. static {
    35. for (int i = 1; i < 8; i++) {
    36. imgs[i] = "img/" + i + ".png";
    37. }
    38. }
    39. public Champion(GameFrame gameFrame, int x, int y) {
    40. super(gameFrame);
    41. setImg("img/stand.png");
    42. setX(x);
    43. setY(y);
    44. setSpd(75);
    45. setHp(24000);
    46. setDis(250);
    47. setAttackCoolDownTime(100);
    48. setCurrentHp(getHp());
    49. championList.add(new ChampionDaji(gameFrame));
    50. championList.add(new ChampionHouyi(gameFrame));
    51. }
    52. public Champion(GameFrame gameFrame) {
    53. // TODO Auto-generated constructor stub
    54. super(gameFrame);
    55. setImg("img/stand.png");
    56. setX(700);
    57. setY(3800);
    58. setSpd(75);
    59. setHp(24000);
    60. setDis(250);
    61. setAttackCoolDownTime(100);
    62. setCurrentHp(getHp());
    63. }
    64. public void keyPressed(KeyEvent e) {
    65. int key = e.getKeyCode();
    66. if (key == KeyEvent.VK_D) {
    67. right = true;
    68. }
    69. if (key == KeyEvent.VK_A) {
    70. left = true;
    71. }
    72. if (key == KeyEvent.VK_W) {
    73. up = true;
    74. }
    75. if (key == KeyEvent.VK_S) {
    76. down = true;
    77. }
    78. }
    79. public void keyReleased(KeyEvent e) {
    80. int key = e.getKeyCode();
    81. if (key == KeyEvent.VK_D) {
    82. right = false;
    83. }
    84. if (key == KeyEvent.VK_A) {
    85. left = false;
    86. }
    87. if (key == KeyEvent.VK_W) {
    88. up = false;
    89. }
    90. if (key == KeyEvent.VK_S) {
    91. down = false;
    92. }
    93. }
    94. public void move() {
    95. if (up) {
    96. setY(getY() - getSpd());
    97. }
    98. if (down) {
    99. setY(getY() + getSpd());
    100. }
    101. if (left) {
    102. setX(getX() - getSpd());
    103. }
    104. if (right) {
    105. setX(getX() + getSpd());
    106. }
    107. if (up || down || left || right) {
    108. setImg(imgs[moveCount]);
    109. moveCount++;
    110. if (moveCount == 8) {
    111. moveCount = 1;
    112. }
    113. } else {
    114. setImg("img/stand.png");
    115. }
    116. }
    117. /**
    118. * 添加三个技能按钮
    119. * */
    120. public void addButton() {
    121. JButton button1 = new JButton();
    122. button1.setSize(100, 100);
    123. button1.setLocation(1056, 513);
    124. button1.addActionListener(new ActionListener() {
    125. @Override
    126. public void actionPerformed(ActionEvent e) {
    127. abilityOne();
    128. }
    129. });
    130. JButton button2 = new JButton();
    131. button2.setSize(100, 100);
    132. button2.setLocation(1090, 370);
    133. button2.addActionListener(new ActionListener() {
    134. @Override
    135. public void actionPerformed(ActionEvent e) {
    136. abilityTwo();
    137. }
    138. });
    139. JButton button3 = new JButton();
    140. button3.setSize(100, 100);
    141. button3.setLocation(1220, 300);
    142. button3.addActionListener(new ActionListener() {
    143. @Override
    144. public void actionPerformed(ActionEvent e) {
    145. abilityThree();
    146. }
    147. });
    148. gameFrame.add(button1);
    149. gameFrame.add(button2);
    150. gameFrame.add(button3);
    151. }
    152. public abstract void abilityOne();
    153. public abstract void abilityTwo();
    154. public abstract void abilityThree();
    155. public abstract void abilityEffect(Graphics g);
    156. @Override
    157. public void paintSelf(Graphics g) {
    158. // TODO Auto-generated method stub
    159. // 生命值为0
    160. if (getCurrentHp() <= 0) {
    161. setAlive(false);
    162. gameFrame.removeList.add(this);
    163. } else {
    164. // 添加生命值
    165. addHp(g, 30, 80, 80, 20, Color.GREEN);
    166. //绘制技能图片
    167. g.drawImage(abilityOne, getX() + 360, getY() + 180, null);
    168. g.drawImage(abilityTwo, getX() + 400, getY() + 40, null);
    169. g.drawImage(abilityThree, getX() + 520, getY() - 30, null);
    170. // 绘制图片
    171. g.drawImage(this.getImg(), getX() - 33, getY() - 50, null);
    172. // 改变画笔颜色
    173. //g.setColor(Color.GREEN);
    174. // 绘制中心圆点
    175. //g.fillOval(getX(), getY(), 10, 10);
    176. // 绘制矩形边框
    177. //g.drawRect(getX() - 23, getY() - 50, 60, 120);
    178. move();
    179. abilityEffect(g);
    180. }
    181. }
    182. @Override
    183. public Rectangle getRec() {
    184. // TODO Auto-generated method stub
    185. return new Rectangle(getX() - 30, getY() - 60, 60, 120);
    186. }
    187. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Rectangle;
    5. import com.sxt.beast.Beast;
    6. public class Bullet extends GameObject {
    7. // 发射子弹的游戏元素
    8. GameObject attacker;
    9. // 目标
    10. GameObject target;
    11. // 攻击力
    12. int ad;
    13. public Bullet(GameFrame gameFrame, GameObject attacker, GameObject target, int ad, int spd) {
    14. super(attacker.getX(), attacker.getY(), gameFrame);
    15. this.attacker = attacker;
    16. this.target = target;
    17. setAd(ad);
    18. setSpd(spd);
    19. // TODO Auto-generated constructor stub
    20. }
    21. public Bullet(GameFrame gameFrame, GameObject attacker, GameObject target, int ad, int spd, String img) {
    22. super(attacker.getX(), attacker.getY(), gameFrame);
    23. this.attacker = attacker;
    24. this.target = target;
    25. setImg(img);
    26. setAd(ad);
    27. setSpd(spd);
    28. // TODO Auto-generated constructor stub
    29. }
    30. public Bullet() {
    31. super();
    32. // TODO Auto-generated constructor stub
    33. }
    34. public void move() {
    35. // 子弹与目标碰撞,子弹消失,目标减血
    36. if (recIntersectsRec(getRec(), target.getRec())) {
    37. if (Beast.class.isAssignableFrom(target.getClass())) {
    38. target.setTarget(gameFrame.player);
    39. target.setHasTarget(true);
    40. }
    41. target.setCurrentHp(target.getCurrentHp() - getAd());
    42. gameFrame.removeList.add(this);
    43. }
    44. double dis = getDis(getX(), getY(), target.getX(), target.getY());
    45. int xSpeed = (int) (getSpd() * (target.getX() - getX()) / dis);
    46. int ySpeed = (int) (getSpd() * (target.getY() - getY()) / dis);
    47. setX(getX() + xSpeed);
    48. setY(getY() + ySpeed);
    49. }
    50. @Override
    51. public void paintSelf(Graphics g) {
    52. // TODO Auto-generated method stub
    53. g.drawImage(getImg(), getX() - 16, getY() - 16, null);
    54. if (this.getImg() == null) {
    55. g.setColor(Color.BLACK);
    56. g.fillOval(getX() - 5, getY() - 5, 10, 10);
    57. g.drawRect(getX() - 5, getY() - 5, 10, 10);
    58. }
    59. move();
    60. }
    61. @Override
    62. public Rectangle getRec() {
    63. // TODO Auto-generated method stub
    64. return new Rectangle(getX() - 5, getY() - 5, 10, 10);
    65. }
    66. /**
    67. * @return the ad
    68. */
    69. public int getAd() {
    70. return ad;
    71. }
    72. /**
    73. * @param ad the ad to set
    74. */
    75. public void setAd(int ad) {
    76. this.ad = ad;
    77. }
    78. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Polygon;
    5. import java.awt.Toolkit;
    6. import java.awt.event.MouseAdapter;
    7. import java.awt.event.MouseEvent;
    8. import java.util.ArrayList;
    9. import java.util.Random;
    10. import com.sxt.beast.Beast;
    11. public class ChampionDaji extends Champion {
    12. // 技能是否处于释放状态
    13. boolean ifAbilityOne = false;
    14. boolean ifAbilityTwo = false;
    15. // 鼠标监视器
    16. MouseMonitor m;
    17. // 一技能多边形
    18. Polygon p;
    19. // 一技能三角函数
    20. double sin;
    21. double cos;
    22. // 一技能已经攻击过的目标
    23. ArrayList attacked;
    24. // 一技能移动次数
    25. int step = 0;
    26. // 技能二目标
    27. GameObject abilityTwoTarget;
    28. // 技能二子弹
    29. Bullet abilityTwoBullet;
    30. // 三技能子弹列表
    31. Bullet[] bulletList = { new Bullet(), new Bullet(), new Bullet(), new Bullet(), new Bullet() };
    32. public ChampionDaji(GameFrame gameFrame) {
    33. super(gameFrame);
    34. abilityOne = Toolkit.getDefaultToolkit().getImage("img/abilityOne.jpg");
    35. abilityTwo = Toolkit.getDefaultToolkit().getImage("img/abilityTwo.jpg");
    36. abilityThree = Toolkit.getDefaultToolkit().getImage("img/abilityThree.jpg");
    37. classical = Toolkit.getDefaultToolkit().getImage("img/Classical.jpg");
    38. // 三个技能冷却时间
    39. coolDownTimeOne = 6000;
    40. coolDownTimeTwo = 8000;
    41. coolDownTimeThree = 8000;
    42. }
    43. public void exit() {
    44. this.gameFrame.removeMouseListener(m);
    45. }
    46. public void abilityOneMove() {
    47. p.translate((int) (50 * cos), -(int) (50 * sin));
    48. for (GameObject redObj : gameFrame.objList) {
    49. // 是红色方小兵 && 发生碰撞 && 没在attacked列表里
    50. if (redObj instanceof MinionRed && p.intersects(redObj.getRec()) && attacked.indexOf(redObj) == -1) {
    51. // 小兵扣血,添加到attacked里
    52. redObj.setCurrentHp(redObj.getCurrentHp() - 400);
    53. attacked.add(redObj);
    54. }else if (Beast.class.isAssignableFrom(redObj.getClass()) && p.intersects(redObj.getRec()) && attacked.indexOf(redObj) == -1) {
    55. redObj.setCurrentHp(redObj.getCurrentHp() - 400);
    56. attacked.add(redObj);
    57. }
    58. }
    59. }
    60. @Override
    61. public void abilityOne() {
    62. // TODO Auto-generated method stub
    63. if (coolDownOne) {
    64. m = new MouseMonitor();
    65. p = new Polygon();
    66. gameFrame.addMouseListener(m);
    67. attacked = new ArrayList();
    68. }
    69. }
    70. @Override
    71. public void abilityTwo() {
    72. // TODO Auto-generated method stub
    73. if (coolDownTwo) {
    74. boolean find = false;
    75. for (GameObject redObj : gameFrame.objList) {
    76. // 是红色小兵 && 距离小于250 && 存活
    77. if ((redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass())) && recIntersectsCir(redObj.getRec(), getX(), getY(), 250)
    78. && redObj.isAlive()) {
    79. // 添加子弹
    80. abilityTwoBullet = new Bullet(gameFrame, this, redObj, 250, 60, "img/abilityTwoBullet.png");
    81. gameFrame.objList.add(abilityTwoBullet);
    82. // 给目标赋值
    83. abilityTwoTarget = redObj;
    84. // 释放二技能
    85. ifAbilityTwo = true;
    86. find = true;
    87. break;
    88. }
    89. }
    90. if (find) {
    91. new AbilityTwoCD().start();
    92. find = false;
    93. }
    94. }
    95. }
    96. /**
    97. * 点击技能三释放技能 先将技能范围内目标储存到targetList里 提前定义五个子弹 技能释放时初始化五个子弹 子弹目标从targetList里随机选择
    98. * 如果期间目标死亡,制作一个目标替身,生命值设置为true 子弹与目标或替身碰撞后消失
    99. */
    100. @Override
    101. public void abilityThree() {
    102. // TODO Auto-generated method stub
    103. // 三技能没在冷却状态
    104. if (coolDownThree) {
    105. // 创建列表来储存目标
    106. ArrayList targetList = new ArrayList();
    107. // 遍历redList
    108. for (int i = 0; i < gameFrame.objList.size(); i++) {
    109. GameObject target = gameFrame.objList.get(i);
    110. // 是红色小兵 && 在技能范围里 && 存活
    111. if ((target instanceof MinionRed || Beast.class.isAssignableFrom(target.getClass())) && recIntersectsCir(target.getRec(), getX(), getY(), 250)
    112. && target.isAlive()) {
    113. targetList.add(target);
    114. }
    115. }
    116. //找到目标
    117. if(targetList.size() != 0) {
    118. //初始化五个子弹,随机攻击列表里的目标
    119. Random random = new Random();
    120. int count = 0;
    121. while(count < 5) {
    122. int r = random.nextInt(targetList.size());
    123. if(!targetList.get(r).isAlive()) {
    124. //目标死亡,制作替身
    125. GameObject substitute = targetList.get(r);
    126. substitute.setAlive(true);
    127. bulletList[count] = new Bullet(gameFrame, this, substitute, 250, 60, "img/abilityTwoBullet.png");
    128. }else {
    129. bulletList[count] = new Bullet(gameFrame, this, targetList.get(r), 250, 60, "img/abilityTwoBullet.png");
    130. }
    131. count++;
    132. }
    133. new AbilityThreeBulletCD().start();
    134. new AbilityThreeCD().start();
    135. }
    136. }
    137. }
    138. @Override
    139. public void abilityEffect(Graphics g) {
    140. // TODO Auto-generated method stub
    141. if (ifAbilityOne) {
    142. g.setColor(Color.RED);
    143. g.fillPolygon(p);
    144. abilityOneMove();
    145. step++;
    146. if (step == 10) {
    147. step = 0;
    148. ifAbilityOne = false;
    149. }
    150. }
    151. if (ifAbilityTwo) {
    152. System.out.println(abilityTwoTarget.beControlled);
    153. if (abilityTwoBullet.getRec().intersects(abilityTwoTarget.getRec())) {
    154. new AbilityControllCD().start();
    155. ifAbilityTwo = false;
    156. }
    157. }
    158. }
    159. // 技能一冷却时间
    160. class AbilityOneCD extends Thread {
    161. public void run() {
    162. // 将技能一设置为冷却状态
    163. coolDownOne = false;
    164. // 线程休眠
    165. try {
    166. // one来表示一技能冷却时间
    167. int one = coolDownTimeOne;
    168. while (one > 0) {
    169. Thread.sleep(1000);
    170. System.out.println("一技能冷却时间: " + one / 1000);
    171. one -= 1000;
    172. }
    173. } catch (Exception e) {
    174. e.printStackTrace();
    175. }
    176. // 将技能一设置为攻击状态
    177. coolDownOne = true;
    178. // 线程终止
    179. this.stop();
    180. }
    181. }
    182. // 技能二冷却时间
    183. class AbilityTwoCD extends Thread {
    184. public void run() {
    185. // 将技能二设置为冷却状态
    186. coolDownTwo = false;
    187. // 线程休眠
    188. try {
    189. // one来表示二技能冷却时间
    190. int two = coolDownTimeTwo;
    191. while (two > 0) {
    192. Thread.sleep(1000);
    193. System.out.println("二技能冷却时间: " + two / 1000);
    194. two -= 1000;
    195. }
    196. } catch (Exception e) {
    197. e.printStackTrace();
    198. }
    199. // 将技能二设置为攻击状态
    200. coolDownTwo = true;
    201. // 线程终止
    202. this.stop();
    203. }
    204. }
    205. // 技能二控制时间
    206. class AbilityControllCD extends Thread {
    207. public void run() {
    208. abilityTwoTarget.beControlled = true;
    209. // 线程休眠
    210. try {
    211. Thread.sleep(20000);
    212. } catch (Exception e) {
    213. e.printStackTrace();
    214. }
    215. abilityTwoTarget.beControlled = false;
    216. this.stop();
    217. }
    218. }
    219. // 技能三冷却时间
    220. class AbilityThreeCD extends Thread {
    221. public void run() {
    222. // 将技能三设置为冷却状态
    223. coolDownThree = false;
    224. // 线程休眠
    225. try {
    226. // three来表示三技能冷却时间
    227. int three = coolDownTimeThree;
    228. while (three > 0) {
    229. Thread.sleep(1000);
    230. System.out.println("三技能冷却时间: " + three / 1000);
    231. three -= 1000;
    232. }
    233. } catch (Exception e) {
    234. e.printStackTrace();
    235. }
    236. // 将技能三设置为攻击状态
    237. coolDownThree = true;
    238. // 线程终止
    239. this.stop();
    240. }
    241. }
    242. //技能三子弹时间间隔
    243. class AbilityThreeBulletCD extends Thread{
    244. public void run() {
    245. try {
    246. gameFrame.objList.add(bulletList[0]);
    247. Thread.sleep(200);
    248. gameFrame.objList.add(bulletList[1]);
    249. Thread.sleep(200);
    250. gameFrame.objList.add(bulletList[2]);
    251. Thread.sleep(200);
    252. gameFrame.objList.add(bulletList[3]);
    253. Thread.sleep(200);
    254. gameFrame.objList.add(bulletList[4]);
    255. }catch(Exception e) {
    256. e.printStackTrace();
    257. }
    258. this.stop();
    259. }
    260. }
    261. // 鼠标监视器
    262. private class MouseMonitor extends MouseAdapter {
    263. @Override
    264. public void mousePressed(MouseEvent e) {// 当鼠标点击时
    265. int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;
    266. double dis = getDis(mouseX, mouseY, playerX, playerY);
    267. // 三角函数
    268. cos = (mouseX - playerX) / dis;
    269. sin = -(mouseY - playerY) / dis;
    270. // 坐标差
    271. int difX = (int) (60 * sin);
    272. int difY = (int) (60 * cos);
    273. p.addPoint(getX() - difX, getY() - difY);
    274. p.addPoint(getX() + difX, getY() + difY);
    275. p.addPoint(getX() + difX + (int) (20 * cos), getY() + difY - (int) (20 * sin));
    276. p.addPoint(getX() - difX + (int) (20 * cos), getY() - difY - (int) (20 * sin));
    277. exit();
    278. new AbilityOneCD().start();
    279. ifAbilityOne = true;
    280. }
    281. }
    282. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Polygon;
    5. import java.awt.Toolkit;
    6. import java.awt.event.ActionEvent;
    7. import java.awt.event.ActionListener;
    8. import java.awt.event.MouseAdapter;
    9. import java.awt.event.MouseEvent;
    10. import java.util.ArrayList;
    11. import javax.swing.JButton;
    12. import com.sxt.beast.Beast;
    13. public class ChampionHouyi extends Champion {
    14. // 技能是否处于释放状态
    15. boolean ifAbilityThree = false;
    16. boolean ifAbilityTwo = false;
    17. // 鼠标监视器
    18. MouseMonitor m;
    19. MouseMonitorTwo m2;
    20. // 三技能多边形
    21. Polygon p;
    22. // 三技能三角函数
    23. double sin;
    24. double cos;
    25. // 三技能命中的目标
    26. GameObject abilityThreeTarget;
    27. // 三技能是否出界
    28. boolean ifXOutside;
    29. boolean ifYOutside;
    30. // 二技能位置
    31. int X_AbilityTwo;
    32. int Y_AbilityTwo;
    33. public ChampionHouyi(GameFrame gameFrame) {
    34. super(gameFrame);
    35. abilityOne = Toolkit.getDefaultToolkit().getImage("img/HyabilityOne.jpg");
    36. abilityTwo = Toolkit.getDefaultToolkit().getImage("img/HyabilityTwo.jpg");
    37. abilityThree = Toolkit.getDefaultToolkit().getImage("img/HyabilityThree.jpg");
    38. classical = Toolkit.getDefaultToolkit().getImage("img/后羿-辉光之辰.jpg");
    39. // 三个技能冷却时间
    40. coolDownTimeOne = 14000;
    41. coolDownTimeTwo = 10000;
    42. coolDownTimeThree = 28000;
    43. // TODO Auto-generated constructor stub
    44. }
    45. public ChampionHouyi(GameFrame gameFrame, int i, int j) {
    46. // TODO Auto-generated constructor stub
    47. super(gameFrame, i, j);
    48. }
    49. public void exit(MouseAdapter ma) {
    50. this.gameFrame.removeMouseListener(ma);
    51. }
    52. public void attack() {
    53. if (isAttackCoolDown()) {
    54. ArrayList targets = new ArrayList();// 目标列表,最多三个目标
    55. for (GameObject redObj : this.gameFrame.redList) {
    56. if (this.recIntersectsCir(redObj.getRec(), getX() - 250, getY() - 250, 500)) {
    57. targets.add(redObj);
    58. if (targets.size() == 3) {
    59. break;
    60. }
    61. }
    62. }
    63. for (GameObject beastObj : this.gameFrame.beast.beastList) {
    64. if (this.recIntersectsCir(beastObj.getRec(), getX() - 250, getY() - 250, 500)) {
    65. targets.add(beastObj);
    66. if (targets.size() == 3) {
    67. break;
    68. }
    69. }
    70. }
    71. for (int i = 0; i < targets.size(); i++) {
    72. Bullet bullet;
    73. if (i == 0) {
    74. bullet = new Bullet(gameFrame, this, targets.get(i), 400, 50, "img/bullet.gif");
    75. } else {
    76. bullet = new Bullet(gameFrame, this, targets.get(i), 200, 50, "img/bullet.gif");
    77. }
    78. gameFrame.objList.add(bullet);
    79. }
    80. new AttackCD().start();
    81. }
    82. }
    83. public void abilityTwoAttack() {
    84. for (GameObject redObj : this.gameFrame.objList) {
    85. if (redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass())) {
    86. if (this.recIntersectsCir(redObj.getRec(), X_AbilityTwo - 60, Y_AbilityTwo - 60, 120)) {
    87. redObj.setCurrentHp(redObj.getCurrentHp() - 400);
    88. }
    89. if (this.recIntersectsCir(redObj.getRec(), X_AbilityTwo - 30, Y_AbilityTwo - 30, 60)) {
    90. redObj.setCurrentHp(redObj.getCurrentHp() - 200);
    91. }
    92. }
    93. }
    94. }
    95. public void abilityThreeMove() {
    96. p.translate((int) (50 * cos), -(int) (50 * sin));
    97. for (GameObject redObj : gameFrame.objList) {
    98. // 是红色方小兵 && 发生碰撞
    99. if ((redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass()))
    100. && p.intersects(redObj.getRec())) {
    101. // 击中目标后,目标减血并眩晕,多边形消失
    102. redObj.setCurrentHp(redObj.getCurrentHp() - 400);
    103. abilityThreeTarget = redObj;
    104. new AbilityControlCD().start();
    105. ifAbilityThree = false;
    106. new AbilityThreeCD().start();
    107. }
    108. }
    109. if (!ifXOutside) {
    110. for (int x : p.xpoints) {
    111. if (x < 0 || x >= 5165) {
    112. ifXOutside = true;
    113. break;
    114. }
    115. }
    116. }
    117. if (!ifYOutside) {
    118. for (int y : p.ypoints) {
    119. if (y < 0 || y >= 4085) {
    120. ifYOutside = true;
    121. break;
    122. }
    123. }
    124. }
    125. }
    126. /**
    127. * 一技能 制作游戏界面攻击按钮的替身 替换攻击按钮 新的攻击按钮事件: 1. 定义目标列表 2. 添加目标,最多添加三个 3.
    128. * 目标列表第一个造成400伤害,其余200伤害 4. 持续5秒,结束后替换攻击按钮️
    129. */
    130. @Override
    131. public void abilityOne() {
    132. // TODO Auto-generated method stub
    133. if (coolDownOne) {
    134. new AbilityOneDuration().start();// 强化普攻持续时间
    135. new AbilityOneCD().start();
    136. }
    137. }
    138. /**
    139. * 二技能 先点击按钮释放技能 再点击技能范围内任意位置 之后点击的位置会出现 两个大小不同的圆 在大圆内会受到300伤害 在小圆内受到额外200伤害
    140. */
    141. @Override
    142. public void abilityTwo() {
    143. // TODO Auto-generated method stub
    144. if (coolDownTwo) {
    145. m2 = new MouseMonitorTwo();
    146. gameFrame.addMouseListener(m2);
    147. X_AbilityTwo = 0;
    148. Y_AbilityTwo = 0;
    149. }
    150. }
    151. @Override
    152. public void abilityThree() {
    153. // TODO Auto-generated method stub
    154. if (coolDownThree) {
    155. m = new MouseMonitor();
    156. p = new Polygon();
    157. gameFrame.addMouseListener(m);
    158. ifAbilityThree = true;
    159. ifXOutside = false;
    160. ifYOutside = false;
    161. }
    162. }
    163. @Override
    164. public void abilityEffect(Graphics g) {
    165. // TODO Auto-generated method stub
    166. if (ifAbilityTwo) {
    167. System.out.println("222");
    168. g.setColor(Color.RED);
    169. g.fillOval(X_AbilityTwo - 60, Y_AbilityTwo - 60, 120, 120);
    170. g.setColor(Color.BLACK);
    171. g.fillOval(X_AbilityTwo - 30, Y_AbilityTwo - 30, 60, 60);
    172. abilityTwoAttack();
    173. X_AbilityTwo = 0;
    174. Y_AbilityTwo = 0;
    175. ifAbilityTwo = false;
    176. new AbilityTwoCD().start();
    177. }
    178. if (ifAbilityThree) {
    179. System.out.println("333");
    180. g.setColor(Color.RED);
    181. g.fillPolygon(p);
    182. abilityThreeMove();
    183. // 如果出界,技能释放结束
    184. if (ifXOutside || ifYOutside) {
    185. ifAbilityThree = false;
    186. p = new Polygon();
    187. new AbilityThreeCD().start();
    188. }
    189. }
    190. }
    191. // 攻击冷却时间
    192. class AttackCD extends Thread {
    193. public void run() {
    194. // 将攻击功能设置为冷却状态
    195. setAttackCoolDown(false);
    196. // 线程休眠
    197. try {
    198. Thread.sleep(getAttackCoolDownTime());
    199. } catch (Exception e) {
    200. e.printStackTrace();
    201. }
    202. // 将攻击功能设置为攻击状态
    203. setAttackCoolDown(true);
    204. // 线程终止
    205. this.stop();
    206. }
    207. }
    208. // 一技能冷却时间
    209. class AbilityOneCD extends Thread {
    210. public void run() {
    211. // 将攻击功能设置为冷却状态
    212. coolDownOne = false;
    213. // 休眠
    214. try {
    215. // one用来储存冷却时间
    216. int one = coolDownTimeOne;
    217. while (coolDownTimeOne > 0) {
    218. Thread.sleep(1000);
    219. System.out.println("技能一冷却时间: " + coolDownTimeOne / 1000);
    220. coolDownTimeOne -= 1000;
    221. }
    222. coolDownTimeOne = one;
    223. } catch (Exception e) {
    224. e.printStackTrace();
    225. }
    226. // 将攻击功能解除冷却状态
    227. coolDownOne = true;
    228. // 线程终止
    229. this.stop();
    230. }
    231. }
    232. // 技能一持续时间
    233. class AbilityOneDuration extends Thread {
    234. public void run() {
    235. // 制作攻击按钮的替身
    236. JButton substitute = gameFrame.attackButton;
    237. gameFrame.remove(gameFrame.attackButton);
    238. JButton button = new JButton();
    239. button.setSize(130, 132);
    240. button.setLocation(1150, 430);
    241. button.addActionListener(new ActionListener() {
    242. @Override
    243. public void actionPerformed(ActionEvent e) {
    244. // 获取到的事件源就是按钮本身
    245. attack();
    246. }
    247. });
    248. gameFrame.add(button);
    249. // 休眠
    250. try {
    251. Thread.sleep(5000);
    252. } catch (Exception e) {
    253. e.printStackTrace();
    254. }
    255. gameFrame.remove(button);
    256. gameFrame.add(substitute);
    257. // 线程终止
    258. this.stop();
    259. }
    260. }
    261. // 二技能冷却时间
    262. class AbilityTwoCD extends Thread {
    263. public void run() {
    264. // 将二技能设置为冷却状态
    265. coolDownTwo = false;
    266. // 休眠
    267. try {
    268. int two = coolDownTimeTwo;
    269. while (coolDownTimeTwo > 0) {
    270. Thread.sleep(1000);
    271. System.out.println("技能二冷却时间: " + coolDownTimeTwo / 1000);
    272. coolDownTimeTwo -= 1000;
    273. }
    274. coolDownTimeTwo = two;
    275. } catch (Exception e) {
    276. e.printStackTrace();
    277. }
    278. // 将攻击功能解除冷却状态
    279. coolDownTwo = true;
    280. // 线程终止
    281. this.stop();
    282. }
    283. }
    284. // 技能三冷却时间
    285. class AbilityThreeCD extends Thread {
    286. public void run() {
    287. // 将技能三设置为冷却状态
    288. coolDownThree = false;
    289. // 线程休眠
    290. try {
    291. // three来表示三技能冷却时间
    292. int three = coolDownTimeThree;
    293. while (three > 0) {
    294. Thread.sleep(1000);
    295. System.out.println("三技能冷却时间: " + three / 1000);
    296. three -= 1000;
    297. }
    298. } catch (Exception e) {
    299. e.printStackTrace();
    300. }
    301. // 将技能三设置为攻击状态
    302. coolDownThree = true;
    303. // 线程终止
    304. this.stop();
    305. }
    306. }
    307. // 技能三控制时间
    308. class AbilityControlCD extends Thread {
    309. public void run() {
    310. abilityThreeTarget.beControlled = true;
    311. // 线程休眠
    312. try {
    313. Thread.sleep(20000);
    314. } catch (Exception e) {
    315. e.printStackTrace();
    316. }
    317. abilityThreeTarget.beControlled = false;
    318. this.stop();
    319. }
    320. }
    321. // 鼠标监视器
    322. private class MouseMonitorTwo extends MouseAdapter {
    323. @Override
    324. public void mousePressed(MouseEvent e) {// 当鼠标点击时
    325. System.out.println("pressed");
    326. int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;
    327. double dis = getDis(mouseX, mouseY, playerX, playerY);
    328. if (dis < 250) {
    329. X_AbilityTwo = e.getX() - playerX + getX();
    330. Y_AbilityTwo = e.getY() - playerY + getY();
    331. }
    332. ifAbilityTwo = true;
    333. exit(this);
    334. }
    335. }
    336. // 鼠标监视器
    337. private class MouseMonitor extends MouseAdapter {
    338. @Override
    339. public void mousePressed(MouseEvent e) {// 当鼠标点击时
    340. int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;
    341. double dis = getDis(mouseX, mouseY, playerX, playerY);
    342. // 三角函数
    343. cos = (mouseX - playerX) / dis;
    344. sin = -(mouseY - playerY) / dis;
    345. // 坐标差
    346. int difX = (int) (60 * sin);
    347. int difY = (int) (60 * cos);
    348. p.addPoint(getX() - difX, getY() - difY);
    349. p.addPoint(getX() + difX, getY() + difY);
    350. p.addPoint(getX() + difX + (int) (20 * cos), getY() + difY - (int) (20 * sin));
    351. p.addPoint(getX() - difX + (int) (20 * cos), getY() - difY - (int) (20 * sin));
    352. ifAbilityThree = true;
    353. exit(this);
    354. }
    355. }
    356. }
    1. package com.sxt;
    2. import java.awt.Graphics;
    3. import java.awt.Image;
    4. import java.awt.Toolkit;
    5. import java.awt.event.ActionEvent;
    6. import java.awt.event.ActionListener;
    7. import java.awt.event.KeyAdapter;
    8. import java.awt.event.KeyEvent;
    9. import java.util.ArrayList;
    10. import javax.swing.JButton;
    11. import javax.swing.JFrame;
    12. import com.sxt.beast.Beast;
    13. public class GameFrame extends JFrame {
    14. // 游戏模式 0 选择英雄,1 游戏开始,2 游戏胜利,3 游戏失败
    15. int state = 0;
    16. // 窗口尺寸
    17. private int windowWidth = 1400;
    18. private int windowHeight = 700;
    19. // 双缓冲图片
    20. private Image offScreenImage = null;
    21. // 攻击图片
    22. private Image attack = Toolkit.getDefaultToolkit().getImage("img/attack.jpg");
    23. //游戏胜利失败图片
    24. private Image gameWin = Toolkit.getDefaultToolkit().getImage("img/gameWin.png");
    25. private Image gameLose = Toolkit.getDefaultToolkit().getImage("img/gameLose.png");
    26. // 游戏背景
    27. Background background = new Background(this);
    28. // 游戏玩家
    29. Champion player;
    30. Champion champion = new ChampionHouyi(this,700,3800);
    31. // 双方小兵
    32. MinionBlue mb = new MinionBlue(this);
    33. MinionRed mr = new MinionRed(this);
    34. // 防御塔
    35. Turret turret = new Turret(this);
    36. //野怪
    37. public Beast beast = new Beast(this);
    38. // 攻击按钮
    39. JButton attackButton;
    40. // 游戏元素列表
    41. public ArrayList objList = new ArrayList();
    42. ArrayList redList = new ArrayList();// 红色方
    43. ArrayList blueList = new ArrayList();// 蓝色方
    44. public ArrayList removeList = new ArrayList();// 存放将要删除的元素
    45. public void launch() {
    46. // 设置尺寸
    47. setSize(windowWidth, windowHeight);
    48. // 窗口居中
    49. setLocationRelativeTo(null);
    50. // 关闭事件
    51. setDefaultCloseOperation(3);
    52. // 用户不能调整窗口大小
    53. setResizable(false);
    54. // 标题
    55. setTitle("王者荣耀");
    56. // 窗口可见
    57. setVisible(true);
    58. // 添加键盘监视器
    59. this.addKeyListener(new GameFrame.KeyMonitor());
    60. // 添加游戏元素
    61. objList.add(background);
    62. objList.addAll(turret.turretList);
    63. objList.addAll(beast.beastList);
    64. blueList.add(turret.turretList.get(0));
    65. redList.add(turret.turretList.get(4));
    66. /**
    67. * 攻击按钮
    68. */
    69. attackButton = new JButton();
    70. attackButton.setSize(130, 132);
    71. attackButton.setLocation(1150, 430);
    72. attackButton.addActionListener(new ActionListener() {
    73. @Override
    74. public void actionPerformed(ActionEvent e) {
    75. // 按钮事件
    76. player.attack(redList);
    77. }
    78. });
    79. this.add(attackButton);
    80. while (true) {
    81. if (state == 1) {
    82. // 添加小兵
    83. //mb.createMinion(this, blueList);
    84. //mr.createMinion(this, redList);
    85. // 添加防御塔
    86. turret.addTurret();
    87. }
    88. repaint();
    89. try {
    90. Thread.sleep(17);
    91. } catch (Exception e) {
    92. e.printStackTrace();
    93. }
    94. }
    95. }
    96. public void paint(Graphics g) {
    97. if (offScreenImage == null) {
    98. offScreenImage = this.createImage(5984, 4452);
    99. }
    100. Graphics gImage = offScreenImage.getGraphics();
    101. if (state == 0) {
    102. for(int i = 0; i < champion.championList.size(); i++) {
    103. //添加图片
    104. Image classical = champion.championList.get(i).classical;
    105. gImage.drawImage(classical, i*160, 20, null);
    106. //添加按钮
    107. JButton championButton = new JButton();
    108. championButton.setSize(150, 150);
    109. championButton.setLocation(i*150, 0);
    110. int a = i;
    111. championButton.addActionListener(new ActionListener() {
    112. @Override
    113. public void actionPerformed(ActionEvent e) {
    114. state = 1;
    115. player = champion.championList.get(a);
    116. objList.add(player);
    117. player.addButton();
    118. }
    119. });
    120. this.add(championButton);
    121. }
    122. } else if (state == 1) {
    123. for (int i = 0; i < objList.size(); i++) {
    124. objList.get(i).paintSelf(gImage);
    125. }
    126. // 绘制攻击图片
    127. gImage.drawImage(attack, player.getX() + 500, player.getY() + 100, null);
    128. objList.removeAll(removeList);
    129. } else if (state == 2) {//游戏胜利
    130. gImage.drawImage(gameWin, 0, 5, null);
    131. } else if (state == 3) {//游戏失败
    132. gImage.drawImage(gameLose, 0, 5, null);
    133. }
    134. if (state != 1) {
    135. g.drawImage(offScreenImage, 0, 0, null);
    136. } else {
    137. g.drawImage(offScreenImage, -player.getX() + 700, -player.getY() + 350, null);
    138. }
    139. /**
    140. * 添加按钮后不能调用键盘事件 因为程序的焦点变成了按钮 this.requestFocus() 把焦点重新改变到游戏界面上
    141. */
    142. this.requestFocus();
    143. }
    144. // main方法
    145. public static void main(String[] args) {
    146. GameFrame gameFrame = new GameFrame();
    147. gameFrame.launch();
    148. }
    149. // 键盘事件
    150. private class KeyMonitor extends KeyAdapter {
    151. @Override
    152. public void keyPressed(KeyEvent e) {
    153. int key = e.getKeyCode();
    154. player.keyPressed(e);
    155. }
    156. @Override
    157. public void keyReleased(KeyEvent e) {
    158. int key = e.getKeyCode();
    159. player.keyReleased(e);
    160. }
    161. }
    162. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Image;
    5. import java.awt.Rectangle;
    6. import java.awt.Toolkit;
    7. import java.util.ArrayList;
    8. import com.sxt.beast.Beast;
    9. public abstract class GameObject {
    10. // 坐标
    11. private int x;
    12. private int y;
    13. // 图片
    14. private Image img;
    15. // 游戏界面
    16. public GameFrame gameFrame;
    17. // 速度
    18. private int spd;
    19. // 初始生命值
    20. private int hp;
    21. // 当前生命值
    22. private int currentHp;
    23. // 攻击目标
    24. private GameObject target;
    25. // 是否有目标
    26. private boolean hasTarget = false;
    27. // 攻击距离
    28. private int dis;
    29. // 攻击时间间隔
    30. private int attackCoolDownTime;
    31. // 攻击是否冷却
    32. private boolean attackCoolDown = true;
    33. // 是否存活
    34. private boolean alive = true;
    35. // 是否被控制
    36. boolean beControlled = false;
    37. public GameObject(GameFrame gameFrame) {
    38. this.gameFrame = gameFrame;
    39. }
    40. public GameObject(int x, int y, GameFrame gameFrame) {
    41. this.x = x;
    42. this.y = y;
    43. this.gameFrame = gameFrame;
    44. }
    45. public GameObject() {
    46. // TODO Auto-generated constructor stub
    47. }
    48. public void addHp(Graphics g, int difX, int difY, int width, int height, Color color) {
    49. // 绘制外部轮廓
    50. g.setColor(Color.black);
    51. g.drawRect(getX() - difX, getY() - difY, width, height);
    52. // 填充矩形
    53. g.setColor(color);
    54. g.fillRect(getX() - difX, getY() - difY, (int) (width * getCurrentHp() / getHp()), height);
    55. }
    56. public double getDis(int x1, int y1, int x2, int y2) {
    57. return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    58. }
    59. // 矩形矩形碰撞检测
    60. public boolean recIntersectsRec(Rectangle r1, Rectangle r2) {
    61. return r1.intersects(r2);
    62. }
    63. public boolean recIntersectsCir(Rectangle rec, int x, int y, int r) {
    64. /** 矩形于圆相交: 圆心到至少一个矩形定点的距离小于r */
    65. if ((getDis(x, y, rec.x, rec.y) < r) || (getDis(x, y, rec.x, rec.y + rec.height) < r)
    66. || (getDis(x, y, rec.x + rec.width, rec.y) < r)
    67. || (getDis(x, y, rec.x + rec.width, rec.y + rec.height) < r)) {
    68. return true;
    69. }
    70. return false;
    71. }
    72. // 攻击方法
    73. public void attack(ArrayList gameObjList) {
    74. if (hasTarget) {
    75. // 目标离开范围后寻找新的目标
    76. if (!recIntersectsCir(target.getRec(), getX(), getY(), getDis())) {
    77. setHasTarget(false);
    78. }
    79. // 目标死亡,寻找新目标
    80. else if (!target.isAlive()) {
    81. setHasTarget(false);
    82. } else if (isAttackCoolDown() && isAlive()) {
    83. Bullet bullet = null;
    84. // 防御塔攻击
    85. if (Turret.class.isAssignableFrom(getClass())) {
    86. bullet = new Bullet(gameFrame, this, getTarget(), 500, 50);
    87. }
    88. // 小兵攻击
    89. else if (Minion.class.isAssignableFrom(getClass())) {
    90. bullet = new Bullet(gameFrame, this, getTarget(), 50, 30);
    91. }
    92. // 玩家攻击
    93. else if (this instanceof Champion) {
    94. bullet = new Bullet(gameFrame, this, getTarget(), 500, 50, "img/bullet.gif");
    95. }
    96. gameFrame.objList.add(bullet);
    97. // 线程开始
    98. new AttackCD().start();
    99. }
    100. } else {
    101. // 遍历列表
    102. for (GameObject obj : gameObjList) {
    103. // 判断攻击范围(圆形)与敌方(矩形)是否相交
    104. if (recIntersectsCir(obj.getRec(), getX(), getY(), getDis())) {
    105. // 找到目标
    106. setTarget(obj);
    107. setHasTarget(true);
    108. // 跳出循环
    109. break;
    110. }
    111. }
    112. // 玩家是否在攻击范围内
    113. if (!hasTarget && gameObjList == gameFrame.blueList) {
    114. if (recIntersectsCir(gameFrame.player.getRec(), getX(), getY(), getDis())) {
    115. // 找到目标
    116. setTarget(gameFrame.player);
    117. setHasTarget(true);
    118. }
    119. } else {
    120. for (GameObject obj : gameFrame.beast.beastList) {
    121. // 判断攻击范围(圆形)与敌方(矩形)是否相交
    122. if (recIntersectsCir(obj.getRec(), getX(), getY(), getDis())) {
    123. // 找到目标
    124. setTarget(obj);
    125. setHasTarget(true);
    126. // 跳出循环
    127. break;
    128. }
    129. }
    130. }
    131. }
    132. }
    133. class AttackCD extends Thread {
    134. public void run() {
    135. // 将攻击功能设置为冷却状态
    136. setAttackCoolDown(false);
    137. // 线程休眠
    138. try {
    139. Thread.sleep(attackCoolDownTime);
    140. } catch (Exception e) {
    141. e.printStackTrace();
    142. }
    143. // 将攻击功能设置为攻击状态
    144. setAttackCoolDown(true);
    145. // 线程终止
    146. this.stop();
    147. }
    148. }
    149. // 绘制元素
    150. public abstract void paintSelf(Graphics g);
    151. // 返回矩形
    152. public abstract Rectangle getRec();
    153. /**
    154. * @return the x
    155. */
    156. public int getX() {
    157. return x;
    158. }
    159. /**
    160. * @param x the x to set
    161. */
    162. public void setX(int x) {
    163. this.x = x;
    164. }
    165. /**
    166. * @return the y
    167. */
    168. public int getY() {
    169. return y;
    170. }
    171. /**
    172. * @param y the y to set
    173. */
    174. public void setY(int y) {
    175. this.y = y;
    176. }
    177. /**
    178. * @return the img
    179. */
    180. public Image getImg() {
    181. return img;
    182. }
    183. /**
    184. * @param img the img to set
    185. */
    186. public void setImg(String img) {
    187. this.img = Toolkit.getDefaultToolkit().getImage(img);
    188. }
    189. /**
    190. * @return the spd
    191. */
    192. public int getSpd() {
    193. return spd;
    194. }
    195. /**
    196. * @param spd the spd to set
    197. */
    198. public void setSpd(int spd) {
    199. this.spd = spd;
    200. }
    201. /**
    202. * @return the hp
    203. */
    204. public int getHp() {
    205. return hp;
    206. }
    207. /**
    208. * @param hp the hp to set
    209. */
    210. public void setHp(int hp) {
    211. this.hp = hp;
    212. }
    213. /**
    214. * @return the currentHp
    215. */
    216. public int getCurrentHp() {
    217. return currentHp;
    218. }
    219. /**
    220. * @param currentHp the currentHp to set
    221. */
    222. public void setCurrentHp(int currentHp) {
    223. if (currentHp < getHp()) {
    224. if (Beast.class.isAssignableFrom(getClass())) {
    225. System.out.println("yes");
    226. setTarget(gameFrame.player);
    227. setHasTarget(true);
    228. }
    229. }
    230. this.currentHp = currentHp;
    231. }
    232. /**
    233. * @return the target
    234. */
    235. public GameObject getTarget() {
    236. return target;
    237. }
    238. /**
    239. * @param target the target to set
    240. */
    241. public void setTarget(GameObject target) {
    242. this.target = target;
    243. }
    244. /**
    245. * @return the hasTarget
    246. */
    247. public boolean isHasTarget() {
    248. return hasTarget;
    249. }
    250. /**
    251. * @param hasTarget the hasTarget to set
    252. */
    253. public void setHasTarget(boolean hasTarget) {
    254. this.hasTarget = hasTarget;
    255. }
    256. /**
    257. * @return the dis
    258. */
    259. public int getDis() {
    260. return dis;
    261. }
    262. /**
    263. * @param dis the dis to set
    264. */
    265. public void setDis(int dis) {
    266. this.dis = dis;
    267. }
    268. /**
    269. * @return the attackCoolDownTime
    270. */
    271. public int getAttackCoolDownTime() {
    272. return attackCoolDownTime;
    273. }
    274. /**
    275. * @param attackCoolDownTime the attackCoolDownTime to set
    276. */
    277. public void setAttackCoolDownTime(int attackCoolDownTime) {
    278. this.attackCoolDownTime = attackCoolDownTime;
    279. }
    280. /**
    281. * @return the attackCoolDown
    282. */
    283. public boolean isAttackCoolDown() {
    284. return attackCoolDown;
    285. }
    286. /**
    287. * @param attackCoolDown the attackCoolDown to set
    288. */
    289. public void setAttackCoolDown(boolean attackCoolDown) {
    290. this.attackCoolDown = attackCoolDown;
    291. }
    292. /**
    293. * @return the alive
    294. */
    295. public boolean isAlive() {
    296. return alive;
    297. }
    298. /**
    299. * @param alive the alive to set
    300. */
    301. public void setAlive(boolean alive) {
    302. this.alive = alive;
    303. }
    304. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Rectangle;
    5. import java.util.ArrayList;
    6. public abstract class Minion extends GameObject {
    7. // 是否生成下一个小兵
    8. private boolean nextMinion = true;
    9. // 是否生成下一波小兵
    10. private boolean nextLine = true;
    11. // 生成小兵数量
    12. private int minionCount = 0;
    13. // 是否检测到目标
    14. private boolean ifFindTarget = false;
    15. public Minion(GameFrame gameFrame) {
    16. super(gameFrame);
    17. setHp(800);
    18. setCurrentHp(getHp());
    19. setDis(100);
    20. setAttackCoolDownTime(2000);
    21. // TODO Auto-generated constructor stub
    22. }
    23. /**
    24. * (1325, 3750) (4425, 3750) (5050, 3125) (5050, 1125)
    25. */
    26. public abstract void move(ArrayList objList);
    27. /**
    28. * @param x: 下一步的横坐标
    29. * @param y: 下一步的纵坐标
    30. * @param objList: 小兵列表
    31. * @return 下一步位置与其他小兵是否碰撞
    32. */
    33. public boolean hitMinion(int x, int y, ArrayList objList) {
    34. // 新的区域生成矩形
    35. Rectangle r = new Rectangle(x - 16, y - 16, 45, 45);
    36. for (GameObject obj : objList) {
    37. // 相同类 && 不是自身
    38. if (obj.getClass() == this.getClass() && obj != this) {
    39. if (r.intersects(obj.getRec())) {
    40. return true;
    41. }
    42. }
    43. }
    44. return false;
    45. }
    46. public void findTarget(ArrayList objList) {
    47. for (GameObject obj : objList) {
    48. if (recIntersectsCir(obj.getRec(), getX(), getY(), 200)) {
    49. setTarget(obj);
    50. setIfFindTarget(true);
    51. }
    52. }
    53. if (objList == gameFrame.blueList) {
    54. if (recIntersectsCir(gameFrame.player.getRec(), getX(), getY(), 200)) {
    55. setTarget(gameFrame.player);
    56. setIfFindTarget(true);
    57. }
    58. }
    59. }
    60. public void moveToTarget() {
    61. double dis = getDis(getX(), getY(), getTarget().getX(), getTarget().getY());
    62. int xSpeed = (int) (getSpd() * (getTarget().getX() - getX()) / dis);
    63. int ySpeed = (int) (getSpd() * (getTarget().getY() - getY()) / dis);
    64. if (!hitMinion(getX() + xSpeed, getY(), gameFrame.objList)) {
    65. setX(getX() + xSpeed);
    66. }
    67. if (!hitMinion(getX(), getY() + ySpeed, gameFrame.objList)) {
    68. setY(getY() + ySpeed);
    69. }
    70. }
    71. public void createMinion(GameFrame gameFrame, ArrayList minionList) {
    72. if (nextLine) {
    73. if (nextMinion) {
    74. // 蓝色方小兵
    75. if (minionList == this.gameFrame.blueList) {
    76. MinionBlue mb = new MinionBlue(gameFrame);
    77. gameFrame.objList.add(mb);
    78. minionList.add(mb);
    79. }
    80. // 红色方小兵
    81. else {
    82. MinionRed mr = new MinionRed(gameFrame);
    83. gameFrame.objList.add(mr);
    84. minionList.add(mr);
    85. }
    86. minionCount++;
    87. new NextMinion().start();
    88. }
    89. if (minionCount == 3) {
    90. minionCount = 0;
    91. new NextLine().start();
    92. }
    93. }
    94. }
    95. // 每个小兵生成时间
    96. class NextMinion extends Thread {
    97. public void run() {
    98. nextMinion = false;
    99. // 休眠1.5s
    100. try {
    101. Thread.sleep(1500);
    102. } catch (Exception e) {
    103. e.printStackTrace();
    104. }
    105. nextMinion = true;
    106. // 线程终止
    107. this.stop();
    108. }
    109. }
    110. // 每波小兵生成时间
    111. class NextLine extends Thread {
    112. public void run() {
    113. nextLine = false;
    114. // 休眠15s
    115. try {
    116. Thread.sleep(15000);
    117. } catch (Exception e) {
    118. e.printStackTrace();
    119. }
    120. nextLine = true;
    121. // 线程终止
    122. this.stop();
    123. }
    124. }
    125. @Override
    126. public void paintSelf(Graphics g) {
    127. // TODO Auto-generated method stub
    128. // 生命值为0
    129. if (getCurrentHp() <= 0) {
    130. setAlive(false);
    131. gameFrame.removeList.add(this);
    132. if (this instanceof MinionBlue) {
    133. gameFrame.blueList.remove(this);
    134. } else {
    135. gameFrame.redList.remove(this);
    136. }
    137. } else {
    138. // 添加生命值
    139. if (this instanceof MinionBlue) {
    140. this.addHp(g, 17, 28, 45, 10, Color.GREEN);
    141. } else {
    142. this.addHp(g, 17, 28, 45, 10, Color.RED);
    143. }
    144. g.drawImage(getImg(), getX() - 16, getY() - 16, null);
    145. //绘制检测范围圆形
    146. //g.setColor(Color.RED);
    147. //g.fillOval(getX(), getY(), 10, 10);
    148. //g.drawRect(getX() - 16, getY() - 16, 45, 45);
    149. // 小兵移动
    150. if (!beControlled) {
    151. if (this instanceof MinionBlue) {
    152. move(gameFrame.redList);
    153. } else {
    154. move(gameFrame.blueList);
    155. }
    156. }
    157. }
    158. }
    159. @Override
    160. public Rectangle getRec() {
    161. // TODO Auto-generated method stub
    162. return new Rectangle(getX() - 16, getY() - 16, 45, 45);
    163. }
    164. /**
    165. * @return the ifFindTarget
    166. */
    167. public boolean isIfFindTarget() {
    168. return ifFindTarget;
    169. }
    170. /**
    171. * @param ifFindTarget the ifFindTarget to set
    172. */
    173. public void setIfFindTarget(boolean ifFindTarget) {
    174. this.ifFindTarget = ifFindTarget;
    175. }
    176. }
    1. package com.sxt;
    2. import java.util.ArrayList;
    3. public class MinionBlue extends Minion {
    4. public MinionBlue(GameFrame gameFrame) {
    5. super(gameFrame);
    6. setImg("img/blue.jpg");
    7. setX(1325);
    8. setY(3750);
    9. // TODO Auto-generated constructor stub
    10. }
    11. @Override
    12. public void move(ArrayList objList) {
    13. // TODO Auto-generated method stub
    14. if (isIfFindTarget()) {
    15. // 离开检测范围
    16. if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), 200)) {
    17. setIfFindTarget(false);
    18. } else {
    19. if (!isHasTarget()) {
    20. moveToTarget();
    21. }
    22. attack(objList);
    23. }
    24. } else {
    25. findTarget(objList);
    26. // 原路线移动
    27. if (getX() < 4425) {
    28. setSpd(25);
    29. if (!hitMinion(getX() + getSpd(), getY(), gameFrame.blueList)) {
    30. setX(getX() + getSpd());
    31. }
    32. } else if (getX() < 5100 && getX() >= 4425) {
    33. setSpd(20);
    34. if (!hitMinion(getX() + getSpd(), getY(), gameFrame.blueList)) {
    35. setX(getX() + getSpd());
    36. }
    37. if (!hitMinion(getX(), getY() - getSpd(), gameFrame.blueList)) {
    38. setY(getY() - getSpd());
    39. }
    40. } else if (getX() >= 4900) {
    41. setSpd(18);
    42. if (!hitMinion(getX(), getY() - getSpd(), gameFrame.blueList)) {
    43. setY(getY() - getSpd());
    44. }
    45. }
    46. }
    47. }
    48. }
    1. package com.sxt;
    2. import java.util.ArrayList;
    3. public class MinionRed extends Minion {
    4. public MinionRed(GameFrame gameFrame) {
    5. super(gameFrame);
    6. setImg("img/red.jpg");
    7. setX(5050);
    8. setY(1125);
    9. // TODO Auto-generated constructor stub
    10. }
    11. @Override
    12. public void move(ArrayList objList) {
    13. // TODO Auto-generated method stub
    14. if (isIfFindTarget()) {
    15. // 离开检测范围
    16. if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), 200)) {
    17. setIfFindTarget(false);
    18. } else {
    19. if (!isHasTarget()) {
    20. moveToTarget();
    21. }
    22. attack(objList);
    23. }
    24. } else {
    25. findTarget(objList);
    26. // 原路线移动
    27. if (getY() < 3125) {
    28. setSpd(18);
    29. if (!hitMinion(getX(), getY() + getSpd(), gameFrame.redList)) {
    30. setY(getY() + getSpd());
    31. }
    32. } else if (getY() < 3750 && getY() >= 3125) {
    33. setSpd(20);
    34. if (!hitMinion(getX(), getY() + getSpd(), gameFrame.redList)) {
    35. setY(getY() + getSpd());
    36. }
    37. if (!hitMinion(getX() - getSpd(), getY(), gameFrame.redList)) {
    38. setX(getX() - getSpd());
    39. }
    40. } else if (getY() >= 3750) {
    41. setSpd(25);
    42. if (!hitMinion(getX() - getSpd(), getY(), gameFrame.redList)) {
    43. setX(getX() - getSpd());
    44. }
    45. }
    46. }
    47. }
    48. }
    1. package com.sxt;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Rectangle;
    5. import java.util.ArrayList;
    6. public class Turret extends GameObject {
    7. ArrayList turretList = new ArrayList();
    8. public Turret turretBlueOne;
    9. public Turret turretBlueTwo;
    10. public Turret turretBlueThree;
    11. public Turret turretBlueBase;
    12. public Turret turretRedOne;
    13. public Turret turretRedTwo;
    14. public Turret turretRedThree;
    15. public Turret turretRedBase;
    16. public Turret(GameFrame gameFrame) {
    17. super(gameFrame);
    18. setImg("img/turret.png");
    19. // 初始化八个防御塔
    20. turretList.add(turretBlueOne = new TurretBlue(1860, 3790, gameFrame));
    21. turretList.add(turretBlueTwo = new TurretBlue(2650, 3820, gameFrame));
    22. turretList.add(turretBlueThree = new TurretBlue(3995, 3830, gameFrame));
    23. turretList.add(turretBlueBase = new TurretBlue(1130, 3650, gameFrame));
    24. turretList.add(turretRedOne = new TurretRed(5100, 3030, gameFrame));
    25. turretList.add(turretRedTwo = new TurretRed(5120, 2100, gameFrame));
    26. turretList.add(turretRedThree = new TurretRed(5060, 1570, gameFrame));
    27. turretList.add(turretRedBase = new TurretRed(4850, 1100, gameFrame));
    28. // TODO Auto-generated constructor stub
    29. }
    30. public Turret(int x, int y, GameFrame gameFrame) {
    31. super(x, y, gameFrame);
    32. setImg("img/turret.png");
    33. setHp(6000);
    34. setCurrentHp(getHp());
    35. setAttackCoolDownTime(1000);
    36. setDis(300);
    37. }
    38. public void addTurret() {
    39. /**
    40. * 添加到objList里会被绘制出来,添加到redList和blueList才会被攻击 前一个防御塔爆炸后再把后一个添加到列表里
    41. */
    42. if (!gameFrame.turret.turretBlueOne.isAlive() && gameFrame.turret.turretBlueTwo.isAlive()
    43. && gameFrame.blueList.indexOf(gameFrame.turret.turretBlueTwo) == -1) {
    44. gameFrame.blueList.add(gameFrame.turret.turretBlueTwo);
    45. }
    46. if (!gameFrame.turret.turretBlueTwo.isAlive() && gameFrame.turret.turretBlueThree.isAlive()
    47. && gameFrame.blueList.indexOf(gameFrame.turret.turretBlueThree) == -1) {
    48. gameFrame.blueList.add(gameFrame.turret.turretBlueThree);
    49. }
    50. if (!gameFrame.turret.turretBlueThree.isAlive() && gameFrame.turret.turretBlueBase.isAlive()
    51. && gameFrame.blueList.indexOf(gameFrame.turret.turretBlueBase) == -1) {
    52. gameFrame.blueList.add(gameFrame.turret.turretBlueBase);
    53. }
    54. if (!gameFrame.turret.turretBlueBase.isAlive()) {
    55. //游戏失败
    56. gameFrame.state = 3;
    57. }
    58. if (!gameFrame.turret.turretRedOne.isAlive() && gameFrame.turret.turretRedTwo.isAlive()
    59. && gameFrame.redList.indexOf(gameFrame.turret.turretRedTwo) == -1) {
    60. gameFrame.redList.add(gameFrame.turret.turretRedTwo);
    61. }
    62. if (!gameFrame.turret.turretRedTwo.isAlive() && gameFrame.turret.turretRedThree.isAlive()
    63. && gameFrame.redList.indexOf(gameFrame.turret.turretRedThree) == -1) {
    64. gameFrame.redList.add(gameFrame.turret.turretRedThree);
    65. }
    66. if (!gameFrame.turret.turretRedThree.isAlive() && gameFrame.turret.turretRedBase.isAlive()
    67. && gameFrame.redList.indexOf(gameFrame.turret.turretRedBase) == -1) {
    68. gameFrame.redList.add(gameFrame.turret.turretRedBase);
    69. }
    70. if (!gameFrame.turret.turretRedBase.isAlive()) {
    71. //游戏胜利
    72. gameFrame.state = 2;
    73. }
    74. }
    75. @Override
    76. public void paintSelf(Graphics g) {
    77. // 生命值为0
    78. if (getCurrentHp() <= 0) {
    79. setAlive(false);
    80. gameFrame.removeList.add(this);
    81. if (this instanceof TurretBlue) {
    82. gameFrame.blueList.remove(this);
    83. } else {
    84. gameFrame.redList.remove(this);
    85. }
    86. } else {
    87. // 添加生命值
    88. if (this instanceof TurretBlue) {
    89. this.addHp(g, 50, 130, 100, 20, Color.GREEN);
    90. attack(gameFrame.redList);
    91. } else {
    92. this.addHp(g, 50, 130, 100, 20, Color.RED);
    93. attack(gameFrame.blueList);
    94. }
    95. g.drawImage(getImg(), getX() - 50, getY() - 100, null);
    96. g.drawOval(getX() - 300, getY() - 300, 600, 600);
    97. }
    98. }
    99. @Override
    100. public Rectangle getRec() {
    101. // TODO Auto-generated method stub
    102. return new Rectangle(getX() - 50, getY() - 100, 100, 180);
    103. }
    104. }
    1. package com.sxt;
    2. public class TurretBlue extends Turret {
    3. public TurretBlue(GameFrame gameFrame) {
    4. super(gameFrame);
    5. // TODO Auto-generated constructor stub
    6. }
    7. public TurretBlue(int x, int y, GameFrame gameFrame) {
    8. super(x, y, gameFrame);
    9. }
    10. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class Bear extends Beast {
    4. public Bear(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/bear.jpg");
    7. width = 85;
    8. height = 112;
    9. setDis(65);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }
    1. package com.sxt.beast;
    2. import java.awt.Color;
    3. import java.awt.Graphics;
    4. import java.awt.Rectangle;
    5. import java.util.ArrayList;
    6. import com.sxt.*;
    7. public class Beast extends GameObject {
    8. public ArrayList beastList = new ArrayList();
    9. int width;
    10. int height;
    11. // 初始坐标
    12. int initialX;
    13. int initialY;
    14. // 有没有仇恨值
    15. public boolean isAggressive = false;
    16. // 复活的元素
    17. Beast beast = null;
    18. public Beast(GameFrame gameFrame) {
    19. super(gameFrame);
    20. beastList.add(new RedBuff(3045, 3170, gameFrame));
    21. beastList.add(new Bear(2800, 2855, gameFrame));
    22. beastList.add(new Bird(3570, 3380, gameFrame));
    23. beastList.add(new Xiyi(4585, 2365, gameFrame));
    24. beastList.add(new BlueBuff(4025, 2295, gameFrame));
    25. beastList.add(new Wolf(4235, 1945, gameFrame));
    26. }
    27. public Beast(int x, int y, GameFrame gameFrame) {
    28. super(x, y, gameFrame);
    29. setHp(1000);
    30. setCurrentHp(getHp());
    31. setSpd(10);
    32. setAttackCoolDownTime(2000);
    33. initialX = getX();
    34. initialY = getY();
    35. beast = this;
    36. }
    37. public void moveToTarget() {
    38. double dis = getDis(getX(), getY(), getTarget().getX(), getTarget().getY());
    39. if (dis > 500) {
    40. isAggressive = false;
    41. setHasTarget(false);
    42. } else {
    43. int xSpeed = (int) (getSpd() * (getTarget().getX() - getX()) / dis);
    44. int ySpeed = (int) (getSpd() * (getTarget().getY() - getY()) / dis);
    45. setX(getX() + xSpeed);
    46. setY(getY() + ySpeed);
    47. }
    48. }
    49. public void moveToInitialLocation() {
    50. double dis = getDis(getX(), getY(), initialX, initialY);
    51. if (dis < getSpd()) {
    52. setX(initialX);
    53. setY(initialY);
    54. isAggressive = true;
    55. } else {
    56. int xSpeed = (int) (getSpd() * (initialX - getX()) / dis);
    57. int ySpeed = (int) (getSpd() * (initialY - getY()) / dis);
    58. setX(getX() + xSpeed);
    59. setY(getY() + ySpeed);
    60. }
    61. }
    62. /**
    63. 判断有没有目标及野怪的仇恨值(又没有攻击性)
    64. true,判断是否到攻击范围
    65. false,向目标移动,若中途离开出生点距离大于300或与目标距离大于400,则不再有攻击性。
    66. true,发射子弹,线程开始
    67. false,没有目标,回到出生地,自动回血,再次有攻击性
    68. */
    69. public void move() {
    70. if (isHasTarget() && isAggressive) {
    71. if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), getDis())) {
    72. moveToTarget();
    73. } else if (isAttackCoolDown() && isAlive()) {
    74. Bullet bullet = new Bullet(gameFrame, this, getTarget(), 500, 50, "img/bullet.gif");
    75. gameFrame.objList.add(bullet);
    76. new AttackCD().start();
    77. }
    78. } else {
    79. moveToInitialLocation();
    80. if (getCurrentHp() < getHp()) {
    81. setCurrentHp(getCurrentHp() + 100);
    82. }
    83. }
    84. }
    85. @Override
    86. public void paintSelf(Graphics g) {
    87. // TODO Auto-generated method stub// 生命值为0
    88. if (getCurrentHp() <= 0) {
    89. System.out.println("beast die");
    90. setAlive(false);
    91. gameFrame.removeList.add(this);
    92. gameFrame.beast.beastList.remove(this);
    93. new ReviveCD().start();
    94. } else {
    95. // 添加生命值
    96. addHp(g, width / 2, 80, width, 20, Color.GREEN);
    97. g.drawImage(getImg(), getX() - width / 2, getY() - height / 2, null);
    98. g.setColor(Color.RED);
    99. g.fillOval(getX(), getY(), 10, 10);
    100. g.drawOval(getX() - getDis(), getY() - getDis(), 2 * getDis(), 2 * getDis());
    101. move();
    102. }
    103. }
    104. @Override
    105. public Rectangle getRec() {
    106. // TODO Auto-generated method stub
    107. return new Rectangle(getX() - width / 2, getY() - height / 2, width, height);
    108. }
    109. class AttackCD extends Thread {
    110. public void run() {
    111. // 将攻击功能设置为冷却状态
    112. setAttackCoolDown(false);
    113. // 线程休眠
    114. try {
    115. Thread.sleep(getAttackCoolDownTime());
    116. } catch (Exception e) {
    117. e.printStackTrace();
    118. }
    119. // 将攻击功能设置为攻击状态
    120. setAttackCoolDown(true);
    121. // 线程终止
    122. this.stop();
    123. }
    124. }
    125. class ReviveCD extends Thread {
    126. public void run() {
    127. // 线程休眠
    128. try {
    129. Thread.sleep(5000);
    130. } catch (Exception e) {
    131. e.printStackTrace();
    132. }
    133. Beast reviveBeast;
    134. if (beast instanceof RedBuff) {
    135. reviveBeast = new RedBuff(3045, 3170, gameFrame);
    136. } else if (beast instanceof Bear) {
    137. reviveBeast = new Bear(2800, 2855, gameFrame);
    138. } else if (beast instanceof Bird) {
    139. reviveBeast = new Bird(3570, 3380, gameFrame);
    140. } else if (beast instanceof Xiyi) {
    141. reviveBeast = new Xiyi(4585, 2365, gameFrame);
    142. } else if (beast instanceof BlueBuff) {
    143. reviveBeast = new BlueBuff(4025, 2295, gameFrame);
    144. } else {
    145. reviveBeast = new Wolf(4235, 1945, gameFrame);
    146. }
    147. gameFrame.objList.add(reviveBeast);
    148. gameFrame.beast.beastList.add(reviveBeast);
    149. }
    150. }
    151. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class Bird extends Beast {
    4. public Bird(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/红隼.jpg");
    7. width = 122;
    8. height = 98;
    9. setDis(125);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class BlueBuff extends Beast {
    4. public BlueBuff(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/blueBuff.jpg");
    7. width = 142;
    8. height = 176;
    9. setDis(70);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class RedBuff extends Beast {
    4. public RedBuff(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/redBuff.jpg");
    7. width = 103;
    8. height = 150;
    9. setDis(70);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class Wolf extends Beast {
    4. public Wolf(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/wolf.jpg");
    7. width = 145;
    8. height = 140;
    9. setDis(65);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }
    1. package com.sxt.beast;
    2. import com.sxt.GameFrame;
    3. public class Xiyi extends Beast {
    4. public Xiyi(int x, int y, GameFrame gameFrame) {
    5. super(x, y, gameFrame);
    6. setImg("img/蜥蜴.jpg");
    7. width = 111;
    8. height = 65;
    9. setDis(125);
    10. // TODO Auto-generated constructor stub
    11. }
    12. }

    三.结果呈现 

     ps:图像放主页了,有需要可以下载

  • 相关阅读:
    鸡得关节炎有哪些症状 鸡喂什么药预防球菌病
    典型安全事件专题
    GBase 8c PGXC_CLASS系统表
    云服务的计算服务中的弹性云服务器(ECS)、裸金属服务器(BMS)以及镜像服务(IMS)的概念和深入理解【CloudService】
    推荐4款不足1M的冷门工具
    猿创征文 | H5API之websocket和地理位置的获取
    1347:【例4-8】格子游戏
    杰理之在所有模式下打开喊话增加 mic 自动 mute【篇】
    live555源码分析一
    Windows:VS Code IDE安装ESP-IDF【保姆级】
  • 原文地址:https://blog.csdn.net/m0_73900459/article/details/134635348