java游戲制作-王者榮耀游戲

一.準備工作

首先創建一個新的Java項目命名為“王者榮耀”,并在src下創建兩個包分別命名為“com.sxt"、”com.stx.beast",在相應的包中創建所需的類。

創建一個名為“img”的文件夾來儲存所需的圖片素材。

二.代碼呈現

package com.sxt;import javax.swing.*;
import java.awt.*;public class Background extends GameObject {public Background(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}Image bg = Toolkit.getDefaultToolkit().getImage("img/Map.jpg");public void paintSelf(Graphics g){g.drawImage(bg,0,0,null);}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn null;}
}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;import com.sxt.beast.Beast;public class Bullet extends GameObject {// 發射子彈的游戲元素GameObject attacker;// 目標GameObject target;// 攻擊力int ad;public Bullet(GameFrame gameFrame, GameObject attacker, GameObject target, int ad, int spd) {super(attacker.getX(), attacker.getY(), gameFrame);this.attacker = attacker;this.target = target;setAd(ad);setSpd(spd);// TODO Auto-generated constructor stub}public Bullet(GameFrame gameFrame, GameObject attacker, GameObject target, int ad, int spd, String img) {super(attacker.getX(), attacker.getY(), gameFrame);this.attacker = attacker;this.target = target;setImg(img);setAd(ad);setSpd(spd);// TODO Auto-generated constructor stub}public Bullet() {super();// TODO Auto-generated constructor stub}public void move() {// 子彈與目標碰撞,子彈消失,目標減血if (recIntersectsRec(getRec(), target.getRec())) {if (Beast.class.isAssignableFrom(target.getClass())) {target.setTarget(gameFrame.player);target.setHasTarget(true);}target.setCurrentHp(target.getCurrentHp() - getAd());gameFrame.removeList.add(this);}double dis = getDis(getX(), getY(), target.getX(), target.getY());int xSpeed = (int) (getSpd() * (target.getX() - getX()) / dis);int ySpeed = (int) (getSpd() * (target.getY() - getY()) / dis);setX(getX() + xSpeed);setY(getY() + ySpeed);}@Overridepublic void paintSelf(Graphics g) {// TODO Auto-generated method stubg.drawImage(getImg(), getX() - 16, getY() - 16, null);if (this.getImg() == null) {g.setColor(Color.BLACK);g.fillOval(getX() - 5, getY() - 5, 10, 10);g.drawRect(getX() - 5, getY() - 5, 10, 10);}move();}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn new Rectangle(getX() - 5, getY() - 5, 10, 10);}/*** @return the ad*/public int getAd() {return ad;}/*** @param ad the ad to set*/public void setAd(int ad) {this.ad = ad;}}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;import javax.swing.JButton;public abstract class Champion extends GameObject {// 移動public boolean up, down, left, right;// 移動圖集static String[] imgs = new String[8];// 第幾張圖片int moveCount = 1;//技能圖片Image abilityOne;Image abilityTwo;Image abilityThree;//英雄頭像Image classical;//技能冷卻時間int coolDownTimeOne;int coolDownTimeTwo;int coolDownTimeThree;//三個技能是否處于冷卻狀態boolean coolDownOne = true;boolean coolDownTwo = true;boolean coolDownThree = true;//英雄列表ArrayList<Champion> championList = new ArrayList<Champion>();static {for (int i = 1; i < 8; i++) {imgs[i] = "img/" + i + ".png";}}public Champion(GameFrame gameFrame, int x, int y) {super(gameFrame);setImg("img/stand.png");setX(x);setY(y);setSpd(75);setHp(24000);setDis(250);setAttackCoolDownTime(100);setCurrentHp(getHp());championList.add(new ChampionDaji(gameFrame));championList.add(new ChampionHouyi(gameFrame));}public Champion(GameFrame gameFrame) {// TODO Auto-generated constructor stubsuper(gameFrame);setImg("img/stand.png");setX(700);setY(3800);setSpd(75);setHp(24000);setDis(250);setAttackCoolDownTime(100);setCurrentHp(getHp());}public void keyPressed(KeyEvent e) {int key = e.getKeyCode();if (key == KeyEvent.VK_D) {right = true;}if (key == KeyEvent.VK_A) {left = true;}if (key == KeyEvent.VK_W) {up = true;}if (key == KeyEvent.VK_S) {down = true;}}public void keyReleased(KeyEvent e) {int key = e.getKeyCode();if (key == KeyEvent.VK_D) {right = false;}if (key == KeyEvent.VK_A) {left = false;}if (key == KeyEvent.VK_W) {up = false;}if (key == KeyEvent.VK_S) {down = false;}}public void move() {if (up) {setY(getY() - getSpd());}if (down) {setY(getY() + getSpd());}if (left) {setX(getX() - getSpd());}if (right) {setX(getX() + getSpd());}if (up || down || left || right) {setImg(imgs[moveCount]);moveCount++;if (moveCount == 8) {moveCount = 1;}} else {setImg("img/stand.png");}}/*** 添加三個技能按鈕* */public void addButton() {JButton button1 = new JButton();button1.setSize(100, 100);button1.setLocation(1056, 513);button1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {abilityOne();}});JButton button2 = new JButton();button2.setSize(100, 100);button2.setLocation(1090, 370);button2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {abilityTwo();}});JButton button3 = new JButton();button3.setSize(100, 100);button3.setLocation(1220, 300);button3.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {abilityThree();}});gameFrame.add(button1);gameFrame.add(button2);gameFrame.add(button3);}public abstract void abilityOne();public abstract void abilityTwo();public abstract void abilityThree();public abstract void abilityEffect(Graphics g);@Overridepublic void paintSelf(Graphics g) {// TODO Auto-generated method stub// 生命值為0if (getCurrentHp() <= 0) {setAlive(false);gameFrame.removeList.add(this);} else {// 添加生命值addHp(g, 30, 80, 80, 20, Color.GREEN);//繪制技能圖片g.drawImage(abilityOne, getX() + 360, getY() + 180, null);g.drawImage(abilityTwo, getX() + 400, getY() + 40, null);g.drawImage(abilityThree, getX() + 520, getY() - 30, null);// 繪制圖片g.drawImage(this.getImg(), getX() - 33, getY() - 50, null);// 改變畫筆顏色//g.setColor(Color.GREEN);// 繪制中心圓點//g.fillOval(getX(), getY(), 10, 10);// 繪制矩形邊框//g.drawRect(getX() - 23, getY() - 50, 60, 120);move();abilityEffect(g);}}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn new Rectangle(getX() - 30, getY() - 60, 60, 120);}}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Random;import com.sxt.beast.Beast;public class ChampionDaji extends Champion {// 技能是否處于釋放狀態boolean ifAbilityOne = false;boolean ifAbilityTwo = false;// 鼠標監視器MouseMonitor m;// 一技能多邊形Polygon p;// 一技能三角函數double sin;double cos;// 一技能已經攻擊過的目標ArrayList<GameObject> attacked;// 一技能移動次數int step = 0;// 技能二目標GameObject abilityTwoTarget;// 技能二子彈Bullet abilityTwoBullet;// 三技能子彈列表Bullet[] bulletList = { new Bullet(), new Bullet(), new Bullet(), new Bullet(), new Bullet() };public ChampionDaji(GameFrame gameFrame) {super(gameFrame);abilityOne = Toolkit.getDefaultToolkit().getImage("img/abilityOne.jpg");abilityTwo = Toolkit.getDefaultToolkit().getImage("img/abilityTwo.jpg");abilityThree = Toolkit.getDefaultToolkit().getImage("img/abilityThree.jpg");classical = Toolkit.getDefaultToolkit().getImage("img/Classical.jpg");// 三個技能冷卻時間coolDownTimeOne = 6000;coolDownTimeTwo = 8000;coolDownTimeThree = 8000;}public void exit() {this.gameFrame.removeMouseListener(m);}public void abilityOneMove() {p.translate((int) (50 * cos), -(int) (50 * sin));for (GameObject redObj : gameFrame.objList) {// 是紅色方小兵 && 發生碰撞 && 沒在attacked列表里if (redObj instanceof MinionRed && p.intersects(redObj.getRec()) && attacked.indexOf(redObj) == -1) {// 小兵扣血,添加到attacked里redObj.setCurrentHp(redObj.getCurrentHp() - 400);attacked.add(redObj);}else if (Beast.class.isAssignableFrom(redObj.getClass()) && p.intersects(redObj.getRec()) && attacked.indexOf(redObj) == -1) {redObj.setCurrentHp(redObj.getCurrentHp() - 400);attacked.add(redObj);}}}@Overridepublic void abilityOne() {// TODO Auto-generated method stubif (coolDownOne) {m = new MouseMonitor();p = new Polygon();gameFrame.addMouseListener(m);attacked = new ArrayList<GameObject>();}}@Overridepublic void abilityTwo() {// TODO Auto-generated method stubif (coolDownTwo) {boolean find = false;for (GameObject redObj : gameFrame.objList) {// 是紅色小兵 && 距離小于250 && 存活if ((redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass())) && recIntersectsCir(redObj.getRec(), getX(), getY(), 250)&& redObj.isAlive()) {// 添加子彈abilityTwoBullet = new Bullet(gameFrame, this, redObj, 250, 60, "img/abilityTwoBullet.png");gameFrame.objList.add(abilityTwoBullet);// 給目標賦值abilityTwoTarget = redObj;// 釋放二技能ifAbilityTwo = true;find = true;break;}}if (find) {new AbilityTwoCD().start();find = false;}}}/*** 點擊技能三釋放技能 先將技能范圍內目標儲存到targetList里 提前定義五個子彈 技能釋放時初始化五個子彈 子彈目標從targetList里隨機選擇* 如果期間目標死亡,制作一個目標替身,生命值設置為true 子彈與目標或替身碰撞后消失*/@Overridepublic void abilityThree() {// TODO Auto-generated method stub// 三技能沒在冷卻狀態if (coolDownThree) {// 創建列表來儲存目標ArrayList<GameObject> targetList = new ArrayList<GameObject>();// 遍歷redListfor (int i = 0; i < gameFrame.objList.size(); i++) {GameObject target = gameFrame.objList.get(i);// 是紅色小兵 && 在技能范圍里 && 存活if ((target instanceof MinionRed || Beast.class.isAssignableFrom(target.getClass())) && recIntersectsCir(target.getRec(), getX(), getY(), 250)&& target.isAlive()) {targetList.add(target);}}//找到目標if(targetList.size() != 0) {//初始化五個子彈,隨機攻擊列表里的目標Random random = new Random();int count = 0;while(count < 5) {int r = random.nextInt(targetList.size());if(!targetList.get(r).isAlive()) {//目標死亡,制作替身GameObject substitute = targetList.get(r);substitute.setAlive(true);bulletList[count] = new Bullet(gameFrame, this, substitute, 250, 60, "img/abilityTwoBullet.png");}else {bulletList[count] = new Bullet(gameFrame, this, targetList.get(r), 250, 60, "img/abilityTwoBullet.png");}count++;}new AbilityThreeBulletCD().start();new AbilityThreeCD().start();}}}@Overridepublic void abilityEffect(Graphics g) {// TODO Auto-generated method stubif (ifAbilityOne) {g.setColor(Color.RED);g.fillPolygon(p);abilityOneMove();step++;if (step == 10) {step = 0;ifAbilityOne = false;}}if (ifAbilityTwo) {System.out.println(abilityTwoTarget.beControlled);if (abilityTwoBullet.getRec().intersects(abilityTwoTarget.getRec())) {new AbilityControllCD().start();ifAbilityTwo = false;}}}// 技能一冷卻時間class AbilityOneCD extends Thread {public void run() {// 將技能一設置為冷卻狀態coolDownOne = false;// 線程休眠try {// one來表示一技能冷卻時間int one = coolDownTimeOne;while (one > 0) {Thread.sleep(1000);System.out.println("一技能冷卻時間: " + one / 1000);one -= 1000;}} catch (Exception e) {e.printStackTrace();}// 將技能一設置為攻擊狀態coolDownOne = true;// 線程終止this.stop();}}// 技能二冷卻時間class AbilityTwoCD extends Thread {public void run() {// 將技能二設置為冷卻狀態coolDownTwo = false;// 線程休眠try {// one來表示二技能冷卻時間int two = coolDownTimeTwo;while (two > 0) {Thread.sleep(1000);System.out.println("二技能冷卻時間: " + two / 1000);two -= 1000;}} catch (Exception e) {e.printStackTrace();}// 將技能二設置為攻擊狀態coolDownTwo = true;// 線程終止this.stop();}}// 技能二控制時間class AbilityControllCD extends Thread {public void run() {abilityTwoTarget.beControlled = true;// 線程休眠try {Thread.sleep(20000);} catch (Exception e) {e.printStackTrace();}abilityTwoTarget.beControlled = false;this.stop();}}// 技能三冷卻時間class AbilityThreeCD extends Thread {public void run() {// 將技能三設置為冷卻狀態coolDownThree = false;// 線程休眠try {// three來表示三技能冷卻時間int three = coolDownTimeThree;while (three > 0) {Thread.sleep(1000);System.out.println("三技能冷卻時間: " + three / 1000);three -= 1000;}} catch (Exception e) {e.printStackTrace();}// 將技能三設置為攻擊狀態coolDownThree = true;// 線程終止this.stop();}}//技能三子彈時間間隔class AbilityThreeBulletCD extends Thread{public void run() {try {gameFrame.objList.add(bulletList[0]);Thread.sleep(200);gameFrame.objList.add(bulletList[1]);Thread.sleep(200);gameFrame.objList.add(bulletList[2]);Thread.sleep(200);gameFrame.objList.add(bulletList[3]);Thread.sleep(200);gameFrame.objList.add(bulletList[4]);}catch(Exception e) {e.printStackTrace();}this.stop();}}// 鼠標監視器private class MouseMonitor extends MouseAdapter {@Overridepublic void mousePressed(MouseEvent e) {// 當鼠標點擊時int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;double dis = getDis(mouseX, mouseY, playerX, playerY);// 三角函數cos = (mouseX - playerX) / dis;sin = -(mouseY - playerY) / dis;// 坐標差int difX = (int) (60 * sin);int difY = (int) (60 * cos);p.addPoint(getX() - difX, getY() - difY);p.addPoint(getX() + difX, getY() + difY);p.addPoint(getX() + difX + (int) (20 * cos), getY() + difY - (int) (20 * sin));p.addPoint(getX() - difX + (int) (20 * cos), getY() - difY - (int) (20 * sin));exit();new AbilityOneCD().start();ifAbilityOne = true;}}
}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;import javax.swing.JButton;import com.sxt.beast.Beast;public class ChampionHouyi extends Champion {// 技能是否處于釋放狀態boolean ifAbilityThree = false;boolean ifAbilityTwo = false;// 鼠標監視器MouseMonitor m;MouseMonitorTwo m2;// 三技能多邊形Polygon p;// 三技能三角函數double sin;double cos;// 三技能命中的目標GameObject abilityThreeTarget;// 三技能是否出界boolean ifXOutside;boolean ifYOutside;// 二技能位置int X_AbilityTwo;int Y_AbilityTwo;public ChampionHouyi(GameFrame gameFrame) {super(gameFrame);abilityOne = Toolkit.getDefaultToolkit().getImage("img/HyabilityOne.jpg");abilityTwo = Toolkit.getDefaultToolkit().getImage("img/HyabilityTwo.jpg");abilityThree = Toolkit.getDefaultToolkit().getImage("img/HyabilityThree.jpg");classical = Toolkit.getDefaultToolkit().getImage("img/后羿-輝光之辰.jpg");// 三個技能冷卻時間coolDownTimeOne = 14000;coolDownTimeTwo = 10000;coolDownTimeThree = 28000;// TODO Auto-generated constructor stub}public ChampionHouyi(GameFrame gameFrame, int i, int j) {// TODO Auto-generated constructor stubsuper(gameFrame, i, j);}public void exit(MouseAdapter ma) {this.gameFrame.removeMouseListener(ma);}public void attack() {if (isAttackCoolDown()) {ArrayList<GameObject> targets = new ArrayList<GameObject>();// 目標列表,最多三個目標for (GameObject redObj : this.gameFrame.redList) {if (this.recIntersectsCir(redObj.getRec(), getX() - 250, getY() - 250, 500)) {targets.add(redObj);if (targets.size() == 3) {break;}}}for (GameObject beastObj : this.gameFrame.beast.beastList) {if (this.recIntersectsCir(beastObj.getRec(), getX() - 250, getY() - 250, 500)) {targets.add(beastObj);if (targets.size() == 3) {break;}}}for (int i = 0; i < targets.size(); i++) {Bullet bullet;if (i == 0) {bullet = new Bullet(gameFrame, this, targets.get(i), 400, 50, "img/bullet.gif");} else {bullet = new Bullet(gameFrame, this, targets.get(i), 200, 50, "img/bullet.gif");}gameFrame.objList.add(bullet);}new AttackCD().start();}}public void abilityTwoAttack() {for (GameObject redObj : this.gameFrame.objList) {if (redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass())) {if (this.recIntersectsCir(redObj.getRec(), X_AbilityTwo - 60, Y_AbilityTwo - 60, 120)) {redObj.setCurrentHp(redObj.getCurrentHp() - 400);}if (this.recIntersectsCir(redObj.getRec(), X_AbilityTwo - 30, Y_AbilityTwo - 30, 60)) {redObj.setCurrentHp(redObj.getCurrentHp() - 200);}}}}public void abilityThreeMove() {p.translate((int) (50 * cos), -(int) (50 * sin));for (GameObject redObj : gameFrame.objList) {// 是紅色方小兵 && 發生碰撞if ((redObj instanceof MinionRed || Beast.class.isAssignableFrom(redObj.getClass()))&& p.intersects(redObj.getRec())) {// 擊中目標后,目標減血并眩暈,多邊形消失redObj.setCurrentHp(redObj.getCurrentHp() - 400);abilityThreeTarget = redObj;new AbilityControlCD().start();ifAbilityThree = false;new AbilityThreeCD().start();}}if (!ifXOutside) {for (int x : p.xpoints) {if (x < 0 || x >= 5165) {ifXOutside = true;break;}}}if (!ifYOutside) {for (int y : p.ypoints) {if (y < 0 || y >= 4085) {ifYOutside = true;break;}}}}/*** 一技能 制作游戲界面攻擊按鈕的替身 替換攻擊按鈕 新的攻擊按鈕事件: 1. 定義目標列表 2. 添加目標,最多添加三個 3.* 目標列表第一個造成400傷害,其余200傷害 4. 持續5秒,結束后替換攻擊按鈕?*/@Overridepublic void abilityOne() {// TODO Auto-generated method stubif (coolDownOne) {new AbilityOneDuration().start();// 強化普攻持續時間new AbilityOneCD().start();}}/*** 二技能 先點擊按鈕釋放技能 再點擊技能范圍內任意位置 之后點擊的位置會出現 兩個大小不同的圓 在大圓內會受到300傷害 在小圓內受到額外200傷害*/@Overridepublic void abilityTwo() {// TODO Auto-generated method stubif (coolDownTwo) {m2 = new MouseMonitorTwo();gameFrame.addMouseListener(m2);X_AbilityTwo = 0;Y_AbilityTwo = 0;}}@Overridepublic void abilityThree() {// TODO Auto-generated method stubif (coolDownThree) {m = new MouseMonitor();p = new Polygon();gameFrame.addMouseListener(m);ifAbilityThree = true;ifXOutside = false;ifYOutside = false;}}@Overridepublic void abilityEffect(Graphics g) {// TODO Auto-generated method stubif (ifAbilityTwo) {System.out.println("222");g.setColor(Color.RED);g.fillOval(X_AbilityTwo - 60, Y_AbilityTwo - 60, 120, 120);g.setColor(Color.BLACK);g.fillOval(X_AbilityTwo - 30, Y_AbilityTwo - 30, 60, 60);abilityTwoAttack();X_AbilityTwo = 0;Y_AbilityTwo = 0;ifAbilityTwo = false;new AbilityTwoCD().start();}if (ifAbilityThree) {System.out.println("333");g.setColor(Color.RED);g.fillPolygon(p);abilityThreeMove();// 如果出界,技能釋放結束if (ifXOutside || ifYOutside) {ifAbilityThree = false;p = new Polygon();new AbilityThreeCD().start();}}}// 攻擊冷卻時間class AttackCD extends Thread {public void run() {// 將攻擊功能設置為冷卻狀態setAttackCoolDown(false);// 線程休眠try {Thread.sleep(getAttackCoolDownTime());} catch (Exception e) {e.printStackTrace();}// 將攻擊功能設置為攻擊狀態setAttackCoolDown(true);// 線程終止this.stop();}}// 一技能冷卻時間class AbilityOneCD extends Thread {public void run() {// 將攻擊功能設置為冷卻狀態coolDownOne = false;// 休眠try {// one用來儲存冷卻時間int one = coolDownTimeOne;while (coolDownTimeOne > 0) {Thread.sleep(1000);System.out.println("技能一冷卻時間: " + coolDownTimeOne / 1000);coolDownTimeOne -= 1000;}coolDownTimeOne = one;} catch (Exception e) {e.printStackTrace();}// 將攻擊功能解除冷卻狀態coolDownOne = true;// 線程終止this.stop();}}// 技能一持續時間class AbilityOneDuration extends Thread {public void run() {// 制作攻擊按鈕的替身JButton substitute = gameFrame.attackButton;gameFrame.remove(gameFrame.attackButton);JButton button = new JButton();button.setSize(130, 132);button.setLocation(1150, 430);button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 獲取到的事件源就是按鈕本身attack();}});gameFrame.add(button);// 休眠try {Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}gameFrame.remove(button);gameFrame.add(substitute);// 線程終止this.stop();}}// 二技能冷卻時間class AbilityTwoCD extends Thread {public void run() {// 將二技能設置為冷卻狀態coolDownTwo = false;// 休眠try {int two = coolDownTimeTwo;while (coolDownTimeTwo > 0) {Thread.sleep(1000);System.out.println("技能二冷卻時間: " + coolDownTimeTwo / 1000);coolDownTimeTwo -= 1000;}coolDownTimeTwo = two;} catch (Exception e) {e.printStackTrace();}// 將攻擊功能解除冷卻狀態coolDownTwo = true;// 線程終止this.stop();}}// 技能三冷卻時間class AbilityThreeCD extends Thread {public void run() {// 將技能三設置為冷卻狀態coolDownThree = false;// 線程休眠try {// three來表示三技能冷卻時間int three = coolDownTimeThree;while (three > 0) {Thread.sleep(1000);System.out.println("三技能冷卻時間: " + three / 1000);three -= 1000;}} catch (Exception e) {e.printStackTrace();}// 將技能三設置為攻擊狀態coolDownThree = true;// 線程終止this.stop();}}// 技能三控制時間class AbilityControlCD extends Thread {public void run() {abilityThreeTarget.beControlled = true;// 線程休眠try {Thread.sleep(20000);} catch (Exception e) {e.printStackTrace();}abilityThreeTarget.beControlled = false;this.stop();}}// 鼠標監視器private class MouseMonitorTwo extends MouseAdapter {@Overridepublic void mousePressed(MouseEvent e) {// 當鼠標點擊時System.out.println("pressed");int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;double dis = getDis(mouseX, mouseY, playerX, playerY);if (dis < 250) {X_AbilityTwo = e.getX() - playerX + getX();Y_AbilityTwo = e.getY() - playerY + getY();}ifAbilityTwo = true;exit(this);}}// 鼠標監視器private class MouseMonitor extends MouseAdapter {@Overridepublic void mousePressed(MouseEvent e) {// 當鼠標點擊時int mouseX = e.getX(), mouseY = e.getY(), playerX = 700, playerY = 350;double dis = getDis(mouseX, mouseY, playerX, playerY);// 三角函數cos = (mouseX - playerX) / dis;sin = -(mouseY - playerY) / dis;// 坐標差int difX = (int) (60 * sin);int difY = (int) (60 * cos);p.addPoint(getX() - difX, getY() - difY);p.addPoint(getX() + difX, getY() + difY);p.addPoint(getX() + difX + (int) (20 * cos), getY() + difY - (int) (20 * sin));p.addPoint(getX() - difX + (int) (20 * cos), getY() - difY - (int) (20 * sin));ifAbilityThree = true;exit(this);}}}

package com.sxt;import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;import javax.swing.JButton;
import javax.swing.JFrame;import com.sxt.beast.Beast;public class GameFrame extends JFrame {// 游戲模式 0 選擇英雄,1 游戲開始,2 游戲勝利,3 游戲失敗int state = 0;// 窗口尺寸private int windowWidth = 1400;private int windowHeight = 700;// 雙緩沖圖片private Image offScreenImage = null;// 攻擊圖片private Image attack = Toolkit.getDefaultToolkit().getImage("img/attack.jpg");//游戲勝利失敗圖片private Image gameWin = Toolkit.getDefaultToolkit().getImage("img/gameWin.png");private Image gameLose = Toolkit.getDefaultToolkit().getImage("img/gameLose.png");// 游戲背景Background background = new Background(this);// 游戲玩家Champion player;Champion champion = new ChampionHouyi(this,700,3800);// 雙方小兵MinionBlue mb = new MinionBlue(this);MinionRed mr = new MinionRed(this);// 防御塔Turret turret = new Turret(this);//野怪public Beast beast = new Beast(this);// 攻擊按鈕JButton attackButton;// 游戲元素列表public ArrayList<GameObject> objList = new ArrayList<GameObject>();ArrayList<GameObject> redList = new ArrayList<GameObject>();// 紅色方ArrayList<GameObject> blueList = new ArrayList<GameObject>();// 藍色方public ArrayList<GameObject> removeList = new ArrayList<GameObject>();// 存放將要刪除的元素public void launch() {// 設置尺寸setSize(windowWidth, windowHeight);// 窗口居中setLocationRelativeTo(null);// 關閉事件setDefaultCloseOperation(3);// 用戶不能調整窗口大小setResizable(false);// 標題setTitle("王者榮耀");// 窗口可見setVisible(true);// 添加鍵盤監視器this.addKeyListener(new GameFrame.KeyMonitor());// 添加游戲元素objList.add(background);objList.addAll(turret.turretList);objList.addAll(beast.beastList);blueList.add(turret.turretList.get(0));redList.add(turret.turretList.get(4));/*** 攻擊按鈕*/attackButton = new JButton();attackButton.setSize(130, 132);attackButton.setLocation(1150, 430);attackButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 按鈕事件player.attack(redList);}});this.add(attackButton);while (true) {if (state == 1) {// 添加小兵//mb.createMinion(this, blueList);//mr.createMinion(this, redList);// 添加防御塔turret.addTurret();}repaint();try {Thread.sleep(17);} catch (Exception e) {e.printStackTrace();}}}public void paint(Graphics g) {if (offScreenImage == null) {offScreenImage = this.createImage(5984, 4452);}Graphics gImage = offScreenImage.getGraphics();if (state == 0) {for(int i = 0; i < champion.championList.size(); i++) {//添加圖片Image classical = champion.championList.get(i).classical;gImage.drawImage(classical, i*160, 20, null);//添加按鈕JButton championButton = new JButton();championButton.setSize(150, 150);championButton.setLocation(i*150, 0);int a = i;championButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {state = 1;player = champion.championList.get(a);objList.add(player);player.addButton();}});this.add(championButton);}} else if (state == 1) {for (int i = 0; i < objList.size(); i++) {objList.get(i).paintSelf(gImage);}// 繪制攻擊圖片gImage.drawImage(attack, player.getX() + 500, player.getY() + 100, null);objList.removeAll(removeList);} else if (state == 2) {//游戲勝利gImage.drawImage(gameWin, 0, 5, null);} else if (state == 3) {//游戲失敗gImage.drawImage(gameLose, 0, 5, null);}if (state != 1) {g.drawImage(offScreenImage, 0, 0, null);} else {g.drawImage(offScreenImage, -player.getX() + 700, -player.getY() + 350, null);}/*** 添加按鈕后不能調用鍵盤事件 因為程序的焦點變成了按鈕 this.requestFocus() 把焦點重新改變到游戲界面上*/this.requestFocus();}// main方法public static void main(String[] args) {GameFrame gameFrame = new GameFrame();gameFrame.launch();}// 鍵盤事件private class KeyMonitor extends KeyAdapter {@Overridepublic void keyPressed(KeyEvent e) {int key = e.getKeyCode();player.keyPressed(e);}@Overridepublic void keyReleased(KeyEvent e) {int key = e.getKeyCode();player.keyReleased(e);}}
}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.ArrayList;import com.sxt.beast.Beast;public abstract class GameObject {// 坐標private int x;private int y;// 圖片private Image img;// 游戲界面public GameFrame gameFrame;// 速度private int spd;// 初始生命值private int hp;// 當前生命值private int currentHp;// 攻擊目標private GameObject target;// 是否有目標private boolean hasTarget = false;// 攻擊距離private int dis;// 攻擊時間間隔private int attackCoolDownTime;// 攻擊是否冷卻private boolean attackCoolDown = true;// 是否存活private boolean alive = true;// 是否被控制boolean beControlled = false;public GameObject(GameFrame gameFrame) {this.gameFrame = gameFrame;}public GameObject(int x, int y, GameFrame gameFrame) {this.x = x;this.y = y;this.gameFrame = gameFrame;}public GameObject() {// TODO Auto-generated constructor stub}public void addHp(Graphics g, int difX, int difY, int width, int height, Color color) {// 繪制外部輪廓g.setColor(Color.black);g.drawRect(getX() - difX, getY() - difY, width, height);// 填充矩形g.setColor(color);g.fillRect(getX() - difX, getY() - difY, (int) (width * getCurrentHp() / getHp()), height);}public double getDis(int x1, int y1, int x2, int y2) {return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));}// 矩形矩形碰撞檢測public boolean recIntersectsRec(Rectangle r1, Rectangle r2) {return r1.intersects(r2);}public boolean recIntersectsCir(Rectangle rec, int x, int y, int r) {/** 矩形于圓相交: 圓心到至少一個矩形定點的距離小于r */if ((getDis(x, y, rec.x, rec.y) < r) || (getDis(x, y, rec.x, rec.y + rec.height) < r)|| (getDis(x, y, rec.x + rec.width, rec.y) < r)|| (getDis(x, y, rec.x + rec.width, rec.y + rec.height) < r)) {return true;}return false;}// 攻擊方法public void attack(ArrayList<GameObject> gameObjList) {if (hasTarget) {// 目標離開范圍后尋找新的目標if (!recIntersectsCir(target.getRec(), getX(), getY(), getDis())) {setHasTarget(false);}// 目標死亡,尋找新目標else if (!target.isAlive()) {setHasTarget(false);} else if (isAttackCoolDown() && isAlive()) {Bullet bullet = null;// 防御塔攻擊if (Turret.class.isAssignableFrom(getClass())) {bullet = new Bullet(gameFrame, this, getTarget(), 500, 50);}// 小兵攻擊else if (Minion.class.isAssignableFrom(getClass())) {bullet = new Bullet(gameFrame, this, getTarget(), 50, 30);}// 玩家攻擊else if (this instanceof Champion) {bullet = new Bullet(gameFrame, this, getTarget(), 500, 50, "img/bullet.gif");}gameFrame.objList.add(bullet);// 線程開始new AttackCD().start();}} else {// 遍歷列表for (GameObject obj : gameObjList) {// 判斷攻擊范圍(圓形)與敵方(矩形)是否相交if (recIntersectsCir(obj.getRec(), getX(), getY(), getDis())) {// 找到目標setTarget(obj);setHasTarget(true);// 跳出循環break;}}// 玩家是否在攻擊范圍內if (!hasTarget && gameObjList == gameFrame.blueList) {if (recIntersectsCir(gameFrame.player.getRec(), getX(), getY(), getDis())) {// 找到目標setTarget(gameFrame.player);setHasTarget(true);}} else {for (GameObject obj : gameFrame.beast.beastList) {// 判斷攻擊范圍(圓形)與敵方(矩形)是否相交if (recIntersectsCir(obj.getRec(), getX(), getY(), getDis())) {// 找到目標setTarget(obj);setHasTarget(true);// 跳出循環break;}}}}}class AttackCD extends Thread {public void run() {// 將攻擊功能設置為冷卻狀態setAttackCoolDown(false);// 線程休眠try {Thread.sleep(attackCoolDownTime);} catch (Exception e) {e.printStackTrace();}// 將攻擊功能設置為攻擊狀態setAttackCoolDown(true);// 線程終止this.stop();}}// 繪制元素public abstract void paintSelf(Graphics g);// 返回矩形public abstract Rectangle getRec();/*** @return the x*/public int getX() {return x;}/*** @param x the x to set*/public void setX(int x) {this.x = x;}/*** @return the y*/public int getY() {return y;}/*** @param y the y to set*/public void setY(int y) {this.y = y;}/*** @return the img*/public Image getImg() {return img;}/*** @param img the img to set*/public void setImg(String img) {this.img = Toolkit.getDefaultToolkit().getImage(img);}/*** @return the spd*/public int getSpd() {return spd;}/*** @param spd the spd to set*/public void setSpd(int spd) {this.spd = spd;}/*** @return the hp*/public int getHp() {return hp;}/*** @param hp the hp to set*/public void setHp(int hp) {this.hp = hp;}/*** @return the currentHp*/public int getCurrentHp() {return currentHp;}/*** @param currentHp the currentHp to set*/public void setCurrentHp(int currentHp) {if (currentHp < getHp()) {if (Beast.class.isAssignableFrom(getClass())) {System.out.println("yes");setTarget(gameFrame.player);setHasTarget(true);}}this.currentHp = currentHp;}/*** @return the target*/public GameObject getTarget() {return target;}/*** @param target the target to set*/public void setTarget(GameObject target) {this.target = target;}/*** @return the hasTarget*/public boolean isHasTarget() {return hasTarget;}/*** @param hasTarget the hasTarget to set*/public void setHasTarget(boolean hasTarget) {this.hasTarget = hasTarget;}/*** @return the dis*/public int getDis() {return dis;}/*** @param dis the dis to set*/public void setDis(int dis) {this.dis = dis;}/*** @return the attackCoolDownTime*/public int getAttackCoolDownTime() {return attackCoolDownTime;}/*** @param attackCoolDownTime the attackCoolDownTime to set*/public void setAttackCoolDownTime(int attackCoolDownTime) {this.attackCoolDownTime = attackCoolDownTime;}/*** @return the attackCoolDown*/public boolean isAttackCoolDown() {return attackCoolDown;}/*** @param attackCoolDown the attackCoolDown to set*/public void setAttackCoolDown(boolean attackCoolDown) {this.attackCoolDown = attackCoolDown;}/*** @return the alive*/public boolean isAlive() {return alive;}/*** @param alive the alive to set*/public void setAlive(boolean alive) {this.alive = alive;}
}

?

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;public abstract class Minion extends GameObject {// 是否生成下一個小兵private boolean nextMinion = true;// 是否生成下一波小兵private boolean nextLine = true;// 生成小兵數量private int minionCount = 0;// 是否檢測到目標private boolean ifFindTarget = false;public Minion(GameFrame gameFrame) {super(gameFrame);setHp(800);setCurrentHp(getHp());setDis(100);setAttackCoolDownTime(2000);// TODO Auto-generated constructor stub}/*** (1325, 3750) (4425, 3750) (5050, 3125) (5050, 1125)*/public abstract void move(ArrayList<GameObject> objList);/*** @param x:       下一步的橫坐標* @param y:       下一步的縱坐標* @param objList: 小兵列表* @return 下一步位置與其他小兵是否碰撞*/public boolean hitMinion(int x, int y, ArrayList<GameObject> objList) {// 新的區域生成矩形Rectangle r = new Rectangle(x - 16, y - 16, 45, 45);for (GameObject obj : objList) {// 相同類 && 不是自身if (obj.getClass() == this.getClass() && obj != this) {if (r.intersects(obj.getRec())) {return true;}}}return false;}public void findTarget(ArrayList<GameObject> objList) {for (GameObject obj : objList) {if (recIntersectsCir(obj.getRec(), getX(), getY(), 200)) {setTarget(obj);setIfFindTarget(true);}}if (objList == gameFrame.blueList) {if (recIntersectsCir(gameFrame.player.getRec(), getX(), getY(), 200)) {setTarget(gameFrame.player);setIfFindTarget(true);}}}public void moveToTarget() {double dis = getDis(getX(), getY(), getTarget().getX(), getTarget().getY());int xSpeed = (int) (getSpd() * (getTarget().getX() - getX()) / dis);int ySpeed = (int) (getSpd() * (getTarget().getY() - getY()) / dis);if (!hitMinion(getX() + xSpeed, getY(), gameFrame.objList)) {setX(getX() + xSpeed);}if (!hitMinion(getX(), getY() + ySpeed, gameFrame.objList)) {setY(getY() + ySpeed);}}public void createMinion(GameFrame gameFrame, ArrayList<GameObject> minionList) {if (nextLine) {if (nextMinion) {// 藍色方小兵if (minionList == this.gameFrame.blueList) {MinionBlue mb = new MinionBlue(gameFrame);gameFrame.objList.add(mb);minionList.add(mb);}// 紅色方小兵else {MinionRed mr = new MinionRed(gameFrame);gameFrame.objList.add(mr);minionList.add(mr);}minionCount++;new NextMinion().start();}if (minionCount == 3) {minionCount = 0;new NextLine().start();}}}// 每個小兵生成時間class NextMinion extends Thread {public void run() {nextMinion = false;// 休眠1.5stry {Thread.sleep(1500);} catch (Exception e) {e.printStackTrace();}nextMinion = true;// 線程終止this.stop();}}// 每波小兵生成時間class NextLine extends Thread {public void run() {nextLine = false;// 休眠15stry {Thread.sleep(15000);} catch (Exception e) {e.printStackTrace();}nextLine = true;// 線程終止this.stop();}}@Overridepublic void paintSelf(Graphics g) {// TODO Auto-generated method stub// 生命值為0if (getCurrentHp() <= 0) {setAlive(false);gameFrame.removeList.add(this);if (this instanceof MinionBlue) {gameFrame.blueList.remove(this);} else {gameFrame.redList.remove(this);}} else {// 添加生命值if (this instanceof MinionBlue) {this.addHp(g, 17, 28, 45, 10, Color.GREEN);} else {this.addHp(g, 17, 28, 45, 10, Color.RED);}g.drawImage(getImg(), getX() - 16, getY() - 16, null);//繪制檢測范圍圓形//g.setColor(Color.RED);//g.fillOval(getX(), getY(), 10, 10);//g.drawRect(getX() - 16, getY() - 16, 45, 45);// 小兵移動if (!beControlled) {if (this instanceof MinionBlue) {move(gameFrame.redList);} else {move(gameFrame.blueList);}}}}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn new Rectangle(getX() - 16, getY() - 16, 45, 45);}/*** @return the ifFindTarget*/public boolean isIfFindTarget() {return ifFindTarget;}/*** @param ifFindTarget the ifFindTarget to set*/public void setIfFindTarget(boolean ifFindTarget) {this.ifFindTarget = ifFindTarget;}}

package com.sxt;import java.util.ArrayList;public class MinionBlue extends Minion {public MinionBlue(GameFrame gameFrame) {super(gameFrame);setImg("img/blue.jpg");setX(1325);setY(3750);// TODO Auto-generated constructor stub}@Overridepublic void move(ArrayList<GameObject> objList) {// TODO Auto-generated method stubif (isIfFindTarget()) {// 離開檢測范圍if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), 200)) {setIfFindTarget(false);} else {if (!isHasTarget()) {moveToTarget();}attack(objList);}} else {findTarget(objList);// 原路線移動if (getX() < 4425) {setSpd(25);if (!hitMinion(getX() + getSpd(), getY(), gameFrame.blueList)) {setX(getX() + getSpd());}} else if (getX() < 5100 && getX() >= 4425) {setSpd(20);if (!hitMinion(getX() + getSpd(), getY(), gameFrame.blueList)) {setX(getX() + getSpd());}if (!hitMinion(getX(), getY() - getSpd(), gameFrame.blueList)) {setY(getY() - getSpd());}} else if (getX() >= 4900) {setSpd(18);if (!hitMinion(getX(), getY() - getSpd(), gameFrame.blueList)) {setY(getY() - getSpd());}}}}
}

?

package com.sxt;import java.util.ArrayList;public class MinionRed extends Minion {public MinionRed(GameFrame gameFrame) {super(gameFrame);setImg("img/red.jpg");setX(5050);setY(1125);// TODO Auto-generated constructor stub}@Overridepublic void move(ArrayList<GameObject> objList) {// TODO Auto-generated method stubif (isIfFindTarget()) {// 離開檢測范圍if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), 200)) {setIfFindTarget(false);} else {if (!isHasTarget()) {moveToTarget();}attack(objList);}} else {findTarget(objList);// 原路線移動if (getY() < 3125) {setSpd(18);if (!hitMinion(getX(), getY() + getSpd(), gameFrame.redList)) {setY(getY() + getSpd());}} else if (getY() < 3750 && getY() >= 3125) {setSpd(20);if (!hitMinion(getX(), getY() + getSpd(), gameFrame.redList)) {setY(getY() + getSpd());}if (!hitMinion(getX() - getSpd(), getY(), gameFrame.redList)) {setX(getX() - getSpd());}} else if (getY() >= 3750) {setSpd(25);if (!hitMinion(getX() - getSpd(), getY(), gameFrame.redList)) {setX(getX() - getSpd());}}}}}

package com.sxt;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;public class Turret extends GameObject {ArrayList<Turret> turretList = new ArrayList<Turret>();public Turret turretBlueOne;public Turret turretBlueTwo;public Turret turretBlueThree;public Turret turretBlueBase;public Turret turretRedOne;public Turret turretRedTwo;public Turret turretRedThree;public Turret turretRedBase;public Turret(GameFrame gameFrame) {super(gameFrame);setImg("img/turret.png");// 初始化八個防御塔turretList.add(turretBlueOne = new TurretBlue(1860, 3790, gameFrame));turretList.add(turretBlueTwo = new TurretBlue(2650, 3820, gameFrame));turretList.add(turretBlueThree = new TurretBlue(3995, 3830, gameFrame));turretList.add(turretBlueBase = new TurretBlue(1130, 3650, gameFrame));turretList.add(turretRedOne = new TurretRed(5100, 3030, gameFrame));turretList.add(turretRedTwo = new TurretRed(5120, 2100, gameFrame));turretList.add(turretRedThree = new TurretRed(5060, 1570, gameFrame));turretList.add(turretRedBase = new TurretRed(4850, 1100, gameFrame));// TODO Auto-generated constructor stub}public Turret(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/turret.png");setHp(6000);setCurrentHp(getHp());setAttackCoolDownTime(1000);setDis(300);}public void addTurret() {/*** 添加到objList里會被繪制出來,添加到redList和blueList才會被攻擊 前一個防御塔爆炸后再把后一個添加到列表里*/if (!gameFrame.turret.turretBlueOne.isAlive() && gameFrame.turret.turretBlueTwo.isAlive()&& gameFrame.blueList.indexOf(gameFrame.turret.turretBlueTwo) == -1) {gameFrame.blueList.add(gameFrame.turret.turretBlueTwo);}if (!gameFrame.turret.turretBlueTwo.isAlive() && gameFrame.turret.turretBlueThree.isAlive()&& gameFrame.blueList.indexOf(gameFrame.turret.turretBlueThree) == -1) {gameFrame.blueList.add(gameFrame.turret.turretBlueThree);}if (!gameFrame.turret.turretBlueThree.isAlive() && gameFrame.turret.turretBlueBase.isAlive()&& gameFrame.blueList.indexOf(gameFrame.turret.turretBlueBase) == -1) {gameFrame.blueList.add(gameFrame.turret.turretBlueBase);}if (!gameFrame.turret.turretBlueBase.isAlive()) {//游戲失敗gameFrame.state = 3;}if (!gameFrame.turret.turretRedOne.isAlive() && gameFrame.turret.turretRedTwo.isAlive()&& gameFrame.redList.indexOf(gameFrame.turret.turretRedTwo) == -1) {gameFrame.redList.add(gameFrame.turret.turretRedTwo);}if (!gameFrame.turret.turretRedTwo.isAlive() && gameFrame.turret.turretRedThree.isAlive()&& gameFrame.redList.indexOf(gameFrame.turret.turretRedThree) == -1) {gameFrame.redList.add(gameFrame.turret.turretRedThree);}if (!gameFrame.turret.turretRedThree.isAlive() && gameFrame.turret.turretRedBase.isAlive()&& gameFrame.redList.indexOf(gameFrame.turret.turretRedBase) == -1) {gameFrame.redList.add(gameFrame.turret.turretRedBase);}if (!gameFrame.turret.turretRedBase.isAlive()) {//游戲勝利gameFrame.state = 2;}}@Overridepublic void paintSelf(Graphics g) {// 生命值為0if (getCurrentHp() <= 0) {setAlive(false);gameFrame.removeList.add(this);if (this instanceof TurretBlue) {gameFrame.blueList.remove(this);} else {gameFrame.redList.remove(this);}} else {// 添加生命值if (this instanceof TurretBlue) {this.addHp(g, 50, 130, 100, 20, Color.GREEN);attack(gameFrame.redList);} else {this.addHp(g, 50, 130, 100, 20, Color.RED);attack(gameFrame.blueList);}g.drawImage(getImg(), getX() - 50, getY() - 100, null);g.drawOval(getX() - 300, getY() - 300, 600, 600);}}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn new Rectangle(getX() - 50, getY() - 100, 100, 180);}}
package com.sxt;public class TurretBlue extends Turret {public TurretBlue(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}public TurretBlue(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);}}
package com.sxt;public class TurretRed extends Turret {public TurretRed(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}public TurretRed(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);}}

package com.sxt.beast;import com.sxt.GameFrame;public class Bear extends Beast {public Bear(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/bear.jpg");width = 85;height = 112;setDis(65);// TODO Auto-generated constructor stub}}

package com.sxt.beast;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;import com.sxt.*;public class Beast extends GameObject {public ArrayList<Beast> beastList = new ArrayList<Beast>();int width;int height;// 初始坐標int initialX;int initialY;// 有沒有仇恨值public boolean isAggressive = false;// 復活的元素Beast beast = null;public Beast(GameFrame gameFrame) {super(gameFrame);beastList.add(new RedBuff(3045, 3170, gameFrame));beastList.add(new Bear(2800, 2855, gameFrame));beastList.add(new Bird(3570, 3380, gameFrame));beastList.add(new Xiyi(4585, 2365, gameFrame));beastList.add(new BlueBuff(4025, 2295, gameFrame));beastList.add(new Wolf(4235, 1945, gameFrame));}public Beast(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setHp(1000);setCurrentHp(getHp());setSpd(10);setAttackCoolDownTime(2000);initialX = getX();initialY = getY();beast = this;}public void moveToTarget() {double dis = getDis(getX(), getY(), getTarget().getX(), getTarget().getY());if (dis > 500) {isAggressive = false;setHasTarget(false);} else {int xSpeed = (int) (getSpd() * (getTarget().getX() - getX()) / dis);int ySpeed = (int) (getSpd() * (getTarget().getY() - getY()) / dis);setX(getX() + xSpeed);setY(getY() + ySpeed);}}public void moveToInitialLocation() {double dis = getDis(getX(), getY(), initialX, initialY);if (dis < getSpd()) {setX(initialX);setY(initialY);isAggressive = true;} else {int xSpeed = (int) (getSpd() * (initialX - getX()) / dis);int ySpeed = (int) (getSpd() * (initialY - getY()) / dis);setX(getX() + xSpeed);setY(getY() + ySpeed);}}/**判斷有沒有目標及野怪的仇恨值(又沒有攻擊性)true,判斷是否到攻擊范圍false,向目標移動,若中途離開出生點距離大于300或與目標距離大于400,則不再有攻擊性。true,發射子彈,線程開始false,沒有目標,回到出生地,自動回血,再次有攻擊性*/public void move() {if (isHasTarget() && isAggressive) {if (!recIntersectsCir(getTarget().getRec(), getX(), getY(), getDis())) {moveToTarget();} else if (isAttackCoolDown() && isAlive()) {Bullet bullet = new Bullet(gameFrame, this, getTarget(), 500, 50, "img/bullet.gif");gameFrame.objList.add(bullet);new AttackCD().start();}} else {moveToInitialLocation();if (getCurrentHp() < getHp()) {setCurrentHp(getCurrentHp() + 100);}}}@Overridepublic void paintSelf(Graphics g) {// TODO Auto-generated method stub// 生命值為0if (getCurrentHp() <= 0) {System.out.println("beast die");setAlive(false);gameFrame.removeList.add(this);gameFrame.beast.beastList.remove(this);new ReviveCD().start();} else {// 添加生命值addHp(g, width / 2, 80, width, 20, Color.GREEN);g.drawImage(getImg(), getX() - width / 2, getY() - height / 2, null);g.setColor(Color.RED);g.fillOval(getX(), getY(), 10, 10);g.drawOval(getX() - getDis(), getY() - getDis(), 2 * getDis(), 2 * getDis());move();}}@Overridepublic Rectangle getRec() {// TODO Auto-generated method stubreturn new Rectangle(getX() - width / 2, getY() - height / 2, width, height);}class AttackCD extends Thread {public void run() {// 將攻擊功能設置為冷卻狀態setAttackCoolDown(false);// 線程休眠try {Thread.sleep(getAttackCoolDownTime());} catch (Exception e) {e.printStackTrace();}// 將攻擊功能設置為攻擊狀態setAttackCoolDown(true);// 線程終止this.stop();}}class ReviveCD extends Thread {public void run() {// 線程休眠try {Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}Beast reviveBeast;if (beast instanceof RedBuff) {reviveBeast = new RedBuff(3045, 3170, gameFrame);} else if (beast instanceof Bear) {reviveBeast = new Bear(2800, 2855, gameFrame);} else if (beast instanceof Bird) {reviveBeast = new Bird(3570, 3380, gameFrame);} else if (beast instanceof Xiyi) {reviveBeast = new Xiyi(4585, 2365, gameFrame);} else if (beast instanceof BlueBuff) {reviveBeast = new BlueBuff(4025, 2295, gameFrame);} else {reviveBeast = new Wolf(4235, 1945, gameFrame);}gameFrame.objList.add(reviveBeast);gameFrame.beast.beastList.add(reviveBeast);}}}

?

?

package com.sxt.beast;import com.sxt.GameFrame;public class Bird extends Beast {public Bird(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/紅隼.jpg");width = 122;height = 98;setDis(125);// TODO Auto-generated constructor stub}}

package com.sxt.beast;import com.sxt.GameFrame;public class BlueBuff extends Beast {public BlueBuff(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/blueBuff.jpg");width = 142;height = 176;setDis(70);// TODO Auto-generated constructor stub}}

package com.sxt.beast;import com.sxt.GameFrame;public class RedBuff extends Beast {public RedBuff(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/redBuff.jpg");width = 103;height = 150;setDis(70);// TODO Auto-generated constructor stub}
}

?

?

package com.sxt.beast;import com.sxt.GameFrame;public class Wolf extends Beast {public Wolf(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/wolf.jpg");width = 145;height = 140;setDis(65);// TODO Auto-generated constructor stub}}

?

package com.sxt.beast;import com.sxt.GameFrame;public class Xiyi extends Beast {public Xiyi(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/蜥蜴.jpg");width = 111;height = 65;setDis(125);// TODO Auto-generated constructor stub}
}

?

三.結果呈現

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164566.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Netty Review - 探索ByteBuf的內部機制

文章目錄 概念ByteBuf VS Java NIO BufferByteBuf實現類HeapByteBuf vs DirectByteBufPooledByteBuf vs UnpooledByteBuf其他 ByteBuf的實現機制 概念 ByteBuf是Netty中用于處理二進制數據的緩沖區 Netty的ByteBuf是一個可用于高效存儲和操作字節數據的數據結構。與傳統的Byt…

跳躍游戲[中等]

優質博文&#xff1a;IT-BLOG-CN 一、題目 給你一個非負整數數組nums&#xff0c;你最初位于數組的第一個下標 。數組中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最后一個下標&#xff0c;如果可以&#xff0c;返回true&#xff1b;否則&#xff0c;返…

阿里入局鴻蒙!鴻蒙原生應用再添兩員新丁

今日HarmonyOS微博稱&#xff0c;阿里釘釘、螞蟻集團旗下的移動開發平臺mPaaS與華為達成合作&#xff0c;宣布啟動鴻蒙原生應用的開發&#xff01;相關應用將以原生方式適配#HarmonyOS NEXT#系統。 #HarmonyOS#市場或迎來爆發式增長&#xff01; 阿里釘釘 阿里釘釘與華為達成合…

Android 匿名內存深入分析

Android 匿名內存解析 有了binder機制為什么還需要匿名內存來實現IPC呢&#xff1f;我覺得很大的原因就是binder傳輸是有大小限制的&#xff0c;不說應用層的限制。在驅動中binder的傳輸大小被限制在了4M&#xff0c;分享一張圖片可能就超過了這個限制。匿名內存的主要解決思路…

黑馬點評-10實現用戶點贊和點贊排行榜功能

用戶點贊功能 如果用戶只要點贊一次就對數據庫中blog表中的liked字段的值加1就會導致一個用戶無限點贊 PutMapping("/like/{id}") public Result likeBlog(PathVariable("id") Long id) {// 修改點贊數量,update tb_blog set liked liked 1 where id …

編譯器核心技術概覽

編譯技術是一門龐大的學科&#xff0c;我們無法對其做完善的講解。但不同用途的編譯器或編譯技術的難度可能相差很大&#xff0c;對知識的掌握要求也會相差很多。如果你要實現諸如 C、JavaScript 這類通用用途語言&#xff08;general purpose language&#xff09;&#xff0c…

buck降壓電路

一、Buck電路的拓撲結構 Buck是直流轉直流的降壓電路,下面是拓撲結構,作為硬件工程師,這個最好是能夠記下來,了然于胸。 為啥要記下來,自然是因為這個電路太基礎了,并且誰都會用到,更重要的一點,面試可能會考。。。 上圖是個異步buck,同步buck就是將里面的二極管換成M…

3D火山圖繪制教程

一邊學習&#xff0c;一邊總結&#xff0c;一邊分享&#xff01; 本期教程內容 **注&#xff1a;**本教程詳細內容 Volcano3D繪制3D火山圖 一、前言 火山圖是做差異分析中最常用到的圖形&#xff0c;在前面的推文中&#xff0c;我們也推出了好幾期火山圖的繪制教程&#xff0…

Android——資源IDnonFinalResIds和“Attribute value must be constant”錯誤

一、異常描述 通過資源ID引用資源提示錯誤 Attribute value must be constant 二、解決方案 在根目錄下的文件 gradle.properties 中添加如下配置&#xff0c;然后Sync Project android.nonFinalResIdsfalse 三、問題原因 android.nonFinalResIds 是Android開發中一個用于解…

此處不允許使用特性namespace

1.DOCTYPE 后面改成 mapper 2.PUBLIC一行中的Config改為Mapper 3.將下一行config變為小寫的mapper <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.or…

交叉編譯安裝時報錯 ./install.sh: 15: ./install.sh: Bad substitution

報錯信息截圖如下&#xff1a; 解決方法 vim install.sh #!/bin/sh -e 修改為 !/bin/bash -e重新執行 sudo ./install.sh 成功運行

【Java并發】聊聊線程池原理以及實際應用

線程其實對于操作系統來說是寶貴的資源&#xff0c;java層面的線程其實本質還是依賴于操作系統內核的線程進行處理任務&#xff0c;如果頻繁的創建、使用、銷毀線程&#xff0c;那么勢必會非常浪費資源以及性能不高&#xff0c;所以池化技術&#xff08;數據庫連接池、線程池&a…

暢談Linux在小型微型企業中的應用

在這篇文章里我們討論和暢談一下linux系統在小微型企業中的應用&#xff0c;為什么會寫這篇文章呢&#xff1f;因為在平時的工作中&#xff0c;認識的一些做小微型企業的朋友&#xff0c;他們經常找我咨詢或是去解決一些平時工作中的IT相關的問題&#xff0c;那么小微型企業中的…

相同結構體不同類型轉換

緣由&#xff1a; 最近開發上遇到一個問題&#xff0c;通過grpcgateway 處理后的int64&uint64類型數據均轉換成了字符串類型&#xff0c;本身服務于前端&#xff0c;沒有任何問題。但是 項目部署現場后&#xff0c;發現需要兩套環境&#xff0c;那么就出現一個問題&#x…

2022 年十大 JavaScript 框架

2022 年十大 Web 應用開發 JavaScript 框架。 React.js jQuery Express Angular Vue.js Angular.js Svelte Next.js Ember.js Meteor React.js React.js 于 2013 年由 Meta(Facebook 前身) 推出&#xff0c;是一款開源的、免費的 JavaScript 庫。React.js 被用于開…

C++中的map和set的使用

C中的map詳解 關聯式容器鍵值對樹形結構的關聯式容器set的使用1. set的模板參數列表2. set的構造3. set的迭代器4. set的容量5. set修改操作6. set的使用舉例 map1. map的簡介2. map的模板參數說明3. map的構造4. map的迭代器5. map的容量與元素訪問6. map的元素修改 multimap和…

Linux vim操作教程(vim 基操、vim替換和查找、 vim改變文本顏色、判斷和循環語句)

vim 基操 vim 是一個強大的文本編輯器,常用于在終端環境下編輯文件。下面是一些常用的 vim 操作: 打開文件:在終端中輸入 vim 文件名 來打開一個文件,如果文件不存在,則會創建一個新文件。 模式切換: 按下 i 進入插入模式,在該模式下可以輸入和編輯文本。按下 Esc 鍵返…

python單例模式

單例模式是一種創建型設計模式&#xff0c;它保證一個類僅有一個實例&#xff0c;并提供一個全局訪問點。 在 Python 中&#xff0c;可以使用以下幾種方式來創建單例模式&#xff1a; 使用 __new__ 方法 在 Python 中&#xff0c; __new__ 方法是一個類方法&#xff0c;它在…

msvcp120.dll丟失是什么意思,哪個修復方法最簡單

在計算機使用過程中&#xff0c;我們經常會遇到一些錯誤提示&#xff0c;其中之一就是“找不到msvcp120.dll”。這個錯誤通常發生在運行某些程序或游戲時&#xff0c;它會導致程序無法正常啟動或運行。那么&#xff0c;這個錯誤提示到底是什么意思呢&#xff1f;為了解決這個問…

深入了解Java8新特性-日期時間API_LocalDate類

閱讀建議 嗨&#xff0c;伙計&#xff01;刷到這篇文章咱們就是有緣人&#xff0c;在閱讀這篇文章前我有一些建議&#xff1a; 本篇文章大概12000多字&#xff0c;預計閱讀時間長需要10分鐘。本篇文章的實戰性、理論性較強&#xff0c;是一篇質量分數較高的技術干貨文章&…