Added first sound effect, and sound effect volume control settings

As of now, every single button in the game has the same click sound, but that will change
This commit is contained in:
Yair Morgenstern
2018-12-17 11:45:24 +02:00
parent f5c8b28d82
commit 82f9f64fab
8 changed files with 113 additions and 62 deletions

View File

@ -389,3 +389,10 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
* [Replace](https://thenounproject.com/search/?q=replace&i=17858) By Mike Rowe, AU * [Replace](https://thenounproject.com/search/?q=replace&i=17858) By Mike Rowe, AU
* [Resistance](https://thenounproject.com/term/revolution/1315305/) By By HeadsOfBirds, GB * [Resistance](https://thenounproject.com/term/revolution/1315305/) By By HeadsOfBirds, GB
# Sound credits
Sounds are from FreeSound.org
* [Click 01_Minimal UI Sounds](https://freesound.org/people/cabled_mess/sounds/370962/) By cabled_mess for most clicks
* [SawInOut01](https://freesound.org/people/kingof_thelab/sounds/340243/) By kingof_thelab for construction picking?

Binary file not shown.

View File

@ -9,6 +9,7 @@ class GameSettings {
var resolution: String = "1050x700" var resolution: String = "1050x700"
var tutorialsShown = ArrayList<String>() var tutorialsShown = ArrayList<String>()
var hasCrashedRecently = false var hasCrashedRecently = false
var soundEffectsVolume = 1.0f
fun save(){ fun save(){
GameSaver().setGeneralSettings(this) GameSaver().setGeneralSettings(this)

View File

@ -122,9 +122,11 @@ fun Label.setFontSize(size:Int): Label {
return this // for chaining return this // for chaining
} }
// If there are other buttons that require special clicks then we'll have an onclick that will accept a string parameter, no worries
fun Actor.onClick(function: () -> Unit) { fun Actor.onClick(function: () -> Unit) {
this.addListener(object : ClickListener() { this.addListener(object : ClickListener() {
override fun clicked(event: InputEvent?, x: Float, y: Float) { override fun clicked(event: InputEvent?, x: Float, y: Float) {
Sounds.play("click")
function() function()
} }
} ) } )

View File

@ -190,4 +190,5 @@ object ImageGetter {
return line return line
} }
} }

View File

@ -0,0 +1,20 @@
package com.unciv.ui.utils
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.audio.Sound
import com.unciv.UnCivGame
object Sounds{
val soundMap = HashMap<String, Sound>()
fun get(name:String):Sound{
if(!soundMap.containsKey(name))
soundMap[name] = Gdx.audio.newSound(Gdx.files.internal("sounds/$name.mp3"));
return soundMap[name]!!
}
fun play(name:String){
get(name).play(UnCivGame.Current.settings.soundEffectsVolume)
}
}

View File

@ -93,20 +93,20 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
}) })
} }
private fun onTileClicked(tileInfo: TileInfo, tileGroup: WorldTileGroup){ private fun onTileClicked(tileInfo: TileInfo, tileGroup: WorldTileGroup) {
worldScreen.displayTutorials("TileClicked") worldScreen.displayTutorials("TileClicked")
if (moveToOverlay != null) moveToOverlay!!.remove() if (moveToOverlay != null) moveToOverlay!!.remove()
selectedTile = tileInfo selectedTile = tileInfo
val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit
if (selectedUnit != null && selectedUnit.getTile() != tileInfo if (selectedUnit != null && selectedUnit.getTile() != tileInfo
&& selectedUnit.canMoveTo(tileInfo) && selectedUnit.movementAlgs().canReach(tileInfo)) { && selectedUnit.canMoveTo(tileInfo) && selectedUnit.movementAlgs().canReach(tileInfo)) {
// this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread // this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread
queueAddMoveHereButton(selectedUnit, tileInfo) queueAddMoveHereButton(selectedUnit, tileInfo)
} }
worldScreen.bottomBar.unitTable.tileSelected(tileInfo) worldScreen.bottomBar.unitTable.tileSelected(tileInfo)
worldScreen.shouldUpdate=true worldScreen.shouldUpdate = true
} }
private fun queueAddMoveHereButton(selectedUnit: MapUnit, tileInfo: TileInfo) { private fun queueAddMoveHereButton(selectedUnit: MapUnit, tileInfo: TileInfo) {

View File

@ -5,13 +5,17 @@ import com.badlogic.gdx.graphics.g2d.Batch
import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.Slider
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
import com.badlogic.gdx.utils.Array
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.Fonts import com.unciv.ui.utils.Fonts
import com.unciv.ui.utils.Sounds
import com.unciv.ui.utils.center import com.unciv.ui.utils.center
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
import kotlin.concurrent.thread
class Language(val language:String){ class Language(val language:String){
val percentComplete:Int val percentComplete:Int
@ -27,7 +31,7 @@ class Language(val language:String){
} }
class WorldScreenDisplayOptionsTable : PopupTable(){ class WorldScreenDisplayOptionsTable : PopupTable(){
val languageSelectBox = SelectBox<Language>(CameraStageBaseScreen.skin) val languageSelectBox = SelectBox<Language>(skin)
init { init {
update() update()
@ -48,55 +52,9 @@ class WorldScreenDisplayOptionsTable : PopupTable(){
else addButton("{Show} {resources and improvements}") { settings.showResourcesAndImprovements = true; update() } else addButton("{Show} {resources and improvements}") { settings.showResourcesAndImprovements = true; update() }
val languageArray = com.badlogic.gdx.utils.Array<Language>() addLanguageSelectBox()
GameBasics.Translations.getLanguages().map { Language(it) }.sortedByDescending { it.percentComplete }
.forEach { languageArray.add(it) }
languageSelectBox.items = languageArray
languageSelectBox.selected = languageArray.first { it.language== UnCivGame.Current.settings.language}
add(languageSelectBox).pad(10f).row()
languageSelectBox.addListener(object : ChangeListener() { val resolutionSelectBox= SelectBox<String>(skin)
override fun changed(event: ChangeEvent?, actor: Actor?) {
val selectedLanguage = languageSelectBox.selected.language
if (Fonts().containsFont(Fonts().getFontForLanguage(selectedLanguage)))
selectLanguage()
else {
val spaceSplitLang = selectedLanguage.replace("_"," ")
YesNoPopupTable("This language requires you to download fonts.\n" +
"Do you want to download fonts for $spaceSplitLang?",
{
val downloading = PopupTable()
downloading.add(Label("Downloading...", CameraStageBaseScreen.skin))
downloading.pack()
downloading.center(stage)
stage.addActor(downloading)
Gdx.input.inputProcessor = null // no interaction until download is over
kotlin.concurrent.thread {
Fonts().downloadFontForLanguage(selectedLanguage)
// The language selection must be done on the render thread, because it requires a GL context.
// This means that we have to tell the table to create it on render.
shouldSelectLanguage=true
}
})
}
}
})
if(languageSelectBox.selected.percentComplete!=100) {
add(Label("Missing translations:", CameraStageBaseScreen.skin)).pad(5f).row()
val missingTextSelectBox = SelectBox<String>(CameraStageBaseScreen.skin)
val missingTextArray = com.badlogic.gdx.utils.Array<String>()
val currentLanguage = UnCivGame.Current.settings.language
GameBasics.Translations.filter { !it.value.containsKey(currentLanguage) }.forEach { missingTextArray.add(it.key) }
missingTextSelectBox.items = missingTextArray
missingTextSelectBox.selected = "Untranslated texts"
add(missingTextSelectBox).pad(10f).width(UnCivGame.Current.worldScreen.stage.width / 2).row()
}
val resolutionSelectBox= SelectBox<String>(CameraStageBaseScreen.skin)
val resolutionArray = com.badlogic.gdx.utils.Array<String>() val resolutionArray = com.badlogic.gdx.utils.Array<String>()
resolutionArray.addAll("900x600","1050x700","1200x800","1500x1000") resolutionArray.addAll("900x600","1050x700","1200x800","1500x1000")
resolutionSelectBox.items = resolutionArray resolutionSelectBox.items = resolutionArray
@ -113,6 +71,18 @@ class WorldScreenDisplayOptionsTable : PopupTable(){
} }
}) })
val soundEffectsVolumeSlider = Slider(0f,1.0f,0.1f,false,skin)
soundEffectsVolumeSlider.value = UnCivGame.Current.settings.soundEffectsVolume
soundEffectsVolumeSlider.addListener(object: ChangeListener(){
override fun changed(event: ChangeEvent?, actor: Actor?) {
UnCivGame.Current.settings.soundEffectsVolume= soundEffectsVolumeSlider.value
UnCivGame.Current.settings.save()
Sounds.play("click")
}
})
add("Sound effects volume").row()
add(soundEffectsVolumeSlider).row()
addButton("Close"){ remove() } addButton("Close"){ remove() }
pack() // Needed to show the background. pack() // Needed to show the background.
@ -120,6 +90,56 @@ class WorldScreenDisplayOptionsTable : PopupTable(){
UnCivGame.Current.worldScreen.shouldUpdate=true UnCivGame.Current.worldScreen.shouldUpdate=true
} }
private fun addLanguageSelectBox() {
val languageArray = Array<Language>()
GameBasics.Translations.getLanguages().map { Language(it) }.sortedByDescending { it.percentComplete }
.forEach { languageArray.add(it) }
languageSelectBox.items = languageArray
languageSelectBox.selected = languageArray.first { it.language == UnCivGame.Current.settings.language }
add(languageSelectBox).pad(10f).row()
languageSelectBox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {
val selectedLanguage = languageSelectBox.selected.language
if (Fonts().containsFont(Fonts().getFontForLanguage(selectedLanguage)))
selectLanguage()
else {
val spaceSplitLang = selectedLanguage.replace("_", " ")
YesNoPopupTable("This language requires you to download fonts.\n" +
"Do you want to download fonts for $spaceSplitLang?",
{
val downloading = PopupTable()
downloading.add(Label("Downloading...", skin))
downloading.pack()
downloading.center(stage)
stage.addActor(downloading)
Gdx.input.inputProcessor = null // no interaction until download is over
thread {
Fonts().downloadFontForLanguage(selectedLanguage)
// The language selection must be done on the render thread, because it requires a GL context.
// This means that we have to tell the table to create it on render.
shouldSelectLanguage = true
}
})
}
}
})
if (languageSelectBox.selected.percentComplete != 100) {
add(Label("Missing translations:", skin)).pad(5f).row()
val missingTextSelectBox = SelectBox<String>(skin)
val missingTextArray = Array<String>()
val currentLanguage = UnCivGame.Current.settings.language
GameBasics.Translations.filter { !it.value.containsKey(currentLanguage) }.forEach { missingTextArray.add(it.key) }
missingTextSelectBox.items = missingTextArray
missingTextSelectBox.selected = "Untranslated texts"
add(missingTextSelectBox).pad(10f).width(UnCivGame.Current.worldScreen.stage.width / 2).row()
}
}
fun selectLanguage(){ fun selectLanguage(){
UnCivGame.Current.settings.language = languageSelectBox.selected.language UnCivGame.Current.settings.language = languageSelectBox.selected.language