Update "Entity-Management"
parent
d8eca08a79
commit
0417da11b9
|
|
@ -1,3 +1,6 @@
|
|||
# Entity Management
|
||||
*Last modified: 2025-12-01*
|
||||
|
||||
# Entity Management
|
||||
|
||||
Entities are game objects that implement behavior and live on Grids. While Grids handle rendering and mediate interactions, Entities encapsulate game logic like movement, combat, and AI.
|
||||
|
|
@ -18,6 +21,7 @@ Entities are game objects that implement behavior and live on Grids. While Grids
|
|||
**Related Issues:**
|
||||
- [#115](../../issues/115) - SpatialHash for fast queries (Open)
|
||||
- [#117](../../issues/117) - Memory Pool for entities (Open)
|
||||
- [#16](../../issues/16) - Entity knowledge contents (Open)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -28,6 +32,7 @@ Entities are game objects that:
|
|||
- **Have a sprite** for visual rendering
|
||||
- **Have grid position** (integer cell coordinates)
|
||||
- **Implement behavior** (movement, AI, combat, inventory)
|
||||
- **Track visibility** (which cells they can see / have seen)
|
||||
|
||||
**Key distinction:** Entities implement behavior. Grids mediate interaction between entities and render them to screen.
|
||||
|
||||
|
|
@ -103,6 +108,93 @@ current_grid = entity.grid # Read-only, set by collection operations
|
|||
|
||||
---
|
||||
|
||||
## Field of View & Visibility
|
||||
|
||||
Entities track what they can see via `gridstate` - a per-cell record of visible and discovered states.
|
||||
|
||||
### FOV Configuration
|
||||
|
||||
```python
|
||||
# Grid-level FOV settings
|
||||
grid.fov = mcrfpy.FOV.SHADOW # Algorithm (BASIC, DIAMOND, SHADOW, etc.)
|
||||
grid.fov_radius = 10 # Default view radius
|
||||
|
||||
# Module-level default
|
||||
mcrfpy.default_fov = mcrfpy.FOV.PERMISSIVE_2
|
||||
```
|
||||
|
||||
### Updating Visibility
|
||||
|
||||
```python
|
||||
# Compute FOV from entity's position and update gridstate
|
||||
entity.update_visibility()
|
||||
|
||||
# This also updates any ColorLayers bound via apply_perspective()
|
||||
```
|
||||
|
||||
### Querying Visible Entities
|
||||
|
||||
```python
|
||||
# Get list of other entities this entity can see
|
||||
visible_enemies = entity.visible_entities()
|
||||
|
||||
# With custom FOV settings
|
||||
nearby = entity.visible_entities(radius=5)
|
||||
visible = entity.visible_entities(fov=mcrfpy.FOV.BASIC, radius=8)
|
||||
```
|
||||
|
||||
### Fog of War with ColorLayers
|
||||
|
||||
```python
|
||||
# Create a ColorLayer for fog of war
|
||||
fov_layer = grid.add_layer('color', z_index=-1)
|
||||
fov_layer.fill((0, 0, 0, 255)) # Start black (unknown)
|
||||
|
||||
# Bind to entity - layer auto-updates when entity.update_visibility() is called
|
||||
fov_layer.apply_perspective(
|
||||
entity=player,
|
||||
visible=(0, 0, 0, 0), # Transparent when visible
|
||||
discovered=(40, 40, 60, 180), # Dark overlay when discovered
|
||||
unknown=(0, 0, 0, 255) # Black when never seen
|
||||
)
|
||||
|
||||
# Now whenever player moves:
|
||||
player.x = new_x
|
||||
player.y = new_y
|
||||
player.update_visibility() # Automatically updates the fog layer
|
||||
```
|
||||
|
||||
### One-Time FOV Draw
|
||||
|
||||
```python
|
||||
# Draw FOV without binding (useful for previews, spell ranges, etc.)
|
||||
fov_layer.draw_fov(
|
||||
source=(player.x, player.y),
|
||||
radius=10,
|
||||
fov=mcrfpy.FOV.SHADOW,
|
||||
visible=(255, 255, 200, 64),
|
||||
discovered=(100, 100, 100, 128),
|
||||
unknown=(0, 0, 0, 255)
|
||||
)
|
||||
```
|
||||
|
||||
### Gridstate Access
|
||||
|
||||
```python
|
||||
# Entity's per-cell visibility memory
|
||||
for state in entity.gridstate:
|
||||
print(f"visible={state.visible}, discovered={state.discovered}")
|
||||
|
||||
# Access specific cell state
|
||||
state = entity.at(x, y)
|
||||
if state.visible:
|
||||
print("Entity can currently see this cell")
|
||||
elif state.discovered:
|
||||
print("Entity has seen this cell before")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## EntityCollection
|
||||
|
||||
`grid.entities` is an `EntityCollection` with list-like operations:
|
||||
|
|
@ -160,6 +252,9 @@ entity.pos = (new_x, new_y)
|
|||
# Animated movement
|
||||
mcrfpy.Animation("x", target_x, 0.3, "easeOutQuad").start(entity)
|
||||
mcrfpy.Animation("y", target_y, 0.3, "easeOutQuad").start(entity)
|
||||
|
||||
# Update visibility after movement
|
||||
entity.update_visibility()
|
||||
```
|
||||
|
||||
### Removal
|
||||
|
|
@ -188,7 +283,7 @@ def transfer_entity(entity, to_grid, new_pos):
|
|||
|
||||
## Common Patterns
|
||||
|
||||
### Player Entity
|
||||
### Player Entity with FOV
|
||||
|
||||
```python
|
||||
class Player:
|
||||
|
|
@ -196,16 +291,32 @@ class Player:
|
|||
self.entity = mcrfpy.Entity(pos=start_pos, sprite_index=0, name="player")
|
||||
grid.entities.append(self.entity)
|
||||
|
||||
# Set up fog of war
|
||||
self.fov_layer = grid.add_layer('color', z_index=-1)
|
||||
self.fov_layer.fill((0, 0, 0, 255))
|
||||
self.fov_layer.apply_perspective(
|
||||
entity=self.entity,
|
||||
visible=(0, 0, 0, 0),
|
||||
discovered=(30, 30, 50, 180),
|
||||
unknown=(0, 0, 0, 255)
|
||||
)
|
||||
self.entity.update_visibility()
|
||||
|
||||
def move(self, dx, dy):
|
||||
new_x = self.entity.x + dx
|
||||
new_y = self.entity.y + dy
|
||||
|
||||
# Check walkability via grid
|
||||
point = self.entity.grid.at(new_x, new_y)
|
||||
if point and point.walkable:
|
||||
self.entity.pos = (new_x, new_y)
|
||||
self.entity.update_visibility() # Update FOV after move
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_visible_enemies(self):
|
||||
"""Get enemies this player can currently see."""
|
||||
return [e for e in self.entity.visible_entities()
|
||||
if e.name and e.name.startswith("enemy")]
|
||||
```
|
||||
|
||||
### Enemy Entity
|
||||
|
|
@ -213,7 +324,7 @@ class Player:
|
|||
```python
|
||||
class Enemy:
|
||||
def __init__(self, grid, pos, aggro_range=10):
|
||||
self.entity = mcrfpy.Entity(pos=pos, sprite_index=1)
|
||||
self.entity = mcrfpy.Entity(pos=pos, sprite_index=1, name="enemy")
|
||||
self.aggro_range = aggro_range
|
||||
self.health = 100
|
||||
grid.entities.append(self.entity)
|
||||
|
|
@ -312,4 +423,4 @@ See [[Performance-and-Profiling]] for optimization guidance.
|
|||
|
||||
---
|
||||
|
||||
*Last updated: 2025-11-29*
|
||||
*Last updated: 2025-12-01*
|
||||
Loading…
Reference in New Issue