diff --git a/core/assets/common/screen/gamemenu/sfx/ambient.mp3 b/core/assets/common/screen/gamemenu/sfx/ambient.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..40471c1831e84c74df53992b94ab29e3e21958ec Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/ambient.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/bankovniloupez_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/bankovniloupez_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b702a4bb65d0b21f2ed1d65584fb5eb934af56e4 Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/bankovniloupez_intro.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/nocnisledovani_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/nocnisledovani_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c2755b3499e92210e007a50eda83565049a54b0c Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/nocnisledovani_intro.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/potme_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/potme_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..400c3ec19d1c6b6c57439cc28fbb692286902acf Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/potme_intro.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/pronasledovani_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/pronasledovani_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..56d0a5c8b40fb2a95b41503713e07c72d3e138a6 Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/pronasledovani_intro.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/step_1_2.mp3 b/core/assets/common/screen/gamemenu/sfx/step_1_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..1f64e195a7da388d030b8d76279168de75c439da Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/step_1_2.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/step_2_1.mp3 b/core/assets/common/screen/gamemenu/sfx/step_2_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..822cbad02fa83e76ccbb7e89a1884fbc75dbc653 Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/step_2_1.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/step_2_3.mp3 b/core/assets/common/screen/gamemenu/sfx/step_2_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..715a10d30137e2a6f6a4b4e655f275fe6932c36e Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/step_2_3.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/step_3_2.mp3 b/core/assets/common/screen/gamemenu/sfx/step_3_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..679b7d33ff30c8112a9461995299a66434941001 Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/step_3_2.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/strelnice_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/strelnice_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..5c71704892906451320ca14085ac867505967920 Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/strelnice_intro.mp3 differ diff --git a/core/assets/common/screen/gamemenu/sfx/unos_intro.mp3 b/core/assets/common/screen/gamemenu/sfx/unos_intro.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..ff08ee212ba82955d6502aa76fd2989aeb1ff4ab Binary files /dev/null and b/core/assets/common/screen/gamemenu/sfx/unos_intro.mp3 differ diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java index 10b6ad395fd98e73330d46baf20dc43337f91607..4059798910bc0adc9552d76e631e26a9812c5788 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuAssets.java @@ -1,11 +1,5 @@ package cz.nic.tablexia.screen.gamemenu; -import java.util.ArrayList; -import java.util.List; - -import cz.nic.tablexia.game.GameDefinition; -import cz.nic.tablexia.menu.game.GameMenuDefinition; - /** * Created by lhoracek on 3/11/15. * Edited by Drahomir Karchnak @@ -15,29 +9,86 @@ public final class GameMenuAssets { } public static final String GFX_PATH = "gfx/"; + public static final String SFX_PATH = "sfx/"; - public static final String OFFICE = GFX_PATH + "office"; - public static final String OFFICE_HALLOFFAME = GFX_PATH + "office_halloffame"; - public static final String OFFICE_CLICKMAP = GFX_PATH + "clickablemap"; - public static final String OFFICE_HELP = GFX_PATH + "helplayer"; - public static final String OVERLAY = GFX_PATH + "overlay"; - public static final String VIGNETTE = GFX_PATH + "vignetting"; - public static final String DESK = GFX_PATH + "desk"; + public static final String OFFICE = GFX_PATH + "office"; + public static final String OFFICE_HALLOFFAME = GFX_PATH + "office_halloffame"; + public static final String OFFICE_CLICKMAP = GFX_PATH + "clickablemap"; + public static final String OFFICE_HELP = GFX_PATH + "helplayer"; + public static final String OVERLAY = GFX_PATH + "overlay"; + public static final String VIGNETTE = GFX_PATH + "vignetting"; + public static final String DESK = GFX_PATH + "desk"; public static final String ENCYCLOPEDIA_PRESSED = GFX_PATH + "encyclopedia_pressed"; - public static final String HALLOFFAME_PRESSED = GFX_PATH + "halloffame_pressed"; - public static final String STATISTICS_PRESSED = GFX_PATH + "statistics_pressed"; - public static final String DOOR_PRESSED = GFX_PATH + "streetdoor_pressed"; - public static final String PROFILE_PRESSED = GFX_PATH + "profile_pressed"; - - public static final String HELP_BUTTON_PRESSED = GFX_PATH + "helpbutton_pressed"; - public static final String HELP_BUTTON_RELEASE = GFX_PATH + "helpbutton_unpressed"; - - public static final String DIFF_BAR = GFX_PATH + "difficultyseekbar_background"; - public static final String DIFF_THUMB = GFX_PATH + "difficultyseekbar_thumb"; - public static final String DIFF_THUMB_EASY = GFX_PATH + "difficultyseekbar_thumb_easy"; - public static final String DIFF_THUMB_HARD = GFX_PATH + "difficultyseekbar_thumb_hard"; + public static final String HALLOFFAME_PRESSED = GFX_PATH + "halloffame_pressed"; + public static final String STATISTICS_PRESSED = GFX_PATH + "statistics_pressed"; + public static final String DOOR_PRESSED = GFX_PATH + "streetdoor_pressed"; + public static final String PROFILE_PRESSED = GFX_PATH + "profile_pressed"; + + public static final String HELP_BUTTON_PRESSED = GFX_PATH + "helpbutton_pressed"; + public static final String HELP_BUTTON_RELEASE = GFX_PATH + "helpbutton_unpressed"; + + public static final String DIFF_BAR = GFX_PATH + "difficultyseekbar_background"; + public static final String DIFF_THUMB = GFX_PATH + "difficultyseekbar_thumb"; + public static final String DIFF_THUMB_EASY = GFX_PATH + "difficultyseekbar_thumb_easy"; + public static final String DIFF_THUMB_HARD = GFX_PATH + "difficultyseekbar_thumb_hard"; public static final String DIFF_THUMB_MEDIUM = GFX_PATH + "difficultyseekbar_thumb_medium"; - public static final String WALL_MID = GFX_PATH + "wall_mid"; + public static final String BASE_ASSETS_ROBBERY = "bankovniloupez"; + public static final String BASE_ASSETS_PURSUIT = "pronasledovani"; + public static final String BASE_ASSETS_KIDNAPPING = "unos"; + public static final String BASE_ASSETS_NIGHT_WATCH = "nocnisledovani"; + public static final String BASE_ASSETS_SHOOTING_RANGE = "strelnice"; + public static final String BASE_ASSETS_IN_THE_DARKNESS = "potme"; + + public static final String BASE_ASSETS_FOREGROUND_POSTFIX = "fore"; + public static final String BASE_ASSETS_MIDDLE_POSTFIX = "mid"; + public static final String BASE_ASSETS_BACKGROUND_POSTFIX = "back"; + public static final String BASE_ASSETS_TITLE_POSTFIX = "title"; + public static final String BASE_ASSETS_START_BUTTON_RELEASED_POSTFIX = "startbutton"; + public static final String BASE_ASSETS_START_BUTTON_PRESSED_POSTFIX = "startbutton_pressed"; + public static final String BASE_ASSETS_INTRO_SOUND_POSTFIX = "intro.mp3"; + + public static final String WALL_MID = GFX_PATH + "wall_mid"; public static final String WALL_BACK = GFX_PATH + "wall_back"; -} \ No newline at end of file + + public static final String STEP_EASY_MEDIUM = SFX_PATH + "step_1_2.mp3"; + public static final String STEP_MEDIUM_EASY = SFX_PATH + "step_2_1.mp3"; + public static final String STEP_MEDIUM_HARD = SFX_PATH + "step_2_3.mp3"; + public static final String STEP_HARD_MEDIUM = SFX_PATH + "step_3_2.mp3"; + + public static final String AMBIENT_MUSIC = SFX_PATH + "ambient.mp3"; + + /** + * This enum represents all type of assets for GameMenuPage + * Both graphics and sounds are included + * + * field folder tells you in which folder the file is in... for example "gfx/" + * field postFix tells you whats the post fix of the file... for example "_mid" + * + */ + public enum AssetType { + FORE (GFX_PATH, BASE_ASSETS_FOREGROUND_POSTFIX), + MID (GFX_PATH, BASE_ASSETS_MIDDLE_POSTFIX), + BACK (GFX_PATH, BASE_ASSETS_BACKGROUND_POSTFIX), + TITLE (GFX_PATH, BASE_ASSETS_TITLE_POSTFIX), + STARTBUTTON (GFX_PATH, BASE_ASSETS_START_BUTTON_RELEASED_POSTFIX), + STARTBUTTON_PRESSED (GFX_PATH, BASE_ASSETS_START_BUTTON_PRESSED_POSTFIX), + INTRO (SFX_PATH, BASE_ASSETS_INTRO_SOUND_POSTFIX); + + private String folder; + private String postFix; + + AssetType(String folder, String postFix) { + this.folder = folder; + this.postFix = postFix; + } + + public String getFolder() { + return folder; + } + + public String getPostFix() { + return postFix; + } + } +} diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java index 0f2946f0c0b382c83550757971ed675010286a52..4ff58a229c5d3f2a1ca261fa28680f45b8037d67 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java @@ -1,6 +1,8 @@ package cz.nic.tablexia.screen.gamemenu; +import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.ui.Image; @@ -18,6 +20,7 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.gamemenu.actions.ScrollHomeAction; import cz.nic.tablexia.screen.gamemenu.event.ShowGameMenuPageEvent; import cz.nic.tablexia.screen.gamemenu.pages.GameMenuPage; +import cz.nic.tablexia.screen.gamemenu.pages.MenuPage; import cz.nic.tablexia.screen.gamemenu.pages.OfficeMenuPage; import cz.nic.tablexia.screen.gamemenu.pages.WallPage; import cz.nic.tablexia.util.Utility; @@ -30,23 +33,16 @@ import cz.nic.tablexia.util.ui.PagedScrollPane; public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { public static final String SCREEN_STATE_PAGE_NUMBER = "pageNumber"; - public enum GameMenuLayers { - FORE, - MID, - BACK, - TITLE, - STARTBUTTON, - STARTBUTTON_PRESSED - } + private Music ambientMusic; public enum GameMenuPageDefinition { OFFICE_PAGE(0, null, null), - ROBBERY_PAGE(1, GameDefinition.ROBBERY, "bankovniloupez"), - PURSUIT_PAGE(2, GameDefinition.PURSUIT, "pronasledovani"), - KIDNAPPING_PAGE(3, GameDefinition.KIDNAPPING, "unos"), - NIGH_WATCH_PAGE(4, GameDefinition.NIGHT_WATCH, "nocnisledovani"), - SHOOTING_RANGE_PAGE(5, GameDefinition.SHOOTING_RANGE, "strelnice"), - IN_THE_DARKNESS_PAGE(6, GameDefinition.IN_THE_DARKNESS, "potme"); + ROBBERY_PAGE( 1, GameDefinition.ROBBERY, GameMenuAssets.BASE_ASSETS_ROBBERY), + PURSUIT_PAGE( 2, GameDefinition.PURSUIT, GameMenuAssets.BASE_ASSETS_PURSUIT), + KIDNAPPING_PAGE( 3, GameDefinition.KIDNAPPING, GameMenuAssets.BASE_ASSETS_KIDNAPPING), + NIGH_WATCH_PAGE( 4, GameDefinition.NIGHT_WATCH, GameMenuAssets.BASE_ASSETS_NIGHT_WATCH), + SHOOTING_RANGE_PAGE( 5, GameDefinition.SHOOTING_RANGE, GameMenuAssets.BASE_ASSETS_SHOOTING_RANGE), + IN_THE_DARKNESS_PAGE(6, GameDefinition.IN_THE_DARKNESS, GameMenuAssets.BASE_ASSETS_IN_THE_DARKNESS); private int pageNumber; private GameDefinition gameDefinition; @@ -68,10 +64,11 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { return pageNumber; } - public static String getResourcePath(GameDefinition gameDefinition, GameMenuLayers gameMenuLayer) { + public static String getResourcePath(GameDefinition gameDefinition, GameMenuAssets.AssetType assetType) { for(GameMenuPageDefinition game : GameMenuPageDefinition.values()) { + //TODO - GameNumber, PageNumber ?! if(gameDefinition.getGameNumber() == game.getPageNumber()) { - return GameMenuAssets.GFX_PATH + game.getBaseAssetsPath() + "_" + gameMenuLayer.name().toLowerCase(); + return assetType.getFolder() + "" + game.getBaseAssetsPath() + "_" + assetType.getPostFix(); } } @@ -103,7 +100,6 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { @Override protected String prepareScreenTextResourcesAssetName() { - // no text loading return null; } @@ -158,6 +154,11 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { } }))); } + + ambientMusic = getMusic(GameMenuAssets.AMBIENT_MUSIC); + ambientMusic.setLooping(true); + ambientMusic.play(); + screenResized(0, 0); } @@ -170,6 +171,11 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { protected void screenResized(int width, int height) { super.screenResized(width, height); prepareVignetteAndPagerSize(); + + for(Actor a : pagedScrollPane.getContentTable().getChildren()) { + MenuPage page = (MenuPage) a; + page.onResize(); + } } @Handler @@ -195,4 +201,23 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { public PagedScrollPane getPagedScrollPane() { return pagedScrollPane; } + + @Override + protected void screenDisposed() { + for (Actor a : pagedScrollPane.getContentTable().getChildren()) { + MenuPage page = (MenuPage) a; + page.dispose(); + } + + ambientMusic.stop(); + ambientMusic.dispose(); + + //Disposes sounds, which GameMenuPages use when changing difficulty + getMusic(GameMenuAssets.STEP_HARD_MEDIUM).dispose(); + getMusic(GameMenuAssets.STEP_MEDIUM_HARD).dispose(); + getMusic(GameMenuAssets.STEP_EASY_MEDIUM).dispose(); + getMusic(GameMenuAssets.STEP_MEDIUM_EASY).dispose(); + + super.screenDisposed(); + } } \ No newline at end of file diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java index 4bcd8a47dc197f44290c070b1b39f8c3a9c5c531..25f4223dbd5759ad8dcb82989594ed5805344354 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java @@ -1,5 +1,6 @@ package cz.nic.tablexia.screen.gamemenu.pages; +import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; @@ -7,7 +8,9 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.AlphaAction; +import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Stack; @@ -23,6 +26,7 @@ import cz.nic.tablexia.game.difficulty.GameDifficulty; import cz.nic.tablexia.loader.application.ApplicationFontManager; import cz.nic.tablexia.screen.gamemenu.GameMenuAssets; import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; +import cz.nic.tablexia.util.MusicUtil; import cz.nic.tablexia.util.ui.ClickListenerWithSound; import cz.nic.tablexia.util.ui.Switch; @@ -63,6 +67,8 @@ public class GameMenuPage extends MenuPage { */ private static final float DIFFICULTY_BAR_EDGE_OFFSET = 14/251f; + private static final float INTRO_SOUND_DELAY = 1.0f; //Delay in seconds + //Font for difficulty labels private static final ApplicationFontManager.FontType LABELS_FONT_STYLE = ApplicationFontManager.FontType.ROBOTO_BOLD_18; private static BitmapFont labelsFont; @@ -84,6 +90,23 @@ public class GameMenuPage extends MenuPage { //to position all elements correctly private float pagedScrollPaneOffsetY; + private boolean playClickSound = false; + + private Music introSound; + + //Can we play the step sounds on difficulty change ? + private boolean stepSoundsReady = false; + + //Step sounds assets + private Music step_easy_medium, step_medium_easy; + private Music step_medium_hard, step_hard_medium; + + + private int lastDragDifficultyStep = 0; + + //Is this page the currently active page ? + private boolean isPageActive = false; + public GameMenuPage(GameMenuScreen screen, GameDefinition game) { super(screen); this.screen = screen; @@ -94,17 +117,29 @@ public class GameMenuPage extends MenuPage { //offset is needed to properly calculate position of elements pagedScrollPaneOffsetY = screen.getPagedScrollPane().getY(); + prepareSounds(); prepareTitle(); prepareStartButton(); prepareDifficulty(); } + /** + * Prepares/Loads Sounds + */ + private void prepareSounds() { + step_easy_medium = getScreen().getMusic(GameMenuAssets.STEP_EASY_MEDIUM); + step_medium_easy = getScreen().getMusic(GameMenuAssets.STEP_MEDIUM_EASY); + + step_medium_hard = getScreen().getMusic(GameMenuAssets.STEP_MEDIUM_HARD); + step_hard_medium = getScreen().getMusic(GameMenuAssets.STEP_HARD_MEDIUM); + } + /** * Creates and repares Title */ public void prepareTitle() { //Resources - TextureRegion title = getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.TITLE)); + TextureRegion title = getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.TITLE)); final Image titleImage = new Image(title); //Size @@ -127,7 +162,7 @@ public class GameMenuPage extends MenuPage { public void prepareStartButton() { // Prepare Start Button UP/Released // Resources - TextureRegion start = getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.STARTBUTTON)); + TextureRegion start = getScreen().getScreenTextureRegion( GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.STARTBUTTON)); final Image startButton = new Image(start); // Size @@ -149,7 +184,7 @@ public class GameMenuPage extends MenuPage { //Prepare Strat Button Down/Pressed // Resources - TextureRegion startDown = getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.STARTBUTTON_PRESSED)); + TextureRegion startDown = getScreen().getScreenTextureRegion( GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.STARTBUTTON_PRESSED)); final Image startDownButton = new Image(startDown); //Size @@ -177,27 +212,16 @@ public class GameMenuPage extends MenuPage { startButton.addListener(new ClickListenerWithSound() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { - super.touchDown(event, x + scrollXOffset, y, pointer, button); + super.touchDown(event, x, y, pointer, button); startButton.addAction(new AlphaAction()); startDownButton.setVisible(true); - setLastTouch(x, y); + setLastTouch(x + scrollXOffset, y); return true; } - @Override - public void clicked(InputEvent event, float x, float y) { - if(inTapSquare(x, y)) - super.clicked(event, x, y); - } - - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, int button) { - super.touchUp(event, x + scrollXOffset, y, pointer, button); - } - @Override public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { AlphaAction aa = new AlphaAction(); @@ -209,10 +233,19 @@ public class GameMenuPage extends MenuPage { @Override public void onClick(InputEvent event, float x, float y) { - super.onClick(event, x, y); + playClickSound = false; - ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(GameMenuPage.this.game.getScreenClass(), + if(isClick(x + scrollXOffset, y)) { + playClickSound = true; + ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(GameMenuPage.this.game.getScreenClass(), TablexiaApplication.ScreenTransaction.FADE)); + } + } + + @Override + protected void playButtonSound() { + if(playClickSound) + super.playButtonSound(); } }); } @@ -339,6 +372,34 @@ public class GameMenuPage extends MenuPage { public void movedToStep(int step) { for (int i = 0; i < diffStack.getChildren().size; i++) { diffStack.getChildren().get(i).setVisible(i == step); + if(i == step) { + if(lastDragDifficultyStep != step) { + GameDifficulty difficulty; + + switch (step) { + case 0: + difficulty = GameDifficulty.EASY; + break; + case 1: + difficulty = GameDifficulty.MEDIUM; + break; + case 2: + difficulty = GameDifficulty.HARD; + break; + default: + difficulty = GameDifficulty.DEFAULT_DIFFICULTY; + } + + if(stepSoundsReady) { + playStepSound(gameDifficulty, difficulty); + } else { + stepSoundsReady = true; + } + + difficultyChanged(difficulty); + lastDragDifficultyStep = step; + } + } } } }); @@ -362,6 +423,25 @@ public class GameMenuPage extends MenuPage { TablexiaSettings.getInstance().setGameDifficulty(game, difficulty); } + private void playStepSound(GameDifficulty previous, GameDifficulty current) { + switch (previous) { + case EASY: + step_easy_medium.play(); + break; + case MEDIUM: + if(current == GameDifficulty.EASY) + step_medium_easy.play(); + else + step_medium_hard.play(); + break; + case HARD: + step_hard_medium.play(); + break; + case TUTORIAL: + break; + } + } + /** * Custom draw method * @param batch @@ -375,7 +455,7 @@ public class GameMenuPage extends MenuPage { Color color = new Color(this.getColor().r, this.getColor().g, this.getColor().b, this.getColor().a * parentAlpha); batch.setColor(color); - TextureRegion back = getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.BACK)); + TextureRegion back = getScreen().getScreenTextureRegion( GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.BACK)); batch.disableBlending(); //Just adjusting sourceX coordinate to get animated background/sky @@ -395,7 +475,7 @@ public class GameMenuPage extends MenuPage { batch.enableBlending(); // Mid layer travels the same speed - batch.draw( getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.MID)), + batch.draw( getScreen().getScreenTextureRegion( GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.MID)), getScreen().getSceneLeftX() + getX(), getScreen().getSceneOuterBottomY() - pagedScrollPaneOffsetY, getScreen().getSceneWidth(), @@ -404,7 +484,7 @@ public class GameMenuPage extends MenuPage { batch.enableBlending(); // Foreground layer travels faster and could be wider than screen. Needs to be clipped - batch.draw( getScreen().getScreenTextureRegion(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuScreen.GameMenuLayers.FORE)), + batch.draw( getScreen().getScreenTextureRegion( GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.FORE)), getScreen().getSceneLeftX() + getX() + (scrollXOffset / 2), getScreen().getSceneOuterBottomY() - pagedScrollPaneOffsetY, getScreen().getSceneWidth(), @@ -422,6 +502,39 @@ public class GameMenuPage extends MenuPage { @Override public void onScrolledToPage() { ApplicationBus.getInstance().post(new GameMenuPageScrolledEvent(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(game))).asynchronously(); + + //Was scrolled to this page from different page + if(!isPageActive) { + //Loads music if needed + introSound = getScreen().getMusic(GameMenuScreen.GameMenuPageDefinition.getResourcePath(game, GameMenuAssets.AssetType.INTRO)); + introSound.setVolume(1.0f); + + //Waits for INTRO_SOUND_DELAY seconds and plays the music + addAction(new SequenceAction(Actions.delay(INTRO_SOUND_DELAY), Actions.run(new Runnable() { + @Override + public void run() { + if (isPageActive) { + introSound.play(); + } + } + }))); + } + + isPageActive = true; + } + + @Override + public void onScrollPageExit() { + isPageActive = false; + MusicUtil.fadeOut(introSound, 1); + } + + @Override + public void onResize() { } + + @Override + public void dispose() { + disposeSounds(); } @Override @@ -440,4 +553,9 @@ public class GameMenuPage extends MenuPage { return gameMenuPageDefinition; } } + + public void disposeSounds() { + if(introSound != null) + introSound.dispose(); + } } diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java index 8d3473d84d3967aa93228f7f44d17c1d1afb3514..5aecc5e4f16ac158f2f5f964f719f28bd4d8b257 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/MenuPage.java @@ -31,6 +31,28 @@ public abstract class MenuPage extends Group { public abstract void onScroll(float scroll); public abstract void onScrolledToPage(); + public abstract void onScrollPageExit(); + + public abstract void onResize(); + + public abstract void dispose(); + + /** + * Checks distance between coordinates of the last touchdown event and x, y + * I made this because ClickListeners clicked method doesnt work that good when actor is in scrollpane + * and ClickListeners inTapSquare didn't work on android for some reason + * @param x X coord + * @param y Y coord + * @return returns true if touchup event at x, y was a click + */ + public boolean isClick(float x, float y) { + if(lastTouchX < 0 || lastTouchY < 0) return false; + + float deltaX = Math.abs(x - lastTouchX); + float deltaY = Math.abs(y - lastTouchY); + + return Math.sqrt(deltaX*deltaX + deltaY*deltaY) <= MAX_CLICK_RADIUS; + } public void setLastTouch(float x, float y) { lastTouchX = x; diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java index a26e90f355bc5e4a9e876cfbbcc46a175b144e7f..37d0741d471be52c1d0c6b723578b455803c500f 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java @@ -49,8 +49,8 @@ public class OfficeMenuPage extends MenuPage { //Help Button private static final float HELP_BUTTON_SCALE = 0.85f; - private static final float HELP_BUTTON_OFFSET_RIGHT = 0.07f; - private static final float HELP_BUTTON_OFFSET_BOTTOM = 0.05f; + private static final float HELP_BUTTON_OFFSET_RIGHT = 0.04f; + private static final float HELP_BUTTON_OFFSET_BOTTOM = 0.018f; //Group for all helping elements, so we can hide/show 'em all at once private Group helpGroup; @@ -79,6 +79,8 @@ public class OfficeMenuPage extends MenuPage { private float scrollXOffset = 0; + private boolean playClickSound = false; + public OfficeMenuPage(AbstractTablexiaScreen screen) { super(screen); @@ -115,11 +117,6 @@ public class OfficeMenuPage extends MenuPage { sizeChanged(); } - @Override - protected void sizeChanged() { - super.sizeChanged(); - } - /** * Creates, prepares and adds InputListener to OfficeMenuPage */ @@ -127,9 +124,9 @@ public class OfficeMenuPage extends MenuPage { addListener(new ClickListenerWithSound() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { - super.touchDown(event, x + scrollXOffset, y, pointer, button); + super.touchDown(event, x, y, pointer, button); - setLastTouch(x, y); + setLastTouch(x + scrollXOffset, y); //Don't do anything if help overlay is still visible if (helpOverlayStack.isVisible()) { @@ -158,14 +155,18 @@ public class OfficeMenuPage extends MenuPage { @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { - super.touchUp(event, x + scrollXOffset, y, pointer, button); + super.touchUp(event, x, y, pointer, button); hideAllActions(); } @Override - public void clicked(InputEvent event, float x, float y) { - if(!inTapSquare(x, y)) + public void onClick(InputEvent event, float x, float y) { + playClickSound = true; + + if(!isClick(x + scrollXOffset, y)) { + playClickSound = false; return; + } Color color = getTouchedColor(x, y); @@ -181,12 +182,14 @@ public class OfficeMenuPage extends MenuPage { ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(ProfileScreen.class, TablexiaApplication.ScreenTransaction.FADE)); } else { - //Wont let super.clicked to run - //and play the click sound - return; + playClickSound = false; } + } - super.clicked(event, x, y); + @Override + protected void playButtonSound() { + if(playClickSound) + super.playButtonSound(); } }); } @@ -200,7 +203,7 @@ public class OfficeMenuPage extends MenuPage { new TextureRegionDrawable(getScreen().getScreenTextureRegion(GameMenuAssets.HELP_BUTTON_PRESSED)) ); - toggleHelpButton.addListener( new ClickListenerWithSound() { + toggleHelpButton.addListener(new ClickListenerWithSound() { @Override public void onClick(InputEvent event, float x, float y) { super.onClick(event, x, y); @@ -210,13 +213,17 @@ public class OfficeMenuPage extends MenuPage { } }); + resizeAndPositionHelpButton(); + + helpGroup.addActor(toggleHelpButton); + } + + private void resizeAndPositionHelpButton() { toggleHelpButton.setSize(toggleHelpButton.getPrefWidth() * HELP_BUTTON_SCALE, toggleHelpButton.getPrefHeight() * HELP_BUTTON_SCALE); - toggleHelpButton.setPosition(getScreen().getSceneRightX() - toggleHelpButton.getPrefWidth() - getScreen().getSceneWidth() * HELP_BUTTON_OFFSET_RIGHT, - getScreen().getSceneInnerBottomY() - pagedScrollPaneOffsetY + getScreen().getSceneInnerHeight() * HELP_BUTTON_OFFSET_BOTTOM); - - helpGroup.addActor(toggleHelpButton); + toggleHelpButton.setPosition(getScreen().getViewportRightX() - toggleHelpButton.getWidth() - (HELP_BUTTON_OFFSET_RIGHT * getScreen().getSceneWidth()), + getScreen().getViewportBottomY() - pagedScrollPaneOffsetY + (HELP_BUTTON_OFFSET_BOTTOM * getScreen().getSceneOuterHeight())); } /** @@ -300,6 +307,17 @@ public class OfficeMenuPage extends MenuPage { ApplicationBus.getInstance().post(new GameMenuPage.GameMenuPageScrolledEvent(GameMenuScreen.GameMenuPageDefinition.OFFICE_PAGE)).asynchronously(); } + @Override + public void onScrollPageExit() { } + + @Override + public void onResize() { + resizeAndPositionHelpButton(); + } + + @Override + public void dispose() { } + @Override public void onScroll(float offset) { scrollXOffset = offset; diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/WallPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/WallPage.java index edb1c92bd946de4cff174970fc207fec22a32e3d..dda9d34d4039b14ce42b798391d3621ac26ab997 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/WallPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/WallPage.java @@ -9,6 +9,8 @@ import cz.nic.tablexia.screen.gamemenu.GameMenuAssets; import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; /** + * This class represents the page between the office and game menu pages + * It works as a separator and PagedScrollPane can't snap to this page * Created by Drahomir Karchnak on 02/12/15. */ public class WallPage extends MenuPage{ @@ -21,8 +23,10 @@ public class WallPage extends MenuPage{ public WallPage(AbstractTablexiaScreen<int[][]> screen) { super(screen); + //offset of the pagedScrollPane pagedScrollPaneOffsetY = ((GameMenuScreen) screen).getPagedScrollPane().getY(); + //Sets size and position of WallPage setSize(mid.getRegionWidth(), getScreen().getSceneOuterHeight()); setPosition(getScreen().getSceneWidth(), getScreen().getSceneOuterBottomY() - getScreen().getSceneOuterBottomY()); } @@ -31,6 +35,7 @@ public class WallPage extends MenuPage{ public void draw(Batch batch, float parentAlpha) { batch.setColor(batch.getColor().r, batch.getColor().g, batch.getColor().b, parentAlpha); + //Disables Blending, no need when drawing the background batch.disableBlending(); //Just adjusting sourceX coordinate to get animated background/sky @@ -48,13 +53,14 @@ public class WallPage extends MenuPage{ false); + //Enables Blending for foreground layer batch.enableBlending(); - batch.draw( mid, - getScreen().getSceneLeftX() + getX(), - getScreen().getSceneOuterBottomY() - pagedScrollPaneOffsetY, - getWidth(), - getHeight()); + batch.draw(mid, + getScreen().getSceneLeftX() + getX(), + getScreen().getSceneOuterBottomY() - pagedScrollPaneOffsetY, + getWidth(), + getHeight()); super.draw(batch, parentAlpha); @@ -62,6 +68,7 @@ public class WallPage extends MenuPage{ @Override public boolean isSnapToAllowed() { + //PagedScrollPane can't snap to this page return false; } @@ -70,4 +77,13 @@ public class WallPage extends MenuPage{ @Override public void onScrolledToPage() { } + + @Override + public void onScrollPageExit() { } + + @Override + public void onResize() { } + + @Override + public void dispose() { } } diff --git a/core/src/cz/nic/tablexia/util/MusicUtil.java b/core/src/cz/nic/tablexia/util/MusicUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..026b66825f0c8789fde2db26677adaa6c34d5e77 --- /dev/null +++ b/core/src/cz/nic/tablexia/util/MusicUtil.java @@ -0,0 +1,108 @@ +package cz.nic.tablexia.util; + +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.utils.Timer; + + +/** + * Created by Drahomir Karchnak on 05/12/15. + */ +public class MusicUtil { + public static final float SOUND_EFFECT_INTERVAL = 0.05f; + public static final float MAX_EFFECT_DURATION = 5; + + //TODO - Different ways of interpolating ? Linear/Cosine.. ? + + /** + * Fades Out music by adjusting its volume over given time + * and disposes it after the effect is done + * @param music Music you want to apply the effect to + * @param time Duration of the effect in seconds + */ + public static void fadeOut(final Music music, float time) { + //Wrong arguments ? return... + if(music == null || music.getVolume() <= 0 || !music.isPlaying()) return; + + //Volume values we start with and we are trying to reach + float startVolume = music.getVolume(); + final float endVolume = 0.0f; + + //How many times to repeat the "loop" to reach endVolume + int repeatCount = (int) (time / SOUND_EFFECT_INTERVAL); + + //Wrong arguments ? return... + if(time <= 0 || time > MAX_EFFECT_DURATION || repeatCount <= 0) + return; + + //How much to substract from/add to volume value + final float volumeStep = (startVolume - endVolume) / repeatCount; + + //Timer with SOUND_EFFECT_INTERVAL and repeatCount to fit choosen time + Timer.schedule(new Timer.Task() { + @Override + public void run() { + if(music != null) { + float currentVolume = music.getVolume(); + float volume = MathUtils.clamp(currentVolume - volumeStep, 0, 1); + + if(volume <= endVolume) { + music.dispose(); + cancel(); + } + else { + music.setVolume(volume); + } + } + } + }, 0, SOUND_EFFECT_INTERVAL, repeatCount); + } + + + /** + * Fades In music by adjusting its volume over given time + * and disposes it after the effect is done + * @param music Music you want to apply the effect to + * @param time Duration of the effect in seconds + */ + public static void fadeIn(final Music music, float time) { + //Wrong arguments ? return... + if(music == null || music.getVolume() >= 1 || !music.isPlaying()) return; + + //Volume values we start with and we are trying to reach + float startVolume = music.getVolume(); + final float endVolume = 1.0f; + + //How many times to repeat the "loop" to reach endVolume + int repeatCount = (int) (time / SOUND_EFFECT_INTERVAL); + + //Wrong arguments ? return... + if(time <= 0 || time > MAX_EFFECT_DURATION || repeatCount <= 0) + return; + + //How much to substract from/add to volume value + final float volumeStep = (endVolume - startVolume) / repeatCount; + + if(!music.isPlaying()) + music.play(); + + //Timer with SOUND_EFFECT_INTERVAL and repeatCount to fit choosen time + Timer.schedule(new Timer.Task() { + @Override + public void run() { + if(music != null) { + float currentVolume = music.getVolume(); + float volume = MathUtils.clamp(currentVolume + volumeStep, 0, 1); + + if(volume >= endVolume) { + music.dispose(); + cancel(); + } + else { + music.setVolume(volume); + } + } + } + }, 0, SOUND_EFFECT_INTERVAL, repeatCount); + } +} diff --git a/core/src/cz/nic/tablexia/util/ui/ClickListenerWithSound.java b/core/src/cz/nic/tablexia/util/ui/ClickListenerWithSound.java index 44aab2ace08e6ff3078a16bfd8768b081ce7d10e..8ee46e80db141bd69228535e3a50802b8b88bd8d 100644 --- a/core/src/cz/nic/tablexia/util/ui/ClickListenerWithSound.java +++ b/core/src/cz/nic/tablexia/util/ui/ClickListenerWithSound.java @@ -11,15 +11,13 @@ import cz.nic.tablexia.loader.application.ApplicationSoundManager; public class ClickListenerWithSound extends ClickListener { @Override - public void clicked (InputEvent event, float x, float y) { - playButtonSound(); + public final void clicked (InputEvent event, float x, float y) { super.clicked(event, x, y); onClick(event, x, y); + playButtonSound(); } - public void onClick(InputEvent event, float x, float y) { - - } + public void onClick(InputEvent event, float x, float y) { } protected void playButtonSound() { ApplicationSoundManager.getInstance().getSound(ApplicationSoundManager.MAINMENU_BUTTON).play(); diff --git a/core/src/cz/nic/tablexia/util/ui/PagedScrollPane.java b/core/src/cz/nic/tablexia/util/ui/PagedScrollPane.java index 4f6d3cf2bcbecf99cf323e35d3861c15aaf29396..427f80d2c921876beef1b28a5da38e52f50e96fe 100644 --- a/core/src/cz/nic/tablexia/util/ui/PagedScrollPane.java +++ b/core/src/cz/nic/tablexia/util/ui/PagedScrollPane.java @@ -20,10 +20,12 @@ public class PagedScrollPane extends ScrollPane { private Table contentTable; + private int currentPage; private int indexCurrentPage; - private float distanceToChangePage = 120; + private float distanceToChangePage = 120; private float lastScrollX = -1; + private float lastTouchX = -1; public PagedScrollPane() { @@ -57,11 +59,11 @@ public class PagedScrollPane extends ScrollPane { //TODO - Use TablexiaSettings for Key Bindings, and enable keydown events switch (keycode) { case Input.Keys.LEFT: - scrollToPage(indexCurrentPage - 1, true); + scrollToPage(currentPage - 1, true); break; case Input.Keys.RIGHT: - scrollToPage(indexCurrentPage + 1, true); + scrollToPage(currentPage + 1, true); break; } @@ -92,17 +94,17 @@ public class PagedScrollPane extends ScrollPane { setVelocityX(0); if(Math.abs(touchDownX - touchUpX) <= distanceToChangePage) { - scrollToPage(indexCurrentPage, true); + scrollToPage(currentPage, true); return; } else { if(touchDownX - touchUpX > 0) { //swiped right //scroll to next valid page - scrollToPage(indexCurrentPage + 1, true); + scrollToPage(currentPage + 1, true); } else { //swiped left //scroll to previous valid page - scrollToPage(indexCurrentPage - 1, true); + scrollToPage(currentPage - 1, true); } } } @@ -169,8 +171,8 @@ public class PagedScrollPane extends ScrollPane { int validPagesCount = 0; //iterates through all children of contentTable - for (Actor a : contentTable.getChildren()) { - MenuPage page = (MenuPage) a; + for (int i = 0; i < contentTable.getChildren().size; i++) { + MenuPage page = (MenuPage) (contentTable.getChildren().get(i)); //tells if pagedScrollPane can snap to this child if (page.isSnapToAllowed()) { @@ -179,13 +181,20 @@ public class PagedScrollPane extends ScrollPane { setSmoothScrolling(smooth); setScrollX(page.getX()); + //Is changing page ? + if(indexCurrentPage != i) { + MenuPage leavePage = (MenuPage) contentTable.getChildren().get(indexCurrentPage); + leavePage.onScrollPageExit(); + } + //in case smooth scrolling is set to false, we need to update visual scroll if (!smooth) { updateVisualScroll(); } //Saves index of current page, index doesnt include invalid pages - indexCurrentPage = validPagesCount; + currentPage = validPagesCount; + indexCurrentPage = i; break; } validPagesCount++; @@ -204,7 +213,11 @@ public class PagedScrollPane extends ScrollPane { distanceToChangePage = Math.abs(distance); } - public int getIndexCurrentPage() { - return indexCurrentPage; + public int getCurrentPage() { + return currentPage; + } + + public Table getContentTable() { + return contentTable; } }