Rotation
This commit is contained in:
parent
486087b9cb
commit
da434dcc64
14 changed files with 1076 additions and 60 deletions
86
tests/unit/grid_camera_rotation_test.py
Normal file
86
tests/unit/grid_camera_rotation_test.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Test UIGrid camera_rotation functionality"""
|
||||
import mcrfpy
|
||||
from mcrfpy import automation
|
||||
import sys
|
||||
|
||||
# Create test scene
|
||||
test_scene = mcrfpy.Scene("grid_rotation_test")
|
||||
ui = test_scene.children
|
||||
|
||||
# Create background
|
||||
bg = mcrfpy.Frame(pos=(0, 0), size=(800, 600), fill_color=mcrfpy.Color(30, 30, 40))
|
||||
ui.append(bg)
|
||||
|
||||
# Create a grid with entities to visualize rotation
|
||||
grid = mcrfpy.Grid(grid_size=(8, 8), pos=(50, 50), size=(300, 300))
|
||||
grid.fill_color = mcrfpy.Color(60, 60, 80)
|
||||
|
||||
# Add some entities to visualize the rotation
|
||||
for i in range(8):
|
||||
entity = mcrfpy.Entity((i, 0)) # Top row
|
||||
grid.entities.append(entity)
|
||||
|
||||
for i in range(1, 8):
|
||||
entity = mcrfpy.Entity((0, i)) # Left column
|
||||
grid.entities.append(entity)
|
||||
|
||||
# Apply camera rotation
|
||||
grid.camera_rotation = 30.0 # 30 degree rotation
|
||||
grid.center_camera((4, 4)) # Center on middle of grid
|
||||
|
||||
ui.append(grid)
|
||||
|
||||
# Create a second grid without rotation for comparison
|
||||
grid2 = mcrfpy.Grid(grid_size=(8, 8), pos=(400, 50), size=(300, 300))
|
||||
grid2.fill_color = mcrfpy.Color(60, 60, 80)
|
||||
|
||||
# Add same entities pattern
|
||||
for i in range(8):
|
||||
entity = mcrfpy.Entity((i, 0))
|
||||
grid2.entities.append(entity)
|
||||
|
||||
for i in range(1, 8):
|
||||
entity = mcrfpy.Entity((0, i))
|
||||
grid2.entities.append(entity)
|
||||
|
||||
grid2.camera_rotation = 0.0 # No rotation
|
||||
grid2.center_camera((4, 4))
|
||||
|
||||
ui.append(grid2)
|
||||
|
||||
# Labels
|
||||
label1 = mcrfpy.Caption(text="Grid with camera_rotation=30", pos=(50, 20))
|
||||
ui.append(label1)
|
||||
|
||||
label2 = mcrfpy.Caption(text="Grid with camera_rotation=0", pos=(400, 20))
|
||||
ui.append(label2)
|
||||
|
||||
# Create a third grid with viewport rotation (different from camera rotation)
|
||||
grid3 = mcrfpy.Grid(grid_size=(6, 6), pos=(175, 400), size=(200, 150))
|
||||
grid3.fill_color = mcrfpy.Color(80, 60, 60)
|
||||
|
||||
# Add entities
|
||||
for i in range(6):
|
||||
entity = mcrfpy.Entity((i, 0))
|
||||
grid3.entities.append(entity)
|
||||
|
||||
# Apply viewport rotation (entire grid rotates)
|
||||
grid3.rotation = 15.0
|
||||
grid3.origin = (100, 75) # Center origin for rotation
|
||||
grid3.center_camera((3, 3))
|
||||
|
||||
ui.append(grid3)
|
||||
|
||||
label3 = mcrfpy.Caption(text="Grid with viewport rotation=15 (rotates entire widget)", pos=(100, 560))
|
||||
ui.append(label3)
|
||||
|
||||
# Activate scene
|
||||
mcrfpy.current_scene = test_scene
|
||||
|
||||
# Advance the game loop to render, then take screenshot
|
||||
mcrfpy.step(0.1)
|
||||
automation.screenshot("grid_camera_rotation_test.png")
|
||||
print("Screenshot saved as grid_camera_rotation_test.png")
|
||||
print("PASS")
|
||||
sys.exit(0)
|
||||
163
tests/unit/rotation_test.py
Normal file
163
tests/unit/rotation_test.py
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Test rotation support for UIDrawable subclasses"""
|
||||
import mcrfpy
|
||||
import sys
|
||||
|
||||
def test_rotation_properties():
|
||||
"""Test rotation, origin, rotate_with_camera properties on all UIDrawable types"""
|
||||
print("Testing rotation properties on all UIDrawable types...")
|
||||
|
||||
# Test UIFrame
|
||||
frame = mcrfpy.Frame(pos=(100, 100), size=(50, 50))
|
||||
assert frame.rotation == 0.0, f"Frame default rotation should be 0, got {frame.rotation}"
|
||||
frame.rotation = 45.0
|
||||
assert frame.rotation == 45.0, f"Frame rotation should be 45, got {frame.rotation}"
|
||||
|
||||
# Test origin as Vector
|
||||
frame.origin = (25, 25)
|
||||
assert frame.origin.x == 25.0, f"Frame origin.x should be 25, got {frame.origin.x}"
|
||||
assert frame.origin.y == 25.0, f"Frame origin.y should be 25, got {frame.origin.y}"
|
||||
|
||||
# Test rotate_with_camera
|
||||
assert frame.rotate_with_camera == False, "Default rotate_with_camera should be False"
|
||||
frame.rotate_with_camera = True
|
||||
assert frame.rotate_with_camera == True, "rotate_with_camera should be True after setting"
|
||||
print(" Frame: PASS")
|
||||
|
||||
# Test UISprite
|
||||
sprite = mcrfpy.Sprite(pos=(100, 100))
|
||||
assert sprite.rotation == 0.0, f"Sprite default rotation should be 0, got {sprite.rotation}"
|
||||
sprite.rotation = 90.0
|
||||
assert sprite.rotation == 90.0, f"Sprite rotation should be 90, got {sprite.rotation}"
|
||||
sprite.origin = (8, 8)
|
||||
assert sprite.origin.x == 8.0, f"Sprite origin.x should be 8, got {sprite.origin.x}"
|
||||
print(" Sprite: PASS")
|
||||
|
||||
# Test UICaption
|
||||
caption = mcrfpy.Caption(text="Test", pos=(100, 100))
|
||||
assert caption.rotation == 0.0, f"Caption default rotation should be 0, got {caption.rotation}"
|
||||
caption.rotation = -30.0
|
||||
assert caption.rotation == -30.0, f"Caption rotation should be -30, got {caption.rotation}"
|
||||
caption.origin = (0, 0)
|
||||
assert caption.origin.x == 0.0, f"Caption origin.x should be 0, got {caption.origin.x}"
|
||||
print(" Caption: PASS")
|
||||
|
||||
# Test UICircle
|
||||
circle = mcrfpy.Circle(center=(100, 100), radius=25)
|
||||
assert circle.rotation == 0.0, f"Circle default rotation should be 0, got {circle.rotation}"
|
||||
circle.rotation = 180.0
|
||||
assert circle.rotation == 180.0, f"Circle rotation should be 180, got {circle.rotation}"
|
||||
print(" Circle: PASS")
|
||||
|
||||
# Test UILine
|
||||
line = mcrfpy.Line(start=(0, 0), end=(100, 100))
|
||||
assert line.rotation == 0.0, f"Line default rotation should be 0, got {line.rotation}"
|
||||
line.rotation = 45.0
|
||||
assert line.rotation == 45.0, f"Line rotation should be 45, got {line.rotation}"
|
||||
print(" Line: PASS")
|
||||
|
||||
# Test UIArc
|
||||
arc = mcrfpy.Arc(center=(100, 100), radius=50, start_angle=0, end_angle=90)
|
||||
assert arc.rotation == 0.0, f"Arc default rotation should be 0, got {arc.rotation}"
|
||||
arc.rotation = 270.0
|
||||
assert arc.rotation == 270.0, f"Arc rotation should be 270, got {arc.rotation}"
|
||||
print(" Arc: PASS")
|
||||
|
||||
print("All rotation property tests passed!")
|
||||
return True
|
||||
|
||||
def test_rotation_animation():
|
||||
"""Test that rotation can be animated"""
|
||||
print("\nTesting rotation animation...")
|
||||
|
||||
frame = mcrfpy.Frame(pos=(100, 100), size=(50, 50))
|
||||
frame.rotation = 0.0
|
||||
|
||||
# Test that animate method exists and accepts rotation
|
||||
try:
|
||||
frame.animate("rotation", 360.0, 1.0, mcrfpy.Easing.LINEAR)
|
||||
print(" Animation started successfully")
|
||||
except Exception as e:
|
||||
print(f" Animation failed: {e}")
|
||||
return False
|
||||
|
||||
# Test origin animation
|
||||
try:
|
||||
frame.animate("origin_x", 25.0, 0.5, mcrfpy.Easing.LINEAR)
|
||||
frame.animate("origin_y", 25.0, 0.5, mcrfpy.Easing.LINEAR)
|
||||
print(" Origin animation started successfully")
|
||||
except Exception as e:
|
||||
print(f" Origin animation failed: {e}")
|
||||
return False
|
||||
|
||||
print("Rotation animation tests passed!")
|
||||
return True
|
||||
|
||||
def test_grid_camera_rotation():
|
||||
"""Test UIGrid camera_rotation property"""
|
||||
print("\nTesting Grid camera_rotation...")
|
||||
|
||||
grid = mcrfpy.Grid(grid_size=(10, 10), pos=(50, 50), size=(200, 200))
|
||||
|
||||
# Test default camera_rotation
|
||||
assert grid.camera_rotation == 0.0, f"Grid default camera_rotation should be 0, got {grid.camera_rotation}"
|
||||
|
||||
# Test setting camera_rotation
|
||||
grid.camera_rotation = 45.0
|
||||
assert grid.camera_rotation == 45.0, f"Grid camera_rotation should be 45, got {grid.camera_rotation}"
|
||||
|
||||
# Test negative rotation
|
||||
grid.camera_rotation = -90.0
|
||||
assert grid.camera_rotation == -90.0, f"Grid camera_rotation should be -90, got {grid.camera_rotation}"
|
||||
|
||||
# Test full rotation
|
||||
grid.camera_rotation = 360.0
|
||||
assert grid.camera_rotation == 360.0, f"Grid camera_rotation should be 360, got {grid.camera_rotation}"
|
||||
|
||||
# Grid also has regular rotation (viewport rotation)
|
||||
assert grid.rotation == 0.0, f"Grid viewport rotation should default to 0, got {grid.rotation}"
|
||||
grid.rotation = 15.0
|
||||
assert grid.rotation == 15.0, f"Grid viewport rotation should be 15, got {grid.rotation}"
|
||||
|
||||
# Test camera_rotation animation
|
||||
try:
|
||||
grid.animate("camera_rotation", 90.0, 1.0, mcrfpy.Easing.EASE_IN_OUT)
|
||||
print(" Camera rotation animation started successfully")
|
||||
except Exception as e:
|
||||
print(f" Camera rotation animation failed: {e}")
|
||||
return False
|
||||
|
||||
print("Grid camera_rotation tests passed!")
|
||||
return True
|
||||
|
||||
def run_all_tests():
|
||||
"""Run all rotation tests"""
|
||||
print("=" * 50)
|
||||
print("UIDrawable Rotation Tests")
|
||||
print("=" * 50)
|
||||
|
||||
results = []
|
||||
results.append(("Rotation Properties", test_rotation_properties()))
|
||||
results.append(("Rotation Animation", test_rotation_animation()))
|
||||
results.append(("Grid Camera Rotation", test_grid_camera_rotation()))
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("Test Results Summary")
|
||||
print("=" * 50)
|
||||
|
||||
all_passed = True
|
||||
for name, passed in results:
|
||||
status = "PASS" if passed else "FAIL"
|
||||
print(f" {name}: {status}")
|
||||
if not passed:
|
||||
all_passed = False
|
||||
|
||||
if all_passed:
|
||||
print("\nAll tests PASSED!")
|
||||
return 0
|
||||
else:
|
||||
print("\nSome tests FAILED!")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run_all_tests())
|
||||
114
tests/unit/rotation_visual_test.py
Normal file
114
tests/unit/rotation_visual_test.py
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Visual test for rotation support - uses direct screenshot"""
|
||||
import mcrfpy
|
||||
from mcrfpy import automation
|
||||
import sys
|
||||
|
||||
# Create test scene
|
||||
test_scene = mcrfpy.Scene("rotation_test")
|
||||
ui = test_scene.children
|
||||
|
||||
# Create background
|
||||
bg = mcrfpy.Frame(pos=(0, 0), size=(800, 600), fill_color=mcrfpy.Color(40, 40, 50))
|
||||
ui.append(bg)
|
||||
|
||||
# Row 1: Frames with different rotations
|
||||
# Frame at 0 degrees
|
||||
frame1 = mcrfpy.Frame(pos=(100, 100), size=(60, 60), fill_color=mcrfpy.Color(200, 50, 50))
|
||||
frame1.rotation = 0.0
|
||||
frame1.origin = (30, 30) # Center origin
|
||||
ui.append(frame1)
|
||||
|
||||
# Frame at 45 degrees
|
||||
frame2 = mcrfpy.Frame(pos=(250, 100), size=(60, 60), fill_color=mcrfpy.Color(50, 200, 50))
|
||||
frame2.rotation = 45.0
|
||||
frame2.origin = (30, 30)
|
||||
ui.append(frame2)
|
||||
|
||||
# Frame at 90 degrees
|
||||
frame3 = mcrfpy.Frame(pos=(400, 100), size=(60, 60), fill_color=mcrfpy.Color(50, 50, 200))
|
||||
frame3.rotation = 90.0
|
||||
frame3.origin = (30, 30)
|
||||
ui.append(frame3)
|
||||
|
||||
# Label for row 1
|
||||
label1 = mcrfpy.Caption(text="Frames: 0, 45, 90 degrees", pos=(100, 50))
|
||||
ui.append(label1)
|
||||
|
||||
# Row 2: Captions with rotation
|
||||
caption1 = mcrfpy.Caption(text="Rotated Text", pos=(100, 250))
|
||||
caption1.rotation = 0.0
|
||||
ui.append(caption1)
|
||||
|
||||
caption2 = mcrfpy.Caption(text="Rotated Text", pos=(300, 250))
|
||||
caption2.rotation = -15.0
|
||||
ui.append(caption2)
|
||||
|
||||
caption3 = mcrfpy.Caption(text="Rotated Text", pos=(500, 250))
|
||||
caption3.rotation = 30.0
|
||||
ui.append(caption3)
|
||||
|
||||
# Label for row 2
|
||||
label2 = mcrfpy.Caption(text="Captions: 0, -15, 30 degrees", pos=(100, 200))
|
||||
ui.append(label2)
|
||||
|
||||
# Row 3: Circles (rotation with offset origin causes orbiting)
|
||||
circle1 = mcrfpy.Circle(center=(100, 400), radius=25, fill_color=mcrfpy.Color(200, 200, 50))
|
||||
circle1.rotation = 0.0
|
||||
ui.append(circle1)
|
||||
|
||||
circle2 = mcrfpy.Circle(center=(250, 400), radius=25, fill_color=mcrfpy.Color(200, 50, 200))
|
||||
circle2.rotation = 45.0
|
||||
circle2.origin = (20, 0) # Offset origin to show orbiting effect
|
||||
ui.append(circle2)
|
||||
|
||||
circle3 = mcrfpy.Circle(center=(400, 400), radius=25, fill_color=mcrfpy.Color(50, 200, 200))
|
||||
circle3.rotation = 90.0
|
||||
circle3.origin = (20, 0) # Same offset
|
||||
ui.append(circle3)
|
||||
|
||||
# Label for row 3
|
||||
label3 = mcrfpy.Caption(text="Circles with offset origin: 0, 45, 90 degrees", pos=(100, 350))
|
||||
ui.append(label3)
|
||||
|
||||
# Row 4: Lines with rotation
|
||||
line1 = mcrfpy.Line(start=(100, 500), end=(150, 500), thickness=3, color=mcrfpy.Color(255, 255, 255))
|
||||
line1.rotation = 0.0
|
||||
ui.append(line1)
|
||||
|
||||
line2 = mcrfpy.Line(start=(250, 500), end=(300, 500), thickness=3, color=mcrfpy.Color(255, 200, 200))
|
||||
line2.rotation = 45.0
|
||||
line2.origin = (125, 500) # Rotate around line center
|
||||
ui.append(line2)
|
||||
|
||||
line3 = mcrfpy.Line(start=(400, 500), end=(450, 500), thickness=3, color=mcrfpy.Color(200, 255, 200))
|
||||
line3.rotation = -45.0
|
||||
line3.origin = (200, 500)
|
||||
ui.append(line3)
|
||||
|
||||
# Label for row 4
|
||||
label4 = mcrfpy.Caption(text="Lines: 0, 45, -45 degrees", pos=(100, 470))
|
||||
ui.append(label4)
|
||||
|
||||
# Arcs with rotation
|
||||
arc1 = mcrfpy.Arc(center=(600, 100), radius=40, start_angle=0, end_angle=90, thickness=5)
|
||||
arc1.rotation = 0.0
|
||||
ui.append(arc1)
|
||||
|
||||
arc2 = mcrfpy.Arc(center=(700, 100), radius=40, start_angle=0, end_angle=90, thickness=5)
|
||||
arc2.rotation = 45.0
|
||||
ui.append(arc2)
|
||||
|
||||
# Label for arcs
|
||||
label5 = mcrfpy.Caption(text="Arcs: 0, 45 degrees", pos=(550, 50))
|
||||
ui.append(label5)
|
||||
|
||||
# Activate scene
|
||||
mcrfpy.current_scene = test_scene
|
||||
|
||||
# Advance the game loop to render, then take screenshot
|
||||
mcrfpy.step(0.1)
|
||||
automation.screenshot("rotation_visual_test.png")
|
||||
print("Screenshot saved as rotation_visual_test.png")
|
||||
print("PASS")
|
||||
sys.exit(0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue