Java的一个王者荣耀游戏,主要实现键盘控制人物移动,按钮点击事件,英雄动作的改变,鼠标事件,碰撞检测,妲己的三个技能外加普攻,显示生命值,小兵的自动生成和自动移动,防御塔自动攻击,子弹自动追击,野怪的自动复活,窗口的移动,添加背景音乐等功能。
分为游戏主窗口,游戏元素类(野怪类,小兵类,防御塔类,背景类,英雄类)两大部分
1:
作用:初始化基本变量,定义addHp()方法,两点之间的距离方法,矩形与矩形的碰撞检测方法,矩形与圆形的碰撞检测方法,定义防御塔,英雄,小兵的攻击方法,用线程实现攻击的冷却时间。
package com.sxt;
import java.awt.*;
import java.util.ArrayList;
//游戏元素的父类
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() {
}
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);
}
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;
}
}
}
}
}
//public abstract void addTurret();
class AttackCD extends Thread {
public void run() {
// 将攻击功能设置为冷却状态
setAttackCoolDown(false);
// 线程休眠
try {
Thread.sleep(attackCoolDownTime);
} catch (Exception e) {
e.printStackTrace();
}
// 将攻击功能设置为攻击状态
setAttackCoolDown(true);
// 线程终止
this.interrupt();
}
}
// 绘制元素
public abstract void paintSelf(Graphics g);
// 返回矩形
public abstract Rectangle getRec();
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Image getImg() {
return img;
}
public void setImg(String img) {
this.img = Toolkit.getDefaultToolkit().getImage(img);
}
public int getSpd() {
return spd;
}
public void setSpd(int spd) {
this.spd = spd;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getCurrentHp() {
return currentHp;
}
public void setCurrentHp(int currentHp) {
this.currentHp = currentHp;
}
public GameObject getTarget() {
return target;
}
public void setTarget(GameObject target) {
this.target = target;
}
public boolean isHasTarget() {
return hasTarget;
}
public void setHasTarget(boolean hasTarget) {
this.hasTarget = hasTarget;
}
public int getDis() {
return dis;
}
public void setDis(int dis) {
this.dis = dis;
}
public int getAttackCoolDownTime() {
return attackCoolDownTime;
}
public void setAttackCoolDownTime(int attackCoolDownTime) {
this.attackCoolDownTime = attackCoolDownTime;
}
public boolean isAttackCoolDown() {
return attackCoolDown;
}
public void setAttackCoolDown(boolean attackCoolDown) {
this.attackCoolDown = attackCoolDown;
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
}
作用:初始化防御塔并添加到窗口中,游戏失败与胜利方法,在绘制自身方法中通过判断血量删除元素或者绘制防御塔。
package com.sxt;
import java.awt.*;
import java.util.ArrayList;
//防御塔类
public class Turret extends GameObject{
ArrayList<Turret> turretList = new ArrayList<>();
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("C:\\Users\\23839\\IdeaProjects\\asd\\src\\imgs\\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));
}
public Turret(int x, int y, GameFrame gameFrame) {
super(x, y, gameFrame);
setImg("C:\\Users\\23839\\IdeaProjects\\asd\\src\\imgs\\turret.png");
setHp(6000);
setCurrentHp(getHp());
setAttackCoolDownTime(1000);
setDis(300);
}
public void isLive(){
if(gameFrame.turret.turretBlueBase.getCurrentHp()==0){
gameFrame.state=2;
}
if(gameFrame.turret.turretRedBase.getCurrentHp()==0){
gameFrame.state=1;
}
}
@Override
public void paintSelf(Graphics g) {
// 生命值为0
if (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.fillOval(getX(), getY(), 10, 10);
g.drawRect(getX() - 50, getY() - 100, 100, 180);
g.drawOval(getX() - 300, getY() - 300, 600, 600);
}
}
@Override
public Rectangle getRec() {
return new Rectangle(getX() - 50, getY() - 100, 100, 180);
}
}
3:英雄类
package com.sxt;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
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;
//技能冷却时间
int coolDownTimeOne;
int coolDownTimeTwo;
int coolDownTimeThree;
//三个技能是否处于冷却状态
boolean coolDownOne = true;
boolean coolDownTwo = true;
boolean coolDownThree = true;
static {
for (int i = 1; i < 8; i++) {
imgs[i] = "C:\\Users\\23839\\IdeaProjects\\asd\\src\\imgs\\move\\" + i + ".png";
}
}
public Champion(GameFrame gameFrame) {
super(gameFrame);
//定义英雄的图片和坐标
setImg("C:\\Users\\23839\\IdeaProjects\\HonorOfKings\\src\\imgs\\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("C:\\Users\\23839\\IdeaProjects\\asd\\src\\imgs\\stand.png");
}
}
//添加三个技能按钮
public void addButton() {
JButton button1 = new JButton();
button1.setSize(100, 100);
button1.setLocation(1056, 513);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
abilityOne();
}
});
JButton button2 = new JButton();
button2.setSize(100, 100);
button2.setLocation(1090, 370);
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
abilityTwo();
}
});
JButton button3 = new JButton();
button3.setSize(100, 100);
button3.setLocation(1220, 300);
button3.addActionListener(new ActionListener() {
@Override
public 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);
@Override
public void paintSelf(Graphics g) {
// 生命值为0
if (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);
}
}
@Override
public Rectangle getRec() {
return new Rectangle(getX() - 30, getY() - 60, 60, 120);
}
}
5:小兵类
package com.sxt;
import java.awt.*;
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);
}
/**
* (1325, 3750) (4425, 3750) (5050, 3125) (5050, 1125)
*/
public abstract void move(ArrayList<GameObject> objList);
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() {
int dis = (int) getDis(getX(), getY(), getTarget().getX(), getTarget().getY());
if(dis!=0) {
int xSpeed = (getSpd() * (getTarget().getX() - getX()) / dis);
int ySpeed = (getSpd() * (getTarget().getY() - getY()) / dis);
setX(getX() + xSpeed);
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.5s
try {
Thread.sleep(1500);
} catch (Exception e) {
e.printStackTrace();
}
nextMinion = true;
// 线程终止
this.interrupt();
}
}
// 每波小兵生成时间
class NextLine extends Thread {
public void run() {
nextLine = false;
// 休眠15s
try {
Thread.sleep(15000);
} catch (Exception e) {
e.printStackTrace();
}
nextLine = true;
// 线程终止
this.interrupt();
}
}
@Override
public void paintSelf(Graphics g) {
// 生命值为0
if (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);
g.drawOval(getX() - 200, getY() - 200, 400, 400);
// 小兵移动
if (!beControlled) {
if (this instanceof MinionBlue) {
move(gameFrame.redList);
} else {
move(gameFrame.blueList);
}
}
}
}
@Override
public Rectangle getRec() {
return new Rectangle(getX() - 16, getY() - 16, 45, 45);
}
public boolean isIfFindTarget() {
return ifFindTarget;
}
public void setIfFindTarget(boolean ifFindTarget) {
this.ifFindTarget = ifFindTarget;
}
}
6:背景
package com.sxt;
import java.awt.*;
//背景类
public class Background extends GameObject{
public Background(GameFrame gameFrame) {
super(gameFrame);
}
Image bg = Toolkit.getDefaultToolkit().getImage("C:\\Users\\23839\\IdeaProjects\\asd\\src\\imgs\\Map.jpg");
public void paintSelf(Graphics g){
g.drawImage(bg,0,0,null);
}
@Override
public Rectangle getRec() {
return null;
}
}
7:野怪
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<>();
int width;
int height;
// 复活的元素
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());
beast = this;
}
@Override
public void paintSelf(Graphics g) {
if (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());
}
}
@Override
public Rectangle getRec() {
return new Rectangle(getX() - width / 2, getY() - height / 2, width, height);
}
//野怪复活
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);
}
}
}
结果: