DDR 游戏、箭头和音乐不同步 [英] DDR Game, Arrows, and Music out of sync

查看:89
本文介绍了DDR 游戏、箭头和音乐不同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm programming a game similar to DDR, using MIDI files as music. I wrote a small class to generate the arrows based on the notes in any given MIDI file. In the actual game, the song starts playing when the first arrow reaches the white arrows at the bottom (http://puu.sh/5LuVO.png). My problem is that while the song and the arrows start out in sync, by the end of the song they are off by 3-5 seconds. Any solution? Here is the code for how I am generating the arrows:

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 事件,将一个与事件具有相同刻度的箭头添加到数组中.这是我在主类中用来向面板添加箭头的计时器侦听器.

So basically I go through the MIDI events, adding an arrow with the same tick as the event to an array. This is the timer listener I am using in the main class to add the arrows to the panel.

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

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

Why are the arrows getting out of sync with the music?

推荐答案

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

Your problem is that musicTime is not computed correctly.

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

A timer is not guaranteed to execute at exactly the desired time; it might be delayed by some random amount. So by adding up the desired delay, any errors will accumulate.

要获取当前时间,请不要使用相对时间偏移,而是要求系统提供绝对时间戳.对于 Sequencer,请使用 getMicrosecondPositiongetTickPosition.

To get the current time, do not use relative time offsets but ask the system for an absolute time stamp. In the case of the Sequencer, use getMicrosecondPosition or getTickPosition.

这篇关于DDR 游戏、箭头和音乐不同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆