/
username0273
/
TextAdventure
Обзор
Документация
Войти
/
username0273
/
TextAdventure
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/src/main/java/com/example/textadventure/ui/GameScreen.kt
397 строк
17 KB
Simon
Добавлена поддержка Android 6.0 и исправлены мелкие баги
05 июн 2026, 20:16
05 июн 2026, 20:16
ec1a76e
Код
Авторство
О чём код?
package com.example.textadventure.ui import android.content.Intent import android.content.pm.ActivityInfo import android.os.Bundle import android.text.Spannable import android.text.SpannableString import android.text.style.AbsoluteSizeSpan import android.text.style.ForegroundColorSpan import android.view.View import android.view.ViewGroup import android.widget.TextView import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.get import androidx.fragment.app.Fragment import com.example.textadventure.R import com.example.textadventure.gamelogic.enums.GameMode import com.example.textadventure.gamelogic.enums.WeaponProperty import com.example.textadventure.gamelogic.items.ItemFactory import com.example.textadventure.gamelogic.rolesystem.Player import com.example.textadventure.gamelogic.model.Story import com.example.textadventure.gamelogic.quests.QuestFactory import com.example.textadventure.gamelogic.quests.QuestManager import com.example.textadventure.gamelogic.save.GameSave import com.example.textadventure.gamelogic.save.SaveManager import com.example.textadventure.utils.SoundManager import com.google.android.material.bottomnavigation.BottomNavigationView import androidx.core.view.size class GameScreen : AppCompatActivity() { companion object { const val EXTRA_CHARACTER_NAME = "CHARACTER_NAME" const val EXTRA_CHARACTER_BACKGROUND = "CHARACTER_BACKGROUND" const val EXTRA_CHARACTER_STRENGTH = "CHARACTER_STRENGTH" const val EXTRA_CHARACTER_DEXTERITY = "CHARACTER_DEXTERITY" const val EXTRA_CHARACTER_CONSTITUTION = "CHARACTER_CONSTITUTION" } private lateinit var player: Player private lateinit var bottomNav: BottomNavigationView private lateinit var story: Story private lateinit var gameMode: GameMode private lateinit var soundManager: SoundManager private lateinit var questManager: QuestManager private lateinit var storyFragment: StoryFragment private lateinit var characterFragment: CharacterFragment private lateinit var inventoryFragment: InventoryFragment private lateinit var mapFragment: MapFragment // --------------------------------------------------------------------------------------------- // getters & setters // --------------------------------------------------------------------------------------------- fun getPlayer() = player fun getBottomNav() = bottomNav fun getStory() = story fun getSoundManager() = soundManager fun getQuestManager() = questManager fun getInventoryFragment() = inventoryFragment fun setGameMode(mode: GameMode) { gameMode = mode } // --------------------------------------------------------------------------------------------- // on create // --------------------------------------------------------------------------------------------- override fun onCreate(savedInstanceState: Bundle?) { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_game_screen) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } // ----------------------------------------------------------------------------------------- // init sounds // ----------------------------------------------------------------------------------------- soundManager = SoundManager(this) soundManager.loadSound(R.raw.click) soundManager.loadSound(R.raw.equip_armor) soundManager.loadSound(R.raw.equip_weapon) soundManager.loadSound(R.raw.hit_bludgeoning) soundManager.loadSound(R.raw.hit_ranged) soundManager.loadSound(R.raw.hit_slashing) soundManager.loadSound(R.raw.level_up) soundManager.loadSound(R.raw.miss) soundManager.loadSound(R.raw.tab_switch) soundManager.loadSound(R.raw.use_potion) soundManager.playBackgroundMusic(R.raw.background_exploration_loop) // ----------------------------------------------------------------------------------------- // override return button behavior // ----------------------------------------------------------------------------------------- onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { showExitDialog() } }) // ----------------------------------------------------------------------------------------- // set up fragments // ----------------------------------------------------------------------------------------- if (savedInstanceState == null) { storyFragment = StoryFragment() characterFragment = CharacterFragment() inventoryFragment = InventoryFragment() mapFragment = MapFragment() supportFragmentManager.beginTransaction() .add(R.id.fragmentContainer, storyFragment, "STORY") .add(R.id.fragmentContainer, characterFragment, "CHARACTER") .hide(characterFragment) .add(R.id.fragmentContainer, inventoryFragment, "INVENTORY") .hide(inventoryFragment) .add(R.id.fragmentContainer, mapFragment, "MAP") .hide(mapFragment) .commit() } else { storyFragment = supportFragmentManager.findFragmentByTag("STORY") as StoryFragment characterFragment = supportFragmentManager.findFragmentByTag("CHARACTER") as CharacterFragment inventoryFragment = supportFragmentManager.findFragmentByTag("INVENTORY") as InventoryFragment mapFragment = supportFragmentManager.findFragmentByTag("MAP") as MapFragment } // ----------------------------------------------------------------------------------------- // set up navigation tabs // ----------------------------------------------------------------------------------------- bottomNav = findViewById<BottomNavigationView>(R.id.bottomNavigationView) // responsive text size val menu = bottomNav.menu for (i in 0 until menu.size) { val item = bottomNav.findViewById<View>(menu[i].itemId) findAndScaleTextViews(item) } // tab switching bottomNav.setOnItemSelectedListener { soundManager.playSound(R.raw.tab_switch) when (it.itemId) { R.id.storyFragment -> { openFragment(storyFragment) storyFragment.getBarHP().text = "${player.getCurrentHP()}" storyFragment.getBarXP().text = "${player.getXp()}" } R.id.characterFragment -> { openFragment(characterFragment) characterFragment.updateUI() } R.id.inventoryFragment -> { openFragment(inventoryFragment) inventoryFragment.getAdapter().updateInventory() } R.id.mapFragment -> { openFragment(mapFragment) mapFragment.updateMap() } } true } // ----------------------------------------------------------------------------------------- // load game // ----------------------------------------------------------------------------------------- loadGame() } // --------------------------------------------------------------------------------------------- // scale text size // --------------------------------------------------------------------------------------------- private fun findAndScaleTextViews(view: View) { if (view is TextView) { view.textSize = resources.getDimension(R.dimen.tiny_text) / resources.displayMetrics.scaledDensity } else if (view is ViewGroup) { for (i in 0 until view.childCount) { findAndScaleTextViews(view.getChildAt(i)) } } } // --------------------------------------------------------------------------------------------- // load saved game // --------------------------------------------------------------------------------------------- private fun loadGame() { val save = SaveManager.load(this) if (save != null) { // loading save player = Player.loadPlayer(save.getPlayer()) player.loadInventory(save.getInventory()) player.restoreEquipment( save.getPlayer().getEquippedWeaponId(), save.getPlayer().getEquippedArmorId() ) questManager = QuestManager(player, QuestFactory.createAllQuests()) questManager.loadQuests(save.getQuests()) openFragment(storyFragment.apply { setLaunchPosition(save.getStoryPosition()) }) } else { // getting values from character creation activity val backgroundString = intent.getStringExtra(EXTRA_CHARACTER_BACKGROUND) ?: "StreetFighter" val characterBackground = when (backgroundString) { "StreetFighter" -> WeaponProperty.HEAVY "Fencer" -> WeaponProperty.LIGHT "Hunter" -> WeaponProperty.RANGED else -> WeaponProperty.HEAVY } player = Player( name = intent.getStringExtra(EXTRA_CHARACTER_NAME) ?: "Путник", strength = intent.getIntExtra(EXTRA_CHARACTER_STRENGTH, 8), dexterity = intent.getIntExtra(EXTRA_CHARACTER_DEXTERITY, 8), constitution = intent.getIntExtra(EXTRA_CHARACTER_CONSTITUTION, 8), weaponProficiency = characterBackground, level = 1 ) when (player.getWeaponProficiency()) { WeaponProperty.HEAVY -> player.addToInventory(ItemFactory.createItem("flangedMace", 1)!!) WeaponProperty.LIGHT -> player.addToInventory(ItemFactory.createItem("dagger", 1)!!) WeaponProperty.RANGED -> player.addToInventory(ItemFactory.createItem("bow", 1)!!) } questManager = QuestManager(player, QuestFactory.createAllQuests()) openFragment(storyFragment) } } // --------------------------------------------------------------------------------------------- // pause or release sounds when activity is paused or destroyed // --------------------------------------------------------------------------------------------- override fun onPause() { super.onPause() soundManager.pauseBackgroundMusic() } override fun onResume() { super.onResume() soundManager.resumeBackgroundMusic() } override fun onDestroy() { super.onDestroy() soundManager.release() } // --------------------------------------------------------------------------------------------- // tab switching // --------------------------------------------------------------------------------------------- private fun openFragment(fragment: Fragment) { supportFragmentManager.beginTransaction().apply { // hide all fragments first supportFragmentManager.fragments.forEach { hide(it) } // show the requested fragment show(fragment) commit() } } // --------------------------------------------------------------------------------------------- // open story tab on death if it's not open // --------------------------------------------------------------------------------------------- fun openStoryTab() { val storyId = R.id.storyFragment if (bottomNav.selectedItemId != storyId) bottomNav.selectedItemId = storyId } // --------------------------------------------------------------------------------------------- // initialize story // --------------------------------------------------------------------------------------------- fun initStory(storyFragment: StoryFragment) { story = Story(storyFragment, this) } // --------------------------------------------------------------------------------------------- // in-game menu // --------------------------------------------------------------------------------------------- private fun showExitDialog() { val builder = androidx.appcompat.app.AlertDialog.Builder(this) val title = SpannableString("МЕНЮ") title.setSpan( ForegroundColorSpan(ContextCompat.getColor(this, R.color.judge_gray)), 0, title.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE ) title.setSpan( AbsoluteSizeSpan(resources.getDimension(R.dimen.normal_text).toInt()), 0, title.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE ) builder.setTitle(title) if (gameMode == GameMode.COMBAT) { builder.setMessage("Сохранение недоступно во время боя!") builder.setPositiveButton("Продолжить") { dialog, _ -> soundManager.playSound(R.raw.click) dialog.dismiss() } builder.setNegativeButton("Выйти без сохранения") { dialog, _ -> soundManager.playSound(R.raw.click) goToTitleScreen() dialog.dismiss() } } else { builder.setPositiveButton("Сохранить") { dialog, _ -> soundManager.playSound(R.raw.click) saveGame() Toast.makeText(this, "Игра сохранена", Toast.LENGTH_SHORT).show() dialog.dismiss() } builder.setNegativeButton("В главное меню") { dialog, _ -> soundManager.playSound(R.raw.click) goToTitleScreen() dialog.dismiss() } builder.setNeutralButton("Продолжить") { dialog, _ -> soundManager.playSound(R.raw.click) dialog.dismiss() } } val dialog = builder.create() dialog.show() dialog.findViewById<TextView>(android.R.id.message)?.apply { setTextColor(ContextCompat.getColor(this@GameScreen, R.color.judge_gray)) textSize = resources.getDimension(R.dimen.extra_small_text) / resources.displayMetrics.scaledDensity } dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.apply { textSize = resources.getDimension(R.dimen.tiny_text) / resources.displayMetrics.scaledDensity setTextColor(ContextCompat.getColor(this@GameScreen, R.color.judge_gray)) } dialog.getButton(AlertDialog.BUTTON_NEGATIVE)?.apply { textSize = resources.getDimension(R.dimen.tiny_text) / resources.displayMetrics.scaledDensity setTextColor(ContextCompat.getColor(this@GameScreen, R.color.judge_gray)) } dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.apply { textSize = resources.getDimension(R.dimen.tiny_text) / resources.displayMetrics.scaledDensity setTextColor(ContextCompat.getColor(this@GameScreen, R.color.judge_gray)) } dialog.window?.setBackgroundDrawableResource(R.color.zombie) } // --------------------------------------------------------------------------------------------- // save game // --------------------------------------------------------------------------------------------- fun saveGame() { if (gameMode == GameMode.STORY) { SaveManager.save(this, GameSave( player = player.savePlayer(), inventory = player.saveInventory(), storyPosition = story.getCurrentStoryPosition(), quests = questManager.saveQuests() ) ) } } // --------------------------------------------------------------------------------------------- // open TitleScreen activity // --------------------------------------------------------------------------------------------- fun goToTitleScreen() { val titleS = Intent(this, TitleScreen::class.java) startActivity(titleS) } // --------------------------------------------------------------------------------------------- // open Epilogue activity // --------------------------------------------------------------------------------------------- fun launchEpilogue(mainEnd: String, townEnd: String, catEnd: String) { val epilogueS = Intent(this, EpilogueScreen::class.java) epilogueS.putExtra("MAIN_ENDING", mainEnd) epilogueS.putExtra("TOWN_ENDING", townEnd) epilogueS.putExtra("CAT_ENDING", catEnd) startActivity(epilogueS) } }