超级玛丽游戏开发五(动作音效)

 

实现功能:

马里奥跳跃、撞击、游戏开始、结束、游戏中的背景音乐。

  • 在进行某个动作的时候需要调用进行播放音效的方法。
  • 包装一个Sound类,有具体地方法来播放给定的音效。
  • 每一个音效都对应不同的音乐文件,和不同的使用场景,特别是背景音乐需要循环播放,因此需要用到线程,可以包装一个Music类实现Runnable接口。

 

1.Sound类

public class Sound {
		
	    static final String DIR = "music/";// 音乐文件夹
	 	
	    static final String START = "mario.wav";// 开始音乐	    
	    static final String HIT = "brick_smash.wav";// 击中铁墙
	    static final String JUMP = "jump.wav";//跳跃
	    static final String DEATH = "death.wav";//死亡
	    static final String KICK = "kick.wav";//踩踏敌人
	    static final String COIN = "coin.wav";//吃金币
	    static final String DELIFE = "deLife.wav";//吃金币
	    static final String BACKMUSIC = "mario.wav";// 背景音乐
	    static Music bgMusic = null;//背景音乐
	    /**
	     * 播放跟牌音效
	     */
	    static public void start() {
	        
	    	play(DIR+START,false);// 开始游戏
	    }


	    static public void HIT() {
	        play(DIR + HIT, false);//击中铁墙
	    }
	    
	    static public void JUMP() {
	        play(DIR + JUMP, false);//跳跃
	    }
	    
	    static public void DEATH() {
	    	bgMusic.stop();
	        play(DIR + DEATH, false);//死亡
	    }
	    
	    static public void KICK() {
	        play(DIR + KICK, false);//攻击敌人
	    }
	    
	    static public void COIN(){
	    	play(DIR + COIN, false);//吃金币
	    }
	    
	    static public void deLife(){
	    	play(DIR + DELIFE, false);//减少生命值
	    }
	    
	    //背景音乐
	    static public void BACKMUSIC() {
	    	play(DIR + BACKMUSIC, true);
	    }
	   
	    /**
	     * 播放
	     * @param file
	     * 音乐文件完整名称
	     * @param circulate
	     * 是否循环播放
	     */
	    
	        private static void play(String file, boolean circulate) {
	        try {
	            // 创建播放器
	            Music player = new Music(file, circulate);
	            player.play();// 播放器开始播放
	            if(file.equals(DIR+BACKMUSIC)){
	            	bgMusic = player;
	            }
	            
	        } catch (FileNotFoundException e) {
	            e.printStackTrace();
	        }
	    }
	}

2.Music类

实现Runnable接口,播放对应的音乐

public class Music implements Runnable{
	
		/**
		 * 音乐播放器
		 *  
		 * @author
		 */	
	    File soundFile; // 音乐文件
	    Thread thread;// 父线程
	    boolean circulate;// 是否循环播放

	    /**
	     * 构造方法,默认不循环播放
	     * 
	     * @param filepath
	     * 音乐文件完整名称
	     * @throws FileNotFoundException
	     */
	    
	    public Music(String filepath) throws FileNotFoundException {
	        this(filepath, false);
	    }

	    /**
	     * 构造方法
	     * 
	     * @param filepath
	     * 音乐文件完整名称
	     * @param circulate
	     * 是否循环播放
	     * @throws FileNotFoundException
	     */
	    public Music(String filepath, boolean circulate)
	            throws FileNotFoundException {
	        this.circulate = circulate;
	        soundFile = new File(filepath);
	        if (!soundFile.exists()) {// 如果文件不存在
	            
	        	throw new FileNotFoundException(filepath + "未找到");
	        }
	    }

	    /**
	     * 播放
	     */ 
	    public void play() {
	        thread = new Thread(this);// 创建线程对象
	        thread.start();// 开启线程
	    }

	    /**
	     * 停止播放
	     */
	    public void stop() {
		circulate = false;
	        thread.stop();// 强制关闭线程
	    }

	    /**
	     * 重写线程执行方法
	     */
		
	    public void run() {
	        byte[] auBuffer = new byte[1024*128];// 创建128k缓冲区
	        do {
	            AudioInputStream audioInputStream = null; // 创建音频输入流对象
	            SourceDataLine auline = null; // 混频器源数据行
	            try {
	                // 从音乐文件中获取音频输入流
	                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
	                AudioFormat format = audioInputStream.getFormat(); // 获取音频格式
	                // 按照源数据行类型和指定音频格式创建数据行对象
	                DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);
	                // 利用音频系统类获得与指定 Line.Info 对象中的描述匹配的行,并转换为源数据行对象
	                auline = (SourceDataLine) AudioSystem.getLine(info);
	                auline.open(format);// 按照指定格式打开源数据行
	                auline.start();// 源数据行开启读写活动
	                int byteCount = 0;// 记录音频输入流读出的字节数
	                while (byteCount != -1) {// 如果音频输入流中读取的字节数不为-1
	                    // 从音频数据流中读出128K的数据
	                    byteCount = audioInputStream.read(auBuffer, 0,auBuffer.length);
	                    if (byteCount >= 0) {// 如果读出有效数据
	                        auline.write(auBuffer, 0, byteCount);// 将有效数据写入数据行中
	                    
	                    }
	                }
	            } catch (IOException e) {
	                e.printStackTrace();
	            } catch (UnsupportedAudioFileException e) {
	                e.printStackTrace();
	            } catch (LineUnavailableException e) {
	                e.printStackTrace();
	            } finally {
	            	
	                auline.drain();// 清空数据行
	                auline.close();// 关闭数据行
	            }
	        } while (circulate);// 根据循环标志判断是否循环播放
	    }

	}

然后在对应的场合调用Sound类的方法就可以了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hnu哈哈

请接受直女的么么哒????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值