mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-23 11:34:54 -04:00
Limit camera movement within explored region (#8661)
* Load game resets scroll position * Limit camera within explored region
This commit is contained in:
parent
b5ce086860
commit
713f116400
@ -252,7 +252,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
*
|
*
|
||||||
* Sets the returned `WorldScreen` as the only active screen.
|
* Sets the returned `WorldScreen` as the only active screen.
|
||||||
*/
|
*/
|
||||||
suspend fun loadGame(newGameInfo: GameInfo): WorldScreen = withThreadPoolContext toplevel@{
|
suspend fun loadGame(newGameInfo: GameInfo, callFromLoadScreen: Boolean = false): WorldScreen = withThreadPoolContext toplevel@{
|
||||||
val prevGameInfo = gameInfo
|
val prevGameInfo = gameInfo
|
||||||
gameInfo = newGameInfo
|
gameInfo = newGameInfo
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
initializeResources(prevGameInfo, newGameInfo)
|
initializeResources(prevGameInfo, newGameInfo)
|
||||||
|
|
||||||
val isLoadingSameGame = worldScreen != null && prevGameInfo != null && prevGameInfo.gameId == newGameInfo.gameId
|
val isLoadingSameGame = worldScreen != null && prevGameInfo != null && prevGameInfo.gameId == newGameInfo.gameId
|
||||||
val worldScreenRestoreState = if (isLoadingSameGame) worldScreen!!.getRestoreState() else null
|
val worldScreenRestoreState = if (!callFromLoadScreen && isLoadingSameGame) worldScreen!!.getRestoreState() else null
|
||||||
|
|
||||||
lateinit var loadingScreen: LoadingScreen
|
lateinit var loadingScreen: LoadingScreen
|
||||||
|
|
||||||
|
@ -542,6 +542,8 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
}) {
|
}) {
|
||||||
for (unit in civInfo.units.getCivUnits())
|
for (unit in civInfo.units.getCivUnits())
|
||||||
unit.updateVisibleTiles(false) // this needs to be done after all the units are assigned to their civs and all other transients are set
|
unit.updateVisibleTiles(false) // this needs to be done after all the units are assigned to their civs and all other transients are set
|
||||||
|
if(civInfo.playerType == PlayerType.Human)
|
||||||
|
civInfo.exploredRegion.setMapParameters(tileMap.mapParameters.worldWrap, tileMap.mapParameters.mapSize.radius) // Required for the correct calculation of the explored region on world wrap maps
|
||||||
civInfo.cache.updateSightAndResources() // only run ONCE and not for each unit - this is a huge performance saver!
|
civInfo.cache.updateSightAndResources() // only run ONCE and not for each unit - this is a huge performance saver!
|
||||||
|
|
||||||
// Since this depends on the cities of ALL civilizations,
|
// Since this depends on the cities of ALL civilizations,
|
||||||
|
@ -188,6 +188,9 @@ class Civilization : IsPartOfGameInfoSerialization {
|
|||||||
var citiesCreated = 0
|
var citiesCreated = 0
|
||||||
var exploredTiles = HashSet<Vector2>()
|
var exploredTiles = HashSet<Vector2>()
|
||||||
|
|
||||||
|
// Limit camera within explored region
|
||||||
|
var exploredRegion = ExploredRegion()
|
||||||
|
|
||||||
fun hasExplored(tile: Tile) = tile.isExplored(this)
|
fun hasExplored(tile: Tile) = tile.isExplored(this)
|
||||||
|
|
||||||
var lastSeenImprovement = HashMapVector2<String>()
|
var lastSeenImprovement = HashMapVector2<String>()
|
||||||
@ -271,6 +274,7 @@ class Civilization : IsPartOfGameInfoSerialization {
|
|||||||
// Cloning it by-pointer is a horrific move, since the serialization would go over it ANYWAY and still lead to concurrency problems.
|
// Cloning it by-pointer is a horrific move, since the serialization would go over it ANYWAY and still lead to concurrency problems.
|
||||||
// Cloning it by iterating on the tilemap values may seem ridiculous, but it's a perfectly thread-safe way to go about it, unlike the other solutions.
|
// Cloning it by iterating on the tilemap values may seem ridiculous, but it's a perfectly thread-safe way to go about it, unlike the other solutions.
|
||||||
toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles })
|
toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles })
|
||||||
|
toReturn.exploredRegion = exploredRegion.clone()
|
||||||
toReturn.lastSeenImprovement.putAll(lastSeenImprovement)
|
toReturn.lastSeenImprovement.putAll(lastSeenImprovement)
|
||||||
toReturn.notifications.addAll(notifications)
|
toReturn.notifications.addAll(notifications)
|
||||||
toReturn.notificationsLog.addAll(notificationsLog)
|
toReturn.notificationsLog.addAll(notificationsLog)
|
||||||
|
165
core/src/com/unciv/logic/civilization/ExploredRegion.kt
Normal file
165
core/src/com/unciv/logic/civilization/ExploredRegion.kt
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
package com.unciv.logic.civilization
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2
|
||||||
|
import com.unciv.logic.IsPartOfGameInfoSerialization
|
||||||
|
import com.unciv.logic.map.HexMath.getLatitude
|
||||||
|
import com.unciv.logic.map.HexMath.getLongitude
|
||||||
|
import com.unciv.logic.map.HexMath.worldFromLatLong
|
||||||
|
import com.unciv.ui.components.tilegroups.TileGroupMap
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class ExploredRegion () : IsPartOfGameInfoSerialization {
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private var isWorldWrap = false
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private var mapRadius = 0f
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private val tileRadius = (TileGroupMap.groupSize + 4) * 0.75f
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private var shouldRecalculateCoords = true
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private var shouldRestrictX = false
|
||||||
|
|
||||||
|
// Top left point of the explored region in stage (x;y) starting from the top left corner
|
||||||
|
@Transient
|
||||||
|
private var topLeftStage = Vector2()
|
||||||
|
|
||||||
|
// Bottom right point of the explored region in stage (x;y) starting from the top left corner
|
||||||
|
@Transient
|
||||||
|
private var bottomRightStage = Vector2()
|
||||||
|
|
||||||
|
// Top left point of the explored region in hex (long;lat) from the center of the map
|
||||||
|
private var topLeft = Vector2()
|
||||||
|
|
||||||
|
// Bottom right point of the explored region in hex (long;lat) from the center of the map
|
||||||
|
private var bottomRight = Vector2()
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
fun shouldRecalculateCoords(): Boolean = shouldRecalculateCoords
|
||||||
|
fun shouldRestrictX(): Boolean = shouldRestrictX
|
||||||
|
fun getLeftX(): Float = topLeftStage.x
|
||||||
|
fun getRightX():Float = bottomRightStage.x
|
||||||
|
fun getTopY(): Float = topLeftStage.y
|
||||||
|
fun getBottomY():Float = bottomRightStage.y
|
||||||
|
|
||||||
|
fun clone(): ExploredRegion {
|
||||||
|
val toReturn = ExploredRegion()
|
||||||
|
toReturn.topLeft = topLeft
|
||||||
|
toReturn.bottomRight = bottomRight
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMapParameters(worldWrap: Boolean, radius: Int)
|
||||||
|
{
|
||||||
|
isWorldWrap = worldWrap
|
||||||
|
mapRadius = radius.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if tilePosition is beyond explored region
|
||||||
|
fun checkTilePosition(tilePosition: Vector2, explorerPosition: Vector2?) {
|
||||||
|
var longitude = getLongitude(tilePosition)
|
||||||
|
val latitude = getLatitude(tilePosition)
|
||||||
|
|
||||||
|
// First time call
|
||||||
|
if (topLeft == Vector2.Zero && bottomRight == Vector2.Zero) {
|
||||||
|
topLeft = Vector2(longitude, latitude)
|
||||||
|
bottomRight = Vector2(longitude, latitude)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check X coord
|
||||||
|
if (topLeft.x >= bottomRight.x) {
|
||||||
|
if (longitude > topLeft.x) {
|
||||||
|
// For world wrap maps when the maximumX is reached, we move to a minimumX - 1f
|
||||||
|
if (isWorldWrap && longitude == mapRadius) longitude = mapRadius * -1f
|
||||||
|
topLeft.x = longitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
} else if (longitude < bottomRight.x) {
|
||||||
|
// For world wrap maps when the minimumX is reached, we move to a maximumX + 1f
|
||||||
|
if (isWorldWrap && longitude == (mapRadius * -1f + 1f)) longitude = mapRadius + 1f
|
||||||
|
bottomRight.x = longitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// When we cross the map edge with world wrap, the vectors are swapped along the x-axis
|
||||||
|
if (longitude < bottomRight.x && longitude > topLeft.x) {
|
||||||
|
val rightSideDistance: Float
|
||||||
|
val leftSideDistance: Float
|
||||||
|
|
||||||
|
// If we have explorerPosition, get distance to explorer
|
||||||
|
// This solves situations when a newly explored cell is in the middle of an unexplored area
|
||||||
|
if(explorerPosition != null) {
|
||||||
|
val explorerLongitude = getLongitude(explorerPosition)
|
||||||
|
|
||||||
|
rightSideDistance = if(explorerLongitude < 0 && bottomRight.x > 0)
|
||||||
|
// The explorer is still on the right edge of the map, but has explored over the edge
|
||||||
|
mapRadius * 2f + explorerLongitude - bottomRight.x
|
||||||
|
else
|
||||||
|
abs(explorerLongitude - bottomRight.x)
|
||||||
|
|
||||||
|
leftSideDistance = if(explorerLongitude > 0 && topLeft.x < 0)
|
||||||
|
// The explorer is still on the left edge of the map, but has explored over the edge
|
||||||
|
mapRadius * 2f - explorerLongitude + topLeft.x
|
||||||
|
else
|
||||||
|
abs(topLeft.x - explorerLongitude)
|
||||||
|
} else {
|
||||||
|
// If we don't have explorerPosition, we calculate the distance to the edges of the explored region
|
||||||
|
// e.g. when capitals are revealed
|
||||||
|
rightSideDistance = bottomRight.x - longitude
|
||||||
|
leftSideDistance = longitude - topLeft.x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand region from the nearest edge
|
||||||
|
if (rightSideDistance > leftSideDistance) {
|
||||||
|
topLeft.x = longitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
} else {
|
||||||
|
bottomRight.x = longitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Y coord
|
||||||
|
if (latitude > topLeft.y) {
|
||||||
|
topLeft.y = latitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
} else if (latitude < bottomRight.y) {
|
||||||
|
bottomRight.y = latitude
|
||||||
|
shouldRecalculateCoords = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun calculateStageCoords(mapMaxX: Float, mapMaxY: Float) {
|
||||||
|
shouldRecalculateCoords = false
|
||||||
|
|
||||||
|
// Check if we explored the whole world wrap map horizontally
|
||||||
|
shouldRestrictX = bottomRight.x - topLeft.x != 1f
|
||||||
|
|
||||||
|
// Get world (x;y)
|
||||||
|
val topLeftWorld = worldFromLatLong(topLeft, tileRadius)
|
||||||
|
val bottomRightWorld = worldFromLatLong(bottomRight, tileRadius)
|
||||||
|
|
||||||
|
// Convert X to the stage coords
|
||||||
|
val mapCenterX = mapMaxX * 0.5f + tileRadius
|
||||||
|
var left = mapCenterX + topLeftWorld.x
|
||||||
|
var right = mapCenterX + bottomRightWorld.x
|
||||||
|
|
||||||
|
// World wrap over edge check
|
||||||
|
if (left > mapMaxX) left = 10f
|
||||||
|
if (right < 0f) right = mapMaxX - 10f
|
||||||
|
|
||||||
|
// Convert Y to the stage coords
|
||||||
|
val mapCenterY = mapMaxY * 0.5f
|
||||||
|
val top = mapCenterY-topLeftWorld.y
|
||||||
|
val bottom = mapCenterY-bottomRightWorld.y
|
||||||
|
|
||||||
|
topLeftStage = Vector2(left, top)
|
||||||
|
bottomRightStage = Vector2(right, bottom)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.unciv.logic.civilization.transients
|
package com.unciv.logic.civilization.transients
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.City
|
import com.unciv.logic.city.City
|
||||||
@ -74,7 +75,7 @@ class CivInfoTransientCache(val civInfo: Civilization) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is a big performance
|
// This is a big performance
|
||||||
fun updateViewableTiles() {
|
fun updateViewableTiles(explorerPosition: Vector2? = null) {
|
||||||
setNewViewableTiles()
|
setNewViewableTiles()
|
||||||
|
|
||||||
updateViewableInvisibleTiles()
|
updateViewableInvisibleTiles()
|
||||||
@ -87,7 +88,7 @@ class CivInfoTransientCache(val civInfo: Civilization) {
|
|||||||
// and we never actually iterate on the explored tiles (only check contains()),
|
// and we never actually iterate on the explored tiles (only check contains()),
|
||||||
// so there's no fear of concurrency problems.
|
// so there's no fear of concurrency problems.
|
||||||
civInfo.viewableTiles.asSequence().forEach { tile ->
|
civInfo.viewableTiles.asSequence().forEach { tile ->
|
||||||
tile.setExplored(civInfo, true)
|
tile.setExplored(civInfo, true, explorerPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +48,15 @@ object HexMath {
|
|||||||
return Vector2(x, y)
|
return Vector2(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert hex latitude and longitude into world coordinates.
|
||||||
|
*/
|
||||||
|
fun worldFromLatLong(vector: Vector2, tileRadius: Float): Vector2 {
|
||||||
|
val x = vector.x * tileRadius * 1.5f * -1f
|
||||||
|
val y = vector.y * tileRadius * sqrt(3f) * 0.5f
|
||||||
|
return Vector2(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
/** returns a vector containing width and height a rectangular map should have to have
|
/** returns a vector containing width and height a rectangular map should have to have
|
||||||
* approximately the same number of tiles as an hexagonal map given a height/width ratio */
|
* approximately the same number of tiles as an hexagonal map given a height/width ratio */
|
||||||
fun getEquivalentRectangularSize(size: Int, ratio: Float = 0.65f): Vector2 {
|
fun getEquivalentRectangularSize(size: Int, ratio: Float = 0.65f): Vector2 {
|
||||||
|
@ -290,7 +290,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
|
|||||||
/**
|
/**
|
||||||
* Update this unit's cache of viewable tiles and its civ's as well.
|
* Update this unit's cache of viewable tiles and its civ's as well.
|
||||||
*/
|
*/
|
||||||
fun updateVisibleTiles(updateCivViewableTiles:Boolean = true) {
|
fun updateVisibleTiles(updateCivViewableTiles:Boolean = true, explorerPosition: Vector2? = null) {
|
||||||
val oldViewableTiles = viewableTiles
|
val oldViewableTiles = viewableTiles
|
||||||
|
|
||||||
viewableTiles = when {
|
viewableTiles = when {
|
||||||
@ -302,7 +302,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
|
|||||||
|
|
||||||
// Set equality automatically determines if anything changed - https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-abstract-set/equals.html
|
// Set equality automatically determines if anything changed - https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-abstract-set/equals.html
|
||||||
if (updateCivViewableTiles && oldViewableTiles != viewableTiles)
|
if (updateCivViewableTiles && oldViewableTiles != viewableTiles)
|
||||||
civ.cache.updateViewableTiles()
|
civ.cache.updateViewableTiles(explorerPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isActionUntilHealed() = action?.endsWith("until healed") == true
|
fun isActionUntilHealed() = action?.endsWith("until healed") == true
|
||||||
@ -607,7 +607,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
|
|||||||
promotions.addPromotion(promotion, true)
|
promotions.addPromotion(promotion, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVisibleTiles()
|
updateVisibleTiles(true, currentTile.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putInTile(tile: Tile) {
|
fun putInTile(tile: Tile) {
|
||||||
|
@ -245,10 +245,12 @@ open class Tile : IsPartOfGameInfoSerialization {
|
|||||||
return exploredBy.contains(player.civName) || player.exploredTiles.contains(position)
|
return exploredBy.contains(player.civName) || player.exploredTiles.contains(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setExplored(player: Civilization, isExplored: Boolean) {
|
fun setExplored(player: Civilization, isExplored: Boolean, explorerPosition: Vector2? = null) {
|
||||||
if (isExplored) {
|
if (isExplored) {
|
||||||
exploredBy.add(player.civName)
|
exploredBy.add(player.civName)
|
||||||
player.exploredTiles.add(position)
|
player.exploredTiles.add(position)
|
||||||
|
if(player.playerType == PlayerType.Human)
|
||||||
|
player.exploredRegion.checkTilePosition(position, explorerPosition)
|
||||||
} else {
|
} else {
|
||||||
exploredBy.remove(player.civName)
|
exploredBy.remove(player.civName)
|
||||||
player.exploredTiles.remove(position)
|
player.exploredTiles.remove(position)
|
||||||
|
@ -290,8 +290,8 @@ open class ZoomableScrollPane(
|
|||||||
onPanStartListener?.invoke()
|
onPanStartListener?.invoke()
|
||||||
}
|
}
|
||||||
setScrollbarsVisible(true)
|
setScrollbarsVisible(true)
|
||||||
scrollX -= deltaX
|
scrollX = restrictX(deltaX)
|
||||||
scrollY += deltaY
|
scrollY = restrictY(deltaY)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
continuousScrollingX && scrollPercentX >= 1 && deltaX < 0 -> {
|
continuousScrollingX && scrollPercentX >= 1 && deltaX < 0 -> {
|
||||||
@ -316,6 +316,9 @@ open class ZoomableScrollPane(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun restrictX(deltaX: Float): Float = scrollX - deltaX
|
||||||
|
open fun restrictY(deltaY:Float): Float = scrollY + deltaY
|
||||||
|
|
||||||
override fun getFlickScrollListener(): ActorGestureListener {
|
override fun getFlickScrollListener(): ActorGestureListener {
|
||||||
return FlickScrollListener()
|
return FlickScrollListener()
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
|||||||
try {
|
try {
|
||||||
// This is what can lead to ANRs - reading the file and setting the transients, that's why this is in another thread
|
// This is what can lead to ANRs - reading the file and setting the transients, that's why this is in another thread
|
||||||
val loadedGame = game.files.loadGameByName(selectedSave)
|
val loadedGame = game.files.loadGameByName(selectedSave)
|
||||||
game.loadGame(loadedGame)
|
game.loadGame(loadedGame, true)
|
||||||
} catch (notAPlayer: UncivShowableException) {
|
} catch (notAPlayer: UncivShowableException) {
|
||||||
launchOnGLThread {
|
launchOnGLThread {
|
||||||
val (message) = getLoadExceptionMessage(notAPlayer)
|
val (message) = getLoadExceptionMessage(notAPlayer)
|
||||||
@ -146,7 +146,7 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
|||||||
try {
|
try {
|
||||||
val clipboardContentsString = Gdx.app.clipboard.contents.trim()
|
val clipboardContentsString = Gdx.app.clipboard.contents.trim()
|
||||||
val loadedGame = UncivFiles.gameInfoFromString(clipboardContentsString)
|
val loadedGame = UncivFiles.gameInfoFromString(clipboardContentsString)
|
||||||
game.loadGame(loadedGame)
|
game.loadGame(loadedGame, true)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
launchOnGLThread { handleLoadGameException(ex, "Could not load game from clipboard!") }
|
launchOnGLThread { handleLoadGameException(ex, "Could not load game from clipboard!") }
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
|||||||
handleLoadGameException(result.exception!!, "Could not load game from custom location!")
|
handleLoadGameException(result.exception!!, "Could not load game from custom location!")
|
||||||
} else if (result.isSuccessful()) {
|
} else if (result.isSuccessful()) {
|
||||||
Concurrency.run {
|
Concurrency.run {
|
||||||
game.loadGame(result.gameData!!)
|
game.loadGame(result.gameData!!, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -777,6 +777,40 @@ class WorldMapHolder(
|
|||||||
super.reloadMaxZoom()
|
super.reloadMaxZoom()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun restrictX(deltaX: Float): Float {
|
||||||
|
val exploredRegion = worldScreen.viewingCiv.exploredRegion
|
||||||
|
var result = scrollX - deltaX
|
||||||
|
|
||||||
|
if (exploredRegion.shouldRecalculateCoords()) exploredRegion.calculateStageCoords(maxX, maxY)
|
||||||
|
|
||||||
|
if (!exploredRegion.shouldRestrictX()) return result
|
||||||
|
|
||||||
|
val leftX = exploredRegion.getLeftX()
|
||||||
|
val rightX = exploredRegion.getRightX()
|
||||||
|
|
||||||
|
if (deltaX < 0 && scrollX <= rightX && result > rightX)
|
||||||
|
result = rightX
|
||||||
|
else if (deltaX > 0 && scrollX >= leftX && result < leftX)
|
||||||
|
result = leftX
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun restrictY(deltaY: Float): Float {
|
||||||
|
val exploredRegion = worldScreen.viewingCiv.exploredRegion
|
||||||
|
var result = scrollY + deltaY
|
||||||
|
|
||||||
|
if (exploredRegion.shouldRecalculateCoords()) exploredRegion.calculateStageCoords(maxX, maxY)
|
||||||
|
|
||||||
|
val topY = exploredRegion.getTopY()
|
||||||
|
val bottomY = exploredRegion.getBottomY()
|
||||||
|
|
||||||
|
if (result < topY) result = topY
|
||||||
|
else if (result > bottomY) result = bottomY
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// For debugging purposes
|
// For debugging purposes
|
||||||
override fun draw(batch: Batch?, parentAlpha: Float) = super.draw(batch, parentAlpha)
|
override fun draw(batch: Batch?, parentAlpha: Float) = super.draw(batch, parentAlpha)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user