前言:
代码中所使用到的许多数据和部分素材参考了gitee上一位大佬的代码,有兴趣的可以去搜索拳皇KOF。游戏中尽量还原了拳皇游戏中的草稚京和八神庵两人的动作技能,加入了这段决斗的经典音乐。
游戏界面展示
开始界面会播放音乐,鼠标点击开始游戏,进入对战界面
对战界面会播放另一段音乐,按下相应按键可使角色做出相应动作(ps:没有跳跃)
当一方血量为0时,结束战斗,此时点击回车进行下一场对局。
思路
一.主窗口类Main
1.音乐播放
new Thread(()->{while(true) {playtitalMusic();} //while中的true可换成参数来控制音乐的停止播放 }).start();// Lambda表达式 new Thread(new Runnable() { @Override public void run() { while (true) { playtitalMusic(); } } }).start();// 开启一个线程用来播放音乐
2.面板窗口
JFrame frame = new JFrame("KOF拳皇"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(960, 550); frame.setLocationRelativeTo(null); // 创建一个面板 JPanel panel = new JPanel(); frame.add(panel); //显示窗口 frame.setVisible(true);
3.背景图片
/背景图 ImageIcon backgroundIcon = new ImageIcon("C:\\Users\\伊蕾娜\\Desktop\\kof-1.0\\src\\com\\kof\\www\\images\\background.png"); JLabel backgroundlabel = new JLabel(backgroundIcon); backgroundlabel.setLayout(new BorderLayout());
4.鼠标监听和调用KOFGame
panel.add(backgroundlabel); frame.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { KofGame kofGame = new KofGame(); frame.dispose();//关闭Main flag = false; kofGame.run();//调用KofGame运行游戏 } });
二.副窗口KOFGame
1.音乐播放
new Thread(()->{while(true) {playMusic();} //while中的true可换成参数来控制音乐的停止播放 }).start();// Lambda表达式 new Thread(new Runnable() { @Override public void run() { while (true) { playMusic(); } } }).start();// 开启一个线程用来播放音乐 //与Main中所用的方法相同
2.角色初始化
BaShenAn baShenAn = new BaShenAn(Constant.PLAYER_X, Constant.PLAYER_Y, Constant.PLAYER_WIDTH, Constant.PLAYER_HEIGHT);// 八神庵角色 CaoZhiJing caoZhiJing = new CaoZhiJing(Constant.GAME_WIDTH - Constant.PLAYER_X - Constant.PLAYER_WIDTH, Constant.PLAYER_Y, Constant.PLAYER_WIDTH, Constant.PLAYER_HEIGHT);// 草稚京角色 GameUtil gameUtil = new GameUtil(baShenAn, caoZhiJing);
3.绘画
Image bg = GameUtil.getImage("com/kof/www/images/bg.jpg");// 背景图 Image portrait1 = GameUtil.getImage("com/kof/www/images/portrait1.png");// player1头像 Image portrait2 = GameUtil.getImage("com/kof/www/images/portrait2.png");// player2头像 //绘画 @Override public void paint (Graphics g){ Color c = g.getColor(); // 画背景 g.drawImage(bg, 0, 0, Constant.GAME_WIDTH, Constant.GAME_HEIGHT, null, null); // 出招表提示 Font f = new Font("", Font.BOLD, 24); g.setFont(f); g.setColor(Color.white); // 角色血条显示 g.drawImage(portrait1, 35, 90, 42, 42, null, null); g.drawImage(portrait2, 1275, 90, 42, 42, null, null); Graphics2D g2d = (Graphics2D) g; g2d.setStroke(new BasicStroke(10.0f)); g.drawRect(769, 90, 502, 42); g.drawRect(79, 90, 502, 42); g.setColor(Color.RED); g.drawString(gameUtil.blood1 + "%", 595, 121); g.drawString(gameUtil.blood2 + "%", 700, 121); g.setColor(Color.RED); g.fillRect(80, 91, 5 * gameUtil.blood1, 40); g.fillRect(770 + (500 - 5 * gameUtil.blood2), 91, 5 * gameUtil.blood2, 40); // 碰撞检测 boolean peng = baShenAn.getRect().intersects(caoZhiJing.getRect());//intersects:检查两个矩形是否相交的方法。如果两个矩形相交,返回 true;否则,返回 false //getRect():获取 矩形表示 // 优先级检查 gameUtil.check(peng); // 画八神庵 baShenAn.drawSelf(g, peng); // 画草稚京 caoZhiJing.drawSelf(g, peng);
4.胜利条件判断
if (gameUtil.blood1 <= 0 || gameUtil.blood2 <= 0) { gameUtil.ko(g); baShenAn.stand = true; caoZhiJing.stand = true; }
5.初始化窗口
public void launchFrame () { this.setTitle("kof拳皇"); this.setVisible(true); this.setLocationRelativeTo(null); this.setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); this.setLocation(Constant.GAME_X, Constant.GAME_Y); this.addWindowListener(new WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { System.exit(3); } }); new PaintThread().start(); // 启动重画窗口的线程 addKeyListener(new KeyMonitor()); // 给窗口增加键盘的监听 }
6.双缓冲防止背景的闪烁
class PaintThread extends Thread { public void run(){ while (true){ repaint(); try{ Thread.sleep(55); }catch (InterruptedException e){ e.printStackTrace(); } } } } private Image offScreenImage = null; public void update (Graphics g){ if (offScreenImage == null) { //这是游戏窗口的宽度和高度 offScreenImage = this.createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); } Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0, 0, null); }
7.键盘监听
class KeyMonitor extends KeyAdapter { public void keyPressed(java.awt.event.KeyEvent e) { if (gameUtil.ko) { gameUtil.addDirection(e); } baShenAn.addDirection(e); caoZhiJing.addDirection(e); } public void keyReleased(java.awt.event.KeyEvent e) { baShenAn.minusDirection(e); caoZhiJing.minusDirection(e); } }
三.游戏工具类
1.游戏逻辑
public void check(boolean peng){ long time1 = baShenAn.time; long time2 = caoZhiJing.time; if (peng) { // 八神庵后出手,打破草稚京攻势 if (time1 > time2 || (time2 == 0 && time1 != 0) || caoZhiJing.stand || caoZhiJing.l) { // 八神庵i大于于草稚京i if (caoZhiJing.i && baShenAn.i){ caoZhiJingBeaten();return; } // 八神庵i大于草稚京u if (baShenAn.i && caoZhiJing.u){ caoZhiJingBeaten();return; } // 八神庵u小于草稚京i if (baShenAn.u && caoZhiJing.i){ baShenAnBeaten();return; } // 八神庵u小于草稚京u if (baShenAn.u && caoZhiJing.u){ baShenAnBeaten();return; } // 八神庵ui大于草稚京adjkl if ((baShenAn.u || baShenAn.i) && (caoZhiJing.j || caoZhiJing.k || caoZhiJing.stand || caoZhiJing.after || caoZhiJing.before || caoZhiJing.l)){ caoZhiJingBeaten();return; } // 八神庵adjkl小于草稚京ui if ((caoZhiJing.u || caoZhiJing.i) && (baShenAn.j || baShenAn.k || baShenAn.stand || baShenAn.after || baShenAn.before)){ baShenAnBeaten();return; } caoZhiJingBeaten(); } // 草稚京后出手,打破八神庵攻势 if (time1 < time2 || (time1 == 0 && time2 != 0) || baShenAn.stand || baShenAn.l) { // 草稚京i小于于八神庵i if (caoZhiJing.i && baShenAn.i){ caoZhiJingBeaten();return; } // 草稚京i大于八神庵u if (caoZhiJing.i && baShenAn.i){ baShenAnBeaten();return; } // 草稚京u大于于八神庵i if (caoZhiJing.u && baShenAn.i){ baShenAnBeaten();return; } // 草稚京u小于八神庵u if (caoZhiJing.u && baShenAn.u){ caoZhiJingBeaten();return; } // 草稚京ui大于八神庵adjkl if ((caoZhiJing.u || caoZhiJing.i) && (baShenAn.j || baShenAn.k || baShenAn.stand || baShenAn.after || baShenAn.before)){ baShenAnBeaten();return; } // 草稚京adjkl小于八神庵ui if ((baShenAn.u || baShenAn.i) && (caoZhiJing.j || caoZhiJing.k || caoZhiJing.stand || caoZhiJing.after || caoZhiJing.before || caoZhiJing.l)){ caoZhiJingBeaten();return; } baShenAnBeaten(); } } } /* * 草稚京血量 */ public void caoZhiJingBlood(){ if (blood1 > 0 && blood2 > 0){ blood2 -= 1; } } /* * 八神庵血量 */ public void baShenAnBlood(){ if (blood1 > 0 && blood2 > 0) { blood1 -= 1; } } /* * ko画面 */ static Image koImg = GameUtil.getImage("com/kof/www/images/ko.png"); public void ko(Graphics g){ Font f = new Font("", Font.BOLD, 36); g.setColor(Color.white); g.setFont(f); ko = true; if (blood2 <= 0){ g.drawString("player1取得了游戏的胜利!!!",850,700); baShenAn.stand =false; caoZhiJing.stand = false; }else{ g.drawString("player2取得了游戏的胜利!!!",850,700); baShenAn.stand =false; caoZhiJing.stand = false; } g.drawString("按回车键继续下一场的对局",850,736); g.drawImage(koImg, 0, 0, Constant.GAME_WIDTH,Constant.GAME_HEIGHT, null,null); }public void caoZhiJingBeaten(){ // 草稚京挨揍 if (baShenAn.j || baShenAn.k || baShenAn.u || baShenAn.i) { if (!caoZhiJing.down && !baShenAn.l && !baShenAn.down) { caoZhiJing.beaten = true; caoZhiJingBlood(); } }// 草稚京被击飞 if (BaShenAn.downKCount >= 2 || BaShenAn.uCount >= 8 || BaShenAn.iCount >= 8 || BaShenAn.afterJCount >= 2) { if (!caoZhiJing.down || (caoZhiJing.down && caoZhiJing.k)) { caoZhiJing.beaten = false; caoZhiJing.fly = true; caoZhiJingBlood(); } } }public void baShenAnBeaten(){ // 八神庵挨揍 if (caoZhiJing.j || caoZhiJing.k || caoZhiJing.u || caoZhiJing.i) { if (!baShenAn.down && !caoZhiJing.l && !caoZhiJing.down) { baShenAn.beaten = true; baShenAnBlood(); } }// 八神庵被击飞 if (CaoZhiJing.downKCount >= 5 || CaoZhiJing.uCount >= 6 || CaoZhiJing.iCount >= 8 || CaoZhiJing.beforeJCount >= 5 || CaoZhiJing.afterKCount >= 4) { if (!baShenAn.down || (baShenAn.down && baShenAn.k)) { baShenAn.beaten = false; baShenAn.fly = true; baShenAnBlood(); } }
2.为下一场战斗做准备
/* * ko后的重置游戏键盘监听 */ public void addDirection(KeyEvent e){ if (e.getKeyCode() == KeyEvent.VK_ENTER){ blood1 = blood2 = 100; baShenAn.stand=true; caoZhiJing.stand = true; ko = false; baShenAn.x = Constant.PLAYER_X; caoZhiJing.x = Constant.GAME_WIDTH-Constant.PLAYER_X-Constant.PLAYER_WIDTH; } } /* * 返回指定路径文件的图片对象 */ public static Image getImage(String path) { BufferedImage bi = null; try { URL u = GameUtil.class.getClassLoader().getResource(path); bi = ImageIO.read(u); } catch (IOException e) { e.printStackTrace(); } return bi; }
四.常量类
1.游戏常量
public class Constant { /窗口的宽高/ public static final int GAME_WIDTH = 1350; public static final int GAME_HEIGHT = 750; /窗口坐标/ public static final int GAME_X = 150; public static final int GAME_Y = 50; /角色宽高/ public static final int PLAYER_WIDTH = 150; public static final int PLAYER_HEIGHT = 350; /角色坐标/ public static final int PLAYER_X = 300; public static final int PLAYER_Y = 370; }
五.角色类
1.接口
public interface Player { /站立/ void stand(Graphics g); /蹲/ void down(Graphics g); /后/ void after(Graphics g); /前/ void before(Graphics g); /挨打/ void beaten(Graphics g); /拳/ void j(Graphics g); /腿/ void k(Graphics g); /闪避/ void l(Graphics g); /技能一/ void u(Graphics g); /技能二/ void i(Graphics g);
2.八神庵
public class BaShenAn implements Player { int x,y,width,height; int tempW; int speed = 20;// 移动的基础速度 boolean stand = true;// boolean值记录角色状态 int maxX = 99999; long time = 0;// 角色出招时间 boolean before,after,down,j,k,l,u,i,peng,beaten,fly;//前,后,下,拳,脚,技能u,技能i,挨打,被击飞 public BaShenAn(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public void addDirection(KeyEvent e){ switch (e.getKeyCode()) { case KeyEvent.VK_S: stand = false; down = true; break; case KeyEvent.VK_A: stand = false; after = true; break; case KeyEvent.VK_D: stand = false; before = true; break; case KeyEvent.VK_J: stand = false; j = true; break; case KeyEvent.VK_K: stand = false; k = true; break; case KeyEvent.VK_L: stand = false; l = true; break; case KeyEvent.VK_U: u = true; break; case KeyEvent.VK_I: i = true; break; } } public void minusDirection(KeyEvent e){ clean(); switch (e.getKeyCode()) { case KeyEvent.VK_S: down = false; break; case KeyEvent.VK_A: after = false; break; case KeyEvent.VK_D: before = false; break; case KeyEvent.VK_J: j = false; break; case KeyEvent.VK_K: k = false; break; case KeyEvent.VK_L: l = false; break; case KeyEvent.VK_U: u = false; break; case KeyEvent.VK_I: i = false; break; } } /************************************************************************ * 站立 ************************************************************************/ static Image[] standImgs = new Image[18]; static int standCount; static { for (int i = 0; i < 18; i++) { if (i>8){ standImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/stand/0-" + (17-i) + ".png"); }else{ standImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/stand/0-" + i + ".png"); } standImgs[i].getWidth(null); } } @Override public void stand(Graphics g) { //System.out.println("八神庵:站立"); if (standCount >= 18) { standCount = 0; } g.drawImage(standImgs[standCount], x, y, width+30,height,null,null); tempW = width + 30; standCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 下蹲 ************************************************************************/ static Image[] downImgs = new Image[6]; static int downCount; static Image[] downKImgs = new Image[11]; static int downKCount; static { for (int i = 0; i < 6; i++) { downImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/down/11-" + (i+1) + ".png"); downImgs[i].getWidth(null); } for (int i = 0; i < 11; i++) { downKImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/downk/0-" + i + ".png"); downKImgs[i].getWidth(null); } } @Override public void down(Graphics g) { if (k){ //System.out.println("八神庵:组合技=下蹲+腿击"); if (downKCount >= 11) { downKCount=0; } if (downKCount >=2 && downKCount <= 5){ g.drawImage(downKImgs[downKCount], x, y+height/3, width*5/2,height*2/3,null,null); tempW = width*5/2; }else{ g.drawImage(downKImgs[downKCount], x, y+height*2/5, width*3/2,height*3/5,null,null); tempW = width+50; } downKCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } return; } //System.out.println("八神庵:下蹲防御"); if (downCount >= 6) { downCount=0; } g.drawImage(downImgs[downCount], x, Constant.PLAYER_Y+Constant.PLAYER_HEIGHT/2-50, width+50,Constant.PLAYER_HEIGHT/2+50,null,null); tempW = width + 50; downCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 后退 ************************************************************************/ static Image[] afterImgs = new Image[9]; static int afterCount; static { for (int i = 0; i < 9; i++) { afterImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/after/21-" + i + ".png"); afterImgs[i].getWidth(null); } } @Override public void after(Graphics g) { //System.out.println("八神庵:后退"); if (afterCount >= 9) { afterCount=0; } g.drawImage(afterImgs[afterCount], x, y, width,height,null,null); tempW = width; afterCount++; if (x>=speed){ x -= speed; } } /************************************************************************ * 前进 ************************************************************************/ static Image[] beforeImgs = new Image[9]; static int beforeCount; static { for (int i = 0; i < 9; i++) { beforeImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/before/21-" + i + ".png"); beforeImgs[i].getWidth(null); } } @Override public void before(Graphics g) { //System.out.println("八神庵:前进"); if (!l){ if (beforeCount >= 9) { beforeCount=0; } g.drawImage(beforeImgs[beforeCount], x, y, width, height,null,null); tempW = width; beforeCount++; if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH) && x<maxX && !peng){ x += speed; } }else{ l(g);l(g); if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH) && x<maxX && !peng){ x += 4*speed; } } } /************************************************************************ * 挨揍 ************************************************************************/ static Image[] beatenImgs = new Image[4]; static int beatenCount; static { for (int i = 0; i < 4; i++) { beatenImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/beaten/0-" + i + ".png"); beatenImgs[i].getWidth(null); } } @Override public void beaten(Graphics g) { if (down){ down(g);return; } if (beatenCount >= 4) { beatenCount=0; beaten = false; } //System.out.println("八神庵:挨揍"); g.drawImage(beatenImgs[beatenCount], x, y, width+80, height,null,null); tempW = width; beatenCount++; if (x>=speed){ x -= speed/3; } try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 拳击 / static Image[] jImgs = new Image[4]; static int jCount; static Image[] beforeJImgs = new Image[8]; static int beforeJCount; static Image[] afterJImgs = new Image[8]; static int afterJCount; static Image[] beforeJImgs2 = new Image[8]; static { for (int i = 0; i < 4; i++) { jImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/j/1-" + i + ".png"); jImgs[i].getWidth(null);//拳击 } for (int i = 0; i < 8; i++){ afterJImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/afterj/0-" + i + ".png"); afterJImgs[i].getWidth(null);//后+拳击 } for (int i = 0; i < 8; i++){ beforeJImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/beforej/0-" + i + ".png"); beforeJImgs[i].getWidth(null);//前+拳击 } for (int i = 0; i < 8; i++){ beforeJImgs2[i] = GameUtil.getImage("com/kof/www/images/bashenan/beforej/1-" + i + ".png"); beforeJImgs2[i].getWidth(null);//特效 } } @Override public void j(Graphics g) { time = System.currentTimeMillis();//获取当前系统时间的毫秒数,并将其赋值给变量 if (after){ //System.out.println("八神庵:组合技=后退+拳击"); if (afterJCount >= 8) { afterJCount=0; } g.drawImage(afterJImgs[afterJCount], x+30, y, width*3/2,height,null,null); tempW = width*3/2; afterJCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } return; } if (before){ if (beforeJCount >= 8) { beforeJCount=0; } g.drawImage(beforeJImgs[beforeJCount], x, y, width+50,height,null,null); g.drawImage(beforeJImgs2[beforeJCount], x+120+60*beforeJCount, y+3*height/4-25, width+50,height/4+35,null,null); tempW = 60*beforeJCount+290; beforeJCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } return; } //System.out.println("八神庵:拳击"); if (jCount >= 4) { jCount=0; } if (jCount==2 || jCount==3){ g.drawImage(jImgs[jCount], x, y, width+150,height,null,null); tempW = width + 150; }else{ g.drawImage(jImgs[jCount], x, y, width+80,height,null,null); tempW = width + 80; } jCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 腿击 ************************************************************************/ static Image[] kImgs = new Image[4]; static int kCount; static Image[] afterKImgs = new Image[10]; static int afterKCount; static Image[] beforeKImgs = new Image[9]; static int beforeKCount; static { for (int i = 0; i < 4; i++) { kImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/k/0-" + i + ".png"); kImgs[i].getWidth(null); } for (int i = 0; i < 10; i++) { afterKImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/afterk/0-" + i + ".png"); afterKImgs[i].getWidth(null); } for (int i = 0; i < 9; i++) { beforeKImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/beforek/0-" + i + ".png"); beforeKImgs[i].getWidth(null); } } @Override public void k(Graphics g) { time = System.currentTimeMillis(); if (after){ //System.out.println("八神庵:组合技=后退+腿击"); if (afterKCount >= 10) { afterKCount=0; } if (afterKCount >= 0 && afterKCount <= 2){ g.drawImage(afterKImgs[afterKCount], x+35, y-50, width+30,height+60,null,null); tempW = 0; } if (afterKCount >= 3 && afterKCount <= 7){ g.drawImage(afterKImgs[afterKCount], x-10, y-10, width+120,height+10,null,null); tempW = width*3/2; } if (afterKCount >7){ g.drawImage(afterKImgs[afterKCount], x+35, y-40, width,height+40,null,null); tempW = 0; } afterKCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } return; } if (before){ //System.out.println("八神庵:组合技=前进+腿击"); if (beforeKCount >= 9) { beforeKCount=0; } if (beforeKCount == 0 || beforeKCount == 7 || beforeKCount == 8){ g.drawImage(beforeKImgs[beforeKCount], x, y, width+50,height,null,null); tempW = 0; }else{ g.drawImage(beforeKImgs[beforeKCount], x, y, width*3/2+30,height,null,null); tempW = width*3/2; } if (x<=Constant.GAME_WIDTH-2*Constant.PLAYER_WIDTH-speed && !peng){ x += speed; } beforeKCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } return; } //System.out.println("八神庵:腿击"); if (kCount >= 4) { kCount=0; } if (kCount==0 || kCount==1){ g.drawImage(kImgs[kCount], x, y, width+150,height,null,null); tempW = width + 135; }else{ g.drawImage(kImgs[kCount], x, y, width+75,height,null,null); tempW = width + 75; } kCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 闪避 ************************************************************************/ static Image[] lImgs1 = new Image[9]; static Image[] lImgs2 = new Image[1]; static int lCount1; static int lCount2; static { for (int i = 0; i < 9; i++) { lImgs1[i] = GameUtil.getImage("com/kof/www/images/bashenan/l/1-" + i + ".png"); lImgs1[i].getWidth(null); } for (int i = 0; i < 1; i++) { lImgs2[i] = GameUtil.getImage("com/kof/www/images/bashenan/l/9-" + i + ".png"); lImgs2[i].getWidth(null); } } @Override public void l(Graphics g) { stand = false; if (after){ //System.out.println("八神庵:向后闪避"); if (lCount1 >= 9) { lCount1=0; } g.drawImage(lImgs1[lCount1], x, y+height/2, width+30,height/2,null,null); lCount1++; if (x >= 3*speed){ x -= 3*speed; } }else{ //System.out.println("八神庵:向前闪避"); if (lCount2 >= 1) { lCount2=0; } g.drawImage(lImgs2[lCount2], x, y+height/2, 2*width,height/2,null,null); tempW = width*2-100; lCount2++; if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH-20) && !peng){ x += 2*speed; } } } /************************************************************************ * 技能一 ************************************************************************/ static Image[] uImgs1 = new Image[18]; static int uCount; static Image[] uImgs2 = new Image[18]; static { for (int i = 0; i < 18; i++) { if (i>=13){ uImgs1[i] = GameUtil.getImage("com/kof/www/images/bashenan/u/5-" + 13 + ".png"); }else{ uImgs1[i] = GameUtil.getImage("com/kof/www/images/bashenan/u/5-" + (i+1) + ".png"); } uImgs2[i] = GameUtil.getImage("com/kof/www/images/bashenan/u/6-" + i + ".png"); uImgs2[i].getWidth(null); uImgs1[i].getWidth(null); } } @Override public void u(Graphics g) { time = System.currentTimeMillis(); //System.out.println("八神庵:技能一"); if (uCount < 18) { g.drawImage(uImgs1[uCount], x, y, width*3/2,height,null,null); g.drawImage(uImgs2[uCount], x+2*width, y-(3*height/2-height), 2*width,3*height/2,null,null); tempW = width*3; uCount++; }else{ uCount=0; } try { Thread.sleep(65); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 技能二 ************************************************************************/ static Image[] iImgs = new Image[18]; static int iCount; static { for (int i = 0; i < 18; i++) { iImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/i/4-" + (i+1) + ".png"); iImgs[i].getWidth(null); } } @Override public void i(Graphics g) { //System.out.println("八神庵:技能二"); if (iCount < 18) { g.drawImage(iImgs[iCount],x+width*3/2, y-height+10, width*3/2, 2*height,null,null); tempW = 3*width-30; iCount++; }else{ iCount=0; } try { Thread.sleep(30); } catch (InterruptedException e) { throw new RuntimeException(e); } } /************************************************************************ * 被击飞 ************************************************************************/ static Image[] flyImgs = new Image[9]; static int flyCount; static { for (int i = 0; i < 9; i++) { flyImgs[i] = GameUtil.getImage("com/kof/www/images/bashenan/fly/0-" + i + ".png"); flyImgs[i].getWidth(null);//触发图像加载 } } public void fly(Graphics g) { time = System.currentTimeMillis(); if (flyCount >= 9) { flyCount=0;fly = false;stand(g);return; } if (flyCount <= 1){ g.drawImage(flyImgs[flyCount],x-width, y+height/3-50, 2*width+80, height*2/3+50,null,null); if (x>speed*8){ x -= speed*8; } } if (flyCount >= 2 && flyCount <= 6){ g.drawImage(flyImgs[flyCount],x-width+20, y+height/3+20, 2*width-20, height*2/3-20,null,null); } if (flyCount >= 7 && flyCount <= 8){ g.drawImage(flyImgs[flyCount],x-width+100, y+80, 2*width-80, height-80,null,null); } tempW = width; flyCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } } //出招控制器 public void drawSelf(Graphics g,boolean peng) { this.peng = peng; if (beaten || fly){ if (fly){ fly(g); }else{ beaten(g); } }else{ if (stand){ if (i && after && !down){ stand(g);i(g); return; } if (i && !down){ stand(g);i(g); return; } if(u && !down){ u(g); return; } stand(g); }else{ if (before && !down && !k){ after = false; if (l){ l(g);l(g);return; } if (j){ j(g);return; } if (u){ u(g);return; } if (i){ stand(g); i(g);return; } before(g); return; } if (after && !down && !j && !k){ before = false; if (l){ l(g);l(g);return; } if (u){ u(g);return; } if (i){ stand(g); i(g);return; } after(g); return; } if (down){ before = false;after = false; down(g); return; } if (j && !down){ j(g); return; } if (k && !down){ k(g); return; } if (l && !down){ l(g);l(g); return; } stand(g); stand = true; } } } //返回物体所在的矩形。便于后续的碰撞检测 public Rectangle getRect(){ return new Rectangle(x, y, tempW, height); } //技能计数器归零 public void clean(){ // 基础技能归零 lCount2=lCount1=uCount=jCount=kCount=iCount=0; // 后退组合技归零 afterCount=afterJCount=afterKCount=0; // 出招时间归零 time = 0; // 下蹲组合技归零 downCount=downKCount=0; // 前进组合技归零 beforeCount=beforeKCount=beforeJCount=0; } }
3.草稚京
public class CaoZhiJing implements Player{ int x,y,width,height; int tempX; long time = 0;// 角色出招时间 int speed = 20;// 移动的基础速度 boolean stand = true;// boolean值记录角色状态 boolean before,after,down,j,k,l,u,i,peng,beaten,fly; public CaoZhiJing(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } /************************************************************************ * 按下某个键,增加相应的方向 ************************************************************************/ public void addDirection(KeyEvent e){ switch (e.getKeyCode()) { case 40: stand = false; down = true; break; case 37: stand = false; after = true; break; case 39: stand = false; before = true; break; case KeyEvent.VK_NUMPAD1: stand = false; j = true; break; case KeyEvent.VK_NUMPAD2: stand = false; k = true; break; case KeyEvent.VK_NUMPAD3: stand = false; l = true; break; case KeyEvent.VK_NUMPAD4: u = true; break; case KeyEvent.VK_NUMPAD5: i = true; break; } } /************************************************************************ * 按下某个键,取消相应的方向 ************************************************************************/ public void minusDirection(KeyEvent e){ clean(); switch (e.getKeyCode()) { case 40:// 下 down = false; break; case 39:// 右 after = false; before = false; break; case 37:// 左 after = false; before = false; break; case KeyEvent.VK_NUMPAD1:// 1 j = false; break; case KeyEvent.VK_NUMPAD2:// 2 k = false; break; case KeyEvent.VK_NUMPAD3:// 3 l = false; break; case KeyEvent.VK_NUMPAD4:// 4 u = false; break; case KeyEvent.VK_NUMPAD5:// 5 i = false; break; } } /************************************************************************ * 站立 ************************************************************************/ static Image[] standImgs = new Image[10]; static int standCount; static { for (int i = 0; i < 10; i++) { standImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/stand/0-" + i + ".png"); standImgs[i].getWidth(null); } } @Override public void stand(Graphics g) { //System.out.println("草稚京:站立"); if (standCount >= 10) { standCount = 0; } g.drawImage(standImgs[standCount], x, y, width+20,height,null,null); tempX = x; standCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 下蹲 ************************************************************************/ static Image downImgs; static int downCount; static Image[] downKImgs = new Image[9]; static int downKCount; static { downImgs = GameUtil.getImage("com/kof/www/images/caozhijing/down/6-2.png"); downImgs.getWidth(null); for (int i = 0; i < 9; i++) { downKImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/downk/0-" + i + ".png"); downKImgs[i].getWidth(null); } } @Override public void down(Graphics g) { if (k){ //System.out.println("草稚京:组合技=下蹲+腿击"); if (downKCount >= 9) { downKCount=0; } if (downKCount <= 3){ g.drawImage(downKImgs[downKCount], x, Constant.PLAYER_Y+Constant.PLAYER_HEIGHT/2-80, width+80,Constant.PLAYER_HEIGHT/2+80,null,null); tempX = x; } if (downKCount == 4){ g.drawImage(downKImgs[downKCount], x-150, y+height*2/3-150, width*2+100,height/3+150,null,null); tempX = x-120; } if (downKCount > 4 && downKCount <=8){ g.drawImage(downKImgs[downKCount], x, Constant.PLAYER_Y+Constant.PLAYER_HEIGHT/2-130, width+130,Constant.PLAYER_HEIGHT/2+130,null,null); tempX = x; } downKCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } return; } //System.out.println("草稚京:下蹲防御"); g.drawImage(downImgs, x, Constant.PLAYER_Y+Constant.PLAYER_HEIGHT/2-40, width+20,Constant.PLAYER_HEIGHT/2+50,null,null); tempX = x; downCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 后退 ************************************************************************/ static Image[] afterImgs = new Image[11]; static int afterCount; static { for (int i = 0; i < 11; i++) { afterImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/after/0-" + i + ".png"); afterImgs[i].getWidth(null); } } @Override public void after(Graphics g) { //System.out.println("草稚京:前进"); if (afterCount >= 11) { afterCount=0; } g.drawImage(afterImgs[afterCount], x, y, width,height,null,null); tempX = x; afterCount++; if (x>=speed && !peng){ x -= speed; } } /************************************************************************ * 前进 ************************************************************************/ static Image[] beforeImgs = new Image[11]; static int beforeCount; static { for (int i = 0; i < 11; i++) { beforeImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/before/0-" + i + ".png"); beforeImgs[i].getWidth(null); } } @Override public void before(Graphics g) { //System.out.println("草稚京:后退"); if (!l){ if (beforeCount >= 11) { beforeCount=0; } g.drawImage(beforeImgs[beforeCount], x, y, width, height,null,null); tempX = x; beforeCount++; if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH)){ x += speed; } }else{ l(g);l(g); if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH)){ x += 4*speed; } } } /************************************************************************ * 挨揍 ************************************************************************/ static Image[] beatenImgs = new Image[5]; static int beatenCount; static { for (int i = 0; i < 5; i++) { beatenImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/beaten/0-" + i + ".png"); beatenImgs[i].getWidth(null); } } @Override public void beaten(Graphics g) { if (down){ down(g);return; } if (beatenCount >= 5) { beatenCount=0; beaten = false; } // System.out.println("草稚京:挨揍"); g.drawImage(beatenImgs[beatenCount], x, y, width+80, height,null,null); tempX = x; beatenCount++; if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH)){ x += speed/3; } try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 拳击 ************************************************************************/ static Image[] jImgs = new Image[2]; static int jCount; static Image[] beforeJImgs = new Image[6]; static int beforeJCount; static Image[] afterJImgs = new Image[7]; static int afterJCount; static Image afterJImg = GameUtil.getImage("com/kof/www/images/caozhijing/afterj/1-1.png"); static { for (int i = 0; i < 2; i++) { jImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/j/0-" + i + ".png"); jImgs[i].getWidth(null); } for (int i = 0; i < 6; i++){ beforeJImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/beforej/0-" + i + ".png"); beforeJImgs[i].getWidth(null); } for (int i = 0; i < 7; i++){ afterJImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/afterj/0-" + i + ".png"); afterJImgs[i].getWidth(null); } } @Override public void j(Graphics g) { time = System.currentTimeMillis(); if (before){ //System.out.println("草稚京:组合技=前进+拳击"); if (beforeJCount >= 6) { beforeJCount=0; } g.drawImage(beforeJImgs[beforeJCount], x-80, y, width+80,height,null,null); tempX = x-80; beforeJCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } return; } if(after){ //System.out.println("草稚京:组合技=后退+拳击"); if (afterJCount >= 7) { afterJCount=0; } g.drawImage(afterJImgs[afterJCount], x-80, y+30, width*2-30,height-30,null,null); if (afterJCount>=3){ g.drawImage(afterJImg, x-180, y-30, width,height-30,null,null); } tempX = x-180; afterJCount++; try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } return; } if (jCount >= 2) { jCount=0; } //System.out.println("草稚京:拳击"); g.drawImage(jImgs[jCount], x-80, y, width+100,height,null,null); tempX = x-100; jCount++; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 腿击 ************************************************************************/ static Image[] kImgs = new Image[4]; static int kCount; static Image[] afterKImgs = new Image[5]; static int afterKCount; static Image[] beforeKImgs = new Image[10]; static int beforeKCount; static { for (int i = 0; i < 4; i++) { kImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/k/0-" + i + ".png"); kImgs[i].getWidth(null); } for (int i = 0; i < 5; i++) { afterKImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/afterk/0-" + i + ".png"); afterKImgs[i].getWidth(null); } for (int i = 0; i < 10; i++) { beforeKImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/beforek/2-" + i + ".png"); beforeKImgs[i].getWidth(null); } } @Override public void k(Graphics g) { time = System.currentTimeMillis(); if (after){ System.out.println("草稚京:组合技=前进+腿击"); if (afterKCount >= 5) { afterKCount=0; } if (afterKCount>=0 && afterKCount<=2){ g.drawImage(afterKImgs[afterKCount], x-50, y, width+50,height,null,null); tempX = x; } if (afterKCount==3){ g.drawImage(afterKImgs[afterKCount], x-width, y-30, 2*width,height-30,null,null); tempX = x-width; } if (afterKCount==4){ g.drawImage(afterKImgs[afterKCount], x-width-50, y-30, 2*width-45,height-20,null,null); tempX = x-width-30; } afterKCount++; if (x>speed+2*Constant.PLAYER_WIDTH-50 && !peng){ x -= speed; } try { Thread.sleep(65); } catch (InterruptedException e) { e.printStackTrace(); } return; } if (before){ //System.out.println("草稚京:组合技=后退+腿击"); if (beforeKCount >= 10) { beforeKCount=0; } if(beforeKCount <= 3){ g.drawImage(beforeKImgs[beforeKCount], x-30, y, width+10,height,null,null); tempX = x; } if (beforeKCount == 4 || beforeKCount == 5){ g.drawImage(beforeKImgs[beforeKCount], x-30, y-80, width-10,height+80,null,null); tempX = x; } if (beforeKCount > 5){ g.drawImage(beforeKImgs[beforeKCount], x-width+50, y-10, width*3/2-30,height+10,null,null); tempX = x-width+50; } beforeKCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } return; } // System.out.println("草稚京:腿击"); if (kCount >= 4) { kCount=0; } if (kCount==0 || kCount==1){ g.drawImage(kImgs[kCount], x-50, y, width+50,height,null,null); tempX = x; } if (kCount==2 || kCount==3){ g.drawImage(kImgs[kCount], x-150, y, width+150,height,null,null); tempX = x-100; } kCount++; try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 闪避 ************************************************************************/ static Image[] lImgs1 = new Image[6]; static Image[] lImgs2 = new Image[6]; static int lCount1; static int lCount2; static { for (int i = 0; i < 6; i++) { lImgs1[i] = GameUtil.getImage("com/kof/www/images/caozhijing/l/0-" + i + ".png"); lImgs1[i].getWidth(null); } for (int i = 0; i < 6; i++) { lImgs2[i] = GameUtil.getImage("com/kof/www/images/caozhijing/l/1-" + i + ".png"); lImgs2[i].getWidth(null); } } @Override public void l(Graphics g) { stand = false; if (before){ // System.out.println("草稚京:向后闪避"); if (lCount1 >= 6) { lCount1=0; } g.drawImage(lImgs1[lCount1], x, y+height/2, width+30,height/2,null,null); tempX = x-30; lCount1++; if (x<(Constant.GAME_WIDTH-Constant.PLAYER_WIDTH)){ x += 2*speed; } }else{ // System.out.println("草稚京:向前闪避"); if (lCount2 >= 6) { lCount2=0; } g.drawImage(lImgs2[lCount2], x, y+height/2, width+30,height/2,null,null); tempX = x-30; lCount2++; if (x >= 3*speed && !peng){ x -= 4*speed; } } } /************************************************************************ * 技能一 ************************************************************************/ static Image[] uImgs1 = new Image[10]; static int uCount; static Image[] uImgs2 = new Image[10]; static { for (int i = 0; i < 10; i++) { uImgs1[i] = GameUtil.getImage("com/kof/www/images/caozhijing/u/0-" + i + ".png"); uImgs1[i].getWidth(null); } for (int i = 0; i < 10; i++) { uImgs2[i] = GameUtil.getImage("com/kof/www/images/caozhijing/u/1-" + i + ".png"); uImgs2[i].getWidth(null); } } @Override public void u(Graphics g) { time = System.currentTimeMillis(); // System.out.println("草稚京:技能一"); if (uCount < 10) { g.drawImage(uImgs2[uCount], x, y, width*3/2,height,null,null); g.drawImage(uImgs1[uCount], x-2*width+30, y+height-height/2-180, 2*width,height-30,null,null); tempX = x-2*width+50; uCount++; }else{ uCount=0; } try { Thread.sleep(65); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 技能二 ************************************************************************/ static Image[] iImgs = new Image[17]; static int iCount; static { for (int i = 0; i < 17; i++) { iImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/i/0-" + i + ".png"); iImgs[i].getWidth(null); } } @Override public void i(Graphics g) { time = System.currentTimeMillis(); //System.out.println("草稚京:技能二"); if (iCount < 17) { if (iCount<=4){ g.drawImage(iImgs[iCount],x-width*2, y-height+75, width*3/2, 2*height,null,null); }else{ g.drawImage(iImgs[iCount],x-width*2, y-height+10, width*3/2, 2*height,null,null); } tempX = x-width-width*3/2+80; iCount++; }else{ iCount=0; } try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } /************************************************************************ * 被击飞 ************************************************************************/ static Image[] flyImgs = new Image[9]; static int flyCount; static { for (int i = 0; i < 9; i++) { flyImgs[i] = GameUtil.getImage("com/kof/www/images/caozhijing/fly/0-" + i + ".png"); flyImgs[i].getWidth(null); } } public void fly(Graphics g) { if (flyCount >= 9) { flyCount=0;fly = false;stand(g);return; } if (flyCount == 0 || flyCount == 8 || flyCount == 5){ g.drawImage(flyImgs[flyCount],x, y+height/4, width+100, height*3/4,null,null); } if (flyCount >= 1 && flyCount <= 3){ g.drawImage(flyImgs[flyCount],x, y+height/2+50, 2*width+50, height/2-50,null,null); } if (flyCount == 4){ g.drawImage(flyImgs[flyCount],x, y+height/3, height*2/3+50, height*2/3,null,null); } if (flyCount == 6){ g.drawImage(flyImgs[flyCount],x, y+height/3, width+50+50, height*2/3,null,null); } if (flyCount == 7){ g.drawImage(flyImgs[flyCount],x, y-50, width, height+50,null,null); } if(flyCount >= 0 && flyCount <= 3 && x<Constant.GAME_WIDTH-width-8*speed){ x += 8*speed; } tempX = x; flyCount++; try { Thread.sleep(55); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 出招控制器 */ public void drawSelf(Graphics g,boolean peng) { this.peng = peng; if (beaten || fly){ if (fly){ fly(g); }else{ beaten(g); } }else{ if (stand) { if (i && !down) { stand(g);i(g); return; } if (u && !down) { u(g); return; } stand(g); } else { if (before && !down && !j && !k) { after = false; if (l) { l(g);l(g);return; } if (i){ stand(g); i(g);return; } if (u){ u(g);return; } before(g); return; } if (after && !down && !j && !k) { before = false; if (l) { l(g);l(g);return; } if (i){ stand(g); i(g);return; } if (u){ u(g);return; } after(g); return; } if (down) { before = false;after = false; down(g); return; } if (j && !down) { j(g); return; } if (k && !down) { k(g); return; } if (l && !down) { l(g);l(g); return; } stand(g); stand = true; } } } /*返回物体所在的矩形。便于后续的碰撞检测*/ public Rectangle getRect(){ return new Rectangle(tempX, y, width, height); } /*技能计数器归零*/ public void clean(){ // 基础技能归零 lCount2=lCount1=uCount=jCount=kCount=iCount=0; // 后退组合技归零 afterCount=afterJCount=afterKCount=0; // 出招时间归零 time = 0; // 下蹲组合技归零 downCount=downKCount=0; // 前进组合技归零 beforeCount=beforeKCount=beforeJCount=0; } }
六.音乐类
1.开始界面音乐
public class titalMusic extends Thread{ static boolean flag = true; static void playtitalMusic() {// 背景音乐播放 try { AudioInputStream ais = AudioSystem.getAudioInputStream(new File("C:\\Users\\伊蕾娜\\Desktop\\kof-1.0\\src\\titalMusic.wav")); //绝对路径 AudioFormat aif = ais.getFormat(); final SourceDataLine sdl; DataLine.Info info = new DataLine.Info(SourceDataLine.class, aif); sdl = (SourceDataLine) AudioSystem.getLine(info); sdl.open(aif); sdl.start(); FloatControl fc = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN); // value可以用来设置音量,从0-2.0 double value = 0.5; float dB = (float) (Math.log(value == 0.0 ? 0.0001 : value) / Math.log(10.0) * 20.0); fc.setValue(dB); int nByte = 0; final int SIZE = 1024 * 64; byte[] buffer = new byte[SIZE]; while (nByte != -1) {// 判断 播放/暂停 状态 if(flag) { nByte = ais.read(buffer, 0, SIZE); sdl.write(buffer, 0, nByte); }else { nByte = ais.read(buffer, 0, 0); } } sdl.stop(); } catch (Exception e) { e.printStackTrace(); } } }
2.战斗界面音乐
public class Music extends Thread{ static void playMusic() {// 背景音乐播放 try { AudioInputStream ais = AudioSystem.getAudioInputStream(new File("C:\\Users\\伊蕾娜\\Desktop\\kof-1.0\\src\\KOF.wav")); //绝对路径 AudioFormat aif = ais.getFormat(); final SourceDataLine sdl; DataLine.Info info = new DataLine.Info(SourceDataLine.class, aif); sdl = (SourceDataLine) AudioSystem.getLine(info); sdl.open(aif); sdl.start(); FloatControl fc = (FloatControl) sdl.getControl(FloatControl.Type.MASTER_GAIN); // value可以用来设置音量,从0-2.0 double value = 0.5; float dB = (float) (Math.log(value == 0.0 ? 0.0001 : value) / Math.log(10.0) * 20.0); fc.setValue(dB); int nByte = 0; final int SIZE = 1024 * 64; byte[] buffer = new byte[SIZE]; while (nByte != -1) { nByte = ais.read(buffer, 0, SIZE); sdl.write(buffer, 0, nByte); } sdl.stop(); } catch (Exception e) { e.printStackTrace(); } } }
七.images
1.八神庵
2.草稚京
新手上路,做的不好还请多多见谅。