202 lines
5.7 KiB
Python
202 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Interactive Visibility Demo
|
|
==========================
|
|
|
|
Controls:
|
|
- WASD: Move the player (green @)
|
|
- Arrow keys: Move enemy (red E)
|
|
- Tab: Cycle perspective (Omniscient → Player → Enemy → Omniscient)
|
|
- Space: Update visibility for current entity
|
|
- R: Reset positions
|
|
"""
|
|
|
|
import mcrfpy
|
|
import sys
|
|
|
|
# Create scene and grid
|
|
mcrfpy.createScene("visibility_demo")
|
|
grid = mcrfpy.Grid(grid_x=30, grid_y=20)
|
|
grid.fill_color = mcrfpy.Color(20, 20, 30) # Dark background
|
|
|
|
# Initialize grid - all walkable and transparent
|
|
for y in range(20):
|
|
for x in range(30):
|
|
cell = grid.at(x, y)
|
|
cell.walkable = True
|
|
cell.transparent = True
|
|
cell.color = mcrfpy.Color(100, 100, 120) # Floor color
|
|
|
|
# Create walls
|
|
walls = [
|
|
# Central cross
|
|
[(15, y) for y in range(8, 12)],
|
|
[(x, 10) for x in range(13, 18)],
|
|
|
|
# Rooms
|
|
# Top-left room
|
|
[(x, 5) for x in range(2, 8)] + [(8, y) for y in range(2, 6)],
|
|
[(2, y) for y in range(2, 6)] + [(x, 2) for x in range(2, 8)],
|
|
|
|
# Top-right room
|
|
[(x, 5) for x in range(22, 28)] + [(22, y) for y in range(2, 6)],
|
|
[(28, y) for y in range(2, 6)] + [(x, 2) for x in range(22, 28)],
|
|
|
|
# Bottom-left room
|
|
[(x, 15) for x in range(2, 8)] + [(8, y) for y in range(15, 18)],
|
|
[(2, y) for y in range(15, 18)] + [(x, 18) for x in range(2, 8)],
|
|
|
|
# Bottom-right room
|
|
[(x, 15) for x in range(22, 28)] + [(22, y) for y in range(15, 18)],
|
|
[(28, y) for y in range(15, 18)] + [(x, 18) for x in range(22, 28)],
|
|
]
|
|
|
|
for wall_group in walls:
|
|
for x, y in wall_group:
|
|
if 0 <= x < 30 and 0 <= y < 20:
|
|
cell = grid.at(x, y)
|
|
cell.walkable = False
|
|
cell.transparent = False
|
|
cell.color = mcrfpy.Color(40, 20, 20) # Wall color
|
|
|
|
# Create entities
|
|
player = mcrfpy.Entity(5, 10, grid=grid)
|
|
player.sprite_index = 64 # @
|
|
enemy = mcrfpy.Entity(25, 10, grid=grid)
|
|
enemy.sprite_index = 69 # E
|
|
|
|
# Update initial visibility
|
|
player.update_visibility()
|
|
enemy.update_visibility()
|
|
|
|
# Global state
|
|
current_perspective = -1
|
|
perspective_names = ["Omniscient", "Player", "Enemy"]
|
|
|
|
# UI Setup
|
|
ui = mcrfpy.sceneUI("visibility_demo")
|
|
ui.append(grid)
|
|
grid.position = (50, 100)
|
|
grid.size = (900, 600) # 30*30, 20*30
|
|
|
|
# Title
|
|
title = mcrfpy.Caption("Interactive Visibility Demo", 350, 20)
|
|
title.fill_color = mcrfpy.Color(255, 255, 255)
|
|
ui.append(title)
|
|
|
|
# Info displays
|
|
perspective_label = mcrfpy.Caption("Perspective: Omniscient", 50, 50)
|
|
perspective_label.fill_color = mcrfpy.Color(200, 200, 200)
|
|
ui.append(perspective_label)
|
|
|
|
controls = mcrfpy.Caption("WASD: Move player | Arrows: Move enemy | Tab: Cycle perspective | Space: Update visibility | R: Reset", 50, 730)
|
|
controls.fill_color = mcrfpy.Color(150, 150, 150)
|
|
ui.append(controls)
|
|
|
|
player_info = mcrfpy.Caption("Player: (5, 10)", 700, 50)
|
|
player_info.fill_color = mcrfpy.Color(100, 255, 100)
|
|
ui.append(player_info)
|
|
|
|
enemy_info = mcrfpy.Caption("Enemy: (25, 10)", 700, 70)
|
|
enemy_info.fill_color = mcrfpy.Color(255, 100, 100)
|
|
ui.append(enemy_info)
|
|
|
|
# Helper functions
|
|
def move_entity(entity, dx, dy):
|
|
"""Move entity if target is walkable"""
|
|
new_x = int(entity.x + dx)
|
|
new_y = int(entity.y + dy)
|
|
|
|
if 0 <= new_x < 30 and 0 <= new_y < 20:
|
|
cell = grid.at(new_x, new_y)
|
|
if cell.walkable:
|
|
entity.x = new_x
|
|
entity.y = new_y
|
|
entity.update_visibility()
|
|
return True
|
|
return False
|
|
|
|
def update_info():
|
|
"""Update info displays"""
|
|
player_info.text = f"Player: ({int(player.x)}, {int(player.y)})"
|
|
enemy_info.text = f"Enemy: ({int(enemy.x)}, {int(enemy.y)})"
|
|
|
|
def cycle_perspective():
|
|
"""Cycle through perspectives"""
|
|
global current_perspective
|
|
|
|
# Cycle: -1 → 0 → 1 → -1
|
|
current_perspective = (current_perspective + 2) % 3 - 1
|
|
|
|
grid.perspective = current_perspective
|
|
name = perspective_names[current_perspective + 1]
|
|
perspective_label.text = f"Perspective: {name}"
|
|
|
|
# Key handlers
|
|
def handle_keys(key, state):
|
|
"""Handle keyboard input"""
|
|
if state == "end": return
|
|
key = key.lower()
|
|
# Player movement (WASD)
|
|
if key == "w":
|
|
move_entity(player, 0, -1)
|
|
elif key == "s":
|
|
move_entity(player, 0, 1)
|
|
elif key == "a":
|
|
move_entity(player, -1, 0)
|
|
elif key == "d":
|
|
move_entity(player, 1, 0)
|
|
|
|
# Enemy movement (Arrows)
|
|
elif key == "up":
|
|
move_entity(enemy, 0, -1)
|
|
elif key == "down":
|
|
move_entity(enemy, 0, 1)
|
|
elif key == "left":
|
|
move_entity(enemy, -1, 0)
|
|
elif key == "right":
|
|
move_entity(enemy, 1, 0)
|
|
|
|
# Tab to cycle perspective
|
|
elif key == "tab":
|
|
cycle_perspective()
|
|
|
|
# Space to update visibility
|
|
elif key == "space":
|
|
player.update_visibility()
|
|
enemy.update_visibility()
|
|
print("Updated visibility for both entities")
|
|
|
|
# R to reset
|
|
elif key == "r":
|
|
player.x, player.y = 5, 10
|
|
enemy.x, enemy.y = 25, 10
|
|
player.update_visibility()
|
|
enemy.update_visibility()
|
|
update_info()
|
|
print("Reset positions")
|
|
|
|
# Q to quit
|
|
elif key == "q":
|
|
print("Exiting...")
|
|
sys.exit(0)
|
|
|
|
update_info()
|
|
|
|
# Set scene first
|
|
mcrfpy.setScene("visibility_demo")
|
|
|
|
# Register key handler (operates on current scene)
|
|
mcrfpy.keypressScene(handle_keys)
|
|
|
|
print("Interactive Visibility Demo")
|
|
print("===========================")
|
|
print("WASD: Move player (green @)")
|
|
print("Arrows: Move enemy (red E)")
|
|
print("Tab: Cycle perspective")
|
|
print("Space: Update visibility")
|
|
print("R: Reset positions")
|
|
print("Q: Quit")
|
|
print("\nCurrent perspective: Omniscient (shows all)")
|
|
print("Try moving entities and switching perspectives!")
|