feat: implement hold piece functionality with swipe up gesture

This commit is contained in:
cmclark00 2025-03-29 23:20:49 -04:00
parent 47c9bbddec
commit 53c46c9864
3 changed files with 151 additions and 0 deletions

View file

@ -172,6 +172,15 @@ class MainActivity : AppCompatActivity() {
binding.nextPieceView.invalidate()
}
// Set up hold piece preview
binding.holdPieceView.setGameView(gameView)
gameBoard.onPieceLock = {
binding.holdPieceView.invalidate()
}
gameBoard.onPieceMove = {
binding.holdPieceView.invalidate()
}
// Set up music toggle
binding.musicToggle.setOnClickListener {
isMusicEnabled = !isMusicEnabled

View file

@ -0,0 +1,134 @@
package com.mintris.game
import android.content.Context
import android.graphics.BlurMaskFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import com.mintris.model.GameBoard
import com.mintris.model.Tetromino
import kotlin.math.min
/**
* View that displays the currently held piece
*/
class HoldPieceView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private var gameView: GameView? = null
private var gameBoard: GameBoard? = null
// Rendering
private val blockPaint = Paint().apply {
color = Color.WHITE
isAntiAlias = true
style = Paint.Style.FILL
}
private val glowPaint = Paint().apply {
color = Color.WHITE
alpha = 40
isAntiAlias = true
style = Paint.Style.STROKE
strokeWidth = 1.5f
maskFilter = BlurMaskFilter(8f, BlurMaskFilter.Blur.OUTER)
}
private val blockGlowPaint = Paint().apply {
color = Color.WHITE
alpha = 60
isAntiAlias = true
style = Paint.Style.FILL
maskFilter = BlurMaskFilter(12f, BlurMaskFilter.Blur.OUTER)
}
/**
* Set the game view reference
*/
fun setGameView(view: GameView) {
gameView = view
gameBoard = view.getGameBoard()
}
/**
* Get the game board reference
*/
private fun getGameBoard(): GameBoard? = gameBoard
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Get the held piece from game board
gameBoard?.let {
it.getHoldPiece()?.let { piece ->
val width = piece.getWidth()
val height = piece.getHeight()
// Calculate block size for the preview (smaller than main board)
val previewBlockSize = min(
canvas.width.toFloat() / (width + 2),
canvas.height.toFloat() / (height + 2)
)
// Center the piece in the preview area
val previewLeft = (canvas.width - width * previewBlockSize) / 2
val previewTop = (canvas.height - height * previewBlockSize) / 2
// Draw subtle background glow
val glowPaint = Paint().apply {
color = Color.WHITE
alpha = 10
maskFilter = BlurMaskFilter(previewBlockSize * 0.5f, BlurMaskFilter.Blur.OUTER)
}
canvas.drawRect(
previewLeft - previewBlockSize,
previewTop - previewBlockSize,
previewLeft + width * previewBlockSize + previewBlockSize,
previewTop + height * previewBlockSize + previewBlockSize,
glowPaint
)
// Draw the held piece
for (y in 0 until height) {
for (x in 0 until width) {
if (piece.isBlockAt(x, y)) {
val left = previewLeft + x * previewBlockSize
val top = previewTop + y * previewBlockSize
val right = left + previewBlockSize
val bottom = top + previewBlockSize
// Draw outer glow
blockGlowPaint.color = Color.WHITE
canvas.drawRect(
left - 2f,
top - 2f,
right + 2f,
bottom + 2f,
blockGlowPaint
)
// Draw block
blockPaint.color = Color.WHITE
canvas.drawRect(left, top, right, bottom, blockPaint)
// Draw inner glow
glowPaint.color = Color.WHITE
canvas.drawRect(
left + 1f,
top + 1f,
right - 1f,
bottom - 1f,
glowPaint
)
}
}
}
}
}
}
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dp"
android:color="#FFFFFF" />
<solid android:color="#00000000" />
</shape>