토이 프로젝트/Spring&Java 갖고놀기

자바 리듬 게임 만들기(3)

TerianP 2022. 3. 22.
728x90

이번 글은 3번째 Track, Music 클래스에 대한 부분입니다.

1. 구현 기능, 목표 및 Main, Dynamic 클래스

2. Game 클래스

3. Track, Music, Beat클래스

4. Note, KeyListener 클래스

 


1. Track 클래스

  • 트랙 클래스는 곡에 대한 정보를 담기 위한 클래스이다. 정확히는 하나의 곡에 대한 여러 정보들을 하나의 객체로 묶어두기 위한 클래스라도고 이야기할 수 있겠다.
  • 앞서 Dynamic Music 에서 ArrayList 로 Track 객체 배열을 만들었다. 이후 Track 클래스 객체를 만들어서 해당 객체를 배열에 넣어준다고 했는데 이때 사용되는 것이 Track 클래스이다.
  • Track 클래스의 객체는 제목이미지, 게임 메뉴 이미지, 곡 선택 시 이미지, 곡 실행 시 음악, 해당 곡 확인 글자 등을 매개변수로 받은 후 하나로 묶은 객체로 생성된다. 
  • 이후 getter, setter 를 사용해서 각 변수들을 가져오거나 변수값을 저장할 수 있다.

public class Track {

   /* 트랙 클래스는 하나의 곡에 대한 정보를 담는 클래스.
   즉, 하나의 곡에 대한 표지, 게임 선택 화면에서의 음악, 게임 실행 시 음악
    */
    private String titleImage; // 제목 이미지
    private String menuImage; // 게임 선택 창 표지 이미지
    private String ingameImage; // 해당 곡을 실행했을 때 표지 이미지
    private String startMusic; // 게임 실행 했을 때 이미지
    private String gameMusic; // 해당 곡을 실행햇을 때 음악
    private String titleName; // 해당 곡 제목 확인
    private String diffiCulity; // 해당 곡 난이도 확인

    public Track(String titleImage, String menuImage, String ingameImage, String startMusic, String gameMusic, String titleName){
        super(); // 아무것도 상속받지 않은 클래스의 super 클래스 즉 상위 클래스는 Object 클래스가 됨
        this.titleImage = titleImage;
        this.menuImage = menuImage;
        this.ingameImage = ingameImage;
        this.startMusic = startMusic;
        this.gameMusic = gameMusic;
        this.titleName = titleName;
    }

    public String getTitleImage() {
        return titleImage;
    }

    public void setTitleImage(String titleImage) {
        this.titleImage = titleImage;
    }

    public String getMenuImage() {
        return menuImage;
    }

    public void setMenuImage(String menuImage) {
        this.menuImage = menuImage;
    }

    public String getIngameImage() {
        return ingameImage;
    }

    public void setIngameImage(String ingameImage) {
        this.ingameImage = ingameImage;
    }

    public String getStartMusic() {
        return startMusic;
    }

    public void setStartMusic(String startMusic) {
        this.startMusic = startMusic;
    }

    public String getGameMusic(){
        return gameMusic;
    }
    public void setGameMusic(String gameMusic){
        this.gameMusic = gameMusic;
    }

    public String getTitleName() {
        return titleName;
    }

    public void setTitleName(String titleName) {
        this.titleName = titleName;
    }

}

 

2. Music

  • Music 클래스는 음악을 재생시키는 클래스로 Thread 를 상속받는다. 이후 Thread 로 Music 가 실행된다.
  • Dynamic Music 에서는 Music 객체를 start() 메소드로 실행한다.
  • 여기서 가장 중요한 점은 InputStream 과 bufferedInputStream 을 사용해서 음악 mp3 파일을 읽어 온 후 Player 클래스를 사용해서 음악을 플레이 시키는 부분이다.
    • 이때 Music 생성자로 name 과 무한loop 여부, mod 를 매개변수로 받아온다. mod 는 게임 음악 파일인지 메뉴 음악 파일인지 구분하기 위해서 사용하는 구분자로서 사용한다.
    • 루프는 게임 선택 메뉴에서의 음악은 계속해서 loop 해서 반복되는 음악이기 때문에 
    • InputStream 으로 파일을 한번 가져오고, BufferedInputStream 에 다시한번 담아서 읽어오도록 한다.
  • getTime 메소드는 음악의 현재 시간을 가져오는 메소드이다.
  • close 메소드는 현재 음악을 종료하고, Thread 를 종료하는 메소드이다.
  • run 메소드 안에 내가 Thread 에서 실행하기를 원하는 코드를 넣는다.
    • run 에 들어가는 코드는 player 의 클래스안에 있는 play() 를 넣어서 player 객체에 담긴 음악을 실행시긴다. 이때 반복은 isLoop 가 true 인 동안만 반복한다 

import javazoom.jl.player.Player;

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


public class Music extends Thread{

    private Player player; // mp3 를 재생해주는 클래스
    private boolean isLoop; // 음악의 무한 루프 확인
    private BufferedInputStream bufferedInputStream;

//    private File file; // 파일을 가져오는 클래스
//    private FileInputStream fileInputStream;

    // 음악 mp3 파일 이름, 음악 반복재생 여부, 게임관련 음악인지 메뉴 관련 음악인지 여부
    public Music(String name, boolean isLoop, String mod) {
        try {
            this.isLoop = isLoop; // isLoop 초기화

            // 음악 파일을 inputstream 에 넣어서 가져옴
            // game 관련 음악이면 game_music 에서 , menu 관련 음악이면 menu_music 에서 출력됨
            if(mod.equals("game")){

                InputStream input = Music.class.getClassLoader().getResourceAsStream("game_music/" + name);

                bufferedInputStream = new BufferedInputStream(input); // 이후 다시 버퍼에 담아서 읽어 올 수 있도록
                player = new Player(bufferedInputStream); // 최종적으로 player 인스턴스는 버퍼에 담긴 음악 파일을 갖음

            }else if(mod.equals("menu")){

                InputStream input = Music.class.getClassLoader().getResourceAsStream("menu_music/" + name);
                bufferedInputStream = new BufferedInputStream(input); // 이후 다시 버퍼에 담아서 읽어 올 수 있도록

                player = new Player(bufferedInputStream); // 최종적으로 player 인스턴스는 버퍼에 담긴 음악 파일을 갖음
            }

        }catch (Exception e){
            System.out.println(e.getMessage());
        }

    }

    public int getTime(){ // 실행되는 음악의 시간 위치 => 3분짜리 음악에 10초 재생중
        // 이것은 나중에 음악에 맞춰 노트를 떨어뜨릴때 getTime을 통해 분석
        if ( player == null){
            return 0;
        }

        return player.getPosition();
    }

    public void close() { // 음악을 종료하는 메서드
        isLoop = false;
        player.close();

        // 해당 스레드를 종료상태로 만듦 => 게임을 실행하는것과 별도로 곡 재생을 하는 스레드가 존재하는데
        // 곡 재생 스레드를 종료해줌
        this.interrupt();
    }

    @Override
    public void run(){
        try{
            do{
                player.play(); // 최종적으로 player 인스턴스는 버퍼에 담긴 음악 파일을 play

            }while(isLoop == true); // isLoop 가 true 인 동안 음악 반복 재생
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

 

3. Beat

  • Beat 클래스는 노트의 시간과 노트의 키보드 값 을 저장하기 위한 클래스이다.
  • Game 에서 이 클래스에 내가 찍은 노트를 time 과 noteType 을 담고, 불러오기 위해서 사용된다.

public class Beat {

    private int time;
    private String noteName;

    public String getNoteName() {
        return noteName;
    }

    public void setNoteName(String noteName) {
        this.noteName = noteName;
    }

    public Beat(int time, String noteName) {
        this.time = time;
        this.noteName = noteName;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
}

댓글