Compare commits

..

11 commits

Author SHA1 Message Date
cmclark00
103a21d9b7 fix: update text styles and sizes across app to match mintris theme 2025-03-29 02:21:15 -04:00
cmclark00
68e8cb160f fix: theme colors and UI improvements 2025-03-29 01:59:14 -04:00
cmclark00
42b9bcfab4 fix: progression screen theme colors and XP bar styling 2025-03-29 01:58:53 -04:00
cmclark00
1980f15a46 Adjust XP progression and improve animations: - Increased XP requirements and curve for slower leveling - Enhanced XP gain animations with smoother transitions - Improved visual feedback for level progression 2025-03-29 00:04:44 -04:00
cmclark00
c6a4339931 Fix: Update theme loading to use PlayerProgressionManager consistently across all activities 2025-03-28 20:47:37 -04:00
cmclark00
83935d35a8 Fix: Replace minOf with min in PlayerProgressionManager 2025-03-28 20:43:40 -04:00
cmclark00
d0700202b7 Update game mechanics and haptic feedback implementation 2025-03-28 20:41:03 -04:00
cmclark00
af0082a6db refactor: modernize codebase - Use KTX extension functions for system services - Update performClick handling in touch events - Modernize back gesture handling with KTX - Improve vibrator service initialization 2025-03-28 20:21:25 -04:00
cmclark00
ebff618fa4 fix: balance progression system - Increased base XP requirements and curve - Added diminishing returns for higher levels - Reduced XP rewards for special moves - Capped level multiplier at level 10 - Added time-based XP reduction 2025-03-28 20:19:17 -04:00
cmclark00
7cdc9988cb fix: enhance block skins to match their respective themes - Classic: Clean white blocks with subtle glow - Neon: Strong glow effects with magenta colors - Retro: Pixelated look with highlights and shadows - Minimalist: Clean black blocks with subtle borders - Galaxy: Cosmic effects with gradient and sparkles 2025-03-28 20:17:44 -04:00
cmclark00
2774703df5 fix: persist block skin selection through app restarts 2025-03-28 19:36:14 -04:00
14 changed files with 525 additions and 310 deletions

View file

@ -66,8 +66,7 @@ class HighScoreEntryActivity : AppCompatActivity() {
} }
private fun loadThemePreference(): String { private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) return progressionManager.getSelectedTheme()
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
} }
private fun applyTheme(themeId: String) { private fun applyTheme(themeId: String) {

View file

@ -58,8 +58,7 @@ class HighScoresActivity : AppCompatActivity() {
} }
private fun loadThemePreference(): String { private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) return progressionManager.getSelectedTheme()
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
} }
private fun applyTheme(themeId: String) { private fun applyTheme(themeId: String) {

View file

@ -91,17 +91,6 @@ class MainActivity : AppCompatActivity() {
themeSelector = binding.themeSelector themeSelector = binding.themeSelector
blockSkinSelector = binding.blockSkinSelector blockSkinSelector = binding.blockSkinSelector
// Load and apply theme preference
currentTheme = progressionManager.getSelectedTheme()
applyTheme(currentTheme)
// Load and apply block skin preference
gameView.setBlockSkin(progressionManager.getSelectedBlockSkin())
// Set up game view
gameView.setGameBoard(gameBoard)
gameView.setHaptics(gameHaptics)
// Set up progression screen // Set up progression screen
progressionScreen = binding.progressionScreen progressionScreen = binding.progressionScreen
progressionScreen.visibility = View.GONE progressionScreen.visibility = View.GONE
@ -110,6 +99,24 @@ class MainActivity : AppCompatActivity() {
binding.gameOverContainer.visibility = View.VISIBLE binding.gameOverContainer.visibility = View.VISIBLE
} }
// Load and apply theme preference
currentTheme = progressionManager.getSelectedTheme()
applyTheme(currentTheme)
// Load and apply block skin preference
gameView.setBlockSkin(progressionManager.getSelectedBlockSkin())
// Update block skin selector with current selection
blockSkinSelector.updateBlockSkins(
progressionManager.getUnlockedBlocks(),
gameView.getCurrentBlockSkin(),
progressionManager.getPlayerLevel()
)
// Set up game view
gameView.setGameBoard(gameBoard)
gameView.setHaptics(gameHaptics)
// Set up theme selector // Set up theme selector
themeSelector.onThemeSelected = { themeId: String -> themeSelector.onThemeSelected = { themeId: String ->
// Apply the new theme // Apply the new theme
@ -351,10 +358,7 @@ class MainActivity : AppCompatActivity() {
var showingHighScore = false var showingHighScore = false
// Show progression screen first with XP animation // Show progression screen first with XP animation
binding.gameOverContainer.visibility = View.GONE showProgressionScreen(xpGained, newRewards)
progressionScreen.visibility = View.VISIBLE
progressionScreen.applyTheme(currentTheme)
progressionScreen.showProgress(progressionManager, xpGained, newRewards, currentTheme)
// Override the continue button behavior if high score needs to be shown // Override the continue button behavior if high score needs to be shown
val originalOnContinue = progressionScreen.onContinue val originalOnContinue = progressionScreen.onContinue
@ -586,63 +590,55 @@ class MainActivity : AppCompatActivity() {
* Apply a theme to the game * Apply a theme to the game
*/ */
private fun applyTheme(themeId: String) { private fun applyTheme(themeId: String) {
// Only apply if the theme is unlocked
if (!progressionManager.isThemeUnlocked(themeId)) return
// Save the selected theme
currentTheme = themeId currentTheme = themeId
progressionManager.setSelectedTheme(themeId) val themeColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE
// Apply theme to title screen if it's visible PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF")
if (titleScreen.visibility == View.VISIBLE) { PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY
titleScreen.applyTheme(themeId) PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F")
PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1")
else -> Color.WHITE
} }
// Apply theme colors based on theme ID // Get background color for the theme
when (themeId) { val backgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> { PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
// Default black theme PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
binding.root.setBackgroundColor(Color.BLACK) PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
} PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_NEON -> { PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
// Neon theme with dark purple background PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
binding.root.setBackgroundColor(Color.parseColor("#0D0221")) else -> Color.BLACK
}
PlayerProgressionManager.THEME_MONOCHROME -> {
// Monochrome dark gray
binding.root.setBackgroundColor(Color.parseColor("#1A1A1A"))
}
PlayerProgressionManager.THEME_RETRO -> {
// Retro arcade theme
binding.root.setBackgroundColor(Color.parseColor("#3F2832"))
}
PlayerProgressionManager.THEME_MINIMALIST -> {
// Minimalist white theme
binding.root.setBackgroundColor(Color.WHITE)
// Update text colors for visibility
binding.scoreText.setTextColor(Color.BLACK)
binding.currentLevelText.setTextColor(Color.BLACK)
binding.linesText.setTextColor(Color.BLACK)
binding.comboText.setTextColor(Color.BLACK)
}
PlayerProgressionManager.THEME_GALAXY -> {
// Galaxy dark blue theme
binding.root.setBackgroundColor(Color.parseColor("#0B0C10"))
}
} }
// Apply theme to progression screen if it's visible and initialized // Apply background color to root view
if (::progressionScreen.isInitialized && progressionScreen.visibility == View.VISIBLE) { binding.root.setBackgroundColor(backgroundColor)
// Apply theme color to title screen
titleScreen.setThemeColor(themeColor)
titleScreen.setBackgroundColor(backgroundColor)
// Apply theme color to game over screen
binding.gameOverContainer.setBackgroundColor(backgroundColor)
binding.gameOverText.setTextColor(themeColor)
binding.scoreText.setTextColor(themeColor)
binding.currentLevelText.setTextColor(themeColor)
binding.linesText.setTextColor(themeColor)
binding.comboText.setTextColor(themeColor)
binding.playAgainButton.setTextColor(themeColor)
binding.playAgainButton.setBackgroundResource(android.R.color.transparent)
binding.playAgainButton.setTextSize(24f)
// Apply theme to progression screen (it will handle its own colors)
progressionScreen.applyTheme(themeId) progressionScreen.applyTheme(themeId)
}
// Apply theme color to the stats button // Apply theme color to game view
val textColor = getThemeColor(currentTheme) gameView.setThemeColor(themeColor)
binding.statsButton.setTextColor(textColor) gameView.setBackgroundColor(backgroundColor)
// Update the game view to apply theme // Save theme preference
gameView.invalidate() progressionManager.setSelectedTheme(themeId)
} }
/** /**
@ -738,4 +734,16 @@ class MainActivity : AppCompatActivity() {
} }
return super.onKeyDown(keyCode, event) return super.onKeyDown(keyCode, event)
} }
private fun showProgressionScreen(xpGained: Long, newRewards: List<String>) {
// Apply theme before showing the screen
progressionScreen.applyTheme(currentTheme)
// Show the progression screen
binding.gameOverContainer.visibility = View.GONE
progressionScreen.visibility = View.VISIBLE
// Display progression data
progressionScreen.showProgress(progressionManager, xpGained, newRewards, currentTheme)
}
} }

View file

@ -44,8 +44,7 @@ class StatsActivity : AppCompatActivity() {
} }
private fun loadThemePreference(): String { private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) return progressionManager.getSelectedTheme()
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
} }
private fun applyTheme(themeId: String) { private fun applyTheme(themeId: String) {

View file

@ -2,12 +2,14 @@ package com.mintris.game
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.graphics.BlurMaskFilter
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Paint import android.graphics.Paint
import android.graphics.Rect import android.graphics.Rect
import android.graphics.RectF import android.graphics.RectF
import android.graphics.BlurMaskFilter import android.graphics.Shader
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@ -151,6 +153,7 @@ class GameView @JvmOverloads constructor(
// Block skin // Block skin
private var currentBlockSkin: String = "block_skin_1" private var currentBlockSkin: String = "block_skin_1"
private val blockSkinPaints = mutableMapOf<String, Paint>() private val blockSkinPaints = mutableMapOf<String, Paint>()
private var currentThemeColor = Color.WHITE
private enum class Direction { private enum class Direction {
HORIZONTAL, VERTICAL HORIZONTAL, VERTICAL
@ -173,6 +176,10 @@ class GameView @JvmOverloads constructor(
// Start with paused state // Start with paused state
pause() pause()
// Load saved block skin
val prefs = context.getSharedPreferences("mintris_progression", Context.MODE_PRIVATE)
currentBlockSkin = prefs.getString("selected_block_skin", "block_skin_1") ?: "block_skin_1"
// Connect our callbacks to the GameBoard // Connect our callbacks to the GameBoard
gameBoard.onPieceMove = { onPieceMove?.invoke() } gameBoard.onPieceMove = { onPieceMove?.invoke() }
gameBoard.onPieceLock = { gameBoard.onPieceLock = {
@ -232,6 +239,7 @@ class GameView @JvmOverloads constructor(
blockSkinPaints["block_skin_1"] = Paint().apply { blockSkinPaints["block_skin_1"] = Paint().apply {
color = Color.WHITE color = Color.WHITE
isAntiAlias = true isAntiAlias = true
style = Paint.Style.FILL
} }
// Neon skin // Neon skin
@ -244,9 +252,8 @@ class GameView @JvmOverloads constructor(
// Retro skin // Retro skin
blockSkinPaints["block_skin_3"] = Paint().apply { blockSkinPaints["block_skin_3"] = Paint().apply {
color = Color.parseColor("#FF5A5F") color = Color.parseColor("#FF5A5F")
isAntiAlias = true isAntiAlias = false // Pixelated look
style = Paint.Style.STROKE style = Paint.Style.FILL
strokeWidth = 2f
} }
// Minimalist skin // Minimalist skin
@ -269,6 +276,9 @@ class GameView @JvmOverloads constructor(
*/ */
fun setBlockSkin(skinId: String) { fun setBlockSkin(skinId: String) {
currentBlockSkin = skinId currentBlockSkin = skinId
// Save the selection to SharedPreferences
val prefs = context.getSharedPreferences("mintris_progression", Context.MODE_PRIVATE)
prefs.edit().putString("selected_block_skin", skinId).commit()
invalidate() invalidate()
} }
@ -594,8 +604,23 @@ class GameView @JvmOverloads constructor(
// Create a clone of the paint to avoid modifying the original // Create a clone of the paint to avoid modifying the original
val blockPaint = Paint(paint) val blockPaint = Paint(paint)
// Special handling for neon skin // Draw block based on current skin
if (currentBlockSkin == "block_skin_2") { when (currentBlockSkin) {
"block_skin_1" -> { // Classic
// Draw outer glow
blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else Color.WHITE
canvas.drawRect(left - 2f, top - 2f, right + 2f, bottom + 2f, blockGlowPaint)
// Draw block
blockPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else Color.WHITE
blockPaint.alpha = if (isGhost) 30 else 255
canvas.drawRect(left, top, right, bottom, blockPaint)
// Draw inner glow
glowPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else Color.WHITE
canvas.drawRect(left + 1f, top + 1f, right - 1f, bottom - 1f, glowPaint)
}
"block_skin_2" -> { // Neon
// Stronger outer glow for neon skin // Stronger outer glow for neon skin
blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 0, 255) else Color.parseColor("#FF00FF") blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 0, 255) else Color.parseColor("#FF00FF")
blockGlowPaint.maskFilter = BlurMaskFilter(16f, BlurMaskFilter.Blur.OUTER) blockGlowPaint.maskFilter = BlurMaskFilter(16f, BlurMaskFilter.Blur.OUTER)
@ -628,27 +653,90 @@ class GameView @JvmOverloads constructor(
} }
canvas.drawRect(left, top, right, bottom, borderPaint) canvas.drawRect(left, top, right, bottom, borderPaint)
// Inner glow for neon blocks - brighter than before // Inner glow for neon blocks
glowPaint.color = if (isGhost) Color.argb(10, 255, 0, 255) else Color.parseColor("#FF00FF") glowPaint.color = if (isGhost) Color.argb(10, 255, 0, 255) else Color.parseColor("#FF00FF")
glowPaint.alpha = if (isGhost) 10 else 100 // More visible inner glow glowPaint.alpha = if (isGhost) 10 else 100
glowPaint.style = Paint.Style.STROKE glowPaint.style = Paint.Style.STROKE
glowPaint.strokeWidth = 2f glowPaint.strokeWidth = 2f
glowPaint.maskFilter = BlurMaskFilter(4f, BlurMaskFilter.Blur.NORMAL) glowPaint.maskFilter = BlurMaskFilter(4f, BlurMaskFilter.Blur.NORMAL)
canvas.drawRect(left + 4f, top + 4f, right - 4f, bottom - 4f, glowPaint) canvas.drawRect(left + 4f, top + 4f, right - 4f, bottom - 4f, glowPaint)
} else { }
// Standard rendering for other skins "block_skin_3" -> { // Retro
// Draw outer glow // Draw pixelated block with retro effect
blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else Color.WHITE blockPaint.color = if (isGhost) Color.argb(30, 255, 90, 95) else Color.parseColor("#FF5A5F")
canvas.drawRect(left - 2f, top - 2f, right + 2f, bottom + 2f, blockGlowPaint)
// Draw block with current skin
blockPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else blockPaint.color
blockPaint.alpha = if (isGhost) 30 else 255 blockPaint.alpha = if (isGhost) 30 else 255
// Draw main block
canvas.drawRect(left, top, right, bottom, blockPaint) canvas.drawRect(left, top, right, bottom, blockPaint)
// Draw inner glow // Draw pixelated highlights
glowPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else Color.WHITE val highlightPaint = Paint().apply {
canvas.drawRect(left + 1f, top + 1f, right - 1f, bottom - 1f, glowPaint) color = Color.parseColor("#FF8A8F")
isAntiAlias = false
style = Paint.Style.FILL
}
// Top and left highlights
canvas.drawRect(left, top, right - 2f, top + 2f, highlightPaint)
canvas.drawRect(left, top, left + 2f, bottom - 2f, highlightPaint)
// Draw pixelated shadows
val shadowPaint = Paint().apply {
color = Color.parseColor("#CC4A4F")
isAntiAlias = false
style = Paint.Style.FILL
}
// Bottom and right shadows
canvas.drawRect(left + 2f, bottom - 2f, right, bottom, shadowPaint)
canvas.drawRect(right - 2f, top + 2f, right, bottom - 2f, shadowPaint)
}
"block_skin_4" -> { // Minimalist
// Draw clean, simple block with subtle border
blockPaint.color = if (isGhost) Color.argb(30, 0, 0, 0) else Color.BLACK
blockPaint.alpha = if (isGhost) 30 else 255
blockPaint.style = Paint.Style.FILL
canvas.drawRect(left, top, right, bottom, blockPaint)
// Draw subtle border
val borderPaint = Paint().apply {
color = Color.parseColor("#333333")
style = Paint.Style.STROKE
strokeWidth = 1f
isAntiAlias = true
}
canvas.drawRect(left, top, right, bottom, borderPaint)
}
"block_skin_5" -> { // Galaxy
// Draw cosmic glow effect
blockGlowPaint.color = if (isGhost) Color.argb(30, 102, 252, 241) else Color.parseColor("#66FCF1")
blockGlowPaint.maskFilter = BlurMaskFilter(20f, BlurMaskFilter.Blur.OUTER)
canvas.drawRect(left - 8f, top - 8f, right + 8f, bottom + 8f, blockGlowPaint)
// Draw main block with gradient
val gradient = LinearGradient(
left, top, right, bottom,
Color.parseColor("#66FCF1"),
Color.parseColor("#45B7AF"),
Shader.TileMode.CLAMP
)
blockPaint.shader = gradient
blockPaint.color = if (isGhost) Color.argb(30, 102, 252, 241) else Color.parseColor("#66FCF1")
blockPaint.alpha = if (isGhost) 30 else 255
blockPaint.style = Paint.Style.FILL
canvas.drawRect(left, top, right, bottom, blockPaint)
// Draw star-like sparkles
if (!isGhost) {
val sparklePaint = Paint().apply {
color = Color.WHITE
style = Paint.Style.FILL
isAntiAlias = true
maskFilter = BlurMaskFilter(4f, BlurMaskFilter.Blur.NORMAL)
}
// Add small white dots for sparkle effect
canvas.drawCircle(left + 4f, top + 4f, 1f, sparklePaint)
canvas.drawCircle(right - 4f, bottom - 4f, 1f, sparklePaint)
}
}
} }
// Draw pulse effect if animation is active and this is a pulsing line // Draw pulse effect if animation is active and this is a pulsing line
@ -963,4 +1051,26 @@ class GameView @JvmOverloads constructor(
} }
pulseAnimator?.start() pulseAnimator?.start()
} }
/**
* Set the theme color for the game view
*/
fun setThemeColor(color: Int) {
currentThemeColor = color
blockPaint.color = color
ghostBlockPaint.color = color
glowPaint.color = color
blockGlowPaint.color = color
borderGlowPaint.color = color
pulsePaint.color = color
invalidate()
}
/**
* Set the background color for the game view
*/
override fun setBackgroundColor(color: Int) {
super.setBackgroundColor(color)
invalidate()
}
} }

View file

@ -46,8 +46,9 @@ class TitleScreen @JvmOverloads constructor(
// Callback for when the user touches the screen // Callback for when the user touches the screen
var onStartGame: (() -> Unit)? = null var onStartGame: (() -> Unit)? = null
// Theme color // Theme color and background color
private var themeColor = Color.WHITE private var themeColor = Color.WHITE
private var backgroundColor = Color.BLACK
// Define tetromino shapes (I, O, T, S, Z, J, L) // Define tetromino shapes (I, O, T, S, Z, J, L)
private val tetrominoShapes = arrayOf( private val tetrominoShapes = arrayOf(
@ -110,7 +111,7 @@ class TitleScreen @JvmOverloads constructor(
init { init {
// Title text settings // Title text settings
titlePaint.apply { titlePaint.apply {
color = Color.WHITE color = themeColor
textSize = 120f textSize = 120f
textAlign = Paint.Align.CENTER textAlign = Paint.Align.CENTER
typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD) typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD)
@ -119,7 +120,7 @@ class TitleScreen @JvmOverloads constructor(
// "Touch to start" text settings // "Touch to start" text settings
promptPaint.apply { promptPaint.apply {
color = Color.WHITE color = themeColor
textSize = 50f textSize = 50f
textAlign = Paint.Align.CENTER textAlign = Paint.Align.CENTER
typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL) typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL)
@ -129,7 +130,7 @@ class TitleScreen @JvmOverloads constructor(
// High scores text settings // High scores text settings
highScorePaint.apply { highScorePaint.apply {
color = Color.WHITE color = themeColor
textSize = 70f textSize = 70f
textAlign = Paint.Align.LEFT // Changed to LEFT alignment textAlign = Paint.Align.LEFT // Changed to LEFT alignment
typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL) // Changed to monospace typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL) // Changed to monospace
@ -137,16 +138,16 @@ class TitleScreen @JvmOverloads constructor(
alpha = 200 alpha = 200
} }
// General paint settings for tetrominos (white) // General paint settings for tetrominos
paint.apply { paint.apply {
color = Color.WHITE color = themeColor
style = Paint.Style.FILL style = Paint.Style.FILL
isAntiAlias = true isAntiAlias = true
} }
// Glow paint settings for tetrominos // Glow paint settings for tetrominos
glowPaint.apply { glowPaint.apply {
color = Color.WHITE color = themeColor
style = Paint.Style.FILL style = Paint.Style.FILL
isAntiAlias = true isAntiAlias = true
alpha = 60 alpha = 60
@ -184,8 +185,8 @@ class TitleScreen @JvmOverloads constructor(
try { try {
super.onDraw(canvas) super.onDraw(canvas)
// Draw background // Draw background using the current background color
canvas.drawColor(Color.BLACK) canvas.drawColor(backgroundColor)
// Add any pending tetrominos // Add any pending tetrominos
tetrominos.addAll(tetrominosToAdd) tetrominos.addAll(tetrominosToAdd)
@ -340,7 +341,7 @@ class TitleScreen @JvmOverloads constructor(
glowPaint.color = themeColor glowPaint.color = themeColor
// Update background color // Update background color
setBackgroundColor(when (themeId) { backgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
@ -348,8 +349,29 @@ class TitleScreen @JvmOverloads constructor(
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10") PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK else -> Color.BLACK
}) }
invalidate() invalidate()
} }
/**
* Set the theme color for the title screen
*/
fun setThemeColor(color: Int) {
themeColor = color
titlePaint.color = color
promptPaint.color = color
highScorePaint.color = color
paint.color = color
glowPaint.color = color
invalidate()
}
/**
* Set the background color for the title screen
*/
override fun setBackgroundColor(color: Int) {
backgroundColor = color
invalidate()
}
} }

View file

@ -5,6 +5,7 @@ import android.content.SharedPreferences
import com.mintris.R import com.mintris.R
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.min
/** /**
* Manages player progression, experience points, and unlockable rewards * Manages player progression, experience points, and unlockable rewards
@ -94,21 +95,22 @@ class PlayerProgressionManager(context: Context) {
*/ */
fun calculateGameXP(score: Int, lines: Int, level: Int, gameTime: Long, fun calculateGameXP(score: Int, lines: Int, level: Int, gameTime: Long,
tetrisCount: Int, perfectClearCount: Int): Long { tetrisCount: Int, perfectClearCount: Int): Long {
// Base XP from score with level multiplier // Base XP from score with level multiplier (capped at level 10)
val scoreXP = (score * (1 + LEVEL_MULTIPLIER * level)).toLong() val cappedLevel = min(level, 10)
val scoreXP = (score * (1 + LEVEL_MULTIPLIER * cappedLevel)).toLong()
// XP from lines cleared // XP from lines cleared (reduced for higher levels)
val linesXP = lines * XP_PER_LINE val linesXP = lines * XP_PER_LINE * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
// XP from special moves // XP from special moves (reduced for higher levels)
val tetrisBonus = tetrisCount * TETRIS_XP_BONUS val tetrisBonus = tetrisCount * TETRIS_XP_BONUS * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
val perfectClearBonus = perfectClearCount * PERFECT_CLEAR_XP_BONUS val perfectClearBonus = perfectClearCount * PERFECT_CLEAR_XP_BONUS * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
// Time bonus (to reward longer gameplay) // Time bonus (reduced for longer games)
val timeBonus = (gameTime / 60000) * TIME_XP_PER_MINUTE // XP per minute played val timeBonus = (gameTime / 60000) * TIME_XP_PER_MINUTE * (1 - (gameTime / 3600000) * 0.1).coerceAtLeast(0.5)
// Calculate total XP // Calculate total XP
return scoreXP + linesXP + tetrisBonus + perfectClearBonus + timeBonus return (scoreXP + linesXP + tetrisBonus + perfectClearBonus + timeBonus).toLong()
} }
/** /**
@ -281,21 +283,19 @@ class PlayerProgressionManager(context: Context) {
private const val KEY_UNLOCKED_THEMES = "unlocked_themes" private const val KEY_UNLOCKED_THEMES = "unlocked_themes"
private const val KEY_UNLOCKED_BLOCKS = "unlocked_blocks" private const val KEY_UNLOCKED_BLOCKS = "unlocked_blocks"
private const val KEY_UNLOCKED_BADGES = "unlocked_badges" private const val KEY_UNLOCKED_BADGES = "unlocked_badges"
private const val KEY_SELECTED_BLOCK_SKIN = "selected_block_skin"
private const val KEY_SELECTED_THEME = "selected_theme" private const val KEY_SELECTED_THEME = "selected_theme"
private const val KEY_SELECTED_BLOCK_SKIN = "selected_block_skin"
// XP curve parameters // XP constants
private const val BASE_XP = 4000.0 // Base XP for level 1 (reduced from 5000) private const val BASE_XP = 3000L
private const val XP_CURVE_FACTOR = 1.9 // Exponential factor for XP curve (reduced from 2.2) private const val XP_CURVE_FACTOR = 2.0
private const val LEVEL_MULTIPLIER = 0.03
private const val XP_PER_LINE = 40L
private const val TETRIS_XP_BONUS = 150L
private const val PERFECT_CLEAR_XP_BONUS = 300L
private const val TIME_XP_PER_MINUTE = 20L
// XP calculation constants // Theme constants
private const val LEVEL_MULTIPLIER = 0.15 // 15% bonus per level (increased from 10%)
private const val XP_PER_LINE = 15L // Increased from 10
private const val TETRIS_XP_BONUS = 75L // Increased from 50
private const val PERFECT_CLEAR_XP_BONUS = 250L // Increased from 200
private const val TIME_XP_PER_MINUTE = 8L // Increased from 5
// Theme IDs with required levels
const val THEME_CLASSIC = "theme_classic" const val THEME_CLASSIC = "theme_classic"
const val THEME_NEON = "theme_neon" const val THEME_NEON = "theme_neon"
const val THEME_MONOCHROME = "theme_monochrome" const val THEME_MONOCHROME = "theme_monochrome"
@ -326,7 +326,7 @@ class PlayerProgressionManager(context: Context) {
*/ */
fun setSelectedBlockSkin(skinId: String) { fun setSelectedBlockSkin(skinId: String) {
if (unlockedBlocks.contains(skinId)) { if (unlockedBlocks.contains(skinId)) {
prefs.edit().putString(KEY_SELECTED_BLOCK_SKIN, skinId).apply() prefs.edit().putString(KEY_SELECTED_BLOCK_SKIN, skinId).commit()
} }
} }

View file

@ -31,6 +31,9 @@ class ProgressionScreen @JvmOverloads constructor(
private val rewardsContainer: LinearLayout private val rewardsContainer: LinearLayout
private val continueButton: TextView private val continueButton: TextView
// Current theme
private var currentTheme: String = PlayerProgressionManager.THEME_CLASSIC
// Callback for when the player dismisses the screen // Callback for when the player dismisses the screen
var onContinue: (() -> Unit)? = null var onContinue: (() -> Unit)? = null
@ -62,6 +65,9 @@ class ProgressionScreen @JvmOverloads constructor(
newRewards: List<String>, newRewards: List<String>,
themeId: String = PlayerProgressionManager.THEME_CLASSIC themeId: String = PlayerProgressionManager.THEME_CLASSIC
) { ) {
// Update current theme
currentTheme = themeId
// Hide rewards container initially if there are no new rewards // Hide rewards container initially if there are no new rewards
rewardsContainer.visibility = if (newRewards.isEmpty()) View.GONE else View.INVISIBLE rewardsContainer.visibility = if (newRewards.isEmpty()) View.GONE else View.INVISIBLE
@ -74,20 +80,39 @@ class ProgressionScreen @JvmOverloads constructor(
playerLevelText.text = "Player Level: $playerLevel" playerLevelText.text = "Player Level: $playerLevel"
xpGainText.text = "+$xpGained XP" xpGainText.text = "+$xpGained XP"
// Begin animation sequence // Update level up text visibility
xpProgressBar.setXPValues(playerLevel, currentXP, xpForNextLevel) val progressionTitle = findViewById<TextView>(R.id.progression_title)
progressionTitle.visibility = if (newRewards.any { it.contains("Level") }) View.VISIBLE else View.GONE
// Animate XP gain text entrance // Start with initial animations
AnimatorSet().apply {
// Fade in the XP gain text
val xpTextAnimator = ObjectAnimator.ofFloat(xpGainText, "alpha", 0f, 1f).apply { val xpTextAnimator = ObjectAnimator.ofFloat(xpGainText, "alpha", 0f, 1f).apply {
duration = 500 duration = 800
interpolator = AccelerateDecelerateInterpolator()
} }
// Schedule animation for the XP bar after text appears // Set up the XP progress bar animation sequence
val xpBarAnimator = ObjectAnimator.ofFloat(xpProgressBar, "alpha", 0f, 1f).apply {
duration = 800
interpolator = AccelerateDecelerateInterpolator()
}
// Play animations in sequence
play(xpTextAnimator)
play(xpBarAnimator).after(xpTextAnimator)
start()
}
// Set initial progress bar state
xpProgressBar.setXPValues(playerLevel, currentXP - xpGained, xpForNextLevel)
// Animate the XP gain after a short delay
postDelayed({ postDelayed({
xpProgressBar.animateXPGain(xpGained, playerLevel, currentXP, xpForNextLevel) xpProgressBar.animateXPGain(xpGained, playerLevel, currentXP, xpForNextLevel)
}, 600) }, 1000) // Increased delay to 1 second for better visual flow
// If there are new rewards, show them with animation // If there are new rewards, show them with animation after XP bar animation
if (newRewards.isNotEmpty()) { if (newRewards.isNotEmpty()) {
// Create reward cards // Create reward cards
rewardsContainer.removeAllViews() rewardsContainer.removeAllViews()
@ -113,18 +138,12 @@ class ProgressionScreen @JvmOverloads constructor(
card.animate() card.animate()
.alpha(1f) .alpha(1f)
.translationY(0f) .translationY(0f)
.setDuration(400) .setDuration(600) // Increased duration for smoother animation
.setStartDelay((i * 150).toLong()) .setStartDelay((i * 200).toLong()) // Increased delay between cards
.setInterpolator(OvershootInterpolator()) .setInterpolator(OvershootInterpolator())
.start() .start()
} }
}, 2000) // Wait for XP bar animation to finish }, 2500) // Increased delay to wait for XP bar animation to finish
}
// Start with initial animations
AnimatorSet().apply {
play(xpTextAnimator)
start()
} }
} }
@ -137,8 +156,17 @@ class ProgressionScreen @JvmOverloads constructor(
cardElevation = 4f cardElevation = 4f
useCompatPadding = true useCompatPadding = true
// Default background color - will be adjusted based on theme // Set background color based on current theme
setCardBackgroundColor(Color.BLACK) val backgroundColor = when (currentTheme) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK
}
setCardBackgroundColor(backgroundColor)
layoutParams = LinearLayout.LayoutParams( layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT,
@ -167,6 +195,8 @@ class ProgressionScreen @JvmOverloads constructor(
* Apply the current theme to the progression screen * Apply the current theme to the progression screen
*/ */
fun applyTheme(themeId: String) { fun applyTheme(themeId: String) {
currentTheme = themeId
// Get reference to the title text // Get reference to the title text
val progressionTitle = findViewById<TextView>(R.id.progression_title) val progressionTitle = findViewById<TextView>(R.id.progression_title)
val rewardsTitle = findViewById<TextView>(R.id.rewards_title) val rewardsTitle = findViewById<TextView>(R.id.rewards_title)
@ -248,10 +278,10 @@ class ProgressionScreen @JvmOverloads constructor(
} }
} }
// Set theme color on XP progress bar // Update XP progress bar theme color
xpProgressBar.setThemeColor(xpThemeColor) xpProgressBar.setThemeColor(xpThemeColor)
// Update card colors for any existing reward cards // Update reward card colors
updateRewardCardColors(themeId) updateRewardCardColors(themeId)
} }
@ -259,8 +289,7 @@ class ProgressionScreen @JvmOverloads constructor(
* Update colors of existing reward cards to match the theme * Update colors of existing reward cards to match the theme
*/ */
private fun updateRewardCardColors(themeId: String) { private fun updateRewardCardColors(themeId: String) {
// Color for card backgrounds based on theme val backgroundColor = when (themeId) {
val cardBackgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
@ -270,28 +299,9 @@ class ProgressionScreen @JvmOverloads constructor(
else -> Color.BLACK else -> Color.BLACK
} }
// Text color for rewards based on theme
val rewardTextColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF")
PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F")
PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1")
else -> Color.WHITE
}
// Update each card in the rewards container
for (i in 0 until rewardsContainer.childCount) { for (i in 0 until rewardsContainer.childCount) {
val card = rewardsContainer.getChildAt(i) as? CardView val card = rewardsContainer.getChildAt(i) as? CardView
card?.let { card?.setCardBackgroundColor(backgroundColor)
it.setCardBackgroundColor(cardBackgroundColor)
// Update text color in the card
if (it.childCount > 0 && it.getChildAt(0) is TextView) {
(it.getChildAt(0) as TextView).setTextColor(rewardTextColor)
}
}
} }
} }
} }

View file

@ -99,6 +99,8 @@ class XPProgressBar @JvmOverloads constructor(
*/ */
fun setThemeColor(color: Int) { fun setThemeColor(color: Int) {
themeColor = color themeColor = color
progressPaint.color = color
textPaint.color = color
levelBadgePaint.color = color levelBadgePaint.color = color
invalidate() invalidate()
} }

View file

@ -62,36 +62,40 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="32sp"
android:fontFamily="sans-serif-light" android:textStyle="bold"
tools:text="Score: 0" /> android:fontFamily="sans-serif"
tools:text="score: 0" />
<TextView <TextView
android:id="@+id/currentLevelText" android:id="@+id/currentLevelText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="32sp"
android:fontFamily="sans-serif-light" android:textStyle="bold"
tools:text="Level: 1" /> android:fontFamily="sans-serif"
tools:text="level: 1" />
<TextView <TextView
android:id="@+id/linesText" android:id="@+id/linesText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="32sp"
android:fontFamily="sans-serif-light" android:textStyle="bold"
tools:text="Lines: 0" /> android:fontFamily="sans-serif"
tools:text="lines: 0" />
<TextView <TextView
android:id="@+id/comboText" android:id="@+id/comboText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="32sp"
android:fontFamily="sans-serif-light" android:textStyle="bold"
tools:text="Combo: 0" /> android:fontFamily="sans-serif"
tools:text="combo: 0" />
</LinearLayout> </LinearLayout>
<!-- Next Piece Preview --> <!-- Next Piece Preview -->
@ -131,16 +135,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/game_over" android:text="@string/game_over"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="36sp"
android:textStyle="bold" /> android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/session_stats" android:text="@string/session_stats"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="20sp" android:textSize="28sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:layout_marginTop="24dp" /> android:layout_marginTop="24dp" />
<TextView <TextView
@ -149,7 +155,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionLinesText" android:id="@+id/sessionLinesText"
@ -157,7 +165,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionPiecesText" android:id="@+id/sessionPiecesText"
@ -165,7 +175,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionTimeText" android:id="@+id/sessionTimeText"
@ -173,7 +185,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionLevelText" android:id="@+id/sessionLevelText"
@ -181,15 +195,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/line_clears" android:text="@string/line_clears"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="20sp" android:textSize="28sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:layout_marginTop="16dp" /> android:layout_marginTop="16dp" />
<TextView <TextView
@ -198,7 +215,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionDoublesText" android:id="@+id/sessionDoublesText"
@ -206,7 +225,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionTriplesText" android:id="@+id/sessionTriplesText"
@ -214,7 +235,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionTetrisesText" android:id="@+id/sessionTetrisesText"
@ -222,7 +245,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<Button <Button
android:id="@+id/playAgainButton" android:id="@+id/playAgainButton"
@ -231,7 +256,10 @@
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/play" android:text="@string/play"
android:textColor="@color/white" /> android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
</LinearLayout> </LinearLayout>
<!-- Player Progression Screen --> <!-- Player Progression Screen -->
@ -270,7 +298,9 @@
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
android:layout_marginEnd="16dp" /> android:fontFamily="sans-serif"
android:layout_marginEnd="16dp"
android:textAllCaps="false" />
<com.mintris.ui.LevelBadge <com.mintris.ui.LevelBadge
android:id="@+id/pauseLevelBadge" android:id="@+id/pauseLevelBadge"
@ -299,7 +329,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/start" android:text="@string/start"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<Button <Button
android:id="@+id/resumeButton" android:id="@+id/resumeButton"
@ -309,7 +342,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/resume" android:text="@string/resume"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<Button <Button
android:id="@+id/pauseRestartButton" android:id="@+id/pauseRestartButton"
@ -319,7 +355,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/restart" android:text="@string/restart"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<Button <Button
android:id="@+id/highScoresButton" android:id="@+id/highScoresButton"
@ -329,7 +368,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/high_scores" android:text="@string/high_scores"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<Button <Button
android:id="@+id/statsButton" android:id="@+id/statsButton"
@ -339,7 +381,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/stats" android:text="@string/stats"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<LinearLayout <LinearLayout
android:id="@+id/levelSelectorContainer" android:id="@+id/levelSelectorContainer"
@ -355,8 +400,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/select_level" android:text="@string/select_level"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="16sp" android:textSize="24sp"
android:textStyle="bold" /> android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -371,7 +418,9 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="" android:text=""
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/pauseLevelText" android:id="@+id/pauseLevelText"
@ -381,7 +430,8 @@
android:text="1" android:text="1"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" /> android:textStyle="bold"
android:fontFamily="sans-serif" />
<Button <Button
android:id="@+id/pauseLevelUpButton" android:id="@+id/pauseLevelUpButton"
@ -390,7 +440,9 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="+" android:text="+"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="24sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -418,7 +470,10 @@
android:background="@color/transparent" android:background="@color/transparent"
android:text="@string/sound_on" android:text="@string/sound_on"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -433,7 +488,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/music" android:text="@string/music"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false"
android:layout_marginEnd="16dp" /> android:layout_marginEnd="16dp" />
<ImageButton <ImageButton

View file

@ -9,10 +9,11 @@
android:id="@+id/available_skins_label" android:id="@+id/available_skins_label"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="BLOCK SKINS" android:text="block skins"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="18sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:gravity="center" android:gravity="center"
android:layout_marginBottom="16dp" /> android:layout_marginBottom="16dp" />

View file

@ -3,16 +3,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp" android:padding="16dp">
android:background="@color/black">
<TextView <TextView
android:id="@+id/progression_title" android:id="@+id/progression_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="LEVEL UP" android:text="level up"
android:textSize="24sp" android:textSize="48sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:textColor="@color/white" android:textColor="@color/white"
android:gravity="center" android:gravity="center"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@ -22,8 +22,10 @@
android:id="@+id/player_level_text" android:id="@+id/player_level_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Player Level: 1" android:text="player level: 1"
android:textSize="20sp" android:textSize="36sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textColor="@color/white" android:textColor="@color/white"
android:gravity="center" android:gravity="center"
android:layout_marginBottom="24dp" /> android:layout_marginBottom="24dp" />
@ -38,10 +40,11 @@
android:id="@+id/xp_gain_text" android:id="@+id/xp_gain_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="+0 XP" android:text="+0 xp"
android:textSize="22sp" android:textSize="42sp"
android:textColor="#50C878"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:textColor="#50C878"
android:gravity="center" android:gravity="center"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="24dp" /> android:layout_marginBottom="24dp" />
@ -50,9 +53,10 @@
android:id="@+id/rewards_title" android:id="@+id/rewards_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="REWARDS UNLOCKED" android:text="rewards unlocked"
android:textSize="20sp" android:textSize="36sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:textColor="#FFD700" android:textColor="#FFD700"
android:gravity="center" android:gravity="center"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@ -76,8 +80,10 @@
android:id="@+id/continue_button" android:id="@+id/continue_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="CONTINUE" android:text="continue"
android:textSize="18sp" android:textSize="32sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"

View file

@ -9,10 +9,11 @@
android:id="@+id/available_themes_label" android:id="@+id/available_themes_label"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="AVAILABLE THEMES" android:text="available themes"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="18sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif"
android:gravity="center" android:gravity="center"
android:layout_marginBottom="16dp" /> android:layout_marginBottom="16dp" />

View file

@ -1,49 +1,49 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Mintris</string> <string name="app_name">mintris</string>
<string name="game_over">Game Over</string> <string name="game_over">game over</string>
<string name="score">Score</string> <string name="score">score</string>
<string name="level">Level</string> <string name="level">level</string>
<string name="lines">Lines</string> <string name="lines">lines</string>
<string name="next">Next</string> <string name="next">next</string>
<string name="play">Play Again</string> <string name="play">play again</string>
<string name="resume">Resume</string> <string name="resume">resume</string>
<string name="pause">PAUSE</string> <string name="pause">pause</string>
<string name="settings">Settings</string> <string name="settings">settings</string>
<string name="start">Start Game</string> <string name="start">start game</string>
<string name="restart">Restart</string> <string name="restart">restart</string>
<string name="select_level">Select Level</string> <string name="select_level">select level</string>
<string name="sound_on">Sound: On</string> <string name="sound_on">sound: on</string>
<string name="sound_off">Sound: Off</string> <string name="sound_off">sound: off</string>
<string name="toggle_music">Toggle music</string> <string name="toggle_music">toggle music</string>
<string name="high_scores">High Scores</string> <string name="high_scores">high scores</string>
<string name="new_high_score">New High Score!</string> <string name="new_high_score">new high score!</string>
<string name="save">Save</string> <string name="save">save</string>
<string name="back">Back</string> <string name="back">back</string>
<!-- Stats Screen --> <!-- Stats Screen -->
<string name="lifetime_stats">Lifetime Stats</string> <string name="lifetime_stats">lifetime stats</string>
<string name="best_performance">Best Performance</string> <string name="best_performance">best performance</string>
<string name="total_games">Total Games: %d</string> <string name="total_games">total games: %d</string>
<string name="total_score">Total Score: %d</string> <string name="total_score">total score: %d</string>
<string name="total_lines">Total Lines: %d</string> <string name="total_lines">total lines: %d</string>
<string name="total_pieces">Total Pieces: %d</string> <string name="total_pieces">total pieces: %d</string>
<string name="total_time">Total Time: %s</string> <string name="total_time">total time: %s</string>
<string name="max_level">Max Level: %d</string> <string name="max_level">max level: %d</string>
<string name="max_score">Max Score: %d</string> <string name="max_score">max score: %d</string>
<string name="max_lines">Max Lines: %d</string> <string name="max_lines">max lines: %d</string>
<string name="stats">Stats</string> <string name="stats">stats</string>
<string name="session_stats">Session Stats</string> <string name="session_stats">session stats</string>
<string name="session_score">Score: %d</string> <string name="session_score">score: %d</string>
<string name="session_lines">Lines: %d</string> <string name="session_lines">lines: %d</string>
<string name="session_pieces">Pieces: %d</string> <string name="session_pieces">pieces: %d</string>
<string name="session_time">Time: %s</string> <string name="session_time">time: %s</string>
<string name="session_level">Level: %d</string> <string name="session_level">level: %d</string>
<string name="line_clears">Line Clears</string> <string name="line_clears">line clears</string>
<string name="singles">Singles: %d</string> <string name="singles">singles: %d</string>
<string name="doubles">Doubles: %d</string> <string name="doubles">doubles: %d</string>
<string name="triples">Triples: %d</string> <string name="triples">triples: %d</string>
<string name="tetrises">Tetrises: %d</string> <string name="tetrises">tetrises: %d</string>
<string name="reset_stats">Reset Stats</string> <string name="reset_stats">reset stats</string>
<string name="music">Music</string> <string name="music">music</string>
</resources> </resources>