2013-12-14 2 views
0

그래서 음악과 마찬가지로 MIDI 파일을 사용하여 DDR과 비슷한 게임을 프로그래밍하고 있습니다. 주어진 MIDI 파일의 음표를 기반으로 화살표를 생성하는 작은 클래스를 작성했습니다. 실제 게임에서 첫 번째 화살표가 아래쪽에있는 흰색 화살표 (http://puu.sh/5LuVO.png)에 도달하면 노래가 재생됩니다. 내 문제는 노래와 화살표가 동기화되어 시작되는 동안 노래가 끝날 때까지 3-5 초 정도 꺼져 있다는 것입니다. 어떤 해결책? 그래서 기본적으로 내가 배열 이벤트와 같은 눈금 화살표를 추가, 미디 이벤트를 통해 이동Java DDR 게임, 화살표 및 음악 동기화 외

Sequence sequence = MidiSystem.getSequence(new File("arbitrary.mid")); 
    int trackNumber = 0; 
    millisecondsPerTick = sequence.getMicrosecondLength()/(sequence.getTickLength()*(float)1000); 
    for (Track track : sequence.getTracks()) { 
     trackNumber++; 
     for (int i=0; i < track.size(); i++) { 
      MidiEvent event = track.get(i); 
      MidiMessage message = event.getMessage(); 
      if (message instanceof ShortMessage) { 
       ShortMessage sm = (ShortMessage) message; 
       if (sm.getCommand() == NOTE_ON) { 
        int key = sm.getData1(); 
        int velocity = sm.getData2(); 
        if(velocity>20) 
        songArrows.add(new Arrow(-20, 20, key%4 , false, (int)event.getTick())); 
       } 
      } 
     } 
    } 

: 는 여기에 내가 화살표를 생성하고 방법에 대한 코드입니다. 패널에 화살표를 추가하기 위해 주 클래스에서 사용하는 타이머 수신기입니다.

generateArrowsTimer.addActionListener(new ActionListener() { 
public void actionPerformed(ActionEvent evt) { 
    for (int i = 0; i < GenerateArrowsTest.songArrows.size(); i++) { 
      if(Math.abs(musicTime - GenerateArrowsTest.millisecondsPerTick*((Arrow)GenerateArrowsTest.songArrows.get(i)).getTime())<=10) 
         movingArrows.add((Arrow)GenerateArrowsTest.songArrows.get(i)); 
        //arrows show up at the top of the screen as they are added, then move down at 4px per 30 milliseconds, using updateTimer 
       } 
     if(musicTime >= updateTimer.getDelay()*520/Arrow.movementIncrement && musicTime < updateTimer.getDelay()*600/Arrow.movementIncrement) 
        sequencer.start(); //Starts playing music about when first arrow reaches a white arrow 
        if(sequencer.isRunning())  
         musicTime += generateArrowsTimer.getDelay(); //delay was initialized to be 30 
     repaint(); 
     } 
     }); 

화살표가 음악과 동기화되지 않는 이유는 무엇입니까?

답변

0

musicTime이 올바르게 계산되지 않았습니다.

타이머가 원하는 시간에 정확히 실행되는 것은 아닙니다. 임의의 양만큼 지연 될 수 있습니다. 원하는 지연 시간을 더하면 오류가 누적됩니다.

현재 시간을 가져 오려면 상대 시간 오프셋을 사용하지 말고 절대 시간 스탬프를 시스템에 요청하십시오. 시퀀서의 경우 getMicrosecondPosition 또는 getTickPosition을 사용하십시오.