Moved sprites to load from external Android storage.

Setup landscape view for battle.
This commit is contained in:
lightheel 2025-08-08 07:44:36 -04:00
parent f0760f9ed0
commit bb1c29bbb4
7 changed files with 280 additions and 226 deletions

View File

@ -5,6 +5,8 @@
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" /> <uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application <application
android:name=".di.VBHelper" android:name=".di.VBHelper"

View File

@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.battle
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Environment
import com.google.gson.Gson import com.google.gson.Gson
import java.io.File import java.io.File
@ -31,8 +32,10 @@ class AttackSpriteManager(private val context: Context) {
private val gson = Gson() private val gson = Gson()
private val characterDataCache = mutableMapOf<String, CharacterData>() private val characterDataCache = mutableMapOf<String, CharacterData>()
// Base path for attack textures (updated for new folder structure) // Get the external storage directory for attack sprites
private val attackTexturesPath = "battle_sprites/extracted_atksprites" private fun getAttackTexturesPath(): String {
return "VBHelper/battle_sprites/extracted_atksprites"
}
fun getAttackSprite(characterId: String, isLarge: Boolean = false): Bitmap? { fun getAttackSprite(characterId: String, isLarge: Boolean = false): Bitmap? {
println("AttackSpriteManager: Getting attack sprite for characterId=$characterId, isLarge=$isLarge") println("AttackSpriteManager: Getting attack sprite for characterId=$characterId, isLarge=$isLarge")
@ -55,9 +58,10 @@ class AttackSpriteManager(private val context: Context) {
return null return null
} }
// Load the attack sprite // Load the attack sprite from external storage
val attackFilePath = "$attackTexturesPath/$attackFileName.png" val externalDir = Environment.getExternalStorageDirectory()
val attackFile = File(context.filesDir, attackFilePath) val attackFilePath = "${getAttackTexturesPath()}/$attackFileName.png"
val attackFile = File(externalDir, attackFilePath)
println("AttackSpriteManager: Attack file path = ${attackFile.absolutePath}") println("AttackSpriteManager: Attack file path = ${attackFile.absolutePath}")
println("AttackSpriteManager: Attack file exists = ${attackFile.exists()}") println("AttackSpriteManager: Attack file exists = ${attackFile.exists()}")
@ -85,8 +89,9 @@ class AttackSpriteManager(private val context: Context) {
} }
try { try {
// Load character data from JSON file // Load character data from JSON file in external storage
val characterDataFile = File(context.filesDir, "battle_sprites/extracted_digimon_stats/character_data/CharacterData.json") val externalDir = Environment.getExternalStorageDirectory()
val characterDataFile = File(externalDir, "VBHelper/battle_sprites/extracted_digimon_stats/character_data/CharacterData.json")
println("AttackSpriteManager: Character data file path = ${characterDataFile.absolutePath}") println("AttackSpriteManager: Character data file path = ${characterDataFile.absolutePath}")
println("AttackSpriteManager: Character data file exists = ${characterDataFile.exists()}") println("AttackSpriteManager: Character data file exists = ${characterDataFile.exists()}")

View File

@ -3,6 +3,7 @@ package com.github.nacabaro.vbhelper.battle
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Environment
import com.google.gson.Gson import com.google.gson.Gson
import java.io.File import java.io.File
@ -37,8 +38,11 @@ class BattleSpriteManager(private val context: Context) {
private val gson = Gson() private val gson = Gson()
private val spriteCache = mutableMapOf<String, Bitmap>() private val spriteCache = mutableMapOf<String, Bitmap>()
// Base directory where your sprites are stored // Get the external storage directory for sprite files
private val spriteBaseDir = File(context.filesDir, "battle_sprites/extracted_assets") private fun getSpriteBaseDir(): File {
val externalDir = Environment.getExternalStorageDirectory()
return File(externalDir, "VBHelper/battle_sprites/extracted_assets")
}
fun loadSprite(spriteName: String, atlasName: String): Bitmap? { fun loadSprite(spriteName: String, atlasName: String): Bitmap? {
val cacheKey = "${spriteName}_${atlasName}" val cacheKey = "${spriteName}_${atlasName}"
@ -49,6 +53,7 @@ class BattleSpriteManager(private val context: Context) {
} }
// Debug: Check if base directory exists // Debug: Check if base directory exists
val spriteBaseDir = getSpriteBaseDir()
if (!spriteBaseDir.exists()) { if (!spriteBaseDir.exists()) {
println("Sprite base directory does not exist: ${spriteBaseDir.absolutePath}") println("Sprite base directory does not exist: ${spriteBaseDir.absolutePath}")
return null return null
@ -130,7 +135,7 @@ class BattleSpriteManager(private val context: Context) {
// Helper method to get available sprites for an atlas // Helper method to get available sprites for an atlas
fun getAvailableSprites(atlasName: String): List<String> { fun getAvailableSprites(atlasName: String): List<String> {
try { try {
val spritesDir = File(spriteBaseDir, "sprites") val spritesDir = File(getSpriteBaseDir(), "sprites")
if (!spritesDir.exists()) { if (!spritesDir.exists()) {
return emptyList() return emptyList()
} }
@ -154,7 +159,7 @@ class BattleSpriteManager(private val context: Context) {
// Helper method to get available atlases // Helper method to get available atlases
fun getAvailableAtlases(): List<String> { fun getAvailableAtlases(): List<String> {
try { try {
val texturesDir = File(spriteBaseDir, "extracted_textures") val texturesDir = File(getSpriteBaseDir(), "extracted_textures")
if (!texturesDir.exists()) { if (!texturesDir.exists()) {
return emptyList() return emptyList()
} }

View File

@ -4,13 +4,17 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Rect import android.graphics.Rect
import android.os.Environment
import java.io.File import java.io.File
class HitEffectSpriteManager(private val context: Context) { class HitEffectSpriteManager(private val context: Context) {
private val spriteCache = mutableMapOf<String, Bitmap>() private val spriteCache = mutableMapOf<String, Bitmap>()
// Base directory where hit effect sprites are stored // Get the external storage directory for hit effect sprites
private val hitSpritesDir = File(context.filesDir, "battle_sprites/extracted_hit_sprites") private fun getHitSpritesDir(): File {
val externalDir = Environment.getExternalStorageDirectory()
return File(externalDir, "VBHelper/battle_sprites/extracted_hit_sprites")
}
/** /**
* Load a hit sprite (hit_01.png, hit_02.png, hit_02_white.png) * Load a hit sprite (hit_01.png, hit_02.png, hit_02_white.png)
@ -26,6 +30,7 @@ class HitEffectSpriteManager(private val context: Context) {
} }
try { try {
val hitSpritesDir = getHitSpritesDir()
val spriteFile = File(hitSpritesDir, "$spriteName.png") val spriteFile = File(hitSpritesDir, "$spriteName.png")
if (!spriteFile.exists()) { if (!spriteFile.exists()) {
@ -68,7 +73,7 @@ class HitEffectSpriteManager(private val context: Context) {
} }
try { try {
val spritesheetFile = File(hitSpritesDir, "$spritesheetName.png") val spritesheetFile = File(getHitSpritesDir(), "$spritesheetName.png")
if (!spritesheetFile.exists()) { if (!spritesheetFile.exists()) {
println("Damage effect spritesheet not found: ${spritesheetFile.absolutePath}") println("Damage effect spritesheet not found: ${spritesheetFile.absolutePath}")
@ -118,28 +123,21 @@ class HitEffectSpriteManager(private val context: Context) {
} }
/** /**
* Get available hit sprite names * Get all available hit sprites
* @return List of available hit sprite names * @return List of hit sprite names (without .png extension)
*/ */
fun getAvailableHitSprites(): List<String> { fun getAvailableHitSprites(): List<String> {
try { val hitSpritesDir = getHitSpritesDir()
if (!hitSpritesDir.exists()) { if (!hitSpritesDir.exists()) {
return emptyList() return emptyList()
} }
val hitFiles = hitSpritesDir.listFiles { file -> return hitSpritesDir.listFiles { file ->
file.name.startsWith("hit_") && file.name.endsWith(".png") file.name.startsWith("hit_") && file.name.endsWith(".png")
} ?: emptyArray() }?.map { file ->
return hitFiles.map { file ->
file.name.substringBefore(".png") file.name.substringBefore(".png")
}.sorted() }?.sorted() ?: emptyList()
} catch (e: Exception) {
println("Error getting available hit sprites: ${e.message}")
e.printStackTrace()
return emptyList()
}
} }
/** /**
@ -148,11 +146,11 @@ class HitEffectSpriteManager(private val context: Context) {
*/ */
fun getAvailableDamageEffectSpritesheets(): List<String> { fun getAvailableDamageEffectSpritesheets(): List<String> {
try { try {
if (!hitSpritesDir.exists()) { if (!getHitSpritesDir().exists()) {
return emptyList() return emptyList()
} }
val dmgFiles = hitSpritesDir.listFiles { file -> val dmgFiles = getHitSpritesDir().listFiles { file ->
file.name.startsWith("dmg_ef") && file.name.endsWith(".png") file.name.startsWith("dmg_ef") && file.name.endsWith(".png")
} ?: emptyArray() } ?: emptyArray()

View File

@ -3,13 +3,17 @@ package com.github.nacabaro.vbhelper.battle
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Environment
import java.io.File import java.io.File
class IndividualSpriteManager(private val context: Context) { class IndividualSpriteManager(private val context: Context) {
private val spriteCache = mutableMapOf<String, Bitmap>() private val spriteCache = mutableMapOf<String, Bitmap>()
// Base directory where individual sprite PNGs are stored // Get the external storage directory for sprite files
private val spriteBaseDir = File(context.filesDir, "battle_sprites/extracted_assets/sprites") private fun getSpriteBaseDir(): File {
val externalDir = Environment.getExternalStorageDirectory()
return File(externalDir, "VBHelper/battle_sprites/extracted_assets/sprites")
}
/** /**
* Load a specific sprite frame for a character * Load a specific sprite frame for a character
@ -26,6 +30,7 @@ class IndividualSpriteManager(private val context: Context) {
} }
// Debug: Check if base directory exists // Debug: Check if base directory exists
val spriteBaseDir = getSpriteBaseDir()
if (!spriteBaseDir.exists()) { if (!spriteBaseDir.exists()) {
println("Sprite base directory does not exist: ${spriteBaseDir.absolutePath}") println("Sprite base directory does not exist: ${spriteBaseDir.absolutePath}")
return null return null
@ -68,10 +73,10 @@ class IndividualSpriteManager(private val context: Context) {
* @return List of frame numbers (1-12) that exist for this character * @return List of frame numbers (1-12) that exist for this character
*/ */
fun getAvailableFrames(characterId: String): List<Int> { fun getAvailableFrames(characterId: String): List<Int> {
try { val spriteBaseDir = getSpriteBaseDir()
val characterDir = File(spriteBaseDir, characterId) val characterDir = File(spriteBaseDir, characterId)
if (!characterDir.exists()) { if (!characterDir.exists()) {
println("Character directory not found: ${characterDir.absolutePath}")
return emptyList() return emptyList()
} }
@ -80,39 +85,26 @@ class IndividualSpriteManager(private val context: Context) {
} ?: emptyArray() } ?: emptyArray()
return spriteFiles.mapNotNull { file -> return spriteFiles.mapNotNull { file ->
// Extract frame number from filename (e.g., "dim012_mon03_01.png" -> 1) val fileName = file.name
val frameNumberStr = file.name.substringAfter("_").substringBefore(".png") val frameMatch = Regex("${characterId}_(\\d{2})\\.png").find(fileName)
frameNumberStr.toIntOrNull() frameMatch?.groupValues?.get(1)?.toIntOrNull()
}.sorted() }.sorted()
} catch (e: Exception) {
println("Error getting available frames: ${e.message}")
e.printStackTrace()
return emptyList()
}
} }
/** /**
* Get all available characters * Get all available character IDs
* @return List of character IDs that have sprite directories * @return List of character IDs that have sprite directories
*/ */
fun getAvailableCharacters(): List<String> { fun getAvailableCharacters(): List<String> {
try { val spriteBaseDir = getSpriteBaseDir()
if (!spriteBaseDir.exists()) { if (!spriteBaseDir.exists()) {
return emptyList() return emptyList()
} }
val characterDirs = spriteBaseDir.listFiles { file -> return spriteBaseDir.listFiles { file ->
file.isDirectory && file.name.matches(Regex("dim\\d+_mon\\d+.*")) file.isDirectory && file.listFiles()?.any { it.name.endsWith(".png") } == true
} ?: emptyArray() }?.map { it.name }?.sorted() ?: emptyList()
return characterDirs.map { it.name }.sorted()
} catch (e: Exception) {
println("Error getting available characters: ${e.message}")
e.printStackTrace()
return emptyList()
}
} }
/** /**
@ -128,7 +120,7 @@ class IndividualSpriteManager(private val context: Context) {
* @return true if the character has sprite files, false otherwise * @return true if the character has sprite files, false otherwise
*/ */
fun hasCharacterSprites(characterId: String): Boolean { fun hasCharacterSprites(characterId: String): Boolean {
val characterDir = File(spriteBaseDir, characterId) val characterDir = File(getSpriteBaseDir(), characterId)
if (!characterDir.exists()) { if (!characterDir.exists()) {
return false return false
} }

View File

@ -1,15 +1,22 @@
package com.github.nacabaro.vbhelper.battle package com.github.nacabaro.vbhelper.battle
import android.content.Context import android.content.Context
import android.os.Environment
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
class SpriteFileManager(private val context: Context) { class SpriteFileManager(private val context: Context) {
fun copySpriteFilesToInternalStorage() { // Get the external storage directory for sprite files
private fun getSpriteBaseDir(): File {
val externalDir = Environment.getExternalStorageDirectory()
return File(externalDir, "VBHelper/battle_sprites")
}
fun copySpriteFilesToExternalStorage() {
try { try {
println("Starting sprite file copy process...") println("Starting sprite file copy process to external storage...")
// Debug: List what's in the assets directory // Debug: List what's in the assets directory
val assetManager = context.assets val assetManager = context.assets
@ -47,17 +54,17 @@ class SpriteFileManager(private val context: Context) {
} }
} }
// Create the base directory for battle_sprites // Create the base directory for battle_sprites in external storage
val battleSpritesDir = File(context.filesDir, "battle_sprites") val battleSpritesDir = getSpriteBaseDir()
if (!battleSpritesDir.exists()) { if (!battleSpritesDir.exists()) {
battleSpritesDir.mkdirs() battleSpritesDir.mkdirs()
println("Created battle_sprites directory: ${battleSpritesDir.absolutePath}") println("Created battle_sprites directory in external storage: ${battleSpritesDir.absolutePath}")
} else { } else {
println("battle_sprites directory already exists: ${battleSpritesDir.absolutePath}") println("battle_sprites directory already exists in external storage: ${battleSpritesDir.absolutePath}")
} }
// Copy all subdirectories from battle_sprites assets to internal storage // Copy all subdirectories from battle_sprites assets to external storage
println("Copying all battle_sprites subdirectories...") println("Copying all battle_sprites subdirectories to external storage...")
battleSpritesFiles?.forEach { subdir -> battleSpritesFiles?.forEach { subdir ->
val sourcePath = "battle_sprites/$subdir" val sourcePath = "battle_sprites/$subdir"
val targetDir = File(battleSpritesDir, subdir) val targetDir = File(battleSpritesDir, subdir)
@ -65,7 +72,7 @@ class SpriteFileManager(private val context: Context) {
copyAssetDirectory(sourcePath, targetDir) copyAssetDirectory(sourcePath, targetDir)
} }
println("Sprite files copied successfully to: ${battleSpritesDir.absolutePath}") println("Sprite files copied successfully to external storage: ${battleSpritesDir.absolutePath}")
// Verify that attack sprites were copied // Verify that attack sprites were copied
val atkspritesDir = File(battleSpritesDir, "extracted_atksprites") val atkspritesDir = File(battleSpritesDir, "extracted_atksprites")
@ -95,7 +102,7 @@ class SpriteFileManager(private val context: Context) {
} }
} catch (e: Exception) { } catch (e: Exception) {
println("Error copying sprite files: ${e.message}") println("Error copying sprite files to external storage: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
} }
@ -180,7 +187,7 @@ class SpriteFileManager(private val context: Context) {
} }
fun checkSpriteFilesExist(): Boolean { fun checkSpriteFilesExist(): Boolean {
val battleSpritesDir = File(context.filesDir, "battle_sprites") val battleSpritesDir = getSpriteBaseDir()
val extractedAssetsDir = File(battleSpritesDir, "extracted_assets") val extractedAssetsDir = File(battleSpritesDir, "extracted_assets")
val extractedStatsDir = File(battleSpritesDir, "extracted_digimon_stats") val extractedStatsDir = File(battleSpritesDir, "extracted_digimon_stats")
val atkspritesDir = File(battleSpritesDir, "extracted_atksprites") val atkspritesDir = File(battleSpritesDir, "extracted_atksprites")
@ -204,7 +211,7 @@ class SpriteFileManager(private val context: Context) {
fun clearSpriteFiles() { fun clearSpriteFiles() {
try { try {
val battleSpritesDir = File(context.filesDir, "battle_sprites") val battleSpritesDir = getSpriteBaseDir()
if (battleSpritesDir.exists()) { if (battleSpritesDir.exists()) {
deleteDirectory(battleSpritesDir) deleteDirectory(battleSpritesDir)

View File

@ -66,9 +66,72 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Environment
import java.io.File import java.io.File
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.foundation.layout.width
@Composable
fun isLandscapeMode(): Boolean {
val configuration = LocalConfiguration.current
return configuration.screenWidthDp > configuration.screenHeightDp
}
@Composable
fun getLandscapeModifier(): Modifier {
val configuration = LocalConfiguration.current
val isLandscape = configuration.screenWidthDp > configuration.screenHeightDp
return if (isLandscape) {
Modifier.width(200.dp).height(8.dp)
} else {
Modifier.fillMaxWidth().height(10.dp)
}
}
@Composable
fun getLandscapeAlignment(): Alignment {
val configuration = LocalConfiguration.current
val isLandscape = configuration.screenWidthDp > configuration.screenHeightDp
return if (isLandscape) Alignment.Center else Alignment.TopStart
}
@Composable
fun getLandscapeHorizontalAlignment(): Alignment.Horizontal {
val configuration = LocalConfiguration.current
val isLandscape = configuration.screenWidthDp > configuration.screenHeightDp
return if (isLandscape) Alignment.CenterHorizontally else Alignment.Start
}
@Composable
fun getLandscapeFontSize(): androidx.compose.ui.unit.TextUnit {
val configuration = LocalConfiguration.current
val isLandscape = configuration.screenWidthDp > configuration.screenHeightDp
return if (isLandscape) 14.sp else 16.sp
}
@Composable
fun getLandscapeBoxModifier(): Modifier {
val configuration = LocalConfiguration.current
val isLandscape = configuration.screenWidthDp > configuration.screenHeightDp
return if (isLandscape) {
Modifier
.width(220.dp) // Slightly wider than the progress bar to accommodate padding
.background(
color = Color.Gray.copy(alpha = 0.6f),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp)
)
.padding(8.dp)
} else {
Modifier
.fillMaxWidth()
.background(
color = Color.Gray.copy(alpha = 0.6f),
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp)
)
.padding(8.dp)
}
}
@Composable @Composable
fun AnimatedDamageNumber( fun AnimatedDamageNumber(
@ -733,21 +796,16 @@ fun MiddleBattleView(
// Enemy HP bar and text with background box // Enemy HP bar and text with background box
Box( Box(
modifier = Modifier modifier = getLandscapeBoxModifier(),
.fillMaxWidth() contentAlignment = getLandscapeAlignment()
.background( ) {
color = Color.Gray.copy(alpha = 0.6f), Column(
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp) horizontalAlignment = getLandscapeHorizontalAlignment()
)
.padding(8.dp)
) { ) {
Column {
// Enemy HP bar (top) // Enemy HP bar (top)
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.opponentHP / (opponentCharacter?.baseHp?.toFloat() ?: 100f), progress = battleSystem.opponentHP / (opponentCharacter?.baseHp?.toFloat() ?: 100f),
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Red, color = Color.Red,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -757,7 +815,7 @@ fun MiddleBattleView(
// Enemy HP display numbers // Enemy HP display numbers
Text( Text(
text = "Enemy HP: ${battleSystem.opponentHP.toInt()}/${opponentCharacter?.baseHp ?: 100}", text = "Enemy HP: ${battleSystem.opponentHP.toInt()}/${opponentCharacter?.baseHp ?: 100}",
fontSize = 16.sp, fontSize = getLandscapeFontSize(),
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
shadow = Shadow( shadow = Shadow(
@ -962,9 +1020,7 @@ fun MiddleBattleView(
// Critical bar // Critical bar
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.critBarProgress / 100f, progress = battleSystem.critBarProgress / 100f,
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Yellow, color = Color.Yellow,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -973,21 +1029,16 @@ fun MiddleBattleView(
// Player HP bar and text with background box // Player HP bar and text with background box
Box( Box(
modifier = Modifier modifier = getLandscapeBoxModifier(),
.fillMaxWidth() contentAlignment = getLandscapeAlignment()
.background( ) {
color = Color.Gray.copy(alpha = 0.6f), Column(
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp) horizontalAlignment = getLandscapeHorizontalAlignment()
)
.padding(8.dp)
) { ) {
Column {
// Player HP bar // Player HP bar
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.playerHP / (activeCharacter?.baseHp?.toFloat() ?: 100f), progress = battleSystem.playerHP / (activeCharacter?.baseHp?.toFloat() ?: 100f),
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Green, color = Color.Green,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -997,7 +1048,7 @@ fun MiddleBattleView(
// Player HP display numbers // Player HP display numbers
Text( Text(
text = "HP: ${battleSystem.playerHP.toInt()}/${activeCharacter?.baseHp ?: 100}", text = "HP: ${battleSystem.playerHP.toInt()}/${activeCharacter?.baseHp ?: 100}",
fontSize = 16.sp, fontSize = getLandscapeFontSize(),
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
shadow = Shadow( shadow = Shadow(
@ -1193,21 +1244,16 @@ fun PlayerBattleView(
// Health bar and text with background box // Health bar and text with background box
Box( Box(
modifier = Modifier modifier = getLandscapeBoxModifier(),
.fillMaxWidth() contentAlignment = getLandscapeAlignment()
.background( ) {
color = Color.Gray.copy(alpha = 0.6f), Column(
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp) horizontalAlignment = getLandscapeHorizontalAlignment()
)
.padding(8.dp)
) { ) {
Column {
// Health bar // Health bar
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.playerHP / (activeCharacter?.baseHp?.toFloat() ?: 100f), progress = battleSystem.playerHP / (activeCharacter?.baseHp?.toFloat() ?: 100f),
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Green, color = Color.Green,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -1217,7 +1263,7 @@ fun PlayerBattleView(
// Health display numbers // Health display numbers
Text( Text(
text = "HP: ${battleSystem.playerHP.toInt()}/${activeCharacter?.baseHp ?: 100}", text = "HP: ${battleSystem.playerHP.toInt()}/${activeCharacter?.baseHp ?: 100}",
fontSize = 16.sp, fontSize = getLandscapeFontSize(),
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
shadow = Shadow( shadow = Shadow(
@ -1363,9 +1409,7 @@ fun PlayerBattleView(
// Critical bar // Critical bar
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.critBarProgress / 100f, progress = battleSystem.critBarProgress / 100f,
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Yellow, color = Color.Yellow,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -1521,21 +1565,16 @@ fun EnemyBattleView(
) { ) {
// Enemy HP bar and text with background box // Enemy HP bar and text with background box
Box( Box(
modifier = Modifier modifier = getLandscapeBoxModifier(),
.fillMaxWidth() contentAlignment = getLandscapeAlignment()
.background( ) {
color = Color.Gray.copy(alpha = 0.6f), Column(
shape = androidx.compose.foundation.shape.RoundedCornerShape(8.dp) horizontalAlignment = getLandscapeHorizontalAlignment()
)
.padding(8.dp)
) { ) {
Column {
// Enemy HP bar // Enemy HP bar
LinearProgressIndicator( LinearProgressIndicator(
progress = battleSystem.opponentHP / (activeCharacter?.baseHp?.toFloat() ?: 100f), progress = battleSystem.opponentHP / (activeCharacter?.baseHp?.toFloat() ?: 100f),
modifier = Modifier modifier = getLandscapeModifier(),
.fillMaxWidth()
.height(10.dp),
color = Color.Red, color = Color.Red,
trackColor = Color.Gray trackColor = Color.Gray
) )
@ -1545,7 +1584,7 @@ fun EnemyBattleView(
// Enemy HP display numbers // Enemy HP display numbers
Text( Text(
text = "Enemy HP: ${battleSystem.opponentHP.toInt()}/${activeCharacter?.baseHp ?: 100}", text = "Enemy HP: ${battleSystem.opponentHP.toInt()}/${activeCharacter?.baseHp ?: 100}",
fontSize = 16.sp, fontSize = getLandscapeFontSize(),
color = Color.White, color = Color.White,
style = TextStyle( style = TextStyle(
shadow = Shadow( shadow = Shadow(
@ -1735,10 +1774,10 @@ fun BattlesScreen() {
println("BATTLESCREEN: LaunchedEffect triggered - checking sprite files...") println("BATTLESCREEN: LaunchedEffect triggered - checking sprite files...")
val spriteFileManager = SpriteFileManager(context) val spriteFileManager = SpriteFileManager(context)
if (!spriteFileManager.checkSpriteFilesExist()) { if (!spriteFileManager.checkSpriteFilesExist()) {
println("BATTLESCREEN: Copying sprite files to internal storage...") println("BATTLESCREEN: Copying sprite files to external storage...")
spriteFileManager.copySpriteFilesToInternalStorage() spriteFileManager.copySpriteFilesToExternalStorage()
} else { } else {
println("BATTLESCREEN: Sprite files already exist in internal storage") println("BATTLESCREEN: Sprite files already exist in external storage")
} }
} }
@ -2077,6 +2116,7 @@ fun BattlesScreen() {
championButton() championButton()
ultimateButton() ultimateButton()
megaButton() megaButton()
/*
Button( Button(
onClick = { onClick = {
showSpriteTester = true showSpriteTester = true
@ -2098,6 +2138,8 @@ fun BattlesScreen() {
) { ) {
Text("Clear Sprite Files") Text("Clear Sprite Files")
} }
*/
} }
} }
} }
@ -2387,10 +2429,11 @@ fun AnimatedBattleBackground(
println("DEBUG: Screen dimensions = ${screenWidth.value}x${screenHeight.value}dp") println("DEBUG: Screen dimensions = ${screenWidth.value}x${screenHeight.value}dp")
} }
// Load background image from internal storage // Load background image from external storage
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
try { try {
val backgroundFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png") val externalDir = Environment.getExternalStorageDirectory()
val backgroundFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png")
if (backgroundFile.exists()) { if (backgroundFile.exists()) {
backgroundBitmap = BitmapFactory.decodeFile(backgroundFile.absolutePath) backgroundBitmap = BitmapFactory.decodeFile(backgroundFile.absolutePath)
println("Successfully loaded battle background: ${backgroundFile.absolutePath}") println("Successfully loaded battle background: ${backgroundFile.absolutePath}")
@ -2469,11 +2512,13 @@ fun MultiLayerAnimatedBattleBackground(
println("DEBUG: Multi-layer screen dimensions = ${screenWidth.value}x${screenHeight.value}dp") println("DEBUG: Multi-layer screen dimensions = ${screenWidth.value}x${screenHeight.value}dp")
} }
// Load all three background layers from internal storage // Load all three background layers from external storage
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
try { try {
val externalDir = Environment.getExternalStorageDirectory()
// Back layer (BattleBg_0018_BattleBg_0013.png) // Back layer (BattleBg_0018_BattleBg_0013.png)
val backLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/BattleBg_0018_BattleBg_0013.png") val backLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/BattleBg_0018_BattleBg_0013.png")
if (backLayerFile.exists()) { if (backLayerFile.exists()) {
backLayerBitmap = BitmapFactory.decodeFile(backLayerFile.absolutePath) backLayerBitmap = BitmapFactory.decodeFile(backLayerFile.absolutePath)
println("Successfully loaded back layer background: ${backLayerFile.absolutePath}") println("Successfully loaded back layer background: ${backLayerFile.absolutePath}")
@ -2482,7 +2527,7 @@ fun MultiLayerAnimatedBattleBackground(
} }
// Middle layer (BattleBg_0015_BattleBg_0012.png) // Middle layer (BattleBg_0015_BattleBg_0012.png)
val middleLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png") val middleLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png")
if (middleLayerFile.exists()) { if (middleLayerFile.exists()) {
middleLayerBitmap = BitmapFactory.decodeFile(middleLayerFile.absolutePath) middleLayerBitmap = BitmapFactory.decodeFile(middleLayerFile.absolutePath)
println("Successfully loaded middle layer background: ${middleLayerFile.absolutePath}") println("Successfully loaded middle layer background: ${middleLayerFile.absolutePath}")
@ -2491,7 +2536,7 @@ fun MultiLayerAnimatedBattleBackground(
} }
// Front layer (BattleBg_0005_BattleBg_0011.png) // Front layer (BattleBg_0005_BattleBg_0011.png)
val frontLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/BattleBg_0005_BattleBg_0011.png") val frontLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/BattleBg_0005_BattleBg_0011.png")
if (frontLayerFile.exists()) { if (frontLayerFile.exists()) {
frontLayerBitmap = BitmapFactory.decodeFile(frontLayerFile.absolutePath) frontLayerBitmap = BitmapFactory.decodeFile(frontLayerFile.absolutePath)
println("Successfully loaded front layer background: ${frontLayerFile.absolutePath}") println("Successfully loaded front layer background: ${frontLayerFile.absolutePath}")