From 336f429638f58b49ea94c57f9704e34cf71ea74c Mon Sep 17 00:00:00 2001 From: ubeefx Date: Sun, 24 Apr 2011 17:12:21 +0000 Subject: [PATCH] Added sound effects to game. --- launch4j/Readme.txt | 1 + src/magic/DeckStrCal.java | 2 +- src/magic/data/GeneralConfig.java | 15 ++++++ src/magic/data/SoundEffects.java | 51 +++++++++++++++++++ src/magic/model/MagicGame.java | 10 +++- src/magic/model/MagicTournament.java | 4 +- .../model/phase/MagicCombatDamagePhase.java | 2 + .../model/phase/MagicEndOfTurnPhase.java | 7 +++ src/magic/model/phase/MagicPhase.java | 2 + src/magic/test/TestGameBuilder.java | 4 +- src/magic/ui/GameController.java | 6 +++ src/magic/ui/MagicFrame.java | 2 +- src/magic/ui/PreferencesDialog.java | 19 ++++--- src/magic/ui/viewer/DeckStrengthViewer.java | 2 +- 14 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 src/magic/data/SoundEffects.java diff --git a/launch4j/Readme.txt b/launch4j/Readme.txt index a398682ead..d2139290cd 100644 --- a/launch4j/Readme.txt +++ b/launch4j/Readme.txt @@ -34,6 +34,7 @@ Release LE 1.13 (April 24, 2011) - default cube (600 cards) - all cube (900 cards) +- added sound effects, disabled by default, can be enabled in preferences - right mouse click on hand zone can now be used as a shortcut for action button - infect and wither abilities are also shown on cards with same icon as deathtouch diff --git a/src/magic/DeckStrCal.java b/src/magic/DeckStrCal.java index fcf5ec142e..fbc5ecb8c3 100644 --- a/src/magic/DeckStrCal.java +++ b/src/magic/DeckStrCal.java @@ -138,7 +138,7 @@ public class DeckStrCal { int played = 0; while (!testTournament.isFinished()) { - final MagicGame game=testTournament.nextGame(); + final MagicGame game=testTournament.nextGame(false); final GameController controller=new GameController(null,game); controller.runGame(); if (testTournament.getGamesPlayed() > played) { diff --git a/src/magic/data/GeneralConfig.java b/src/magic/data/GeneralConfig.java index ef2d0ae83f..bae46e8e4a 100644 --- a/src/magic/data/GeneralConfig.java +++ b/src/magic/data/GeneralConfig.java @@ -33,6 +33,7 @@ public class GeneralConfig { private static final String STRENGTH_DIFFICULTY="strengthDifficulty"; private static final String STRENGTH_GAMES="strengthGames"; private static final String HIGH_QUALITY="hq"; + private static final String SOUND="sound"; private static final int DEFAULT_LEFT=-1; private static final int DEFAULT_TOP=-1; @@ -52,6 +53,7 @@ public class GeneralConfig { private static final int DEFAULT_STRENGTH_DIFFICULTY=2; private static final int DEFAULT_STRENGTH_GAMES=123; private static final boolean DEFAULT_HIGH_QUALITY=true; + private static final boolean DEFAULT_SOUND=false; private int left=DEFAULT_LEFT; private int top=DEFAULT_TOP; @@ -71,6 +73,7 @@ public class GeneralConfig { private int strengthDifficulty=DEFAULT_STRENGTH_DIFFICULTY; private int strengthGames=DEFAULT_STRENGTH_GAMES; private boolean highQuality=DEFAULT_HIGH_QUALITY; + private boolean sound=DEFAULT_SOUND; private GeneralConfig() { @@ -262,6 +265,16 @@ public class GeneralConfig { this.highQuality=highQuality; } + public boolean isSound() { + + return sound; + } + + public void setSound(final boolean sound) { + + this.sound=sound; + } + public void load(final Properties properties) { left=Integer.parseInt(properties.getProperty(LEFT,""+DEFAULT_LEFT)); @@ -282,6 +295,7 @@ public class GeneralConfig { strengthDifficulty=Integer.parseInt(properties.getProperty(STRENGTH_DIFFICULTY,""+DEFAULT_STRENGTH_DIFFICULTY)); strengthGames=Integer.parseInt(properties.getProperty(STRENGTH_GAMES,""+DEFAULT_STRENGTH_GAMES)); highQuality=Boolean.parseBoolean(properties.getProperty(HIGH_QUALITY,""+DEFAULT_HIGH_QUALITY)); + sound=Boolean.parseBoolean(properties.getProperty(SOUND,""+DEFAULT_SOUND)); } public void load() { @@ -313,6 +327,7 @@ public class GeneralConfig { properties.setProperty(STRENGTH_DIFFICULTY,String.valueOf(strengthDifficulty)); properties.setProperty(STRENGTH_GAMES,String.valueOf(strengthGames)); properties.setProperty(HIGH_QUALITY,String.valueOf(highQuality)); + properties.setProperty(SOUND,String.valueOf(sound)); } public void save() { diff --git a/src/magic/data/SoundEffects.java b/src/magic/data/SoundEffects.java new file mode 100644 index 0000000000..e488318913 --- /dev/null +++ b/src/magic/data/SoundEffects.java @@ -0,0 +1,51 @@ +package magic.data; + +import java.io.File; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; + +import magic.MagicMain; +import magic.model.MagicGame; + +public class SoundEffects { + + public static final String WIN_SOUND="win.au"; + public static final String LOSE_SOUND="lose.au"; + public static final String TURN_SOUND="turn.au"; + public static final String RESOLVE_SOUND="resolve.au"; + public static final String COMBAT_SOUND="combat.au"; + + private static final File SOUNDS_PATH=new File(MagicMain.getGamePath(),"sounds"); + private static final SoundEffects INSTANCE=new SoundEffects(); + + private SoundEffects() { + + } + + public void playClip(final String name) { + + if (GeneralConfig.getInstance().isSound()) { + try { + final Clip clip=AudioSystem.getClip(); + final AudioInputStream inputStream=AudioSystem.getAudioInputStream(new File(SOUNDS_PATH,name)); + clip.open(inputStream); + inputStream.close(); + clip.start(); + } catch (Exception e) {} + } + } + + public void playClip(final MagicGame game,final String name) { + + if (game.isSound()) { + playClip(name); + } + } + + public static SoundEffects getInstance() { + + return INSTANCE; + } +} \ No newline at end of file diff --git a/src/magic/model/MagicGame.java b/src/magic/model/MagicGame.java index 3cc34597ad..cae83a12af 100644 --- a/src/magic/model/MagicGame.java +++ b/src/magic/model/MagicGame.java @@ -58,6 +58,7 @@ public class MagicGame { private final MagicEventQueue events; private final MagicStack stack; private final MagicPlayer scorePlayer; + private final boolean sound; private long identifiers[]; private int score=0; private int turn=1; @@ -82,12 +83,13 @@ public class MagicGame { private final MagicLogBook logBook; private final MagicLogMessageBuilder logMessageBuilder; - public MagicGame(final MagicTournament tournament,final MagicGameplay gameplay,final MagicPlayer players[],final MagicPlayer startPlayer) { + public MagicGame(final MagicTournament tournament,final MagicGameplay gameplay,final MagicPlayer players[],final MagicPlayer startPlayer,final boolean sound) { artificial=false; this.tournament=tournament; this.gameplay=gameplay; this.players=players; + this.sound=sound; identifiers=new long[MagicIdentifierType.NR_OF_IDENTIFIERS]; triggers=new MagicPermanentTriggerMap(); turnTriggers=new MagicPermanentTriggerList(); @@ -108,6 +110,7 @@ public class MagicGame { public MagicGame(final MagicGame game,final MagicPlayer scorePlayer) { artificial=true; + sound=false; final MagicCopyMap copyMap=new MagicCopyMap(); this.tournament=game.tournament; this.gameplay=game.gameplay; @@ -198,6 +201,11 @@ public class MagicGame { return artificial; } + public boolean isSound() { + + return sound; + } + public void setFastChoices(final boolean fastChoices) { this.fastChoices=fastChoices; diff --git a/src/magic/model/MagicTournament.java b/src/magic/model/MagicTournament.java index 8fabb49b7d..d2c4be0088 100644 --- a/src/magic/model/MagicTournament.java +++ b/src/magic/model/MagicTournament.java @@ -182,12 +182,12 @@ public class MagicTournament { return players; } - public MagicGame nextGame() { + public MagicGame nextGame(final boolean sound) { final MagicPlayer player=new MagicPlayer(configuration,playerDefinitions[0],0); final MagicPlayer opponent=new MagicPlayer(configuration,playerDefinitions[opponentIndex],1); final MagicPlayer start=startPlayer==0?player:opponent; - return new MagicGame(this,MagicDefaultGameplay.getInstance(),new MagicPlayer[]{player,opponent},start); + return new MagicGame(this,MagicDefaultGameplay.getInstance(),new MagicPlayer[]{player,opponent},start,sound); } public int getNrOfPlayers() { diff --git a/src/magic/model/phase/MagicCombatDamagePhase.java b/src/magic/model/phase/MagicCombatDamagePhase.java index fe632693e5..4768b03f40 100644 --- a/src/magic/model/phase/MagicCombatDamagePhase.java +++ b/src/magic/model/phase/MagicCombatDamagePhase.java @@ -1,5 +1,6 @@ package magic.model.phase; +import magic.data.SoundEffects; import magic.model.MagicGame; import magic.model.MagicPlayer; import magic.model.action.MagicCombatDamageAction; @@ -41,5 +42,6 @@ public class MagicCombatDamagePhase extends MagicPhase { game.logMessage(defendingPlayer,"{c}"+message.toString()); } game.setStep(MagicStep.NextPhase); + SoundEffects.getInstance().playClip(game,SoundEffects.COMBAT_SOUND); } } \ No newline at end of file diff --git a/src/magic/model/phase/MagicEndOfTurnPhase.java b/src/magic/model/phase/MagicEndOfTurnPhase.java index 6f4ab32b37..38a6c7a7b7 100644 --- a/src/magic/model/phase/MagicEndOfTurnPhase.java +++ b/src/magic/model/phase/MagicEndOfTurnPhase.java @@ -1,5 +1,6 @@ package magic.model.phase; +import magic.data.SoundEffects; import magic.model.MagicGame; import magic.model.MagicPermanent; import magic.model.MagicPlayer; @@ -46,4 +47,10 @@ public class MagicEndOfTurnPhase extends MagicPhase { game.executeTrigger(MagicTriggerType.AtEndOfTurn,game.getTurnPlayer()); game.setStep(MagicStep.ActivePlayer); } + + @Override + protected void executeEndOfPhase(final MagicGame game) { + + SoundEffects.getInstance().playClip(game,SoundEffects.TURN_SOUND); + } } \ No newline at end of file diff --git a/src/magic/model/phase/MagicPhase.java b/src/magic/model/phase/MagicPhase.java index dd904b7026..fe7fce5fd7 100644 --- a/src/magic/model/phase/MagicPhase.java +++ b/src/magic/model/phase/MagicPhase.java @@ -1,5 +1,6 @@ package magic.model.phase; +import magic.data.SoundEffects; import magic.model.MagicGame; import magic.model.action.MagicStackResolveAction; import magic.model.event.MagicPriorityEvent; @@ -42,6 +43,7 @@ public abstract class MagicPhase { // Stack can be empty at this point, for instance by a counter unless event. if (!game.getStack().isEmpty()) { game.doAction(new MagicStackResolveAction()); + SoundEffects.getInstance().playClip(game,SoundEffects.RESOLVE_SOUND); } if (game.isArtificial()) { // Resolve stack in one go. diff --git a/src/magic/test/TestGameBuilder.java b/src/magic/test/TestGameBuilder.java index 880452818d..38ed520204 100644 --- a/src/magic/test/TestGameBuilder.java +++ b/src/magic/test/TestGameBuilder.java @@ -107,11 +107,11 @@ public class TestGameBuilder { tournament.setPlayers(new MagicPlayerDefinition[]{player1,player2}); tournament.setStartPlayer(0); - final MagicGame game=tournament.nextGame(); + final MagicGame game=tournament.nextGame(true); game.setPhase(MagicMainPhase.getFirstInstance()); final MagicPlayer player=game.getPlayer(0); final MagicPlayer opponent=game.getPlayer(1); - opponent.setLife(12); + opponent.setLife(1); addToLibrary(player,"Plains",10); addToLibrary(opponent,"Island",10); diff --git a/src/magic/ui/GameController.java b/src/magic/ui/GameController.java index 1a68a9e87b..16c54b7700 100644 --- a/src/magic/ui/GameController.java +++ b/src/magic/ui/GameController.java @@ -15,6 +15,7 @@ import javax.swing.SwingUtilities; import magic.ai.MagicAI; import magic.data.GeneralConfig; import magic.data.IconImages; +import magic.data.SoundEffects; import magic.model.MagicCard; import magic.model.MagicCardDefinition; import magic.model.MagicGame; @@ -434,6 +435,11 @@ public class GameController { game.logMessages(); clearValidChoices(); showMessage(null,"{L} "+game.getLosingPlayer()+" "+(gameConceded?"conceded":"lost")+" the game.|Press {f} to continue."); + if (game.getLosingPlayer().getIndex()==0) { + SoundEffects.getInstance().playClip(SoundEffects.LOSE_SOUND); + } else { + SoundEffects.getInstance().playClip(SoundEffects.WIN_SOUND); + } enableForwardButton(); if (waitForInputOrUndo()) { performUndo(); diff --git a/src/magic/ui/MagicFrame.java b/src/magic/ui/MagicFrame.java index 5f237e8048..d18e0b7b05 100644 --- a/src/magic/ui/MagicFrame.java +++ b/src/magic/ui/MagicFrame.java @@ -388,7 +388,7 @@ public class MagicFrame extends JFrame implements ActionListener { public void nextGame() { tournament.updateDifficulty(); - openGame(tournament.nextGame()); + openGame(tournament.nextGame(true)); } private void openGame(final MagicGame game) { diff --git a/src/magic/ui/PreferencesDialog.java b/src/magic/ui/PreferencesDialog.java index ba5a47df55..3c6bf89097 100644 --- a/src/magic/ui/PreferencesDialog.java +++ b/src/magic/ui/PreferencesDialog.java @@ -31,6 +31,7 @@ public class PreferencesDialog extends JDialog implements ActionListener { private final JComboBox themeComboBox; private final JComboBox avatarComboBox; private final JComboBox aiComboBox; + private final JCheckBox soundCheckBox; private final JCheckBox highQualityCheckBox; private final JCheckBox skipSingleCheckBox; private final JCheckBox alwaysPassCheckBox; @@ -43,7 +44,7 @@ public class PreferencesDialog extends JDialog implements ActionListener { super(frame,true); this.setTitle("Preferences"); - this.setSize(400,390); + this.setSize(400,420); this.setLocationRelativeTo(frame); this.setResizable(false); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); @@ -101,29 +102,34 @@ public class PreferencesDialog extends JDialog implements ActionListener { aiComboBox.setBounds(100,90,255,25); aiComboBox.setSelectedItem(config.getAi()); mainPanel.add(aiComboBox); + + soundCheckBox=new JCheckBox("Enable sound effects",config.isSound()); + soundCheckBox.setBounds(25,135,350,20); + soundCheckBox.setFocusable(false); + mainPanel.add(soundCheckBox); highQualityCheckBox=new JCheckBox("High quality card popup images",config.isHighQuality()); - highQualityCheckBox.setBounds(25,135,350,20); + highQualityCheckBox.setBounds(25,165,350,20); highQualityCheckBox.setFocusable(false); mainPanel.add(highQualityCheckBox); skipSingleCheckBox=new JCheckBox("Skip single option choices when appropriate",config.getSkipSingle()); - skipSingleCheckBox.setBounds(25,165,350,20); + skipSingleCheckBox.setBounds(25,195,350,20); skipSingleCheckBox.setFocusable(false); mainPanel.add(skipSingleCheckBox); alwaysPassCheckBox=new JCheckBox("Always pass during draw and begin of combat step",config.getAlwaysPass()); - alwaysPassCheckBox.setBounds(25,195,350,20); + alwaysPassCheckBox.setBounds(25,225,350,20); alwaysPassCheckBox.setFocusable(false); mainPanel.add(alwaysPassCheckBox); smartTargetCheckBox=new JCheckBox("Filter legal targets when appropriate",config.getSmartTarget()); - smartTargetCheckBox.setBounds(25,225,350,20); + smartTargetCheckBox.setBounds(25,255,350,20); smartTargetCheckBox.setFocusable(false); mainPanel.add(smartTargetCheckBox); popupDelaySlider=new SliderPanel("Popup",IconImages.DELAY,0,500,50,config.getPopupDelay()); - popupDelaySlider.setBounds(60,255,270,50); + popupDelaySlider.setBounds(60,285,270,50); mainPanel.add(popupDelaySlider); getContentPane().setLayout(new BorderLayout()); @@ -142,6 +148,7 @@ public class PreferencesDialog extends JDialog implements ActionListener { config.setTheme((String)themeComboBox.getSelectedItem()); config.setAvatar((String)avatarComboBox.getSelectedItem()); config.setAi((String)aiComboBox.getSelectedItem()); + config.setSound(soundCheckBox.isSelected()); config.setHighQuality(highQualityCheckBox.isSelected()); config.setSkipSingle(skipSingleCheckBox.isSelected()); config.setAlwaysPass(alwaysPassCheckBox.isSelected()); diff --git a/src/magic/ui/viewer/DeckStrengthViewer.java b/src/magic/ui/viewer/DeckStrengthViewer.java index 6427d9e8a1..2233ae1bd2 100644 --- a/src/magic/ui/viewer/DeckStrengthViewer.java +++ b/src/magic/ui/viewer/DeckStrengthViewer.java @@ -214,7 +214,7 @@ public class DeckStrengthViewer extends JPanel implements ActionListener { while (running.get()&&!testTournament.isFinished()) { gameLabel.setText("Game "+(testTournament.getGamesPlayed()+1)); - final MagicGame game=testTournament.nextGame(); + final MagicGame game=testTournament.nextGame(false); controller=new GameController(null,game); controller.runGame(); progressBar.setValue(testTournament.getGamesPlayed());