Editor has chunk loading
This commit is contained in:
@@ -32,6 +32,14 @@ class Chunk:
|
||||
# Update vertices
|
||||
self.tileUpdateVertices()
|
||||
|
||||
def reload(self, newX, newY, newZ):
|
||||
self.x = newX
|
||||
self.y = newY
|
||||
self.z = newZ
|
||||
for tile in self.tiles.values():
|
||||
tile.chunkReload(newX, newY, newZ)
|
||||
self.load()
|
||||
|
||||
def tileUpdateVertices(self):
|
||||
self.vertexBuffer.clear()
|
||||
for tile in self.tiles.values():
|
||||
|
||||
@@ -16,6 +16,9 @@ class Map:
|
||||
self.data = {}
|
||||
self.dataOriginal = {}
|
||||
self.position = [0, 0, 0] # x, y, z
|
||||
self.topLeftX = 0 - (MAP_WIDTH // 2)
|
||||
self.topLeftY = 0 - (MAP_HEIGHT // 2)
|
||||
self.topLeftZ = 0 - (MAP_DEPTH // 2)
|
||||
self.chunks = {}
|
||||
self.onMapData = Event()
|
||||
self.onPositionChange = Event()
|
||||
@@ -31,6 +34,7 @@ class Map:
|
||||
index += 1
|
||||
|
||||
# Only in editor instances:
|
||||
self.moveTo(0, 0, 0)
|
||||
if parent is not None:
|
||||
QTimer.singleShot(16, self.loadLastFile)
|
||||
|
||||
@@ -130,6 +134,68 @@ class Map:
|
||||
return False
|
||||
|
||||
def moveTo(self, x, y, z):
|
||||
if self.position == [x, y, z]:
|
||||
return
|
||||
|
||||
# We need to decide if the chunks should be unloaded here or not.
|
||||
newTopLeftChunkX = x // CHUNK_WIDTH - (MAP_WIDTH // 2)
|
||||
newTopLeftChunkY = y // CHUNK_HEIGHT - (MAP_HEIGHT // 2)
|
||||
newTopLeftChunkZ = z // CHUNK_DEPTH - (MAP_DEPTH // 2)
|
||||
|
||||
if (newTopLeftChunkX != self.topLeftX or
|
||||
newTopLeftChunkY != self.topLeftY or
|
||||
newTopLeftChunkZ != self.topLeftZ):
|
||||
|
||||
chunksToUnload = []
|
||||
chunksToKeep = []
|
||||
for chunk in self.chunks.values():
|
||||
chunkWorldX = chunk.x
|
||||
chunkWorldY = chunk.y
|
||||
chunkWorldZ = chunk.z
|
||||
if (chunkWorldX < newTopLeftChunkX or
|
||||
chunkWorldX >= newTopLeftChunkX + MAP_WIDTH or
|
||||
chunkWorldY < newTopLeftChunkY or
|
||||
chunkWorldY >= newTopLeftChunkY + MAP_HEIGHT or
|
||||
chunkWorldZ < newTopLeftChunkZ or
|
||||
chunkWorldZ >= newTopLeftChunkZ + MAP_DEPTH):
|
||||
chunksToUnload.append(chunk)
|
||||
else:
|
||||
chunksToKeep.append(chunk)
|
||||
|
||||
# Unload chunks that are out of the new bounds.
|
||||
for chunk in chunksToUnload:
|
||||
if chunk.isDirty():
|
||||
print(f"Can't move map, some chunks are dirty: ({chunk.x}, {chunk.y}, {chunk.z})")
|
||||
return
|
||||
|
||||
# Now we can safely unload the chunks.
|
||||
chunkIndex = 0
|
||||
newChunks = {}
|
||||
for chunk in chunksToKeep:
|
||||
newChunks[chunkIndex] = chunk
|
||||
chunkIndex += 1
|
||||
|
||||
for xPos in range(newTopLeftChunkX, newTopLeftChunkX + MAP_WIDTH):
|
||||
for yPos in range(newTopLeftChunkY, newTopLeftChunkY + MAP_HEIGHT):
|
||||
for zPos in range(newTopLeftChunkZ, newTopLeftChunkZ + MAP_DEPTH):
|
||||
# Check if we already have this chunk.
|
||||
found = False
|
||||
for chunk in chunksToKeep:
|
||||
if chunk.x == xPos and chunk.y == yPos and chunk.z == zPos:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
# Create a new chunk.
|
||||
newChunk = chunksToUnload.pop()
|
||||
newChunk.reload(xPos, yPos, zPos)
|
||||
newChunks[chunkIndex] = newChunk
|
||||
chunkIndex += 1
|
||||
|
||||
self.chunks = newChunks
|
||||
self.topLeftX = newTopLeftChunkX
|
||||
self.topLeftY = newTopLeftChunkY
|
||||
self.topLeftZ = newTopLeftChunkZ
|
||||
|
||||
self.position = [x, y, z]
|
||||
self.onPositionChange.invoke(self.position)
|
||||
self.updateEditorConfig()
|
||||
|
||||
@@ -27,6 +27,11 @@ class Tile:
|
||||
self.posX = x * TILE_WIDTH + chunk.x * CHUNK_WIDTH * TILE_WIDTH
|
||||
self.posY = y * TILE_HEIGHT + chunk.y * CHUNK_HEIGHT * TILE_HEIGHT
|
||||
self.posZ = z * TILE_DEPTH + chunk.z * CHUNK_DEPTH * TILE_DEPTH
|
||||
|
||||
def chunkReload(self, newX, newY, newZ):
|
||||
self.posX = self.x * TILE_WIDTH + newX * CHUNK_WIDTH * TILE_WIDTH
|
||||
self.posY = self.y * TILE_HEIGHT + newY * CHUNK_HEIGHT * TILE_HEIGHT
|
||||
self.posZ = self.z * TILE_DEPTH + newZ * CHUNK_DEPTH * TILE_DEPTH
|
||||
|
||||
def load(self, chunkData):
|
||||
self.shape = getItem(chunkData['shapes'], self.index, TILE_SHAPE_NULL)
|
||||
|
||||
@@ -28,14 +28,18 @@ class MapLeftPanel(QWidget):
|
||||
grid.addWidget(self.btnE, 1, 2)
|
||||
layout.addLayout(grid)
|
||||
|
||||
# Panels
|
||||
self.chunkPanel = ChunkPanel(self.parent)
|
||||
self.entityPanel = EntityPanel(self.parent)
|
||||
|
||||
# Tabs
|
||||
self.tabs = QTabWidget()
|
||||
self.chunkPanel = ChunkPanel(self.parent)
|
||||
self.tabs.addTab(self.chunkPanel, "Tiles")
|
||||
self.entityPanel = EntityPanel(self.parent)
|
||||
self.tabs.addTab(self.entityPanel, "Entities")
|
||||
self.tabs.addTab(None, "Triggers")
|
||||
layout.addWidget(self.tabs)
|
||||
|
||||
|
||||
# Event subscriptions
|
||||
self.btnN.clicked.connect(lambda: self.parent.map.moveRelative(0, -1, 0))
|
||||
self.btnS.clicked.connect(lambda: self.parent.map.moveRelative(0, 1, 0))
|
||||
|
||||
Reference in New Issue
Block a user