Merge pull request #236 from Noahsark/master

Added music player that can if activated in preferences play music during the game. Added random background chooser (both developed by Noahsark).
This commit is contained in:
LevelX2 2013-06-13 23:04:50 -07:00
commit 043fa36618
7 changed files with 261 additions and 27 deletions

View file

@ -123,6 +123,21 @@
<version>7.6.3</version>
<!--<scope>runtime</scope>-->
</dependency>
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5-1</version>
</dependency>
<dependency>
<groupId>javazoom</groupId>
<artifactId>jlayer</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.mobicents.external.tritonus</groupId>
<artifactId>tritonus_share</artifactId>
<version>0.3.6</version>
</dependency>
</dependencies>
<build>

View file

@ -66,6 +66,7 @@ import mage.client.tournament.TournamentPanel;
import mage.client.util.EDTExceptionHandler;
import mage.client.util.SettingsManager;
import mage.client.util.gui.ArrowBuilder;
import mage.client.util.MusicPlayer;
import mage.components.ImagePanel;
import mage.interfaces.Action;
import mage.interfaces.MageClient;
@ -540,10 +541,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
ArrowBuilder.getBuilder().hideAllPanels();
if (frame instanceof GamePane) {
ArrowBuilder.getBuilder().showPanel(((GamePane) frame).getGameId());
MusicPlayer.playBGM();
}else{
MusicPlayer.stopBGM();
}
}
public static void deactivate(MagePane frame) {
//MusicPlayer.stopBGM();
frame.setVisible(false);
MagePane topmost = getTopMost(frame);
if (activeFrame != frame) {

View file

@ -80,7 +80,8 @@ public final class Constants {
public static final String RESOURCE_PATH_SET = IO.imageBaseDir + "sets" + File.separator;
public static final String RESOURCE_PATH_SET_SMALL = RESOURCE_PATH_SET + File.separator + "small" + File.separator;
public static final String BASE_SOUND_PATH = "plugins" + File.separator + "sounds" + File.separator;
public static final String BASE_MUSICS_PATH = "plugins" + File.separator + "sounds" + File.separator + "musics" + File.separator ;
public interface IO {
String imageBaseDir = "plugins" + File.separator + "images" + File.separator;
String IMAGE_PROPERTIES_FILE = "image.url.properties";

View file

@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
@ -7,6 +7,7 @@
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
@ -25,7 +26,7 @@
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jTabbedPane1" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<EmptySpace pref="316" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="saveButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="exitButton" min="-2" pref="55" max="-2" attributes="0"/>
@ -81,7 +82,7 @@
<Component id="jPanel3" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jPanel7" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="84" max="32767" attributes="0"/>
<EmptySpace pref="92" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -443,7 +444,7 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jPanel5" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="92" max="32767" attributes="0"/>
<EmptySpace pref="96" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -562,7 +563,10 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Component id="jEnableSounds" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jEnableSounds" min="-2" max="-2" attributes="0"/>
<Component id="jEnableMusics" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="325" max="32767" attributes="0"/>
</Group>
</Group>
@ -572,7 +576,9 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
<Component id="jEnableSounds" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="217" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jEnableMusics" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="194" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -586,6 +592,14 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEnableSoundsActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="jEnableMusics">
<Properties>
<Property name="text" type="java.lang.String" value="enable BGM"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jEnableMusicsActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel6">

View file

@ -73,6 +73,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_CARD_IMAGES_SAVE_TO_ZIP = "cardImagesSaveToZip";
public static final String KEY_SOUNDS_ON = "soundsOn";
public static final String KEY_MUSICS_ON = "MusicsOn";
public static final String KEY_BIG_CARD_TOGGLED = "bigCardToggled";
@ -201,6 +202,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
saveToZipFiles = new javax.swing.JCheckBox();
jPanel22 = new javax.swing.JPanel();
jEnableSounds = new javax.swing.JCheckBox();
jEnableMusics = new javax.swing.JCheckBox();
jPanel6 = new javax.swing.JPanel();
lblProxyType = new javax.swing.JLabel();
cbProxyType = new javax.swing.JComboBox();
@ -322,7 +324,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(84, Short.MAX_VALUE))
.addContainerGap(92, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Main", jPanel1);
@ -537,7 +539,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGroup(jPanel4Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(92, Short.MAX_VALUE))
.addContainerGap(96, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Images", jPanel4);
@ -549,13 +551,22 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
jEnableMusics.setText("enable BGM");
jEnableMusics.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jEnableMusicsActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel22Layout = new javax.swing.GroupLayout(jPanel22);
jPanel22.setLayout(jPanel22Layout);
jPanel22Layout.setHorizontalGroup(
jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel22Layout.createSequentialGroup()
.addGap(19, 19, 19)
.addComponent(jEnableSounds)
.addGroup(jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jEnableSounds)
.addComponent(jEnableMusics))
.addContainerGap(325, Short.MAX_VALUE))
);
jPanel22Layout.setVerticalGroup(
@ -563,7 +574,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGroup(jPanel22Layout.createSequentialGroup()
.addGap(24, 24, 24)
.addComponent(jEnableSounds)
.addContainerGap(217, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jEnableMusics)
.addContainerGap(194, Short.MAX_VALUE))
);
jTabbedPane1.addTab("Sounds", jPanel22);
@ -605,7 +618,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
jLabel11.setFont(new java.awt.Font("Tahoma", 2, 10));
jLabel11.setFont(new java.awt.Font("Tahoma", 2, 10)); // NOI18N
jLabel11.setText("Note: password won't be encrypted!");
javax.swing.GroupLayout pnlProxyLayout = new javax.swing.GroupLayout(pnlProxy);
@ -747,7 +760,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGap(0, 100, Short.MAX_VALUE)
);
jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11));
jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
jLabel12.setText("Choose your avatar:");
jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
@ -789,7 +802,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGap(0, 100, Short.MAX_VALUE)
);
jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11));
jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
jLabel13.setText("New avatars:");
jPanel16.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
@ -975,7 +988,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jTabbedPane1)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(316, Short.MAX_VALUE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(saveButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(exitButton, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
@ -1028,7 +1041,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
// sounds
save(prefs, dialog.jEnableSounds, KEY_SOUNDS_ON, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.jEnableMusics, KEY_MUSICS_ON, "true", "false", UPDATE_CACHE_POLICY);
// connection
save(prefs, dialog.cbProxyType, KEY_PROXY_TYPE);
save(prefs, dialog.txtProxyServer, KEY_PROXY_ADDRESS);
@ -1124,6 +1137,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
// TODO add your handling code here:
}//GEN-LAST:event_jEnableSoundsActionPerformed
private void jEnableMusicsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEnableMusicsActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_jEnableMusicsActionPerformed
private void showProxySettings() {
if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) {
this.pnlProxy.setVisible(true);
@ -1231,6 +1248,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
} else {
dialog.jEnableSounds.setSelected(false);
}
prop = prefs.get(KEY_MUSICS_ON, "true");
if (prop.equals("true")) {
dialog.jEnableMusics.setSelected(true);
} else {
dialog.jEnableMusics.setSelected(false);
}
}
private static void loadProxySettings(Preferences prefs) {
@ -1449,6 +1472,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox displayBigCardsInHand;
private javax.swing.JButton exitButton;
private javax.swing.JTextField imageFolderPath;
private javax.swing.JCheckBox jEnableMusics;
private javax.swing.JCheckBox jEnableSounds;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;

View file

@ -0,0 +1,152 @@
package mage.client.util;
import java.io.File;
import java.awt.List;
import javax.sound.sampled.*;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
import org.apache.log4j.Logger;
/**
*
* @author renli
*/
public class MusicPlayer {
private static final Logger log = Logger.getLogger(AudioManager.class);
String filepath;
String filename;
List filelist = new List();
static MusicPlayer player = null;
//open file and add list
private boolean open(){
filepath = Constants.BASE_MUSICS_PATH;
filelist.removeAll();
File filedir = new File(filepath);
File[] fileread = filedir.listFiles();
if(fileread.length == 0)return false;
String filename;
for(File f:fileread){
filename = f.getName().toLowerCase();
if(filename.endsWith(".mp3") || filename.endsWith(".wav")){
filelist.add(filename);
}
}
if(filelist.getItemCount() == 0) return false;
return true;
}
public static void playBGM(){
stopBGM();
if(player == null){
player = new MusicPlayer();
}
if(player.open()){
player.play();
}
}
public void play(){
String soundsOn = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MUSICS_ON, "true");
if(soundsOn.equals("true")){
player.breaked = false;
player.breaked_out = false;
player.stopped = false;
Thread player = new Thread(new playerThread());
player.start();
}
}
public static void stopBGM(){
if(player != null){
player.stopped = true;
player.breaked_out = true;
player.breaked = true;
try {
Thread.sleep(100);
} catch (Exception e) {
log.error("Thread error: " + e);
}
}
}
public volatile boolean breaked = false;
public volatile boolean breaked_out = false;
public volatile boolean stopped = false;
public volatile FloatControl volume;
AudioInputStream audioInputStream;
AudioFormat audioFormat;
SourceDataLine sourceDataLine;
class playerThread extends Thread{
private void load(File file){
try{
audioInputStream = AudioSystem.getAudioInputStream(file);
audioFormat = audioInputStream.getFormat();
// mp3 decode
if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(), 16, audioFormat.getChannels(), audioFormat.getChannels() * 2,
audioFormat.getSampleRate(), false);
audioInputStream = AudioSystem.getAudioInputStream(audioFormat, audioInputStream);
}
//output
DataLine.Info dataLineInfo = new DataLine.Info(
SourceDataLine.class, audioFormat,
AudioSystem.NOT_SPECIFIED);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
volume = (FloatControl)sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
sourceDataLine.start();
}catch(Exception e){
log.error("Couldn't load file: " + file + " " + e);
}
}
public void run(){
try {
Thread.sleep(100);
} catch (Exception e) {
}
while(!stopped){
int it = (int)Math.abs(Math.random()*(filelist.getItemCount()));
File file = new File(filepath + filelist.getItem(it));
load(file);
Thread PlayThread = new Thread(new PlayThread());
PlayThread.start();
while (!(breaked || breaked_out)) {
try {
Thread.sleep(10);
} catch (Exception e) {
log.error("Thread error: " + e);
}
}
breaked = false;
}
}
};
class PlayThread extends Thread{
byte tempBuffer[] = new byte[320];
public void run(){
try{
int len;
while ((len = audioInputStream.read(tempBuffer, 0,
tempBuffer.length)) != -1){
if(breaked_out) break;
if(len > 0) sourceDataLine.write(tempBuffer, 0, len);
}
//breaked or stopped
sourceDataLine.flush();
sourceDataLine.close();
breaked = true;
}catch(Exception e){
log.error("Thread error: " + e);
}
}
};
}

View file

@ -12,6 +12,7 @@ import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Map;
@ -22,7 +23,9 @@ public class ThemePluginImpl implements ThemePlugin {
private static final Logger log = Logger.getLogger(ThemePluginImpl.class);
private static BufferedImage background;
private List flist = new List();
private String BackgroundDir = "plugins" + File.separator + "plugin.data" + File.separator
+ "background" + File.separator;
@Init
public void init() {
}
@ -36,17 +39,37 @@ public class ThemePluginImpl implements ThemePlugin {
return "[Theme plugin, version 0.5]";
}
public void applyInGame(Map<String, JComponent> ui) {
String filename = "/dragon.png";
try {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
public boolean loadimages(){
File filedir = new File(BackgroundDir);
File[] filelist = filedir.listFiles();
if(filelist == null) return false;
if(filelist.length == 0) return false;
for(File f:filelist){
String filename = f.getName().toLowerCase();
if(filename != null && (filename.endsWith(".png") || filename.endsWith(".jpg")
|| filename.endsWith(".bmp"))){
flist.add(filename);
}
BufferedImage background = ImageIO.read(is);
}
if(flist.getItemCount() == 0) return false;
return true;
}
public void applyInGame(Map<String, JComponent> ui) {
String filename;
BufferedImage background;
try {
if(loadimages()){
int it = (int)Math.abs(Math.random()*(flist.getItemCount()));
filename = BackgroundDir + flist.getItem(it);
background = ImageIO.read(new File(filename));
}else{
filename = "/dragon.png";
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null)
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
background = ImageIO.read(is);
}
if (background == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}