【Java 三国大乱斗部分代码】
前言
提示:三国大乱斗支持键盘操控人物赵云对随机移动的吕布进行攻击,内设有血条,蓝条。目前代码等内容相关尚未完善,仅供参考。
一、游戏最终实现效果是什么?
二、游戏框架
三、游戏代码
1.GameFrame类
代码如下():
package ui; import java.awt.BorderLayout; import java.awt.FileDialog; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.concurrent.TimeUnit; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JTextArea; /** * * 自定义游戏窗体类步骤 * 1.写一个类,继承JFrame 在类名后面加extends JFrame * 2.写一个构造方法,确定窗体的特点 */ public class GameFrame extends JFrame { static String filePath =null;//播放文件路径 JButton btPause, btExit, btPlay, btLoop, btStop; JPanel panel; JMenuBar mb; JMenu menu; JMenuItem menuMi1,menuMi2; JTextArea textarea; //音乐播放的构造方法------------------------------------------------------ public GameFrame(){ //正常构造方法(模具) //设置标题 setTitle("三国大乱斗");//固定格式 //设置大小 setSize(1067,600); //设置位置居中显示 setLocationRelativeTo(null); // 设置关闭窗体时关闭游戏------------------------- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } //--------------------------------------------------------------------- /** * Java程序入口 * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { //创建游戏窗体 GameFrame frame = new GameFrame(); //创建游戏面板 GamePanel panel = new GamePanel(frame); //调用开始游戏的方法 panel.action(); //启动键盘监听器 //panel.keyListener(); //将面板加入到窗体中 frame.add(panel); //显示窗体(true:显示 ,flase:隐藏) frame.setVisible(true); //GameFrame gf = new GameFrame(); Music player = new Music("E:/kkkkk/三国战纪/src/XiongDi.wav"); //创建音乐播放器 player.start(true);//以开始以循环的形式播放,player(false)为不循环播放 TimeUnit.SECONDS.sleep(5); player.stop(); //暂停播放音频 TimeUnit.SECONDS.sleep(4); player.continues(); //继续开始播放音频 } }
2.GamePanel类
package ui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JTextArea; /** * JAVA游戏面板类 * 自定义游戏面板步骤: * 1.写一个类,继承JPanel * 2.写一个构造方法,确定面板的特点 */ public class GamePanel extends JPanel { //定义背景图片 BufferedImage bg; //定义吕布图片 //BufferedImage lbImg; //调用模具,制作一个吕布 LvBu lb = new LvBu(); //调用模具,制作一个赵云 ZhaoYun zy = new ZhaoYun(); //定义一个窗体 GameFrame fr; //构造方法(模具) public GamePanel(GameFrame frame) {//使用模具时丢原料(窗体)进去 this.fr = frame;//赋值 // 声明一个用于放背景图片的窗体 BufferedImage img; //调用读取图片的工具去读取图片 bg = ImageUtil.getImg("/img/bg2.jpg"); //读取吕布图片 //lbImg = ImageUtil.getImg("/img/吕布L1.png"); //设置背景 //setBackground(Color.green); //启动键盘监听器 keyListener(); } //画图方法(先键盘输入“paint”,按Alt+?键,直接回车,弹出以下代码,非常方便) //Graphics g-->画笔 @Override public void paint(Graphics g) { // TODO Auto-generated method stub super.paint(g); //1.画背景图(图片,横坐标,纵坐标,宽度,高度,null<画板>) g.drawImage(bg, 0, 0, null); //2.画血条 g.setColor(Color.red); g.fillRect(100, 0, 350, 30);//赵云 g.fillRect(617, 0, 350, 30);//吕布 //3.画蓝条 g.setColor(Color.blue); g.fillRect(100, 32, 350, 15);//赵云 g.fillRect(617, 32, 350, 15);//吕布 //画赵云吕布头像 g.drawImage(ImageUtil.getImg("/img/lvbu.png"), 970, 2, 90, 45, null); g.drawImage(ImageUtil.getImg("/img/zy.png"), 3, 2, 90, 45, null); //画黄色VS g.setColor(Color.yellow); g.setFont(new Font("宋体", Font.BOLD, 50)); g.drawString("VS", 505, 48); //2.画吕布(如果在画图时不设置宽度和高度,则画出来就是原图的大小) //图片,横坐标,纵坐标,null g.drawImage(lb.img, lb.x, lb.y, null);//传递变量 //3.画赵云 g.drawImage(zy.img, zy.x, zy.y, null); } //键盘监听器(使用键盘控制赵云移动) public void keyListener() { /** * 键盘监听器使用步骤 * 1.创建键盘适配器(类似于电脑键盘USB接口) * */ //1.创建键盘适配器(类似于电脑键盘USB接口) KeyAdapter adapter = new KeyAdapter() { //先输入keyPressed,然后按Alt+?键就会出现下面的代码 //监听键盘按下去的操作 @Override public void keyPressed(KeyEvent e) {//KeyEvent:封装键盘的时间 // TODO Auto-generated method stub //当按下键盘按键时执行的代码 char c = e.getKeyChar(); zy.ZhaoYun_Move_position(); //可以先用它试System.out.println(c); if(c == 'a') { //赵云向左移动 zy.x -= 10;//或者zy.x--; zy.ZhaoYun_Move_positio2(); //控制赵云,右临界点 if(zy.x <= 0) { zy.x = 0; } }else if(c == 'd') { //赵云向右移动 zy.x += 10; //控制赵云,右临界点 if(zy.x >= 1067 - zy.w) { zy.x = 1067 - zy.w;//界面宽度-赵云宽度 } }else if(c == 'w') { //赵云向上移动 zy.y -= 10; if(zy.y <= 0) { zy.y = 0; } }else if(c == 's') { //赵云向下移动 zy.y += 10; if(zy.y >= 600 - zy.h) { zy.y = 600 - zy.h; } } repaint();//刷新界面 } }; //2.将键盘适配器加入到监听器中 fr.addKeyListener(adapter);//只有把监听器加到窗体中才发挥作用 } //开始游戏的方法 public void action() { //创建并启动线程来控制吕布移动 //创建启动线程格式: /** * new Thread(){ * public void run(){ * //需要线程干嘛就在这写什么 * } * }.start(); */ new Thread() { public void run() { //吕布移动(一直移动)--->while循环(不知道循环次数——>死循环) while(true) { lb.lb_Move(); // 声明一个随机数对象 Random random = new Random(); lb.dir = random.nextInt(9 + 1); //lb.x-= 5;//向左移动,数字越大移动越快,X坐标减小(到临界点停止) if(lb.dir == 0) { //0向左 lb.x -= 16; if(lb.x<=0) { //向左移动到边界后改为向右 lb.x =0; //lb.dir = 1; } }else if(lb.dir == 1) { lb.lb_Move2(); //1向右 lb.x += 16; if(lb.x >= 1067-lb.w) { //向右移动到边界后改为向左 lb.x = 1067-lb.w; //lb.dir = 0; } /** * 随机8个方向移动(0,8)代表8个方向,控制吕布反弹 */ }else if(lb.dir ==2) { //2向上 lb.y -=16; if(lb.y<=0) { lb.y = 0; //lb.dir = 3; } }else if(lb.dir ==3) { //3向下 lb.y += 16; if(lb.y >= 600 - lb.h) { lb.y = 600 - lb.h; //lb.dir = 2; } //4左上 }else if (lb.dir == 4) { lb.x -= 16; lb.y -= 16; // 5左下 } else if (lb.dir == 5) { lb.x -= 16; lb.y += 16; //6右上 } else if (lb.dir == 6) { lb.x += 16; lb.y -= 16; //7右下 } else if (lb.dir == 7) { lb.x += 16; lb.y += 16; } else if (lb.dir == 8) { lb.lb_Move3(); } else if (lb.dir == 9) { lb.lb_Move4(); } //线程休眠(让吕布移动一次停一次) try {//试着休眠160毫秒 Thread.sleep(160);//改变移动速度 //重新调用paint方法将吕布绘制到新的位置上 repaint(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); } }
3.ImageUtil类
package ui; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; /** * 读取图片的工具类 * @author gf5971 * */ public class ImageUtil { /** * 根据图片路经读取图片 * @param path * @return */ //将图片路经掺入该方法,自动读取图片 public static BufferedImage getImg(String path) { //加载图片 try { //尝试拿着地址去找图片 BufferedImage img = ImageIO.read(ImageUtil.class.getResource(path)); //找到了,就将图片返回 return img; } catch (IOException e) { // TODO Auto-generated catch block //找不到,输出找不到的原因 e.printStackTrace(); } return null; } }
4.LvBu类
package ui; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; //吕布类 public class LvBu { BufferedImage img;//吕布图片 int x;//吕布横坐标 int y;//吕布纵坐标 int w;//吕布宽度 int h;//吕布高度 List<BufferedImage> list, list2, list3, list4;//吕布动作--------- int dir=0;//吕布移动的方向(<0:向左> <1:向右> <2:向上 > <3:向下>) //构造方法 public LvBu() { //读取吕布图片 img = ImageUtil.getImg("/img/吕布L1.png"); //规定游戏开始时吕布显示的位置 x = 600; y = 200; //规定吕布显示的大小 w = img.getWidth();//获取原图宽度 h = img.getHeight(); list = new ArrayList<BufferedImage>(); for (int i = 1; i <= 7; i++) { list.add(ImageUtil.getImg("/img/吕布L" + i + ".png")); } list2 = new ArrayList<BufferedImage>(); for (int i = 1; i <= 8; i++) { list2.add(ImageUtil.getImg("/img/吕布" + i + ".png")); } list3 = new ArrayList<BufferedImage>(); for (int i = 0; i <= 5; i++) { list3.add(ImageUtil.getImg("/img/a1-L" + i + ".png")); } list4 = new ArrayList<BufferedImage>(); for (int i = 0; i < +5; i++) { list4.add(ImageUtil.getImg("/img/a1-R" + i + ".png")); } } //游戏开始,让吕布向左移动 // 吕布动起来 public void lb_Move() { if (dir >= 7) { dir = 1; } img = list.get(dir); dir++; } // 吕布向后动起来 public void lb_Move2() { if (dir >= 8) { dir = 1; } img = list2.get(dir); dir++; } // 吕布向前攻击 public void lb_Move3() { if (dir >= 5) { dir = 0; } img = list3.get(dir); dir++; } // 吕布向后攻击 public void lb_Move4() { if (dir >= 5) { dir = 0; } img = list4.get(dir); dir++; } // 吕布攻击赵云 public void AttackZy(ZhaoYun heroZy) { if (x - heroZy.x + w <= heroZy.w + w || heroZy.x - x + heroZy.w <= heroZy.w + w || heroZy.x >= x && heroZy.x <= x + w) { // 最大值heroZy.w+w // 最小值w heroZy.x -= 20; System.out.println("1"); } } }
5.ZhaoYun类
package ui; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; //赵云类 public class ZhaoYun { BufferedImage img;//赵云图片 int x;//赵云横坐标 int y;//赵云纵坐标 int w;//赵云宽度 int h;//赵云高度 List<BufferedImage> list,list2;//赵云前进数组 //构造方法(生产赵云的模具) public ZhaoYun() { //确定赵云的样子 img = ImageUtil.getImg("/img/right-0.png"); //确定赵云游戏开始位置 x = 150; y = 200; //确定赵云大小 w = img.getWidth(); h = img.getHeight(); list = new ArrayList<BufferedImage>(); for (int i = 0; i < 8; i++) { list.add(ImageUtil.getImg("/img/right-" + i + ".png")); } list2 = new ArrayList<>(); for (int i = 0; i < 8; i++) { list2.add(ImageUtil.getImg("/img/left-" + i + ".png")); } } // 赵云向前移动 int dir = 0; public void ZhaoYun_Move_position() { if (dir == 7) { dir = 0; } img = list.get(dir); dir++; } // 赵云向后移动 public void ZhaoYun_Move_positio2() { if (dir == 7) { dir = 0; } img = list2.get(dir); dir++; } }
6.Music类
package ui; /** * * Description: 简易音频播放器(只支持AU,RA,WAV) * 在不使用JMF的情况下快速实现音频播放 */ import javax.sound.sampled.*; import java.io.*; import java.util.concurrent.TimeUnit; public class Music { private String musicPath; //音频文件 private volatile boolean run = true; //记录音频是否播放 private Thread mainThread; //播放音频的任务线程 private AudioInputStream audioStream; private AudioFormat audioFormat; private SourceDataLine sourceDataLine; public Music(String musicPath) { this.musicPath = musicPath; prefetch(); } //数据准备 private void prefetch(){ try{ //获取音频输入流 audioStream = AudioSystem.getAudioInputStream(new File(musicPath)); //获取音频的编码对象 audioFormat = audioStream.getFormat(); //包装音频信息 DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat,AudioSystem.NOT_SPECIFIED); //使用包装音频信息后的Info类创建源数据行,充当混频器的源 sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo); sourceDataLine.open(audioFormat); sourceDataLine.start(); }catch(UnsupportedAudioFileException ex){ ex.printStackTrace(); }catch(LineUnavailableException ex){ ex.printStackTrace(); }catch(IOException ex){ ex.printStackTrace(); } } //析构函数:关闭音频读取流和数据行 protected void finalize() throws Throwable{ super.finalize(); sourceDataLine.drain(); sourceDataLine.close(); audioStream.close(); } //播放音频:通过loop参数设置是否循环播放 private void playMusic(boolean loop)throws InterruptedException { try{ if(loop){ while(true){ playMusic(); } }else{ playMusic(); //清空数据行并关闭 sourceDataLine.drain(); sourceDataLine.close(); audioStream.close(); } }catch(IOException ex){ ex.printStackTrace(); } } private void playMusic(){ try{ synchronized(this){ run = true; } //通过数据行读取音频数据流,发送到混音器; //数据流传输过程:AudioInputStream -> SourceDataLine; audioStream = AudioSystem.getAudioInputStream(new File(musicPath)); int count; byte tempBuff[] = new byte[1024]; while((count = audioStream.read(tempBuff,0,tempBuff.length)) != -1){ synchronized(this){ while(!run) wait(); } sourceDataLine.write(tempBuff,0,count); } }catch(UnsupportedAudioFileException ex){ ex.printStackTrace(); }catch(IOException ex){ ex.printStackTrace(); }catch(InterruptedException ex){ ex.printStackTrace(); } } //暂停播放音频 private void stopMusic(){ synchronized(this){ run = false; notifyAll(); } } //继续播放音乐 private void continueMusic(){ synchronized(this){ run = true; notifyAll(); } } //外部调用控制方法:生成音频主线程; public void start(boolean loop){ mainThread = new Thread(new Runnable(){ public void run(){ try { playMusic(loop); } catch (InterruptedException e) { e.printStackTrace(); } } }); mainThread.start(); } //外部调用控制方法:暂停音频线程 public void stop(){ new Thread(new Runnable(){ public void run(){ stopMusic(); } }).start(); } //外部调用控制方法:继续音频线程 public void continues(){ new Thread(new Runnable(){ public void run(){ continueMusic(); } }).start(); } }