马房山实验报告大学Java大作业——贪吃蛇

作业内容

用Java实现贪吃蛇游戏的同时,添加用户登录(无需使用网络编程、无需密码)、用户得分存储、得分排行榜、音乐播放等功能。

开发环境

macOS 10.15 BlueJ(要是当年我知道Eclipse的windowbuilder这个插件的话就不会写的这么痛苦了)

说明

此项目仅供参考(各位看看在BlueJ里面的结构图就知道我这玩意儿耦合性有多高),直接cv只能说分还过得去,但高不了。
在这里插入图片描述

贪吃蛇游戏主体部分参考
音乐播放部分参考案例代码music player

具体实现方法就是把music player的JFrame界面设置一个监听器,监听贪吃蛇界面的位置并跟随(这是在当时只有两天作业就截止的情况下最快的方法);然后再自己实现登录功能以及文件读取以保存得分记录。

播放音乐时,需要将.mp3格式的文件放在工程同级文件夹的名为audio的文件夹中。同样记得修改保存记录以及用户信息的.txt的路径。

源代码

Main.java

import java.awt.*;

public class Main 
{
    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame();
        myFrame.init();
    }
}

MyFrame.java

import java.awt.*;
import java.awt.event.*;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.JFrame;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import java.io.*;

public class MyFrame extends JFrame 
{
    
    public void init() 
    {
        MyFrame frame = new MyFrame();
        frame.setTitle("贪吃蛇");
        frame.setResizable(false);
        frame.setBounds(200,100,1015,810); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.makeMenuBar();
        GamePanel panel = new GamePanel();
        frame.add(panel);
        frame.setVisible(true);
        
        SideWindow gui = new SideWindow();
        gui.makeFrame();
        gui.setVisible(true);
        showLogIn();
        
        frame.addComponentListener(new ComponentAdapter() 
        {
            public void componentMoved(ComponentEvent e) 
            {
                Rectangle rect = frame.getBounds();
                gui.setLocation(rect.x+rect.width-150, rect.y+44);
            }
        });
    }
    
    
    private void makeMenuBar()
    {
        final int SHORTCUT_MASK =
            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

        JMenuBar menubar = new JMenuBar();
        setJMenuBar(menubar);
        
        JMenu menu;
        JMenuItem item;
        
        menu = new JMenu("分数");
        menubar.add(menu);
        
        item = new JMenuItem("排行榜");
        item.addActionListener(e -> showChart());
        menu.add(item);
        
        menu = new JMenu("玩家");
        menubar.add(menu);
        
        item = new JMenuItem("注册/登录");
        item.addActionListener(e -> showLogIn());
        menu.add(item);
    }
    
    
    public void showChart()
    {
        try
        {
            ArrayList<PlayerScore> results = Point.loadAllResults();
            int length = results.size();
            if(length > 10)
            {
                length = 10;
            }
        
            MyFrame frame1 = new MyFrame();
            frame1.setTitle("点击查看排行榜");
            frame1.setResizable(false);
            frame1.setBounds(200,100,200,250);
            frame1.setVisible(true);
            
            for(int i = 0; i < length; i++)
            {
                JTextArea chart = new JTextArea();
                chart.setFont(new Font("苹方-简",Font.BOLD,16));
                chart.setBounds(0, 25 + 20 * i, 180, 20);
                chart.setLineWrap(true); 
                chart.setEditable(false);
                chart.setOpaque(false);
                chart.setVisible(true);     
                PlayerScore result = results.get(i);
                chart.setText(" " + result.getName() + "  " + result.getScore());
                frame1.add(chart);
            }  
            
            JTextArea chart = new JTextArea();
            chart.setFont(new Font("苹方-简",Font.BOLD,16));
            chart.setBounds(0, 0, 180, 20);
            chart.setLineWrap(true); 
            chart.setEditable(false);
            chart.setOpaque(false);
            chart.setVisible(true);  
            chart.setText(" 前十排行榜");
            frame1.add(chart);
        }
        
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
    
    
    public void showLogIn()
    {   
        MyFrame frame2 = new MyFrame();
        frame2.setTitle("注册/登录");
        frame2.setResizable(false);
        frame2.setBounds(300,150,300,100);
        frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
        JPanel pCenter = new JPanel();
        pCenter.setLayout(new FlowLayout());
        JPanel pSouth = new JPanel();
        
        JLabel l1 = new JLabel("用户名:");
        JTextField tf1= new JTextField();
        tf1.setPreferredSize(new Dimension(120,30));
        
        pCenter.add(l1);
        pCenter.add(tf1);
        
        JButton b1 = new JButton("注册");
        JButton b2 = new JButton("登录");
        pSouth.add(b1);
        pSouth.add(b2);
        
        b1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                String name = tf1.getText();
                if(0==name.length())
                {
                    JOptionPane.showMessageDialog(frame2, "用户名不能为空");
                    tf1.grabFocus();
                    return;
                }
                if(Player.isPlayer(name))
                    JOptionPane.showMessageDialog(frame2, "用户名已存在");
                else
                {
                    try 
                    {
                        Player.createPlayer(name);
                        JOptionPane.showMessageDialog(frame2, "创建成功");
                    } 
                    catch (IOException a) 
                    {
                        a.printStackTrace();
                        JOptionPane.showMessageDialog(frame2, "创建失败");
                    }
                    
                }
            }
	});
        
	
	b2.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                String name = tf1.getText();
                if(0==name.length())
                {
                    JOptionPane.showMessageDialog(frame2, "用户名不能为空");
                    tf1.grabFocus();
                    return;
                }
                if(Player.isPlayer(name))
                {
                    Player.name = name;
                    JOptionPane.showMessageDialog(frame2, "登录成功");
                    frame2.dispose();
                }
                else
                    JOptionPane.showMessageDialog(frame2, "用户名不存在");
            }
	});
	
        frame2.setLayout(new BorderLayout());
        frame2.add(pCenter,BorderLayout.CENTER);
        frame2.add(pSouth,BorderLayout.SOUTH);
        frame2.setVisible(true);
    }    
}

GamePanel.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;

public class GamePanel extends JPanel implements KeyListener, ActionListener 
{
    static final int BODYSIZE = 20;
    Snake snake = new Snake();
    Food food = new Food();
    Timer timer = new Timer(100, this);
    static boolean isStart = false;
    static boolean isDead = false;

    public GamePanel() 
    {
        setFocusable(true); 
        addKeyListener(this); 
        food.startTimer();
        timer.start();  
    }

    @Override
    protected void paintComponent(Graphics g) 
    {
        if(Player.name != "")
        {
            super.paintComponent(g); 
            setBackground(Color.BLACK); 
            g.setColor(Color.green);
            for (int i = 0; i < Snake.length; i++)
                g.fillRect(Snake.snakeX[i], Snake.snakeY[i], BODYSIZE, BODYSIZE);

            g.setColor(Color.RED);
            g.fillOval(food.normalX, food.normalY, BODYSIZE, BODYSIZE);
            if (food.hasBonus)  
            {
                g.setColor(Color.YELLOW);
                g.fillOval(food.bonusX, food.bonusY, BODYSIZE, BODYSIZE);
            }

       
            g.setColor(Color.WHITE);
            g.setFont(new Font("苹方-简", Font.PLAIN, 20));
            g.drawString("目前得分:" + Point.point, 5, 20);
            g.drawString("玩家:" + Player.name, 5, 42);
        
         
            if (!isStart) 
            {
                g.setColor(Color.ORANGE);
                g.setFont(new Font("苹方-简", Font.BOLD, 40));
                g.drawString("使用空格开始游戏", 250, 300);
                timer.stop();
            } 
        
            else if (isDead) 
            {
                g.setColor(Color.RED);
                g.setFont(new Font("苹方-简", Font.BOLD, 40));
                g.drawString("GAME OVER", 250, 300);

                try 
                {
                    Point.writeResult();
                    Point.readBestResult();
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
                g.setColor(Color.WHITE);
                g.setFont(new Font("苹方-简", Font.PLAIN, 30));
                g.drawString("最后得分:" + Point.point, 250, 350);
                g.drawString("最高分:" + Point.bestScore, 250, 400);
                timer.stop();
            }
        }
    }


    @Override
    public void keyPressed(KeyEvent e) {
        int keycode = e.getKeyCode();
        if (keycode == KeyEvent.VK_SPACE) 
        {
            isStart = !isStart;
            if (isStart) 
            {
                timer.start();
            }
            if (isDead)
            {
                isStart = false;
                isDead = false;
                snake = new Snake();
                snake.length = 3;
                snake.speedX = 20;
                snake.speedY = 0;
                Point.point = 0;
                timer.start();
            }
        } 
        else if (snake.isTmpMove)    
        {   
            snake.changeDirection(e);
        }
        repaint();
    }


    @Override
    public void actionPerformed(ActionEvent e) 
    {
        snake.move();
        snake.checkEatFood(food);
        food.changeFoodPosition();
        snake.checkCollide();
        repaint();
    }

    
    @Override
    public void keyReleased(KeyEvent e) 
    {

    }

    @Override
    public void keyTyped(KeyEvent e) 
    {

    }
}

Snake.java

import java.awt.event.KeyEvent;

public class Snake 
{
    static String direction = "right";
    static int length = 3;
    static int[] snakeX = new int[1000];
    static int[] snakeY = new int[1000];
    static int speedX = 20;
    static int speedY = 0;
    boolean isTmpMove = true;

    public Snake() {
        snakeX[0] = 400;
        snakeY[0] = 400;
        snakeX[1] = 380;
        snakeY[1] = 400;
        snakeX[2] = 360;
        snakeY[2] = 400;
    }

    public void move() 
    {

        for (int i = length - 1; i > 0; i--) 
        {
            snakeX[i] = snakeX[i - 1];
            snakeY[i] = snakeY[i - 1];
        }
        snakeX[0] += speedX;
        snakeY[0] += speedY;
        isTmpMove = true;
        checkBoundaries();
    }

    public void changeDirection(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP && !direction.equals("down")) 
        {
            direction = "up";
            speedX = 0;
            speedY = -20;
        } 
        else if (e.getKeyCode() == KeyEvent.VK_DOWN && !direction.equals("up")) 
        {
            direction = "down";
            speedX = 0;
            speedY = 20;
        } 
        else if (e.getKeyCode() == KeyEvent.VK_RIGHT && !direction.equals("left")) 
        {
            direction = "right";
            speedX = 20;
            speedY = 0;
        } 
        else if (e.getKeyCode() == KeyEvent.VK_LEFT && !direction.equals("right")) 
        {
            direction = "left";
            speedX = -20;
            speedY = 0;
        }
        isTmpMove = false;
    }

    public void checkBoundaries() {
        if (snakeX[0] > 840) {
            snakeX[0] = 0;
        } else if (snakeX[0] < 0) {
            snakeX[0] = 840;
        } else if (snakeY[0] > 760) {
            snakeY[0] = 0;
        } else if (snakeY[0] < 0) {
            snakeY[0] = 760;
        }
    }

    public void checkEatFood(Food food) {
        if (snakeX[0] == food.normalX && snakeY[0] == food.normalY) {
            food.isEat = true;
            getLonger(food);
        } else if (snakeX[0] == food.bonusX && snakeY[0] == food.bonusY && food.hasBonus) {
            food.isBonusEat = true;
            food.hasBonus = false;
            getLonger(food);
        }
    }

    public void getLonger(Food food) {
        if (food.isEat) {
            Point.getNormalFoodPoint();
            snakeX[length] = snakeX[length - 1] - (snakeX[length - 2] - snakeX[length - 1]);
            snakeY[length] = snakeY[length - 1] - (snakeY[length - 2] - snakeY[length - 1]);
            length++;
        } 
        else if (food.isBonusEat) 
        {
            Point.getBonusFoodPoint();
            snakeX[length] = snakeX[length - 1] - (snakeX[length - 2] - snakeX[length - 1]);
            snakeY[length] = snakeY[length - 1] - (snakeY[length - 2] - snakeY[length - 1]);
            length++;
            food.isBonusEat = false;
        }
    }

    public void checkCollide() 
    {
        for (int i = 1; i < length; i++) 
        {
            if (snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0]) 
            {
                GamePanel.isDead = true;
                break;
            }
        }
    }
}

Food.java

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class Food {
    Random rd = new Random();
    private int tmpX = rd.nextInt(840);
    private int tmpY = rd.nextInt(780);
    int normalX = tmpX - tmpX % 20;
    int normalY = tmpY - tmpY % 20;
    int bonusX;
    int bonusY;
    boolean isEat = false;
    boolean hasBonus = false;
    boolean isBonusEat = false;
    Timer foodTimer = new Timer();  
    
    TimerTask task = new TimerTask() 
    {
        @Override
        public void run() 
        {
            createBonus();
            hasBonus = !hasBonus; 
        }
    };  

    public void changeFoodPosition() {
        if (isEat) {
            tmpX = rd.nextInt(840);
            tmpY = rd.nextInt(780);
            normalX = tmpX - tmpX % 20;
            normalY = tmpY - tmpY % 20;
            isEat = false;
        }
    }

    public void createBonus() {
        int tmpX = rd.nextInt(840);
        int tmpY = rd.nextInt(780);
        bonusX = tmpX - tmpX % 20;
        bonusY = tmpY - tmpY % 20;
    }

    public void startTimer() {
        foodTimer.scheduleAtFixedRate(task, 10000, 10000);
    }

}

Player.java

import java.io.*;
import java.util.ArrayList;

public class Player
{
    static String name = "";
    
    public static String getPlayer()
    {
        return name;
    }
    
    
    public static void setPlayer(String rename)
    {
        name = rename;
    }
    
    
    public static ArrayList<String> loadAllPlayers() throws IOException
    {
        ArrayList<String> players = new ArrayList<String>();
        BufferedReader br = new BufferedReader(new FileReader("玩家.txt"));
        String player;
        while ((player = br.readLine()) != null) 
        {
            players.add(player);
        }
        br.close();
        return players;
    }
    
    
    public static boolean isPlayer(String aplr)
    {
        try 
        {
            ArrayList<String> players = loadAllPlayers();
            for(String player:players)
            {
                if(player.equals(aplr))
                {
                    return true;
                }
            }
            return false;
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
            return false;
        }
    }
    
    public static void createPlayer(String aplr) throws IOException
    {    
        BufferedWriter bw = new BufferedWriter(new FileWriter("玩家.txt", true));
        bw.write(aplr);
        bw.newLine();
        bw.close();
    }
    
}

PlayerScore.java

public class PlayerScore
{
    private String player;
    private int score;

    public PlayerScore(String name, int point)
    {
        player = name;
        score = point;
    }
        
    
    public String getName()
    {
        return player;
    }
    
    
    public int getScore()
    {
        return score;
    }
}

Point.java

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;


public class Point 
{
    static int point = 0;
    static int bestScore;

    public static void getNormalFoodPoint() 
    {
        point += 50;
    }
    
    public static void getBonusFoodPoint() 
    {
        point += 100;
    }    
    
    
    public static void writeResult() throws IOException 
    {
        BufferedWriter bw = new BufferedWriter(new FileWriter("记录.txt", true));
        bw.write(Player.name + "\t" + point);
        bw.newLine();
        bw.close();
    }
    
    
    public static void readBestResult() throws IOException 
    {
        BufferedReader br = new BufferedReader(new FileReader("记录.txt"));
        String line;
        int score;
        while ((line = br.readLine()) != null) 
        {
            String[] tmp = line.split("\t");
            score = Integer.parseInt(tmp[1]);
            if (score > bestScore) 
            {
                bestScore = score;
            }
        }
        br.close();
    }
    
    
    public static ArrayList<PlayerScore> loadAllResults() throws IOException
    {
        BufferedReader br = new BufferedReader(new FileReader("记录.txt"));
        ArrayList<PlayerScore> results = new ArrayList<PlayerScore>();
        String line;
        int score;
        while ((line = br.readLine()) != null) 
        {
            String[] tmp = line.split("\t");
            score = Integer.parseInt(tmp[1]);
            PlayerScore playerscore = new PlayerScore(tmp[0], score);
            results.add(playerscore);
        }
        br.close();
        
        Collections.sort(results,new SortByScore());  
        return results;
    }
}


class SortByScore implements Comparator<PlayerScore>
{
    @Override
    public int compare(PlayerScore s1, PlayerScore s2) 
    {
        if(s1.getScore() < s2.getScore())
        {
            return 1;
        }
        return -1;
    }
}

SideWindow.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import java.io.*;


public class SideWindow extends JFrame
{
    private static final String AUDIO_DIR = "../audio";
    
    private JList<String> fileList;
    private JSlider slider;
    private JLabel infoLabel;
    private MusicOrganizer organizer;
    private MusicPlayer player;
    private List<Track> trackList;
    public SideWindow()
    {
        super("Music Player");
        organizer = new MusicOrganizer(AUDIO_DIR);
        player = new MusicPlayer();
    }
    private void play()
    {
        int index = fileList.getSelectedIndex();
        if(index >= 0 && index < trackList.size()) {
            //slider.setValue(0);
            player.startPlaying(trackList.get(index).getFilename());
        }
    }

  
    private void stop()
    {
        player.stop();
    }

    
 
    private void setListOrdering(String ordering)
    {
        trackList = organizer.sortByField(ordering);
        String[] tracks = getTracksDisplayList(trackList);
        fileList.setListData(tracks);
    }

    private String[] getTracksDisplayList(List<Track> trackList)
    {
        int numTracks = trackList.size();
        String[] tracks = new String[numTracks];
        for(int i = 0; i < numTracks; i++) {
            String[] fields = trackList.get(i).getFields();
            StringBuilder listing = new StringBuilder();
            for(String field : fields) {
                listing.append(field);
                listing.append(" ");
            }
            tracks[i] = listing.toString().trim();
        }
        return tracks;
    }

    public void makeFrame()
    {
        
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        JPanel contentPane = (JPanel) getContentPane();
        contentPane.setBorder(new EmptyBorder(6, 10, 10, 10));
        setUndecorated(true);
        setAlwaysOnTop(true);
        
        contentPane.setLayout(new BorderLayout(8, 8));

        JPanel leftPane = new JPanel();
        {
            leftPane.setLayout(new BorderLayout(8, 8));

            JPanel orderingPanel = new JPanel();
            orderingPanel.setLayout(new BorderLayout());
            orderingPanel.add(new JLabel("Order by:"), BorderLayout.NORTH);
            
            String[] ordering = Track.FIELDS;
            
 
            JComboBox<String> formatList = new JComboBox<>(ordering);
            formatList.addActionListener(a -> {
                int index = formatList.getSelectedIndex();
                if(index >= 0) {
                    String selectedOrder = formatList.getItemAt(index);
                    setListOrdering(selectedOrder);
                }
            }); 
            orderingPanel.add(formatList, BorderLayout.CENTER);
            
            leftPane.add(orderingPanel, BorderLayout.NORTH);
    
            fileList = new JList<>();
            fileList.setForeground(new Color(140,171,226));
            fileList.setBackground(new Color(0,0,0));
            fileList.setSelectionBackground(new Color(87,49,134));
            fileList.setSelectionForeground(new Color(140,171,226));
            JScrollPane scrollPane = new JScrollPane(fileList);
            scrollPane.setColumnHeaderView(new JLabel("Audio files"));
            leftPane.add(scrollPane, BorderLayout.CENTER);
            
         
            setListOrdering(ordering[0]);
        }
        contentPane.add(leftPane, BorderLayout.CENTER);

        JPanel toolbar = new JPanel();
        {
            toolbar.setLayout(new GridLayout(0, 1));
  
            JButton button = new JButton("Play");
            button.addActionListener(a -> play());
            toolbar.add(button);
            
            button = new JButton("Stop");
            button.addActionListener(a -> stop());
            toolbar.add(button);
        }
        contentPane.add(toolbar, BorderLayout.NORTH);
 
        pack();
        setBounds(1065,79,150,766);
        setVisible(true);
    }
    
}

MusicPlayer.java

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;

public class MusicPlayer
{
    private MusicFilePlayer player;

    private String filename;

    

    public MusicPlayer()
    {
        player = null;
        filename = "";
    }
    

    public void startPlaying(final String filename)
    {
        try {
            setupPlayer(filename);
            playFrom(0);
        }
        catch (JavaLayerException ex) {
            reportProblem();
        }
    }
    

    public void stop()
    {
        killPlayer();
    }
    
    

    public int getLength()
    {
        if(player != null) {
            return player.getLength();
        }
        else {
            return 0;
        }
    }

    private void setupPlayer(String filename)
    {
        try {
            if(player != null) {
                killPlayer();
            }
            this.filename = filename;
            player = new MusicFilePlayer(filename);
        }
        catch(JavaLayerException e) {
            System.out.println("Problem setting up player");
            e.printStackTrace();
            reportProblem();
            killPlayer();
        }
    }
    

    private void playFrom(final int start) throws JavaLayerException
    {
        Thread playerThread = new Thread() {
            public void run()
            {
                try {
                    player.playFrom(start);
                }
                catch(JavaLayerException e) {
                    reportProblem();
                    killPlayer();
                }
            }
        };
        playerThread.setPriority(Thread.MIN_PRIORITY);
        playerThread.start();
    }


    private void killPlayer()
    {
        synchronized(this) {
            if(player != null) {
                player.stop();
                player = null;
                filename = "";
            }
        }
    }
    

    private void reportProblem()
    {
        System.out.println("There was a problem playing: " + filename);
    }

}

Track.java


public class Track
{
    private String artist;     
    private String title;      
    private String filename;    
    public static final String[] FIELDS = {
        "Artist",
        "Title",
        "Filename",
    };
    

    public Track(String artist, String title, String filename)
    {
        setDetails(artist, title, filename);
    }
    

    public Track(String filename)
    {
        setDetails("unknown", "unknown", filename);
    }
    
 
    public String getArtist()
    {
        return artist;
    }
    
 
    public String getTitle()
    {
        return title;
    }
    

    public String getFilename()
    {
        return filename;
    }
    

    public String getField(String field) 
    {
        if (field.equals("Artist")) {
            return artist;
        }
        else if (field.equals("Title")) {
            return title;
        }
        else if (field.equals("Filename")) {
            return filename;
        }
        else {
            throw new IllegalArgumentException("Unknown field name: " + field);
        }
    }
    

    public String[] getFields()
    {
        String[] fields = new String[FIELDS.length];
        for(int i = 0; i < FIELDS.length; i++) {
            fields[i] = getField(FIELDS[i]);
        }
        return fields;
    }
            
        
    public String getDetails()
    {
        return artist + ": " + title + "  (file: " + filename + ")";
    }
    

    private void setDetails(String artist, String title, String filename)
    {
        this.artist = artist;
        this.title = title;
        this.filename = filename;
    }
    
}

MuiscOrganizer.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class MusicOrganizer
{
    private ArrayList<Track> tracks;

    private TrackReader reader;

    public MusicOrganizer(String folderName)
    {
        tracks = new ArrayList<>();
        reader = new TrackReader();
        readLibrary(folderName);
    }
    

    public void addFile(String filename)
    {
        tracks.add(new Track(filename));
    }
    

    public void addTrack(Track track)
    {
        tracks.add(track);
    }
    

    public Track getTrack(int index)
    {
        if(indexValid(index)) {
            return tracks.get(index);
        }
        else {
            return null;
        }
    }
    

    public int getNumberOfTracks()
    {
        return tracks.size();
    }
    

    public List<Track> getAllTracks()
    {
        return new ArrayList<>(tracks);
    }
    

    public List<Track> sortByArtist()
    {
        return sortByField("Artist");
    }
    

    public List<Track> sortByTitle()
    {
       return sortByField("Field");
    }
    

    private List<Track> sortBy(Comparator<Track> comparator)
    {
        List<Track> copy = getAllTracks();
        Collections.sort(copy, comparator);
        return copy;
    }
    

    public List<Track> sortByField(final String field)
    {
        return sortBy(new Comparator<Track>() {
            public int compare(Track t1, Track t2)
            {
                return t1.getField(field).compareTo(t2.getField(field));
            }
        });
    }
    

    public void removeTrack(int index)
    {
        if(indexValid(index)) {
            tracks.remove(index);
        }
    }
    

    private boolean indexValid(int index)
    {

        boolean valid;
        
        if(index < 0) {
            System.out.println("Index cannot be negative: " + index);
            valid = false;
        }
        else if(index >= tracks.size()) {
            System.out.println("Index is too large: " + index);
            valid = false;
        }
        else {
            valid = true;
        }
        return valid;
    }
    
    public void readLibrary(String folderName)
    {
        ArrayList<Track> tempTracks = reader.readTracks(folderName, ".mp3");


        for(Track track : tempTracks) {
            addTrack(track);
        }
    }
}

MusicFilePlayer.java

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;

import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;


public class MusicFilePlayer
{
    private Bitstream bitstream;
    private Decoder decoder;
    private AudioDevice audio;
    private boolean playing = false;
    private String filename;
    private int frameCount;
    private int frameNumber;

    public MusicFilePlayer(String filename) throws JavaLayerException
    {
        this.filename = filename;
                
        openAudio();
 
        frameCount = getFrameCount(filename);
        
        openBitstream(filename);
        
        frameNumber = 0;  
    }


    public void play() throws JavaLayerException
    {
        playFrames(0, frameCount);
    }


    public boolean play(int frames) throws JavaLayerException
    {
        return playFrames(frameNumber, frameNumber + frames);
    }


    public boolean play(int start, int end) throws JavaLayerException
    {
        return playFrames(start, start + end);
    }
    
    
    public int getLength()
    {
        return frameCount;
    }
    
   
    public boolean playFrom(int start) throws JavaLayerException
    {
        return playFrames(start, frameCount);
    }
    

    public int getFrameNumber()
    {
        return frameNumber;
    }
    

    private boolean playFrames(int start, int end) throws JavaLayerException
    {
        
        if(end > frameCount) {
            end = frameCount;
        }
        
        synchronized(this) {
            moveTo(start);
            playing = true;
        }

        boolean ok = true;
        while (frameNumber < end && playing && ok) {
            ok = decodeFrame();
            if(ok) {
                frameNumber++;
            }                    
        }

        synchronized(this) {
            playing = false;
            AudioDevice out = audio;
            if (out != null) {
                out.flush();
            }
        }
        return ok;
    }
    
    private void moveTo(int position) throws JavaLayerException
    {
        if(position < frameNumber) {
            synchronized(this) {
                if(bitstream != null) {
                    try {
                        bitstream.close();
                    }
                    catch (BitstreamException ex) {
                    }
                }
                if(audio != null) {
                    audio.close();
                }
                openAudio();
                openBitstream(filename);
                frameNumber = 0;
            }
        }
        
        while(frameNumber < position) {
            skipFrame();
            frameNumber++;
        }            
    }

    public void close()
    {
        synchronized(this) {
            if (audio != null) {
                AudioDevice out = audio;
                audio = null;
                out.close();
                try {
                    bitstream.close();
                }
                catch (BitstreamException ex) {
                }
                bitstream = null;
                decoder = null;
            }
        }
    } 

    protected boolean decodeFrame() throws JavaLayerException
    {
        try
        {
            synchronized (this) {
                if (audio == null) {
                    return false;
                }
    
                Header h = readFrame();
                if (h == null) {
                    return false;
                }
    
                SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);

                if(audio != null) {
                    audio.write(output.getBuffer(), 0, output.getBufferLength());
                }
            }

            bitstream.closeFrame();
        }
        catch (RuntimeException ex) {
            ex.printStackTrace();
            throw new JavaLayerException("Exception decoding audio frame", ex);
        }
        return true;
    }


    protected boolean skipFrame() throws JavaLayerException
    {
        Header h = readFrame();
        if (h == null) {
            return false;
        }
        frameNumber++;
        bitstream.closeFrame();
        return true;
    }


    public void stop()
    {
        close();
    }

    protected int getFrameCount(String filename) throws JavaLayerException
    {
        openBitstream(filename);
        int count = 0;
        while(skipFrame()) {
            count++;
        }
        bitstream.close();
        return count;        
    }
    

    protected Header readFrame() throws JavaLayerException
    {
        if(audio != null) {
            return bitstream.readFrame();
        }
        else {
            return null;
        }
    }
    

    protected void openAudio() throws JavaLayerException
    {
        audio = FactoryRegistry.systemRegistry().createAudioDevice();
        decoder = new Decoder();
        audio.open(decoder);
    }
    

    protected void openBitstream(String filename)
        throws JavaLayerException
    {
        try {
            bitstream = new Bitstream(new BufferedInputStream(
                        new FileInputStream(filename)));
        }
        catch(java.io.IOException ex) {
            throw new JavaLayerException(ex.getMessage(), ex);
        }
                    
    }
}

接下来的面向对象实验——档案管理系统我就不放上来了,有更老的老学长的博文可以搜得到。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值