mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-18 01:45:21 +01:00
Compare commits
11 commits
1c57c438ce
...
103a21d9b7
Author | SHA1 | Date | |
---|---|---|---|
|
103a21d9b7 | ||
|
68e8cb160f | ||
|
42b9bcfab4 | ||
|
1980f15a46 | ||
|
c6a4339931 | ||
|
83935d35a8 | ||
|
d0700202b7 | ||
|
af0082a6db | ||
|
ebff618fa4 | ||
|
7cdc9988cb | ||
|
2774703df5 |
14 changed files with 525 additions and 310 deletions
|
@ -66,8 +66,7 @@ class HighScoreEntryActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun loadThemePreference(): String {
|
||||
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
|
||||
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
|
||||
return progressionManager.getSelectedTheme()
|
||||
}
|
||||
|
||||
private fun applyTheme(themeId: String) {
|
||||
|
|
|
@ -58,8 +58,7 @@ class HighScoresActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun loadThemePreference(): String {
|
||||
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
|
||||
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
|
||||
return progressionManager.getSelectedTheme()
|
||||
}
|
||||
|
||||
private fun applyTheme(themeId: String) {
|
||||
|
|
|
@ -91,17 +91,6 @@ class MainActivity : AppCompatActivity() {
|
|||
themeSelector = binding.themeSelector
|
||||
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
|
||||
progressionScreen = binding.progressionScreen
|
||||
progressionScreen.visibility = View.GONE
|
||||
|
@ -110,6 +99,24 @@ class MainActivity : AppCompatActivity() {
|
|||
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
|
||||
themeSelector.onThemeSelected = { themeId: String ->
|
||||
// Apply the new theme
|
||||
|
@ -351,10 +358,7 @@ class MainActivity : AppCompatActivity() {
|
|||
var showingHighScore = false
|
||||
|
||||
// Show progression screen first with XP animation
|
||||
binding.gameOverContainer.visibility = View.GONE
|
||||
progressionScreen.visibility = View.VISIBLE
|
||||
progressionScreen.applyTheme(currentTheme)
|
||||
progressionScreen.showProgress(progressionManager, xpGained, newRewards, currentTheme)
|
||||
showProgressionScreen(xpGained, newRewards)
|
||||
|
||||
// Override the continue button behavior if high score needs to be shown
|
||||
val originalOnContinue = progressionScreen.onContinue
|
||||
|
@ -586,63 +590,55 @@ class MainActivity : AppCompatActivity() {
|
|||
* Apply a theme to the game
|
||||
*/
|
||||
private fun applyTheme(themeId: String) {
|
||||
// Only apply if the theme is unlocked
|
||||
if (!progressionManager.isThemeUnlocked(themeId)) return
|
||||
|
||||
// Save the selected theme
|
||||
currentTheme = themeId
|
||||
val themeColor = 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
|
||||
}
|
||||
|
||||
// Get background color for the theme
|
||||
val backgroundColor = when (themeId) {
|
||||
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
|
||||
}
|
||||
|
||||
// Apply background color to root view
|
||||
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)
|
||||
|
||||
// Apply theme color to game view
|
||||
gameView.setThemeColor(themeColor)
|
||||
gameView.setBackgroundColor(backgroundColor)
|
||||
|
||||
// Save theme preference
|
||||
progressionManager.setSelectedTheme(themeId)
|
||||
|
||||
// Apply theme to title screen if it's visible
|
||||
if (titleScreen.visibility == View.VISIBLE) {
|
||||
titleScreen.applyTheme(themeId)
|
||||
}
|
||||
|
||||
// Apply theme colors based on theme ID
|
||||
when (themeId) {
|
||||
PlayerProgressionManager.THEME_CLASSIC -> {
|
||||
// Default black theme
|
||||
binding.root.setBackgroundColor(Color.BLACK)
|
||||
}
|
||||
PlayerProgressionManager.THEME_NEON -> {
|
||||
// Neon theme with dark purple background
|
||||
binding.root.setBackgroundColor(Color.parseColor("#0D0221"))
|
||||
}
|
||||
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
|
||||
if (::progressionScreen.isInitialized && progressionScreen.visibility == View.VISIBLE) {
|
||||
progressionScreen.applyTheme(themeId)
|
||||
}
|
||||
|
||||
// Apply theme color to the stats button
|
||||
val textColor = getThemeColor(currentTheme)
|
||||
binding.statsButton.setTextColor(textColor)
|
||||
|
||||
// Update the game view to apply theme
|
||||
gameView.invalidate()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -738,4 +734,16 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
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)
|
||||
}
|
||||
}
|
|
@ -44,8 +44,7 @@ class StatsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun loadThemePreference(): String {
|
||||
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
|
||||
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
|
||||
return progressionManager.getSelectedTheme()
|
||||
}
|
||||
|
||||
private fun applyTheme(themeId: String) {
|
||||
|
|
|
@ -2,12 +2,14 @@ package com.mintris.game
|
|||
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.BlurMaskFilter
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.LinearGradient
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.graphics.BlurMaskFilter
|
||||
import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
@ -151,6 +153,7 @@ class GameView @JvmOverloads constructor(
|
|||
// Block skin
|
||||
private var currentBlockSkin: String = "block_skin_1"
|
||||
private val blockSkinPaints = mutableMapOf<String, Paint>()
|
||||
private var currentThemeColor = Color.WHITE
|
||||
|
||||
private enum class Direction {
|
||||
HORIZONTAL, VERTICAL
|
||||
|
@ -173,6 +176,10 @@ class GameView @JvmOverloads constructor(
|
|||
// Start with paused state
|
||||
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
|
||||
gameBoard.onPieceMove = { onPieceMove?.invoke() }
|
||||
gameBoard.onPieceLock = {
|
||||
|
@ -232,6 +239,7 @@ class GameView @JvmOverloads constructor(
|
|||
blockSkinPaints["block_skin_1"] = Paint().apply {
|
||||
color = Color.WHITE
|
||||
isAntiAlias = true
|
||||
style = Paint.Style.FILL
|
||||
}
|
||||
|
||||
// Neon skin
|
||||
|
@ -244,9 +252,8 @@ class GameView @JvmOverloads constructor(
|
|||
// Retro skin
|
||||
blockSkinPaints["block_skin_3"] = Paint().apply {
|
||||
color = Color.parseColor("#FF5A5F")
|
||||
isAntiAlias = true
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = 2f
|
||||
isAntiAlias = false // Pixelated look
|
||||
style = Paint.Style.FILL
|
||||
}
|
||||
|
||||
// Minimalist skin
|
||||
|
@ -269,6 +276,9 @@ class GameView @JvmOverloads constructor(
|
|||
*/
|
||||
fun setBlockSkin(skinId: String) {
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -594,61 +604,139 @@ class GameView @JvmOverloads constructor(
|
|||
// Create a clone of the paint to avoid modifying the original
|
||||
val blockPaint = Paint(paint)
|
||||
|
||||
// Special handling for neon skin
|
||||
if (currentBlockSkin == "block_skin_2") {
|
||||
// Stronger outer glow for neon skin
|
||||
blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 0, 255) else Color.parseColor("#FF00FF")
|
||||
blockGlowPaint.maskFilter = BlurMaskFilter(16f, BlurMaskFilter.Blur.OUTER)
|
||||
canvas.drawRect(left - 4f, top - 4f, right + 4f, bottom + 4f, blockGlowPaint)
|
||||
|
||||
// For neon, use semi-translucent fill with strong glowing edges
|
||||
blockPaint.style = Paint.Style.FILL_AND_STROKE
|
||||
blockPaint.strokeWidth = 2f
|
||||
blockPaint.maskFilter = BlurMaskFilter(8f, BlurMaskFilter.Blur.NORMAL)
|
||||
|
||||
if (isGhost) {
|
||||
blockPaint.color = Color.argb(30, 255, 0, 255)
|
||||
blockPaint.alpha = 30
|
||||
} else {
|
||||
blockPaint.color = Color.parseColor("#66004D") // Darker magenta fill
|
||||
blockPaint.alpha = 170 // More opaque to be more visible
|
||||
// Draw block based on current skin
|
||||
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)
|
||||
}
|
||||
|
||||
// Draw block with neon effect
|
||||
canvas.drawRect(left, top, right, bottom, blockPaint)
|
||||
|
||||
// Draw a brighter border for better visibility
|
||||
val borderPaint = Paint().apply {
|
||||
color = Color.parseColor("#FF00FF")
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = 3f
|
||||
alpha = 255
|
||||
isAntiAlias = true
|
||||
maskFilter = BlurMaskFilter(6f, BlurMaskFilter.Blur.NORMAL)
|
||||
"block_skin_2" -> { // Neon
|
||||
// Stronger outer glow for neon skin
|
||||
blockGlowPaint.color = if (isGhost) Color.argb(30, 255, 0, 255) else Color.parseColor("#FF00FF")
|
||||
blockGlowPaint.maskFilter = BlurMaskFilter(16f, BlurMaskFilter.Blur.OUTER)
|
||||
canvas.drawRect(left - 4f, top - 4f, right + 4f, bottom + 4f, blockGlowPaint)
|
||||
|
||||
// For neon, use semi-translucent fill with strong glowing edges
|
||||
blockPaint.style = Paint.Style.FILL_AND_STROKE
|
||||
blockPaint.strokeWidth = 2f
|
||||
blockPaint.maskFilter = BlurMaskFilter(8f, BlurMaskFilter.Blur.NORMAL)
|
||||
|
||||
if (isGhost) {
|
||||
blockPaint.color = Color.argb(30, 255, 0, 255)
|
||||
blockPaint.alpha = 30
|
||||
} else {
|
||||
blockPaint.color = Color.parseColor("#66004D") // Darker magenta fill
|
||||
blockPaint.alpha = 170 // More opaque to be more visible
|
||||
}
|
||||
|
||||
// Draw block with neon effect
|
||||
canvas.drawRect(left, top, right, bottom, blockPaint)
|
||||
|
||||
// Draw a brighter border for better visibility
|
||||
val borderPaint = Paint().apply {
|
||||
color = Color.parseColor("#FF00FF")
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = 3f
|
||||
alpha = 255
|
||||
isAntiAlias = true
|
||||
maskFilter = BlurMaskFilter(6f, BlurMaskFilter.Blur.NORMAL)
|
||||
}
|
||||
canvas.drawRect(left, top, right, bottom, borderPaint)
|
||||
|
||||
// Inner glow for neon blocks
|
||||
glowPaint.color = if (isGhost) Color.argb(10, 255, 0, 255) else Color.parseColor("#FF00FF")
|
||||
glowPaint.alpha = if (isGhost) 10 else 100
|
||||
glowPaint.style = Paint.Style.STROKE
|
||||
glowPaint.strokeWidth = 2f
|
||||
glowPaint.maskFilter = BlurMaskFilter(4f, BlurMaskFilter.Blur.NORMAL)
|
||||
canvas.drawRect(left + 4f, top + 4f, right - 4f, bottom - 4f, glowPaint)
|
||||
}
|
||||
"block_skin_3" -> { // Retro
|
||||
// Draw pixelated block with retro effect
|
||||
blockPaint.color = if (isGhost) Color.argb(30, 255, 90, 95) else Color.parseColor("#FF5A5F")
|
||||
blockPaint.alpha = if (isGhost) 30 else 255
|
||||
|
||||
// Draw main block
|
||||
canvas.drawRect(left, top, right, bottom, blockPaint)
|
||||
|
||||
// Draw pixelated highlights
|
||||
val highlightPaint = Paint().apply {
|
||||
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)
|
||||
}
|
||||
}
|
||||
canvas.drawRect(left, top, right, bottom, borderPaint)
|
||||
|
||||
// Inner glow for neon blocks - brighter than before
|
||||
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.style = Paint.Style.STROKE
|
||||
glowPaint.strokeWidth = 2f
|
||||
glowPaint.maskFilter = BlurMaskFilter(4f, BlurMaskFilter.Blur.NORMAL)
|
||||
canvas.drawRect(left + 4f, top + 4f, right - 4f, bottom - 4f, glowPaint)
|
||||
} else {
|
||||
// Standard rendering for other skins
|
||||
// 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 with current skin
|
||||
blockPaint.color = if (isGhost) Color.argb(30, 255, 255, 255) else blockPaint.color
|
||||
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)
|
||||
}
|
||||
|
||||
// Draw pulse effect if animation is active and this is a pulsing line
|
||||
|
@ -963,4 +1051,26 @@ class GameView @JvmOverloads constructor(
|
|||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,9 @@ class TitleScreen @JvmOverloads constructor(
|
|||
// Callback for when the user touches the screen
|
||||
var onStartGame: (() -> Unit)? = null
|
||||
|
||||
// Theme color
|
||||
// Theme color and background color
|
||||
private var themeColor = Color.WHITE
|
||||
private var backgroundColor = Color.BLACK
|
||||
|
||||
// Define tetromino shapes (I, O, T, S, Z, J, L)
|
||||
private val tetrominoShapes = arrayOf(
|
||||
|
@ -110,7 +111,7 @@ class TitleScreen @JvmOverloads constructor(
|
|||
init {
|
||||
// Title text settings
|
||||
titlePaint.apply {
|
||||
color = Color.WHITE
|
||||
color = themeColor
|
||||
textSize = 120f
|
||||
textAlign = Paint.Align.CENTER
|
||||
typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD)
|
||||
|
@ -119,7 +120,7 @@ class TitleScreen @JvmOverloads constructor(
|
|||
|
||||
// "Touch to start" text settings
|
||||
promptPaint.apply {
|
||||
color = Color.WHITE
|
||||
color = themeColor
|
||||
textSize = 50f
|
||||
textAlign = Paint.Align.CENTER
|
||||
typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL)
|
||||
|
@ -129,7 +130,7 @@ class TitleScreen @JvmOverloads constructor(
|
|||
|
||||
// High scores text settings
|
||||
highScorePaint.apply {
|
||||
color = Color.WHITE
|
||||
color = themeColor
|
||||
textSize = 70f
|
||||
textAlign = Paint.Align.LEFT // Changed to LEFT alignment
|
||||
typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL) // Changed to monospace
|
||||
|
@ -137,16 +138,16 @@ class TitleScreen @JvmOverloads constructor(
|
|||
alpha = 200
|
||||
}
|
||||
|
||||
// General paint settings for tetrominos (white)
|
||||
// General paint settings for tetrominos
|
||||
paint.apply {
|
||||
color = Color.WHITE
|
||||
color = themeColor
|
||||
style = Paint.Style.FILL
|
||||
isAntiAlias = true
|
||||
}
|
||||
|
||||
// Glow paint settings for tetrominos
|
||||
glowPaint.apply {
|
||||
color = Color.WHITE
|
||||
color = themeColor
|
||||
style = Paint.Style.FILL
|
||||
isAntiAlias = true
|
||||
alpha = 60
|
||||
|
@ -184,8 +185,8 @@ class TitleScreen @JvmOverloads constructor(
|
|||
try {
|
||||
super.onDraw(canvas)
|
||||
|
||||
// Draw background
|
||||
canvas.drawColor(Color.BLACK)
|
||||
// Draw background using the current background color
|
||||
canvas.drawColor(backgroundColor)
|
||||
|
||||
// Add any pending tetrominos
|
||||
tetrominos.addAll(tetrominosToAdd)
|
||||
|
@ -340,7 +341,7 @@ class TitleScreen @JvmOverloads constructor(
|
|||
glowPaint.color = themeColor
|
||||
|
||||
// Update background color
|
||||
setBackgroundColor(when (themeId) {
|
||||
backgroundColor = when (themeId) {
|
||||
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
|
||||
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
|
||||
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
|
||||
|
@ -348,8 +349,29 @@ class TitleScreen @JvmOverloads constructor(
|
|||
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
|
||||
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
|
||||
else -> Color.BLACK
|
||||
})
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.content.SharedPreferences
|
|||
import com.mintris.R
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* 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,
|
||||
tetrisCount: Int, perfectClearCount: Int): Long {
|
||||
// Base XP from score with level multiplier
|
||||
val scoreXP = (score * (1 + LEVEL_MULTIPLIER * level)).toLong()
|
||||
// Base XP from score with level multiplier (capped at level 10)
|
||||
val cappedLevel = min(level, 10)
|
||||
val scoreXP = (score * (1 + LEVEL_MULTIPLIER * cappedLevel)).toLong()
|
||||
|
||||
// XP from lines cleared
|
||||
val linesXP = lines * XP_PER_LINE
|
||||
// XP from lines cleared (reduced for higher levels)
|
||||
val linesXP = lines * XP_PER_LINE * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
|
||||
|
||||
// XP from special moves
|
||||
val tetrisBonus = tetrisCount * TETRIS_XP_BONUS
|
||||
val perfectClearBonus = perfectClearCount * PERFECT_CLEAR_XP_BONUS
|
||||
// XP from special moves (reduced for higher levels)
|
||||
val tetrisBonus = tetrisCount * TETRIS_XP_BONUS * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
|
||||
val perfectClearBonus = perfectClearCount * PERFECT_CLEAR_XP_BONUS * (1 - (level - 1) * 0.05).coerceAtLeast(0.5)
|
||||
|
||||
// Time bonus (to reward longer gameplay)
|
||||
val timeBonus = (gameTime / 60000) * TIME_XP_PER_MINUTE // XP per minute played
|
||||
// Time bonus (reduced for longer games)
|
||||
val timeBonus = (gameTime / 60000) * TIME_XP_PER_MINUTE * (1 - (gameTime / 3600000) * 0.1).coerceAtLeast(0.5)
|
||||
|
||||
// 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_BLOCKS = "unlocked_blocks"
|
||||
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_BLOCK_SKIN = "selected_block_skin"
|
||||
|
||||
// XP curve parameters
|
||||
private const val BASE_XP = 4000.0 // Base XP for level 1 (reduced from 5000)
|
||||
private const val XP_CURVE_FACTOR = 1.9 // Exponential factor for XP curve (reduced from 2.2)
|
||||
// XP constants
|
||||
private const val BASE_XP = 3000L
|
||||
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
|
||||
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
|
||||
// Theme constants
|
||||
const val THEME_CLASSIC = "theme_classic"
|
||||
const val THEME_NEON = "theme_neon"
|
||||
const val THEME_MONOCHROME = "theme_monochrome"
|
||||
|
@ -326,7 +326,7 @@ class PlayerProgressionManager(context: Context) {
|
|||
*/
|
||||
fun setSelectedBlockSkin(skinId: String) {
|
||||
if (unlockedBlocks.contains(skinId)) {
|
||||
prefs.edit().putString(KEY_SELECTED_BLOCK_SKIN, skinId).apply()
|
||||
prefs.edit().putString(KEY_SELECTED_BLOCK_SKIN, skinId).commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
private val rewardsContainer: LinearLayout
|
||||
private val continueButton: TextView
|
||||
|
||||
// Current theme
|
||||
private var currentTheme: String = PlayerProgressionManager.THEME_CLASSIC
|
||||
|
||||
// Callback for when the player dismisses the screen
|
||||
var onContinue: (() -> Unit)? = null
|
||||
|
||||
|
@ -62,6 +65,9 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
newRewards: List<String>,
|
||||
themeId: String = PlayerProgressionManager.THEME_CLASSIC
|
||||
) {
|
||||
// Update current theme
|
||||
currentTheme = themeId
|
||||
|
||||
// Hide rewards container initially if there are no new rewards
|
||||
rewardsContainer.visibility = if (newRewards.isEmpty()) View.GONE else View.INVISIBLE
|
||||
|
||||
|
@ -74,20 +80,39 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
playerLevelText.text = "Player Level: $playerLevel"
|
||||
xpGainText.text = "+$xpGained XP"
|
||||
|
||||
// Begin animation sequence
|
||||
xpProgressBar.setXPValues(playerLevel, currentXP, xpForNextLevel)
|
||||
// Update level up text visibility
|
||||
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
|
||||
val xpTextAnimator = ObjectAnimator.ofFloat(xpGainText, "alpha", 0f, 1f).apply {
|
||||
duration = 500
|
||||
// Start with initial animations
|
||||
AnimatorSet().apply {
|
||||
// Fade in the XP gain text
|
||||
val xpTextAnimator = ObjectAnimator.ofFloat(xpGainText, "alpha", 0f, 1f).apply {
|
||||
duration = 800
|
||||
interpolator = AccelerateDecelerateInterpolator()
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
|
||||
// Schedule animation for the XP bar after text appears
|
||||
// Set initial progress bar state
|
||||
xpProgressBar.setXPValues(playerLevel, currentXP - xpGained, xpForNextLevel)
|
||||
|
||||
// Animate the XP gain after a short delay
|
||||
postDelayed({
|
||||
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()) {
|
||||
// Create reward cards
|
||||
rewardsContainer.removeAllViews()
|
||||
|
@ -113,18 +138,12 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
card.animate()
|
||||
.alpha(1f)
|
||||
.translationY(0f)
|
||||
.setDuration(400)
|
||||
.setStartDelay((i * 150).toLong())
|
||||
.setDuration(600) // Increased duration for smoother animation
|
||||
.setStartDelay((i * 200).toLong()) // Increased delay between cards
|
||||
.setInterpolator(OvershootInterpolator())
|
||||
.start()
|
||||
}
|
||||
}, 2000) // Wait for XP bar animation to finish
|
||||
}
|
||||
|
||||
// Start with initial animations
|
||||
AnimatorSet().apply {
|
||||
play(xpTextAnimator)
|
||||
start()
|
||||
}, 2500) // Increased delay to wait for XP bar animation to finish
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,8 +156,17 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
cardElevation = 4f
|
||||
useCompatPadding = true
|
||||
|
||||
// Default background color - will be adjusted based on theme
|
||||
setCardBackgroundColor(Color.BLACK)
|
||||
// Set background color based on current theme
|
||||
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(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
|
@ -167,6 +195,8 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
* Apply the current theme to the progression screen
|
||||
*/
|
||||
fun applyTheme(themeId: String) {
|
||||
currentTheme = themeId
|
||||
|
||||
// Get reference to the title text
|
||||
val progressionTitle = findViewById<TextView>(R.id.progression_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)
|
||||
|
||||
// Update card colors for any existing reward cards
|
||||
// Update reward card colors
|
||||
updateRewardCardColors(themeId)
|
||||
}
|
||||
|
||||
|
@ -259,8 +289,7 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
* Update colors of existing reward cards to match the theme
|
||||
*/
|
||||
private fun updateRewardCardColors(themeId: String) {
|
||||
// Color for card backgrounds based on theme
|
||||
val cardBackgroundColor = when (themeId) {
|
||||
val backgroundColor = when (themeId) {
|
||||
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
|
||||
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
|
||||
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
|
||||
|
@ -270,28 +299,9 @@ class ProgressionScreen @JvmOverloads constructor(
|
|||
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) {
|
||||
val card = rewardsContainer.getChildAt(i) as? CardView
|
||||
card?.let {
|
||||
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)
|
||||
}
|
||||
}
|
||||
card?.setCardBackgroundColor(backgroundColor)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,6 +99,8 @@ class XPProgressBar @JvmOverloads constructor(
|
|||
*/
|
||||
fun setThemeColor(color: Int) {
|
||||
themeColor = color
|
||||
progressPaint.color = color
|
||||
textPaint.color = color
|
||||
levelBadgePaint.color = color
|
||||
invalidate()
|
||||
}
|
||||
|
|
|
@ -62,36 +62,40 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="Score: 0" />
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
tools:text="score: 0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/currentLevelText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="Level: 1" />
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
tools:text="level: 1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/linesText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="Lines: 0" />
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
tools:text="lines: 0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/comboText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="Combo: 0" />
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
tools:text="combo: 0" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Next Piece Preview -->
|
||||
|
@ -131,16 +135,18 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/game_over"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/session_stats"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:layout_marginTop="24dp" />
|
||||
|
||||
<TextView
|
||||
|
@ -149,7 +155,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionLinesText"
|
||||
|
@ -157,7 +165,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionPiecesText"
|
||||
|
@ -165,7 +175,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionTimeText"
|
||||
|
@ -173,7 +185,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionLevelText"
|
||||
|
@ -181,15 +195,18 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/line_clears"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
<TextView
|
||||
|
@ -198,7 +215,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionDoublesText"
|
||||
|
@ -206,7 +225,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionTriplesText"
|
||||
|
@ -214,7 +235,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sessionTetrisesText"
|
||||
|
@ -222,7 +245,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/playAgainButton"
|
||||
|
@ -231,7 +256,10 @@
|
|||
android:layout_marginTop="32dp"
|
||||
android:background="@color/transparent"
|
||||
android:text="@string/play"
|
||||
android:textColor="@color/white" />
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Player Progression Screen -->
|
||||
|
@ -270,7 +298,9 @@
|
|||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="16dp" />
|
||||
android:fontFamily="sans-serif"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<com.mintris.ui.LevelBadge
|
||||
android:id="@+id/pauseLevelBadge"
|
||||
|
@ -299,7 +329,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/start"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/resumeButton"
|
||||
|
@ -309,7 +342,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/resume"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pauseRestartButton"
|
||||
|
@ -319,7 +355,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/restart"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/highScoresButton"
|
||||
|
@ -329,7 +368,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/high_scores"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/statsButton"
|
||||
|
@ -339,7 +381,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/stats"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/levelSelectorContainer"
|
||||
|
@ -355,8 +400,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/select_level"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -371,7 +418,9 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="−"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pauseLevelText"
|
||||
|
@ -381,7 +430,8 @@
|
|||
android:text="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pauseLevelUpButton"
|
||||
|
@ -390,7 +440,9 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="+"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -418,7 +470,10 @@
|
|||
android:background="@color/transparent"
|
||||
android:text="@string/sound_on"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -433,7 +488,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/music"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textAllCaps="false"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<ImageButton
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
android:id="@+id/available_skins_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="BLOCK SKINS"
|
||||
android:text="block skins"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="@color/black">
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progression_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="LEVEL UP"
|
||||
android:textSize="24sp"
|
||||
android:text="level up"
|
||||
android:textSize="48sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
|
@ -22,8 +22,10 @@
|
|||
android:id="@+id/player_level_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Player Level: 1"
|
||||
android:textSize="20sp"
|
||||
android:text="player level: 1"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="@color/white"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
@ -38,10 +40,11 @@
|
|||
android:id="@+id/xp_gain_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+0 XP"
|
||||
android:textSize="22sp"
|
||||
android:textColor="#50C878"
|
||||
android:text="+0 xp"
|
||||
android:textSize="42sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="#50C878"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
@ -50,9 +53,10 @@
|
|||
android:id="@+id/rewards_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="REWARDS UNLOCKED"
|
||||
android:textSize="20sp"
|
||||
android:text="rewards unlocked"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="#FFD700"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
|
@ -76,8 +80,10 @@
|
|||
android:id="@+id/continue_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="CONTINUE"
|
||||
android:textSize="18sp"
|
||||
android:text="continue"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
android:id="@+id/available_themes_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="AVAILABLE THEMES"
|
||||
android:text="available themes"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Mintris</string>
|
||||
<string name="game_over">Game Over</string>
|
||||
<string name="score">Score</string>
|
||||
<string name="level">Level</string>
|
||||
<string name="lines">Lines</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="play">Play Again</string>
|
||||
<string name="resume">Resume</string>
|
||||
<string name="pause">PAUSE</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="start">Start Game</string>
|
||||
<string name="restart">Restart</string>
|
||||
<string name="select_level">Select Level</string>
|
||||
<string name="sound_on">Sound: On</string>
|
||||
<string name="sound_off">Sound: Off</string>
|
||||
<string name="toggle_music">Toggle music</string>
|
||||
<string name="high_scores">High Scores</string>
|
||||
<string name="new_high_score">New High Score!</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="back">Back</string>
|
||||
<string name="app_name">mintris</string>
|
||||
<string name="game_over">game over</string>
|
||||
<string name="score">score</string>
|
||||
<string name="level">level</string>
|
||||
<string name="lines">lines</string>
|
||||
<string name="next">next</string>
|
||||
<string name="play">play again</string>
|
||||
<string name="resume">resume</string>
|
||||
<string name="pause">pause</string>
|
||||
<string name="settings">settings</string>
|
||||
<string name="start">start game</string>
|
||||
<string name="restart">restart</string>
|
||||
<string name="select_level">select level</string>
|
||||
<string name="sound_on">sound: on</string>
|
||||
<string name="sound_off">sound: off</string>
|
||||
<string name="toggle_music">toggle music</string>
|
||||
<string name="high_scores">high scores</string>
|
||||
<string name="new_high_score">new high score!</string>
|
||||
<string name="save">save</string>
|
||||
<string name="back">back</string>
|
||||
|
||||
<!-- Stats Screen -->
|
||||
<string name="lifetime_stats">Lifetime Stats</string>
|
||||
<string name="best_performance">Best Performance</string>
|
||||
<string name="total_games">Total Games: %d</string>
|
||||
<string name="total_score">Total Score: %d</string>
|
||||
<string name="total_lines">Total Lines: %d</string>
|
||||
<string name="total_pieces">Total Pieces: %d</string>
|
||||
<string name="total_time">Total Time: %s</string>
|
||||
<string name="max_level">Max Level: %d</string>
|
||||
<string name="max_score">Max Score: %d</string>
|
||||
<string name="max_lines">Max Lines: %d</string>
|
||||
<string name="stats">Stats</string>
|
||||
<string name="session_stats">Session Stats</string>
|
||||
<string name="session_score">Score: %d</string>
|
||||
<string name="session_lines">Lines: %d</string>
|
||||
<string name="session_pieces">Pieces: %d</string>
|
||||
<string name="session_time">Time: %s</string>
|
||||
<string name="session_level">Level: %d</string>
|
||||
<string name="line_clears">Line Clears</string>
|
||||
<string name="singles">Singles: %d</string>
|
||||
<string name="doubles">Doubles: %d</string>
|
||||
<string name="triples">Triples: %d</string>
|
||||
<string name="tetrises">Tetrises: %d</string>
|
||||
<string name="reset_stats">Reset Stats</string>
|
||||
<string name="music">Music</string>
|
||||
<string name="lifetime_stats">lifetime stats</string>
|
||||
<string name="best_performance">best performance</string>
|
||||
<string name="total_games">total games: %d</string>
|
||||
<string name="total_score">total score: %d</string>
|
||||
<string name="total_lines">total lines: %d</string>
|
||||
<string name="total_pieces">total pieces: %d</string>
|
||||
<string name="total_time">total time: %s</string>
|
||||
<string name="max_level">max level: %d</string>
|
||||
<string name="max_score">max score: %d</string>
|
||||
<string name="max_lines">max lines: %d</string>
|
||||
<string name="stats">stats</string>
|
||||
<string name="session_stats">session stats</string>
|
||||
<string name="session_score">score: %d</string>
|
||||
<string name="session_lines">lines: %d</string>
|
||||
<string name="session_pieces">pieces: %d</string>
|
||||
<string name="session_time">time: %s</string>
|
||||
<string name="session_level">level: %d</string>
|
||||
<string name="line_clears">line clears</string>
|
||||
<string name="singles">singles: %d</string>
|
||||
<string name="doubles">doubles: %d</string>
|
||||
<string name="triples">triples: %d</string>
|
||||
<string name="tetrises">tetrises: %d</string>
|
||||
<string name="reset_stats">reset stats</string>
|
||||
<string name="music">music</string>
|
||||
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue