Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1]
1  Java Game APIs & Engines / JOGL Development / Re: OpenGL project in applet, Help~ on: 2010-07-16 08:50:25
1) To use JOGL in an applet, you have to sign it (due to the function System.loadLibrary and the native calls JOGL makes.) You can sign a JAR file here: http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/security/toolfilex/step3.html

2) The class GLDisplay (or whatever class you want to show as the applet) should extend java.awt.Applet or javax.swing.JApplet (for swing).

3) To display it as an applet, you need to create a xHTML/HTML file with the <applet> tag or <object> tag. The <applet> tag has been deprecated by W3C and now W3C recommends you use the <object> tag. A quick google search should reveal some more information on this.

HTH,

 - David
2  Game Development / Networking & Multiplayer / Re: Problem with Lag on: 2010-07-16 08:42:45
are you using tcp or udp?

if youre using tcp, its a better idea to collapse 10 (or so) move packets into a single packet and send one of those every second instead of a seperate move every 100ms. this way, the movement wont be held up as much as if you sent 10 move packets a second (because of tcp, if packet #1 fails to send, the client will send it again, and the server will need to wait for #1 to arrive again before it can process #2-#10.)

if youre using udp, sending 10 small move packets per second should be fine, as a lost packet shouldnt affect anything.

As stated above, you should also use some sort of interpolation (and perhaps extrapolation) to smooth out the movement.

 - David
3  Discussions / General Discussions / Re: Custom Java WebStart and Applet Loading Screens *finally!* on: 2010-07-13 10:04:53
Wow that looks brilliant. Finally we can have professional JWS programs.
4  Game Development / Newbie & Debugging Questions / Re: Level Editor? on: 2010-07-13 09:15:48
Either save the output in a text form (SGML, XML) or a binary form which can be reconstructed to form the level structure.

For a binary structure, the structure will most probably analogous to the following:

1  
2  
3  
4  
 <4 bytes> - Number of objects
 Repeat Number of objects {
  Object information
 }


which is analgous to this in a XML structure:

1  
2  
3  
4  
5  
6  
7  
8  
9  
<Objects>
 <Object1>
  <Attr1="Something" />
  <Attr2="Something>
   <SometingInsideAttr2="
Something Else" />
  </Attr2>
 </Object1>
 ...... And so on
</Objects>


Binary will probably be faster to load, but XML will be easier to edit, (well that depends on how good your Level Editor is.)

I wouldn't really recommend ObjectInputStream and ObjectOutputStream, you might encounter problems loading old levels with a new version of the game.
5  Game Development / Shared Code / Re: Utils essentials on: 2010-07-13 08:51:17
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
   public static Point lineIntersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
      double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
      if (denom == 0.0) { // Lines are parallel.
        return null;
      }
      double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))/denom;
      double ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))/denom;
        if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
            // Get the intersection point.
           return new Point((int) (x1 + ua*(x2 - x1)), (int) (y1 + ua*(y2 - y1)));
        }

      return null;
   }


line intersection algo
6  Games Center / Featured Games / Re: Revenge of the Titans progress on: 2010-06-28 12:00:15
Windows 7 x86 RC 2

Intel i5 Core @ 2.4GHz

nVidia GTX 220M

java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) Client VM (build 14.0-b16, mixed mode, sharing)
7  Games Center / Featured Games / Re: Revenge of the Titans progress on: 2010-06-27 16:25:37
got an error

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
Window sized to 1137 x 640 x 0 @0Hz
        at java.util.Arrays.copyOf(Unknown Source)
        at java.io.ByteArrayOutputStream.toByteArray(Unknown Source)
        at com.shavenpuppy.jglib.sound.OggVorbis.doCreate(OggVorbis.java:489)
        at com.shavenpuppy.jglib.Resources.allocate(Resources.java:466)
        at com.shavenpuppy.jglib.Resource.create(Resource.java:154)
        at com.shavenpuppy.jglib.Resources.get(Resources.java:179)
        at com.shavenpuppy.jglib.openal.SoundBank.doCreate(SoundBank.java:99)
        at com.shavenpuppy.jglib.Resources.allocate(Resources.java:466)
        at com.shavenpuppy.jglib.Resource.create(Resource.java:154)
        at com.shavenpuppy.jglib.openal.SoundClip.doCreate(SoundClip.java:91)
        at com.shavenpuppy.jglib.Resources.allocate(Resources.java:466)
        at com.shavenpuppy.jglib.Resource.create(Resource.java:154)
        at com.shavenpuppy.jglib.Resources.get(Resources.java:179)
        at com.shavenpuppy.jglib.openal.ALBuffer.doALCreate(ALBuffer.java:136)
        at com.shavenpuppy.jglib.openal.ALResource.doCreate(ALResource.java:76)
        at com.shavenpuppy.jglib.Resources.allocate(Resources.java:466)
        at com.shavenpuppy.jglib.Resource.create(Resource.java:154)
        at com.shavenpuppy.jglib.Resources.get(Resources.java:179)
        at com.shavenpuppy.jglib.resources.Feature.defaultCreation(Feature.java:
230)
        at com.shavenpuppy.jglib.resources.Feature.doCreate(Feature.java:278)
        at worm.SFX.doCreate(SFX.java:111)
        at com.shavenpuppy.jglib.Resources.allocate(Resources.java:466)
        at com.shavenpuppy.jglib.Resource.create(Resource.java:154)
        at net.puppygames.applet.effects.SFX.createSFX(SFX.java:132)
        at net.puppygames.applet.Game.init(Game.java:641)
        at net.puppygames.applet.Launcher.main(Launcher.java:64)
[/quote]
8  Game Development / Newbie & Debugging Questions / Re: Newbie learning java by writing simple game engine using Eclipse - help needed. on: 2010-06-26 19:20:39
add System.out.println("paintEvent") in your render method and see how often it gets called
9  Game Development / Newbie & Debugging Questions / Re: Newbie learning java by writing simple game engine using Eclipse - help needed. on: 2010-06-26 18:25:09
in reply to your question - do you have an infinite loop anywhere? that is probably whats causing it
10  Game Development / Shared Code / Re: Asynchronous Sound Player based on JavaSound API on: 2010-06-26 17:25:17
forgot to include this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


package renoria.sound;

/**
 *
 * @author David
 */

public interface SoundListener {
   /**
    * Invoked when the sound is started
    */

   void started();

   /**
    * Invoked when the sound is stopped
    */

   void stopped();

   /**
    * Invoked when the sound is updated.
    * @param data Data read
    * @param off Offset of <tt>data</tt> where the data was read
    * @param len length of data read
    */

   void update(byte[] data, int off, int len);

   /**
    * Invoked when the position of the sound is updated.
    * @param oldPosition Old position
    * @param newPosition New position
    * @param msTicks Milliseconds ticked
    */

   void positionUpdate(long oldPosition, long newPosition, long msTicks);
}
11  Game Development / Shared Code / Fix for docking JToolBars to JSplitPanes on: 2010-06-26 17:20:07
Lately i've tried docking a tool bar to a split pane.. though I found each time it threw an exception Sad

so heres some code I wrote that fixes this problem

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;

/**
 *
 * @author David
 */

public class MySplitPane
      extends JSplitPane {
   private boolean autoCorrectToolBarOrientation = true;

   public MySplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) {
      super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);
   }

   public MySplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {
      super(newOrientation, newLeftComponent, newRightComponent);
   }

   public MySplitPane(int newOrientation, boolean newContinuousLayout) {
      super(newOrientation, newContinuousLayout);
   }

   public MySplitPane(int newOrientation) {
      super(newOrientation);
   }

   public MySplitPane() {
   }

   public boolean isAutoCorrectToolBarOrientation() {
      return autoCorrectToolBarOrientation;
   }

   public void setAutoCorrectToolBarOrientation(boolean autoCorrectToolBarOrientation) {
      this.autoCorrectToolBarOrientation = autoCorrectToolBarOrientation;
   }

   @Override
   protected void addImpl(Component comp, Object constraints, int index) {
      if (comp instanceof JToolBar) {
         if (this.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
            if (constraints.equals(BorderLayout.WEST) || constraints.equals(BorderLayout.SOUTH)) {
               constraints = JSplitPane.LEFT;
            } else if (constraints.equals(BorderLayout.EAST) || constraints.equals(BorderLayout.NORTH)) {
               constraints = JSplitPane.RIGHT;
            }
            if (constraints.equals(JSplitPane.LEFT) && super.getLeftComponent() != null) {
               //System.out.println("UNDOCKABLE");
              if (this.getRightComponent() == null) {
                  constraints = JSplitPane.RIGHT;
               } else {
                  return;
               }
            }
            if (constraints.equals(JSplitPane.RIGHT) && super.getRightComponent() != null) {
               //System.out.println("UNDOCKABLE");
              if (this.getLeftComponent() == null) {
                  constraints = JSplitPane.LEFT;
               } else {
                  return;
               }
            }
         } else if (this.getOrientation() == JSplitPane.VERTICAL_SPLIT) {
            if (constraints.equals(BorderLayout.WEST) || constraints.equals(BorderLayout.SOUTH)) {
               constraints = JSplitPane.BOTTOM;
            } else if (constraints.equals(BorderLayout.EAST) || constraints.equals(BorderLayout.NORTH)) {
               constraints = JSplitPane.TOP;
            }
            if (constraints.equals(JSplitPane.TOP) && super.getTopComponent() != null) {
               //System.out.println("UNDOCKABLE");
              if (this.getBottomComponent() == null) {
                  constraints = JSplitPane.BOTTOM;
               } else {
                  return;
               }
            }
            if (constraints.equals(JSplitPane.BOTTOM) && super.getBottomComponent() != null) {
               //System.out.println("UNDOCKABLE");
              if (this.getTopComponent() == null) {
                  constraints = JSplitPane.TOP;
               } else {
                  return;
               }
            }
         }
      }
      //System.out.println("Constraints: " + constraints);
     super.addImpl(comp, constraints, index);
      if (autoCorrectToolBarOrientation) {
         if (comp instanceof JToolBar) {
            if (this.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
               ((JToolBar) comp).setOrientation(JToolBar.VERTICAL);
            } else if (this.getOrientation() == JSplitPane.VERTICAL_SPLIT) {
               ((JToolBar) comp).setOrientation(JToolBar.HORIZONTAL);
            }
         }
      }
   }
}


use this class instead of JSplitPane

have fun, and report any problems to me
12  Game Development / Shared Code / Re: Asynchronous Sound Player based on JavaSound API on: 2010-06-26 16:47:33
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
      @Override
      public void run() {
         try {
            byte[] buf = new byte[1024];
            while (!shutDown) {
               synchronized (soundSync) {
                  Iterator<SoundInfo> pInfo = playList.iterator();
                  while (pInfo.hasNext()) {
                     inListLoop = true;
                     SoundInfo info = pInfo.next();
                     long oldpos = info.line.getLongFramePosition();
                     long mspos = info.line.getMicrosecondPosition();
                     try {
                        int avail = info.line.available();
                        int read = info.input.read(buf, 0, Math.min(avail, buf.length));
                        if (read > 0) {
                           info.line.write(buf, 0, read);
                           if (info.listeners != null) {
                              synchronized (info.listenerLock) {
                                 Iterator<SoundListener> listeners = info.listeners.iterator();
                                 while (listeners.hasNext()) {
                                    SoundListener listener = listeners.next();
                                    listener.update(buf, 0, read);
                                    listener.positionUpdate(oldpos, info.line.getLongFramePosition(), mspos);
                                 }
                              }
                           }
                        } else if (!info.line.isRunning() ||
                              !info.line.isActive() ||
                              !info.line.isOpen() ||
                              info.line.getLongFramePosition() >= info.length) {
                           info.line.drain();
                           info.line.close();
                           info.input.close();
                           pInfo.remove();
                           AsyncSoundPlayer.this.playingSounds.decrementAndGet();
                           if (info.listeners != null) {
                              synchronized (info.listenerLock) {
                                 Iterator<SoundListener> listeners = info.listeners.iterator();
                                 while (listeners.hasNext()) {
                                    SoundListener listener = listeners.next();
                                    listener.stopped();
                                 }
                              }
                           }
                        } else {
                           if (info.listeners != null) {
                              synchronized (info.listenerLock) {
                                 Iterator<SoundListener> listeners = info.listeners.iterator();
                                 while (listeners.hasNext()) {
                                    SoundListener listener = listeners.next();
                                    listener.positionUpdate(oldpos, info.line.getLongFramePosition(), mspos);
                                 }
                              }
                           }
                        }
                     } catch (IOException e) {
                        throw new IDXException(e);
                     }
                  }
                  inListLoop = false;
                  if (playList.size() < maxPlayingSoundsPerPool) {
                     SoundInfo nextSound = pollQueuedSound();
                     if (nextSound != null) {
                        synchronized (soundSync) {
                           playList.add(nextSound);
                           if (nextSound.listeners != null) {
                              synchronized (nextSound.listenerLock) {
                                 Iterator<SoundListener> listeners = nextSound.listeners.iterator();
                                 while (listeners.hasNext()) {
                                    SoundListener listener = listeners.next();
                                    listener.started();
                                 }
                              }
                           }
                           AsyncSoundPlayer.this.playingSounds.incrementAndGet();
                        }
                     }
                  }
                  try {
                     Thread.sleep(1);
                  } catch (Exception e) {}
               }
               try {
                  Thread.sleep(1);
               } catch (Exception e) {}
            }
         } catch (Throwable t) {
            renoria.Core.handleException(t);
         }
      }
   }

   public static final class SoundInfo {
      private AudioFormat format;
      private SourceDataLine line;
      private AudioInputStream input;
      private BooleanControl muteControl;
      private FloatControl gainControl;
      private FloatControl balanceControl;
      private FloatControl panControl;
      private long length;
      private float volume = 1.0f;
      private List<SoundListener> listeners = null;
      private final Object listenerLock = new Object();
      private AsyncSoundPlayer player;

      private SoundInfo() {
      }

      public boolean isMuteAvailable() {
         return muteControl != null;
      }

      public boolean isGainAvailable() {
         return gainControl != null;
      }

      public boolean isBalanceAvailable() {
         return balanceControl != null;
      }

      public boolean isPanAvailable() {
         return panControl != null;
      }

      public AudioFormat getFormat() {
         return format;
      }

      public FloatControl getBalanceControl() {
         return balanceControl;
      }

      public FloatControl getGainControl() {
         return gainControl;
      }

      public BooleanControl getMuteControl() {
         return muteControl;
      }

      public FloatControl getPanControl() {
         return panControl;
      }

      public void setVolume(float volume) {
         this.volume = volume * player.masterVolume;
         setVolumeIntern();
      }

      private void setVolumeIntern() {
         if (gainControl != null) {
            if (volume <= 0) {
               if (muteControl != null) {
                  muteControl.setValue(true);
               } else {
                  gainControl.setValue(gainControl.getMinimum());
               }
            } else {
               if (muteControl != null) {
                  muteControl.setValue(false);
               }

               float max = gainControl.getMaximum();
               float min = gainControl.getMinimum();
               float vol = (float) (Math.log(volume) / Math.log(10.0) * 20.0);

               vol = Math.max(min, Math.min(max, vol));
               gainControl.setValue(vol);
            }
         }
      }

      public AudioInputStream getInput() {
         return input;
      }

      public long getLength() {
         return length;
      }

      public SourceDataLine getLine() {
         return line;
      }

      public float getVolume() {
         return volume;
      }

      public void addSoundListener(SoundListener listener) {
         if (listeners == null) {
            listeners = new LinkedList();
         }
         synchronized (listenerLock) {
            listeners.add(listener);
         }
      }

      public void removeSoundListener(SoundListener listener) {
         if (listeners == null) {
            throw new IllegalStateException();
         }
         synchronized (listenerLock) {
            listeners.remove(listener);
         }
      }

      public SoundListener[] getListeners() {
         return listeners.toArray(new SoundListener[listeners.size()]);
      }
   }

   public static final class SoundUnavailableException
         extends RuntimeException {
      public SoundUnavailableException(Throwable cause) {
         super(cause);
      }

      public SoundUnavailableException(String message, Throwable cause) {
         super(message, cause);
      }

      public SoundUnavailableException(String message) {
         super(message);
      }

      public SoundUnavailableException() {
      }
   }
}
13  Game Development / Shared Code / Re: Asynchronous Sound Player based on JavaSound API on: 2010-06-26 16:47:03
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
   /**
    * Creates a {@link SoundInfo} context for the given input, and optionally plays the sound on one of the sound
    * player threads.
    * <p>If <tt>instant</tt> is false, only the context is created. To play the sound you must invoke
    * {@link #playSound(renoria.sound.AsyncSoundPlayer.SoundInfo) } to pass it to one of the sound player threads.
    * @param input Input to read from
    * @param instant Whether we should instantly play the sound
    * @return Sound Context
    */

   public SoundInfo playSound(InputStream input, boolean instant) {
      if (!soundAvailable) {
         throw new SoundUnavailableException();
      }
      AudioInputStream stream = getAudioInputStream(input);
      AudioFormat format = stream.getFormat();
      SoundInfo info = new SoundInfo();
      info.format = format;
      info.input = stream;
      info.length = stream.getFrameLength();
      info.player = this;
      SourceDataLine line = null;
      DataLine.Info dinfo = new DataLine.Info(SourceDataLine.class, format);
      try {
         Mixer useMixer = mixer != null ? mixer : AudioSystem.getMixer(null);
         try {
            line = (SourceDataLine) useMixer.getLine(dinfo); // Try using this mixer first
        } catch (Throwable t) {
            line = (SourceDataLine) AudioSystem.getLine(dinfo); // Fallback to another mixer on the system
        }
         if (line == null) {
            throw new SoundUnavailableException();
         }
         line.open(format);
         if (line.isControlSupported(BooleanControl.Type.MUTE)) {
            info.muteControl = (BooleanControl) line.getControl(BooleanControl.Type.MUTE);
         }
         if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
            info.gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
         }
         if (line.isControlSupported(FloatControl.Type.BALANCE)) {
            info.balanceControl = (FloatControl) line.getControl(FloatControl.Type.BALANCE);
         }
         if (line.isControlSupported(FloatControl.Type.PAN)) {
            info.panControl = (FloatControl) line.getControl(FloatControl.Type.PAN);
         }
      } catch (Exception e) {
         throw new IDXException(e);
      }

      line.start();
      info.line = line;
      if (instant) {
         playSound(info);
      }

      return info;
   }

   public List<SoundInfo> allSoundsPlaying() {
      List<SoundInfo> ret = new ArrayList();
      synchronized (poolSync) {
         Iterator<Player> players = playerPool.iterator();
         while (players.hasNext()) {
            Player p = players.next();
            synchronized (p.soundSync) {
               ret.addAll(p.playList);
            }
         }
      }

      return ret;
   }

   public int numPlayingSounds() {
      return playingSounds.get();
   }

   public int getMaxPlayingSoundsPerPool() {
      return maxPlayingSoundsPerPool;
   }

   public void setMaxPlayingSoundsPerPool(int maxPlayingSoundsPerPool) {
      if (playerPool != null) {
         throw new IllegalStateException();
      }
      this.maxPlayingSoundsPerPool = maxPlayingSoundsPerPool;
   }

   public AudioFormat getPlayBackFormat() {
      return playBackFormat;
   }

   public void setPlayBackFormat(AudioFormat playBackFormat) {
      this.playBackFormat = playBackFormat;
   }

   public void playSound(SoundInfo info) {
      if (!soundAvailable) {
         throw new SoundUnavailableException();
      }
      synchronized (poolSync) {
         Iterator<Player> players = playerPool.iterator();
         Player min = null;
         int mini = Integer.MAX_VALUE;
         while (players.hasNext()) {
            Player mplay = players.next();
            int psize = mplay.playList.size();
            if (psize < mini && psize < maxPlayingSoundsPerPool && !mplay.inListLoop) {
               mini = mplay.playList.size();
               min = mplay;
            }
         }
         if (min != null) {
            synchronized (min.soundSync) {
               min.playList.add(info);
            }
            playingSounds.incrementAndGet();
         } else {
            synchronized (queueSync) {
               queuedSounds.addLast(info);
            }
         }
      }
   }

   private SoundInfo pollQueuedSound() {
      synchronized (queueSync) {
         return queuedSounds.poll();
      }
   }

   final class Player
         extends Thread {
      List<SoundInfo> playList = new LinkedList();
      final Object soundSync = new Object();
      boolean inListLoop = false;

      Player() {
         super("IDGEngine-ASPThread");
      }

      public void stopAllSounds(boolean instant) {
         synchronized (soundSync) {
            int i = 0;
            Iterator<SoundInfo> pInfo = playList.iterator();
            while (pInfo.hasNext()) {
               SoundInfo info = pInfo.next();
               if (info.line.isOpen()) {
                  if (!instant) {
                     info.line.drain();
                  }
                  info.line.close();
                  try {
                     info.input.close();
                  } catch (IOException e) {}
               }
               pInfo.remove();
               i++;
            }
            AsyncSoundPlayer.this.playingSounds.addAndGet(-i);
         }
      }
14  Game Development / Shared Code / Asynchronous Sound Player based on JavaSound API on: 2010-06-26 16:46:28
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


package renoria.sound;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import net.idgames.archive.idx.IDXException;

/**
 * An {@link AsyncSoundPlayer} is a sound player with a thread pool using an
 * asynchronous read/write non-blocking method to play sounds concurrently
 * using a few, limited number of threads.
 * @author David
 */

public class AsyncSoundPlayer {
   private Deque<SoundInfo> queuedSounds = new LinkedList();
   private final Object poolSync = new Object();
   private final Object queueSync = new Object();
   private boolean shutDown = false;
   private List<Player> playerPool;
   private int poolsize;
   private AudioFormat playBackFormat;
   private AtomicInteger playingSounds = new AtomicInteger(0);
   private int maxPlayingSoundsPerPool = 32;
   private Mixer mixer;
   private boolean soundAvailable = false;
   private float masterVolume = 1.0f;

   /**
    * Creates a {@link AsyncSoundPlayer} with a pool size of one, and the default mixer.
    */

   public AsyncSoundPlayer() {
      this(1, null);
   }

   public AsyncSoundPlayer(int poolsize, Mixer useMixer) {
      Mixer.Info[] infos = AudioSystem.getMixerInfo();
      if (infos == null || infos.length < 1) {
         throw new SoundUnavailableException();
      }
      if (poolsize <= 0) {
         throw new IllegalArgumentException();
      }
      if (useMixer != null) {
         this.mixer = useMixer;
      } else {
         this.mixer = SoundUtil.getDefaultMixer(SoundUtil.PLAYBACK_MIXER);
      }
      this.poolsize = poolsize;
      soundAvailable = true;
      //this.playBackFormat = playBackFormat;
  }

   public float getMasterVolume() {
      return masterVolume;
   }

   public void setMasterVolume(float masterVolume) {
      this.masterVolume = masterVolume;
   }

   public void start() {
      if (!soundAvailable) {
         throw new SoundUnavailableException();
      }
      if (playerPool == null) {
         playerPool = new LinkedList();
         for (int i = 0; i < poolsize; i++) {
            Player p = new Player();
            p.start();
            playerPool.add(p);
         }
         try {
            mixer.open();
         } catch (LineUnavailableException ex) {
            throw new IDXException(ex);
         }
      } else {
         throw new IllegalStateException();
      }
   }

   /**
    * Stops the Internal Thread Pool that this {@link AsyncSoundPlayer} runs on.
    * This method blocks until all threads in the thread pool finish.
    */

   public void stop() {
      stop(0);
   }

   /**
    * Waits at most {@code maxwait} milliseconds for this {@link AsyncSoundPlayer} to die.
    * @param maxwait Max waiting time in milliseconds
    */

   public void stop(int maxwait) {
      if (playerPool != null) {
         try {
            synchronized (poolSync) {
               Iterator<Player> pItr = playerPool.iterator();
               while (pItr.hasNext()) {
                  Player p = pItr.next();
                  p.join(maxwait);
               }
            }
         } catch (InterruptedException ex) {}
         playerPool = null;
         mixer.close();
      } else {
         throw new IllegalStateException();
      }
   }

   /**
    * Sets the Pool size of this <tt>AsyncSoundPlayer</tt>.
    * <br />
    * If this method is called while the sound player is active, it will throw a {@link IllegalArgumentException}.
    * @param ps New pool size
    * @throws IllegalStateException If the sound player is still active
    */

   public void setPoolSize(int ps)
         throws IllegalStateException {
      if (playerPool != null) {
         throw new IllegalStateException();
      }
      poolsize = ps;
   }

   /**
    * Gets the pool size that this sound player uses.
    * @return Pool size
    */

   public int getPoolsize() {
      return poolsize;
   }
   
    public AudioInputStream getAudioInputStream(InputStream is) {
        try {
            if (!is.markSupported()) {
                is = new BufferedInputStream(is);
            }

            // open the source stream
           AudioInputStream source = AudioSystem.getAudioInputStream(is);

            // convert to playback format
           return playBackFormat != null ? convertStream(source) : source;
        } catch (UnsupportedAudioFileException ex) {
            throw new IDXException(ex);
        } catch (IOException ex) {
            throw new IDXException(ex);
        } catch (IllegalArgumentException ex) {
            throw new IDXException(ex);
        }
    }

   /**
    * Stops all sounds playing from this sound player.
    * @param instant Whether it should instantly stop playing, or wait until all sounds have finished playing.
    */

   public void stopAllSounds(boolean instant) {
      Iterator<Player> pItr = playerPool.iterator();
      while (pItr.hasNext()) {
         Player p = pItr.next();
         p.stopAllSounds(instant);
      }
      playingSounds.set(0);
   }

   static int getMaxDefaultMixerLines(AudioFormat format) {
      try {
         Mixer mixer = AudioSystem.getMixer(null);
         DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
         return mixer.getMaxLines(info);
      } catch (Exception e) {
         renoria.Core.handleException(e);
         return -1;
      }
   }

   private AudioInputStream convertStream(AudioInputStream stream) {
      if (playBackFormat == null) {
         return stream;
      }
      try {
         return AudioSystem.getAudioInputStream(playBackFormat, stream);
      } catch (IllegalArgumentException e) {
         renoria.Core.handleException(e);
         return stream;
      }
   }

   /**
    * Plays a sound instantly.
    * @param input Input
    * @return sound info context
    */

   public SoundInfo playSound(InputStream input) {
      return playSound(input, true);
   }



NOTE: Split into 3 posts due to character limit

Have fun, and report to me any problems you may encounter.

PS: Some exception handing and a few bits of other code are reliant on some of my other code. That code can be edited if you wish
15  Game Development / Newbie & Debugging Questions / Re: Sprite Alpha on: 2010-06-26 16:37:05
whats with all this filtering bullshit when we can just use the AlphaComposite class?!
16  Game Development / Newbie & Debugging Questions / Re: Newbie learning java by writing simple game engine using Eclipse - help needed. on: 2010-06-26 16:33:57
please, create games not game engines.
17  Games Center / Archived Projects / Re: tank defence on: 2010-04-17 12:51:40
Wow I filled every green space with a pink tower and I couldn't lose
Pages: [1]
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

E.R. Fleming (10 views)
2014-07-29 03:07:13

E.R. Fleming (4 views)
2014-07-29 03:06:25

pw (39 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21

Zero Volt (50 views)
2014-07-17 23:47:54

danieldean (42 views)
2014-07-17 23:41:23

MustardPeter (44 views)
2014-07-16 23:30:00
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!