토이 프로젝트/Spring&Java 갖고놀기
자바 리듬 게임 만들기(3)
TerianP
2022. 3. 22. 16:37
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;
}
}