Very buggy map drawing
This commit is contained in:
parent
4b07ce505f
commit
9c65627445
4 changed files with 99 additions and 11 deletions
|
|
@ -23,6 +23,7 @@ import androidx.compose.material3.Slider
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -72,6 +73,8 @@ class MainActivity : ComponentActivity() {
|
|||
@Composable
|
||||
fun Main(vm: TileViewModel = viewModel()) {
|
||||
val sliderValue = rememberSaveable { mutableFloatStateOf(1F) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val tileContainer = TileContainer(vm, coroutineScope)
|
||||
KtHeightMapTheme {
|
||||
Box(modifier = Modifier.background(color = colorScheme.background)) {
|
||||
Scaffold(
|
||||
|
|
@ -84,6 +87,7 @@ fun Main(vm: TileViewModel = viewModel()) {
|
|||
gridColor = colorScheme.primary,
|
||||
backColor = colorScheme.background,
|
||||
scale = sliderValue,
|
||||
tileContainer = tileContainer,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package com.mirenkov.ktheightmap
|
|||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.foundation.gestures.rememberTransformableState
|
||||
import androidx.compose.foundation.gestures.transformable
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableFloatState
|
||||
|
|
@ -13,6 +11,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
|
||||
|
|
@ -21,6 +20,7 @@ fun MapCanvas(
|
|||
backColor: Color,
|
||||
gridColor: Color,
|
||||
scale: MutableFloatState,
|
||||
tileContainer: TileContainer,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val offsetX = rememberSaveable { mutableFloatStateOf(0F) }
|
||||
|
|
@ -40,25 +40,43 @@ fun MapCanvas(
|
|||
size = size
|
||||
)
|
||||
|
||||
val tileOffsetX = offsetX.floatValue.toInt() / TILE_SIZE.toInt()
|
||||
val tileOffsetY = offsetY.floatValue.toInt() / TILE_SIZE.toInt()
|
||||
|
||||
val strippedOffsetX = offsetX.floatValue % TILE_SIZE
|
||||
val strippedOffsetY = offsetY.floatValue % TILE_SIZE
|
||||
|
||||
val level = scale.floatValue.toInt()
|
||||
val strippedScale = scale.floatValue + 1 - level
|
||||
val actualTileSize = TILE_SIZE * strippedScale
|
||||
|
||||
val offset = Offset(strippedOffsetX, strippedOffsetY)
|
||||
val grid = size / actualTileSize
|
||||
|
||||
val grid = size / TILE_SIZE
|
||||
|
||||
val gridWidth = grid.width.toInt()
|
||||
val gridHeight = grid.height.toInt()
|
||||
|
||||
val tiles = tileContainer.getTiles(tileOffsetX, tileOffsetY, tileOffsetX + gridWidth, tileOffsetY + gridHeight, level)
|
||||
|
||||
for (cellX in 0 .. gridWidth + 2) {
|
||||
val offsetX = actualTileSize * (cellX - 1)
|
||||
val tileX = tileOffsetX + cellX
|
||||
val offsetX = TILE_SIZE * (cellX - 1)
|
||||
for (cellY in 0 .. gridHeight + 2) {
|
||||
val offsetY = actualTileSize * (cellY - 1)
|
||||
val tileY = tileOffsetY + cellY
|
||||
val offsetY = TILE_SIZE * (cellY - 1)
|
||||
|
||||
val bitmap = tiles.find { it.x == tileX && it.y == tileY && it.level == level }?.getBitmap()
|
||||
|
||||
bitmap?.let {
|
||||
val imageBitmap = bitmap.asImageBitmap()
|
||||
drawImage(
|
||||
image = imageBitmap,
|
||||
topLeft = offset + Offset(offsetX, offsetY)
|
||||
)
|
||||
}
|
||||
|
||||
drawRect(
|
||||
color = gridColor,
|
||||
size = Size(actualTileSize, actualTileSize),
|
||||
size = Size(TILE_SIZE, TILE_SIZE),
|
||||
topLeft = offset + Offset(offsetX, offsetY),
|
||||
style = Stroke(width = 4F)
|
||||
)
|
||||
|
|
|
|||
65
app/src/main/java/com/mirenkov/ktheightmap/TileContainer.kt
Normal file
65
app/src/main/java/com/mirenkov/ktheightmap/TileContainer.kt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package com.mirenkov.ktheightmap
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
class TileContainer(private val vm: TileViewModel, private val coroutineScope: CoroutineScope) {
|
||||
private val tiles: MutableList<Tile> = mutableListOf()
|
||||
|
||||
private var startX = 0
|
||||
private var startY = 0
|
||||
|
||||
private var endX = 0
|
||||
private var endY = 0
|
||||
|
||||
private var level = 1
|
||||
|
||||
fun getTiles(_startX: Int, _startY: Int, _endX: Int, _endY: Int, _level: Int): List<Tile> {
|
||||
val newParams = arrayOf( _startX, _startY, _endX, _endY, _level )
|
||||
val oldParams = arrayOf( startX, startY, endX, endY, level )
|
||||
var isInvalid = false
|
||||
for (i in 0 until newParams.size) {
|
||||
if (oldParams[i] != newParams[i]) {
|
||||
isInvalid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (isInvalid) {
|
||||
updateTileList(_startX, _startY, _endX, _endY, _level)
|
||||
}
|
||||
|
||||
updateValues(_startX, _startY, _endX, _endY, _level)
|
||||
|
||||
return tiles
|
||||
}
|
||||
|
||||
private fun updateTileList(_startX: Int, _startY: Int, _endX: Int, _endY: Int, _level: Int) {
|
||||
tiles.removeIf {
|
||||
it.level != _level ||
|
||||
it.x < _startX ||
|
||||
it.x > _endX ||
|
||||
it.y < _startY ||
|
||||
it.y > _endY
|
||||
}
|
||||
for (x in _startX .. _endX) {
|
||||
for (y in _startY .. _endY) {
|
||||
if (tiles.find { it.x == x && it.y == y && it.level == _level } == null) {
|
||||
val tile = vm.repository.getTile(x, y, _level)
|
||||
if (tile == null) {
|
||||
tiles.add(Tile(x, y, _level))
|
||||
} else {
|
||||
tiles.add(tile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateValues(_startX: Int, _startY: Int, _endX: Int, _endY: Int, _level: Int) {
|
||||
startX = _startX
|
||||
startY = _startY
|
||||
endX = _endX
|
||||
endY = _endY
|
||||
level = _level
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.mirenkov.ktheightmap
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.future.future
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class TileRepository(private val tileDao: TileDao) {
|
||||
|
|
@ -12,11 +13,11 @@ class TileRepository(private val tileDao: TileDao) {
|
|||
coroutineScope.launch(Dispatchers.IO) { tileDao.pushTile(tile) }
|
||||
}
|
||||
|
||||
suspend fun getTile(x: Int, y: Int, level: Int): Tile? {
|
||||
val tileDeferred = coroutineScope.async(Dispatchers.IO) {
|
||||
fun getTile(x: Int, y: Int, level: Int): Tile? {
|
||||
val tileFuture = coroutineScope.future(Dispatchers.IO) {
|
||||
tileDao.getTile(x, y, level)
|
||||
}
|
||||
return tileDeferred.await()
|
||||
return tileFuture.join()
|
||||
}
|
||||
|
||||
fun clearTiles() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue