代码之家  ›  专栏  ›  技术社区  ›  Rob Nicholas

Java OpenAL:按键播放声音,但只在短时间内播放

  •  1
  • Rob Nicholas  · 技术社区  · 11 年前

    终于有了我的第一个声音要播放了,但是当我按下键时,它会播放一秒的声音,当我释放它时,它将继续播放其余的声音。下面是分别调用的声音类和Input方法。这与我检查输入的方式有关吗?

    package com.evylgaming.rpg;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.nio.FloatBuffer;
    import java.nio.IntBuffer;
    import java.util.ArrayList;
    import java.util.Iterator;
    
    import org.lwjgl.BufferUtils;
    import org.lwjgl.openal.AL10;
    import org.lwjgl.openal.ALC10;
    import org.lwjgl.openal.OpenALException;
    import org.newdawn.slick.openal.WaveData;
    
    public class SoundManager {
        public static final int NUM_BUFFERS = 3;
        public static final int NUM_SOURCES = 3;
    
    
        private static ArrayList<Integer> sources = new ArrayList<Integer>();
        private static ArrayList<Integer> buffers = new ArrayList<Integer>();
        private static ArrayList<String> loadedFiles = new ArrayList<String>();
    
        static FloatBuffer sourcePos = BufferUtils.createFloatBuffer(3*NUM_BUFFERS);
    
    
        static FloatBuffer sourceVel = BufferUtils.createFloatBuffer(3*NUM_BUFFERS);
    
        FloatBuffer listenerPos = BufferUtils.createFloatBuffer(3).put(
                new float[] { 0.0f, 0.0f, 0.0f });
        FloatBuffer listenerVel = BufferUtils.createFloatBuffer(3).put(
                new float[] { 0.0f, 0.0f, 0.0f });
        FloatBuffer listenerOri = BufferUtils.createFloatBuffer(6).put(
                new float[] { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f });
    
    
    
        void setListenerValues() {
            AL10.alListener(AL10.AL_POSITION, listenerPos);
            AL10.alListener(AL10.AL_VELOCITY, listenerVel);
            AL10.alListener(AL10.AL_ORIENTATION, listenerOri);
        }
    
        public static void killALData() {
            IntBuffer scratch = BufferUtils.createIntBuffer(1);
    
            // Release all buffer data.
            for (Iterator<Integer> iter = buffers.iterator(); iter.hasNext();) {
                scratch.put(0, ((Integer) iter.next()).intValue());
                AL10.alDeleteBuffers(scratch);
            }
    
            // Release all source data.
            for (Iterator<Integer> iter = sources.iterator(); iter.hasNext();) {
                scratch.put(0, ((Integer) iter.next()).intValue());
                AL10.alDeleteSources(scratch);
            }
    
            // Destroy the lists.
            buffers.clear();
            sources.clear();
        }
    
        public SoundManager(String fileName) {
            listenerPos.flip();
            listenerVel.flip();
            listenerOri.flip();
        }
    
        public static String getALErrorString(int err) {
            switch (err) {
            case AL10.AL_NO_ERROR:
                return "AL_NO_ERROR";
            case AL10.AL_INVALID_NAME:
                return "AL_INVALID_NAME";
            case AL10.AL_INVALID_ENUM:
                return "AL_INVALID_ENUM";
            case AL10.AL_INVALID_VALUE:
                return "AL_INVALID_VALUE";
            case AL10.AL_INVALID_OPERATION:
                return "AL_INVALID_OPERATION";
            case AL10.AL_OUT_OF_MEMORY:
                return "AL_OUT_OF_MEMORY";
            default:
                return "No such error code";
            }
        }
    
        public static String getALCErrorString(int err) {
            switch (err) {
            case ALC10.ALC_NO_ERROR:
                return "AL_NO_ERROR";
            case ALC10.ALC_INVALID_DEVICE:
                return "ALC_INVALID_DEVICE";
            case ALC10.ALC_INVALID_CONTEXT:
                return "ALC_INVALID_CONTEXT";
            case ALC10.ALC_INVALID_ENUM:
                return "ALC_INVALID_ENUM";
            case ALC10.ALC_INVALID_VALUE:
                return "ALC_INVALID_VALUE";
            case ALC10.ALC_OUT_OF_MEMORY:
                return "ALC_OUT_OF_MEMORY";
            default:
                return "no such error code";
            }
        }
    
        public static int loadALBuffer(String path) throws FileNotFoundException {
            int result;
            IntBuffer buffer = BufferUtils.createIntBuffer(1);
    
            // Load wav data into a buffers.
            AL10.alGenBuffers(buffer);
    
            if ((result = AL10.alGetError()) != AL10.AL_NO_ERROR) {
                throw new OpenALException(getALErrorString(result));
            }
    
            WaveData waveFile = WaveData.create(new BufferedInputStream(new FileInputStream(path)));
            if (waveFile != null) {
                AL10.alBufferData(buffer.get(0), waveFile.format, waveFile.data,
                        waveFile.samplerate);
                waveFile.dispose();
            } else {
                throw new RuntimeException("No such file: " + path);
            }
    
            // Do another error check and return.
            if ((result = AL10.alGetError()) != AL10.AL_NO_ERROR) {
                throw new OpenALException(getALErrorString(result));
            }
    
            return buffer.get(0);
        }
    
        public static int getLoadedALBuffer(String path) throws FileNotFoundException {
            int count = 0;
            for (Iterator<String> i = loadedFiles.iterator(); i.hasNext(); count++) {
                if (i.equals(path)) {
                    return ((Integer) buffers.get(count)).intValue();
                }
            }
    
            int buffer = loadALBuffer(path);
    
            buffers.add(new Integer(buffer));
            loadedFiles.add(path);
    
            return buffer;
        }
    
        public static void killALLoadedData() {
            loadedFiles.clear();
        }
    
        public static void playSound(int index){
            AL10.alSourcePlay(index);
        }
        public static void stopSound(int index){
            AL10.alSourceStop(index);
        }
    
    
        public static int loadALSample(String path, boolean loop) throws FileNotFoundException {
            IntBuffer source = BufferUtils.createIntBuffer(1);
            int buffer;
            int result;
    
    
            buffer = getLoadedALBuffer(path);
            AL10.alGenSources(source);
    
            if ((result = AL10.alGetError()) != AL10.AL_NO_ERROR)
                throw new OpenALException(getALErrorString(result));
    
            AL10.alSourcei(source.get(0), AL10.AL_BUFFER, buffer);
            AL10.alSourcef(source.get(0), AL10.AL_PITCH, 1.0f);
            AL10.alSourcef(source.get(0), AL10.AL_GAIN, 1.0f);
            AL10.alSource(source.get(0), AL10.AL_POSITION, sourcePos);
            AL10.alSource(source.get(0), AL10.AL_VELOCITY, sourceVel);
            AL10.alSourcei(source.get(0), AL10.AL_LOOPING, (loop ? AL10.AL_TRUE: AL10.AL_FALSE));
    
            sources.add(new Integer(source.get(0)));
    
            return source.get(0);
        }
    }  
    

    下面是在主类中调用的输入

    if (mainInput.getRawDelta(RPGInputMap.LEFT)) {
                        SoundManager.playSound(testSound);
                        GL11.glColor3f(1.f, 1.f, 1.f);
                    } else {
                        SoundManager.stopSound(testSound);
                        GL11.glColor3f(.9f, .9f, .9f);
                    }
    

    这里是处理一切的输入类。

    package com.evylgaming.rpg;
    
    import org.lwjgl.input.Keyboard;
    
    public class RPGInputMap {
        public static int CONTROL_CODE_NUM = 5;
        public static int LEFT = 0;
        public static int RIGHT = 1;
        public static int UP = 2;
        public static int DOWN = 3;
        public static int MENU = 4;
    
        private boolean[] controlDelta;
        private boolean[] controlState;
        private int[] controlBinding;
    
        public RPGInputMap() {
            controlDelta = new boolean[5];
            controlState = new boolean[5];
            controlBinding = new int[5];
            controlBinding[0] = Keyboard.KEY_A;
            controlBinding[1] = Keyboard.KEY_D;
            controlBinding[2] = Keyboard.KEY_W;
            controlBinding[3] = Keyboard.KEY_S;
            controlBinding[4] = Keyboard.KEY_ESCAPE;
        }
        public boolean getRawDelta(int controlCode) {
            if(controlCode >= CONTROL_CODE_NUM) {
                return false;
            }
            return controlDelta[controlCode];
        }
        public boolean getRawState(int controlCode) {
            if(controlCode >= CONTROL_CODE_NUM) {
                return false;
            }
            return controlState[controlCode];
        }
        public void pollControls() {
            for(int i=0; i <controlDelta.length; i++) {
                controlDelta[i]=false;
            }
            while (Keyboard.next()) {
                for(int i=0; i<controlBinding.length; i++) {
                    if(controlBinding[i]==Keyboard.getEventKey()) {
                        controlDelta[i]=true;
                        controlState[i]=Keyboard.getEventKeyState();
                    }
                }
            }
        }
    }
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   Rob Nicholas    11 年前

    发现这是由于输入类是如何实现的。

    推荐文章