【问题标题】:DDR Game, Arrows, and Music out of syncDDR 游戏、箭头和音乐不同步
【发布时间】:2019-02-02 16:52:22
【问题描述】:

我正在编写一个类似于 DDR 的游戏,使用 MIDI 文件作为音乐。我编写了一个小类来根据任何给定 MIDI 文件中的音符生成箭头。在实际游戏中,当第一个箭头到达底部的白色箭头 (http://puu.sh/5LuVO.png) 时,歌曲开始播放。我的问题是,虽然歌曲和箭头开始同步,但到歌曲结束时,它们会延迟 3-5 秒。有什么解决办法吗? 这是我如何生成箭头的代码:

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()));
                } 
            } 
        }
    }

所以基本上我会遍历 MIDI 事件,将带有与事件相同刻度的箭头添加到数组中。这是我在主类中用来向面板添加箭头的计时器监听器。

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();
        }
        });

为什么箭头与音乐不同步?

【问题讨论】:

    标签: java timer midi javasound


    【解决方案1】:

    您的问题是 musicTime 计算不正确。

    定时器不能保证在期望的时间执行;它可能会延迟一些随机数量。 因此,通过将所需延迟相加,任何错误都会累积。

    要获取当前时间,不要使用相对时间偏移,而是向系统询问绝对时间戳。 对于 Sequencer,请使用 getMicrosecondPositiongetTickPosition

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多