hotfix: windows build, fresh docs
This commit is contained in:
parent
4144cdf067
commit
96857a41c6
File diff suppressed because it is too large
Load Diff
|
@ -183,7 +183,7 @@
|
|||
<div class="container">
|
||||
|
||||
<h1>McRogueFace API Reference - Complete Documentation</h1>
|
||||
<p><em>Generated on 2025-07-08 11:53:54</em></p>
|
||||
<p><em>Generated on 2025-07-10 01:04:50</em></p>
|
||||
<div class="toc">
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
|
@ -632,13 +632,6 @@ mcrfpy.setScale(2.0) # Double the window size
|
|||
</div>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get_current_value()</code></h5>
|
||||
<p>Get the current interpolated value of the animation.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> float: Current animation value between start and end
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">update(delta_time)</code></h5>
|
||||
<p>Update the animation by the given time delta.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -662,6 +655,13 @@ The UI element to animate
|
|||
<strong>Note:</strong> The target must have the property specified in the animation constructor.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get_current_value()</code></h5>
|
||||
<p>Get the current interpolated value of the animation.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> float: Current animation value between start and end
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Caption</span></h3>
|
||||
|
@ -701,23 +701,6 @@ Attributes:
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -734,12 +717,47 @@ Vertical offset in pixels
|
|||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Color</span></h3>
|
||||
<p>SFML Color Object</p>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">from_hex(hex_string)</code></h5>
|
||||
<p>Create a Color from a hexadecimal color string.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">hex_string</span>
|
||||
<span class="arg-type">(str)</span>:
|
||||
Hex color string (e.g., "#FF0000" or "FF0000")
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> Color: New Color object from hex string
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<strong>Example:</strong>
|
||||
<pre><code>
|
||||
red = Color.from_hex("#FF0000")
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">lerp(other, t)</code></h5>
|
||||
<p>Linearly interpolate between this color and another.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -775,24 +793,6 @@ hex_str = color.to_hex() # Returns "#FF0000"
|
|||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">from_hex(hex_string)</code></h5>
|
||||
<p>Create a Color from a hexadecimal color string.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">hex_string</span>
|
||||
<span class="arg-type">(str)</span>:
|
||||
Hex color string (e.g., "#FF0000" or "FF0000")
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> Color: New Color object from hex string
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<strong>Example:</strong>
|
||||
<pre><code>
|
||||
red = Color.from_hex("#FF0000")
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Drawable</span></h3>
|
||||
|
@ -809,6 +809,23 @@ red = Color.from_hex("#FF0000")
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dx</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Horizontal offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dy</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Vertical offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -825,39 +842,12 @@ New height in pixels
|
|||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dx</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Horizontal offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dy</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Vertical offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Entity</span></h3>
|
||||
<p>UIEntity objects</p>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get_bounds()</code></h5>
|
||||
<p>Get the bounding rectangle of this drawable element.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element's bounds
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -875,6 +865,36 @@ Vertical offset in pixels
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">update_visibility(...)</span>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">index()</code></h5>
|
||||
<p>Get the index of this entity in its parent grid's entity list.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Index position, or -1 if not in a grid
|
||||
</div>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">path_to(...)</span>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">at(x, y)</code></h5>
|
||||
<p>Check if this entity is at the specified grid coordinates.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -892,27 +912,13 @@ Grid y coordinate to check
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
<h5><code class="method">get_bounds()</code></h5>
|
||||
<p>Get the bounding rectangle of this drawable element.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element's bounds
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">index()</code></h5>
|
||||
<p>Get the index of this entity in its parent grid's entity list.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Index position, or -1 if not in a grid
|
||||
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
|
@ -937,21 +943,15 @@ The entity to remove
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">extend(iterable)</code></h5>
|
||||
<p>Add all entities from an iterable to the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">iterable</span>
|
||||
<span class="arg-type">(Iterable[Entity])</span>:
|
||||
Entities to add
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">append(entity)</code></h5>
|
||||
<p>Add an entity to the end of the collection.</p>
|
||||
<h5><code class="method">count(entity)</code></h5>
|
||||
<p>Count the number of occurrences of an entity in the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">entity</span>
|
||||
<span class="arg-type">(Entity)</span>:
|
||||
The entity to add
|
||||
The entity to count
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Number of times entity appears in collection
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
|
@ -967,15 +967,21 @@ The entity to find
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">count(entity)</code></h5>
|
||||
<p>Count the number of occurrences of an entity in the collection.</p>
|
||||
<h5><code class="method">extend(iterable)</code></h5>
|
||||
<p>Add all entities from an iterable to the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">iterable</span>
|
||||
<span class="arg-type">(Iterable[Entity])</span>:
|
||||
Entities to add
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">append(entity)</code></h5>
|
||||
<p>Add an entity to the end of the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">entity</span>
|
||||
<span class="arg-type">(Entity)</span>:
|
||||
The entity to count
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Number of times entity appears in collection
|
||||
The entity to add
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1022,23 +1028,6 @@ Attributes:
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -1055,6 +1044,23 @@ Vertical offset in pixels
|
|||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Grid</span></h3>
|
||||
|
@ -1086,31 +1092,24 @@ Attributes:
|
|||
z_index (int): Rendering order</p>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get_bounds()</code></h5>
|
||||
<p>Get the bounding rectangle of this drawable element.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element's bounds
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dx</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Horizontal offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dy</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Vertical offset in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
|
||||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">at(x, y)</code></h5>
|
||||
<p>Get the GridPoint at the specified grid coordinates.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">x</span>
|
||||
<span class="arg-type">(int)</span>:
|
||||
Grid x coordinate
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">y</span>
|
||||
<span class="arg-type">(int)</span>:
|
||||
Grid y coordinate
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> GridPoint or None: The grid point at (x, y), or None if out of bounds
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">compute_fov(...)</span>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
|
@ -1129,21 +1128,49 @@ New height in pixels
|
|||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">compute_dijkstra(...)</span>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">get_dijkstra_path(...)</span>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">is_in_fov(...)</span>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">find_path(...)</span>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">compute_astar_path(...)</span>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<h5><code class="method">at(x, y)</code></h5>
|
||||
<p>Get the GridPoint at the specified grid coordinates.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dx</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Horizontal offset in pixels
|
||||
<span class="arg-name">x</span>
|
||||
<span class="arg-type">(int)</span>:
|
||||
Grid x coordinate
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">dy</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
Vertical offset in pixels
|
||||
<span class="arg-name">y</span>
|
||||
<span class="arg-type">(int)</span>:
|
||||
Grid y coordinate
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> GridPoint or None: The grid point at (x, y), or None if out of bounds
|
||||
</div>
|
||||
</div>
|
||||
<div class="arg-item">
|
||||
<span class="method">get_dijkstra_distance(...)</span>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get_bounds()</code></h5>
|
||||
<p>Get the bounding rectangle of this drawable element.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element's bounds
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1273,23 +1300,6 @@ Attributes:
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">move(dx, dy)</code></h5>
|
||||
<p>Move the element by a relative offset.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -1306,6 +1316,23 @@ Vertical offset in pixels
|
|||
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">resize(width, height)</code></h5>
|
||||
<p>Resize the element to new dimensions.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">width</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New width in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">height</span>
|
||||
<span class="arg-type">(float)</span>:
|
||||
New height in pixels
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">Texture</span></h3>
|
||||
|
@ -1323,6 +1350,13 @@ Vertical offset in pixels
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">restart()</code></h5>
|
||||
<p>Restart the timer from the beginning.</p>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> Resets the timer's internal clock to zero.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">pause()</code></h5>
|
||||
<p>Pause the timer, stopping its callback execution.</p>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
|
@ -1336,13 +1370,6 @@ Vertical offset in pixels
|
|||
<strong>Note:</strong> After cancelling, the timer object cannot be reused.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">restart()</code></h5>
|
||||
<p>Restart the timer from the beginning.</p>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> Resets the timer's internal clock to zero.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">UICollection</span></h3>
|
||||
|
@ -1358,6 +1385,30 @@ The drawable to remove
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">count(drawable)</code></h5>
|
||||
<p>Count the number of occurrences of a drawable in the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">drawable</span>
|
||||
<span class="arg-type">(UIDrawable)</span>:
|
||||
The drawable to count
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Number of times drawable appears in collection
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">index(drawable)</code></h5>
|
||||
<p>Find the index of the first occurrence of a drawable.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">drawable</span>
|
||||
<span class="arg-type">(UIDrawable)</span>:
|
||||
The drawable to find
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Index of drawable in collection
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">extend(iterable)</code></h5>
|
||||
<p>Add all drawables from an iterable to the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -1375,30 +1426,6 @@ Drawables to add
|
|||
The drawable element to add
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">index(drawable)</code></h5>
|
||||
<p>Find the index of the first occurrence of a drawable.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">drawable</span>
|
||||
<span class="arg-type">(UIDrawable)</span>:
|
||||
The drawable to find
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Index of drawable in collection
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">count(drawable)</code></h5>
|
||||
<p>Count the number of occurrences of a drawable in the collection.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">drawable</span>
|
||||
<span class="arg-type">(UIDrawable)</span>:
|
||||
The drawable to count
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> int: Number of times drawable appears in collection
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method-section">
|
||||
<h3><span class="class-name">UICollectionIter</span></h3>
|
||||
|
@ -1413,28 +1440,10 @@ The drawable to count
|
|||
<p>SFML Vector Object</p>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">magnitude()</code></h5>
|
||||
<p>Calculate the length/magnitude of this vector.</p>
|
||||
<h5><code class="method">copy()</code></h5>
|
||||
<p>Create a copy of this vector.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> float: The magnitude of the vector
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<strong>Example:</strong>
|
||||
<pre><code>
|
||||
length = vector.magnitude()
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">distance_to(other)</code></h5>
|
||||
<p>Calculate the distance to another vector.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">other</span>
|
||||
<span class="arg-type">(Vector)</span>:
|
||||
The other vector
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> float: Distance between the two vectors
|
||||
<strong>Returns:</strong> Vector: New Vector object with same x and y values
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
|
@ -1457,6 +1466,19 @@ The other vector
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">magnitude()</code></h5>
|
||||
<p>Calculate the length/magnitude of this vector.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> float: The magnitude of the vector
|
||||
</div>
|
||||
<div style="margin-left: 20px;">
|
||||
<strong>Example:</strong>
|
||||
<pre><code>
|
||||
length = vector.magnitude()
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">normalize()</code></h5>
|
||||
<p>Return a unit vector in the same direction.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
|
@ -1474,10 +1496,15 @@ The other vector
|
|||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">copy()</code></h5>
|
||||
<p>Create a copy of this vector.</p>
|
||||
<h5><code class="method">distance_to(other)</code></h5>
|
||||
<p>Calculate the distance to another vector.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="arg-name">other</span>
|
||||
<span class="arg-type">(Vector)</span>:
|
||||
The other vector
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> Vector: New Vector object with same x and y values
|
||||
<strong>Returns:</strong> float: Distance between the two vectors
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1486,6 +1513,16 @@ The other vector
|
|||
<p>Window singleton for accessing and modifying the game window properties</p>
|
||||
<h4>Methods:</h4>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get()</code></h5>
|
||||
<p>Get the Window singleton instance.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> Window: The singleton window object
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> This is a static method that returns the same instance every time.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">screenshot(filename)</code></h5>
|
||||
<p>Take a screenshot and save it to a file.</p>
|
||||
<div style="margin-left: 20px;">
|
||||
|
@ -1504,16 +1541,6 @@ Path where to save the screenshot
|
|||
<strong>Note:</strong> Only works if the window is not fullscreen.
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 20px; margin-bottom: 15px;">
|
||||
<h5><code class="method">get()</code></h5>
|
||||
<p>Get the Window singleton instance.</p>
|
||||
<div style="margin-left: 20px; color: #28a745;">
|
||||
<strong>Returns:</strong> Window: The singleton window object
|
||||
</div>
|
||||
<div style="margin-left: 20px; color: #856404;">
|
||||
<strong>Note:</strong> This is a static method that returns the same instance every time.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 id="automation">Automation Module</h2>
|
||||
<p>The <code>mcrfpy.automation</code> module provides testing and automation capabilities.</p>
|
||||
|
|
|
@ -35,7 +35,7 @@ int PyTimer::init(PyTimerObject* self, PyObject* args, PyObject* kwds) {
|
|||
PyObject* callback = nullptr;
|
||||
int interval = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sOi", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sOi", const_cast<char**>(kwlist),
|
||||
&name, &callback, &interval)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -508,8 +508,22 @@ PyMethodDef UIEntity::methods[] = {
|
|||
{"at", (PyCFunction)UIEntity::at, METH_O},
|
||||
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
||||
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, "Remove this entity from its grid"},
|
||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS, "Find path from entity to target position using Dijkstra pathfinding"},
|
||||
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS, "Update entity's visibility state based on current FOV"},
|
||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
||||
"path_to(x: int, y: int) -> bool\n\n"
|
||||
"Find and follow path to target position using A* pathfinding.\n\n"
|
||||
"Args:\n"
|
||||
" x: Target X coordinate\n"
|
||||
" y: Target Y coordinate\n\n"
|
||||
"Returns:\n"
|
||||
" True if a path was found and the entity started moving, False otherwise\n\n"
|
||||
"The entity will automatically move along the path over multiple frames.\n"
|
||||
"Call this again to change the target or repath."},
|
||||
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS,
|
||||
"update_visibility() -> None\n\n"
|
||||
"Update entity's visibility state based on current FOV.\n\n"
|
||||
"Recomputes which cells are visible from the entity's position and updates\n"
|
||||
"the entity's gridstate to track explored areas. This is called automatically\n"
|
||||
"when the entity moves if it has a grid with perspective set."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -522,8 +536,22 @@ PyMethodDef UIEntity_all_methods[] = {
|
|||
{"at", (PyCFunction)UIEntity::at, METH_O},
|
||||
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
||||
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, "Remove this entity from its grid"},
|
||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS, "Find path from entity to target position using Dijkstra pathfinding"},
|
||||
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS, "Update entity's visibility state based on current FOV"},
|
||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
||||
"path_to(x: int, y: int) -> bool\n\n"
|
||||
"Find and follow path to target position using A* pathfinding.\n\n"
|
||||
"Args:\n"
|
||||
" x: Target X coordinate\n"
|
||||
" y: Target Y coordinate\n\n"
|
||||
"Returns:\n"
|
||||
" True if a path was found and the entity started moving, False otherwise\n\n"
|
||||
"The entity will automatically move along the path over multiple frames.\n"
|
||||
"Call this again to change the target or repath."},
|
||||
{"update_visibility", (PyCFunction)UIEntity::update_visibility, METH_NOARGS,
|
||||
"update_visibility() -> None\n\n"
|
||||
"Update entity's visibility state based on current FOV.\n\n"
|
||||
"Recomputes which cells are visible from the entity's position and updates\n"
|
||||
"the entity's gridstate to track explored areas. This is called automatically\n"
|
||||
"when the entity moves if it has a grid with perspective set."},
|
||||
{NULL} // Sentinel
|
||||
};
|
||||
|
||||
|
|
157
src/UIGrid.cpp
157
src/UIGrid.cpp
|
@ -972,7 +972,7 @@ PyObject* UIGrid::py_compute_fov(PyUIGridObject* self, PyObject* args, PyObject*
|
|||
int light_walls = 1;
|
||||
int algorithm = FOV_BASIC;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|ipi", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|ipi", const_cast<char**>(kwlist),
|
||||
&x, &y, &radius, &light_walls, &algorithm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ PyObject* UIGrid::py_find_path(PyUIGridObject* self, PyObject* args, PyObject* k
|
|||
int x1, y1, x2, y2;
|
||||
float diagonal_cost = 1.41f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii|f", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii|f", const_cast<char**>(kwlist),
|
||||
&x1, &y1, &x2, &y2, &diagonal_cost)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1026,7 +1026,7 @@ PyObject* UIGrid::py_compute_dijkstra(PyUIGridObject* self, PyObject* args, PyOb
|
|||
int root_x, root_y;
|
||||
float diagonal_cost = 1.41f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|f", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|f", const_cast<char**>(kwlist),
|
||||
&root_x, &root_y, &diagonal_cost)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1075,7 +1075,7 @@ PyObject* UIGrid::py_compute_astar_path(PyUIGridObject* self, PyObject* args, Py
|
|||
|
||||
static const char* kwlist[] = {"x1", "y1", "x2", "y2", "diagonal_cost", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii|f", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiii|f", const_cast<char**>(kwlist),
|
||||
&x1, &y1, &x2, &y2, &diagonal_cost)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1096,19 +1096,77 @@ PyObject* UIGrid::py_compute_astar_path(PyUIGridObject* self, PyObject* args, Py
|
|||
PyMethodDef UIGrid::methods[] = {
|
||||
{"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS},
|
||||
{"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute field of view from a position. Args: x, y, radius=0, light_walls=True, algorithm=FOV_BASIC"},
|
||||
"compute_fov(x: int, y: int, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None\n\n"
|
||||
"Compute field of view from a position.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate of the viewer\n"
|
||||
" y: Y coordinate of the viewer\n"
|
||||
" radius: Maximum view distance (0 = unlimited)\n"
|
||||
" light_walls: Whether walls are lit when visible\n"
|
||||
" algorithm: FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)\n\n"
|
||||
"Updates the internal FOV state. Use is_in_fov() to check visibility after calling this.\n"
|
||||
"When perspective is set, this also updates visibility overlays automatically."},
|
||||
{"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS,
|
||||
"Check if a cell is in the field of view. Args: x, y"},
|
||||
"is_in_fov(x: int, y: int) -> bool\n\n"
|
||||
"Check if a cell is in the field of view.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate to check\n"
|
||||
" y: Y coordinate to check\n\n"
|
||||
"Returns:\n"
|
||||
" True if the cell is visible, False otherwise\n\n"
|
||||
"Must call compute_fov() first to calculate visibility."},
|
||||
{"find_path", (PyCFunction)UIGrid::py_find_path, METH_VARARGS | METH_KEYWORDS,
|
||||
"Find A* path between two points. Args: x1, y1, x2, y2, diagonal_cost=1.41"},
|
||||
"find_path(x1: int, y1: int, x2: int, y2: int, diagonal_cost: float = 1.41) -> List[Tuple[int, int]]\n\n"
|
||||
"Find A* path between two points.\n\n"
|
||||
"Args:\n"
|
||||
" x1: Starting X coordinate\n"
|
||||
" y1: Starting Y coordinate\n"
|
||||
" x2: Target X coordinate\n"
|
||||
" y2: Target Y coordinate\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing the path, empty list if no path exists\n\n"
|
||||
"Uses A* algorithm with walkability from grid cells."},
|
||||
{"compute_dijkstra", (PyCFunction)UIGrid::py_compute_dijkstra, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute Dijkstra map from root position. Args: root_x, root_y, diagonal_cost=1.41"},
|
||||
"compute_dijkstra(root_x: int, root_y: int, diagonal_cost: float = 1.41) -> None\n\n"
|
||||
"Compute Dijkstra map from root position.\n\n"
|
||||
"Args:\n"
|
||||
" root_x: X coordinate of the root/target\n"
|
||||
" root_y: Y coordinate of the root/target\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Precomputes distances from all reachable cells to the root.\n"
|
||||
"Use get_dijkstra_distance() and get_dijkstra_path() to query results.\n"
|
||||
"Useful for multiple entities pathfinding to the same target."},
|
||||
{"get_dijkstra_distance", (PyCFunction)UIGrid::py_get_dijkstra_distance, METH_VARARGS,
|
||||
"Get distance from Dijkstra root to position. Args: x, y. Returns float or None if invalid."},
|
||||
"get_dijkstra_distance(x: int, y: int) -> Optional[float]\n\n"
|
||||
"Get distance from Dijkstra root to position.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate to query\n"
|
||||
" y: Y coordinate to query\n\n"
|
||||
"Returns:\n"
|
||||
" Distance as float, or None if position is unreachable or invalid\n\n"
|
||||
"Must call compute_dijkstra() first."},
|
||||
{"get_dijkstra_path", (PyCFunction)UIGrid::py_get_dijkstra_path, METH_VARARGS,
|
||||
"Get path from position to Dijkstra root. Args: x, y. Returns list of (x,y) tuples."},
|
||||
"get_dijkstra_path(x: int, y: int) -> List[Tuple[int, int]]\n\n"
|
||||
"Get path from position to Dijkstra root.\n\n"
|
||||
"Args:\n"
|
||||
" x: Starting X coordinate\n"
|
||||
" y: Starting Y coordinate\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing path to root, empty if unreachable\n\n"
|
||||
"Must call compute_dijkstra() first. Path includes start but not root position."},
|
||||
{"compute_astar_path", (PyCFunction)UIGrid::py_compute_astar_path, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute A* path between two points. Args: x1, y1, x2, y2, diagonal_cost=1.41. Returns list of (x,y) tuples. Note: diagonal_cost is currently ignored (uses default 1.41)."},
|
||||
"compute_astar_path(x1: int, y1: int, x2: int, y2: int, diagonal_cost: float = 1.41) -> List[Tuple[int, int]]\n\n"
|
||||
"Compute A* path between two points.\n\n"
|
||||
"Args:\n"
|
||||
" x1: Starting X coordinate\n"
|
||||
" y1: Starting Y coordinate\n"
|
||||
" x2: Target X coordinate\n"
|
||||
" y2: Target Y coordinate\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing the path, empty list if no path exists\n\n"
|
||||
"Alternative A* implementation. Prefer find_path() for consistency."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -1120,19 +1178,77 @@ PyMethodDef UIGrid_all_methods[] = {
|
|||
UIDRAWABLE_METHODS,
|
||||
{"at", (PyCFunction)UIGrid::py_at, METH_VARARGS | METH_KEYWORDS},
|
||||
{"compute_fov", (PyCFunction)UIGrid::py_compute_fov, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute field of view from a position. Args: x, y, radius=0, light_walls=True, algorithm=FOV_BASIC"},
|
||||
"compute_fov(x: int, y: int, radius: int = 0, light_walls: bool = True, algorithm: int = FOV_BASIC) -> None\n\n"
|
||||
"Compute field of view from a position.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate of the viewer\n"
|
||||
" y: Y coordinate of the viewer\n"
|
||||
" radius: Maximum view distance (0 = unlimited)\n"
|
||||
" light_walls: Whether walls are lit when visible\n"
|
||||
" algorithm: FOV algorithm to use (FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0-8)\n\n"
|
||||
"Updates the internal FOV state. Use is_in_fov() to check visibility after calling this.\n"
|
||||
"When perspective is set, this also updates visibility overlays automatically."},
|
||||
{"is_in_fov", (PyCFunction)UIGrid::py_is_in_fov, METH_VARARGS,
|
||||
"Check if a cell is in the field of view. Args: x, y"},
|
||||
"is_in_fov(x: int, y: int) -> bool\n\n"
|
||||
"Check if a cell is in the field of view.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate to check\n"
|
||||
" y: Y coordinate to check\n\n"
|
||||
"Returns:\n"
|
||||
" True if the cell is visible, False otherwise\n\n"
|
||||
"Must call compute_fov() first to calculate visibility."},
|
||||
{"find_path", (PyCFunction)UIGrid::py_find_path, METH_VARARGS | METH_KEYWORDS,
|
||||
"Find A* path between two points. Args: x1, y1, x2, y2, diagonal_cost=1.41"},
|
||||
"find_path(x1: int, y1: int, x2: int, y2: int, diagonal_cost: float = 1.41) -> List[Tuple[int, int]]\n\n"
|
||||
"Find A* path between two points.\n\n"
|
||||
"Args:\n"
|
||||
" x1: Starting X coordinate\n"
|
||||
" y1: Starting Y coordinate\n"
|
||||
" x2: Target X coordinate\n"
|
||||
" y2: Target Y coordinate\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing the path, empty list if no path exists\n\n"
|
||||
"Uses A* algorithm with walkability from grid cells."},
|
||||
{"compute_dijkstra", (PyCFunction)UIGrid::py_compute_dijkstra, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute Dijkstra map from root position. Args: root_x, root_y, diagonal_cost=1.41"},
|
||||
"compute_dijkstra(root_x: int, root_y: int, diagonal_cost: float = 1.41) -> None\n\n"
|
||||
"Compute Dijkstra map from root position.\n\n"
|
||||
"Args:\n"
|
||||
" root_x: X coordinate of the root/target\n"
|
||||
" root_y: Y coordinate of the root/target\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Precomputes distances from all reachable cells to the root.\n"
|
||||
"Use get_dijkstra_distance() and get_dijkstra_path() to query results.\n"
|
||||
"Useful for multiple entities pathfinding to the same target."},
|
||||
{"get_dijkstra_distance", (PyCFunction)UIGrid::py_get_dijkstra_distance, METH_VARARGS,
|
||||
"Get distance from Dijkstra root to position. Args: x, y. Returns float or None if invalid."},
|
||||
"get_dijkstra_distance(x: int, y: int) -> Optional[float]\n\n"
|
||||
"Get distance from Dijkstra root to position.\n\n"
|
||||
"Args:\n"
|
||||
" x: X coordinate to query\n"
|
||||
" y: Y coordinate to query\n\n"
|
||||
"Returns:\n"
|
||||
" Distance as float, or None if position is unreachable or invalid\n\n"
|
||||
"Must call compute_dijkstra() first."},
|
||||
{"get_dijkstra_path", (PyCFunction)UIGrid::py_get_dijkstra_path, METH_VARARGS,
|
||||
"Get path from position to Dijkstra root. Args: x, y. Returns list of (x,y) tuples."},
|
||||
"get_dijkstra_path(x: int, y: int) -> List[Tuple[int, int]]\n\n"
|
||||
"Get path from position to Dijkstra root.\n\n"
|
||||
"Args:\n"
|
||||
" x: Starting X coordinate\n"
|
||||
" y: Starting Y coordinate\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing path to root, empty if unreachable\n\n"
|
||||
"Must call compute_dijkstra() first. Path includes start but not root position."},
|
||||
{"compute_astar_path", (PyCFunction)UIGrid::py_compute_astar_path, METH_VARARGS | METH_KEYWORDS,
|
||||
"Compute A* path between two points. Args: x1, y1, x2, y2, diagonal_cost=1.41. Returns list of (x,y) tuples. Note: diagonal_cost is currently ignored (uses default 1.41)."},
|
||||
"compute_astar_path(x1: int, y1: int, x2: int, y2: int, diagonal_cost: float = 1.41) -> List[Tuple[int, int]]\n\n"
|
||||
"Compute A* path between two points.\n\n"
|
||||
"Args:\n"
|
||||
" x1: Starting X coordinate\n"
|
||||
" y1: Starting Y coordinate\n"
|
||||
" x2: Target X coordinate\n"
|
||||
" y2: Target Y coordinate\n"
|
||||
" diagonal_cost: Cost of diagonal movement (default: 1.41)\n\n"
|
||||
"Returns:\n"
|
||||
" List of (x, y) tuples representing the path, empty list if no path exists\n\n"
|
||||
"Alternative A* implementation. Prefer find_path() for consistency."},
|
||||
{NULL} // Sentinel
|
||||
};
|
||||
|
||||
|
@ -1161,7 +1277,10 @@ PyGetSetDef UIGrid::getsetters[] = {
|
|||
|
||||
{"texture", (getter)UIGrid::get_texture, NULL, "Texture of the grid", NULL}, //TODO 7DRL-day2-item5
|
||||
{"fill_color", (getter)UIGrid::get_fill_color, (setter)UIGrid::set_fill_color, "Background fill color of the grid", NULL},
|
||||
{"perspective", (getter)UIGrid::get_perspective, (setter)UIGrid::set_perspective, "Entity perspective index (-1 for omniscient view)", NULL},
|
||||
{"perspective", (getter)UIGrid::get_perspective, (setter)UIGrid::set_perspective,
|
||||
"Entity perspective index for FOV rendering (-1 for omniscient view, 0+ for entity index). "
|
||||
"When set to an entity index, only cells visible to that entity are rendered normally; "
|
||||
"explored but not visible cells are darkened, and unexplored cells are black.", NULL},
|
||||
{"z_index", (getter)UIDrawable::get_int, (setter)UIDrawable::set_int, "Z-order for rendering (lower values rendered first)", (void*)PyObjectsEnum::UIGRID},
|
||||
{"name", (getter)UIDrawable::get_name, (setter)UIDrawable::set_name, "Name for finding elements", (void*)PyObjectsEnum::UIGRID},
|
||||
UIDRAWABLE_GETSETTERS,
|
||||
|
|
|
@ -1,165 +1,208 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Animation System Demo - Shows all animation capabilities"""
|
||||
"""
|
||||
Animation Demo: Grid Center & Entity Movement
|
||||
=============================================
|
||||
|
||||
Demonstrates:
|
||||
- Animated grid centering following entity
|
||||
- Smooth entity movement along paths
|
||||
- Perspective shifts with zoom transitions
|
||||
- Field of view updates
|
||||
"""
|
||||
|
||||
import mcrfpy
|
||||
import math
|
||||
import sys
|
||||
|
||||
# Create main scene
|
||||
mcrfpy.createScene("animation_demo")
|
||||
ui = mcrfpy.sceneUI("animation_demo")
|
||||
mcrfpy.setScene("animation_demo")
|
||||
# Setup scene
|
||||
mcrfpy.createScene("anim_demo")
|
||||
|
||||
# Title
|
||||
title = mcrfpy.Caption((400, 30), "McRogueFace Animation System Demo", mcrfpy.default_font)
|
||||
title.size = 24
|
||||
title.fill_color = (255, 255, 255)
|
||||
# Note: centered property doesn't exist for Caption
|
||||
# Create grid
|
||||
grid = mcrfpy.Grid(grid_x=30, grid_y=20)
|
||||
grid.fill_color = mcrfpy.Color(20, 20, 30)
|
||||
|
||||
# Simple map
|
||||
for y in range(20):
|
||||
for x in range(30):
|
||||
cell = grid.at(x, y)
|
||||
# Create walls around edges and some obstacles
|
||||
if x == 0 or x == 29 or y == 0 or y == 19:
|
||||
cell.walkable = False
|
||||
cell.transparent = False
|
||||
cell.color = mcrfpy.Color(40, 30, 30)
|
||||
elif (x == 10 and 5 <= y <= 15) or (y == 10 and 5 <= x <= 25):
|
||||
cell.walkable = False
|
||||
cell.transparent = False
|
||||
cell.color = mcrfpy.Color(60, 40, 40)
|
||||
else:
|
||||
cell.walkable = True
|
||||
cell.transparent = True
|
||||
cell.color = mcrfpy.Color(80, 80, 100)
|
||||
|
||||
# Create entities
|
||||
player = mcrfpy.Entity(5, 5, grid=grid)
|
||||
player.sprite_index = 64 # @
|
||||
|
||||
enemy = mcrfpy.Entity(25, 15, grid=grid)
|
||||
enemy.sprite_index = 69 # E
|
||||
|
||||
# Update visibility
|
||||
player.update_visibility()
|
||||
enemy.update_visibility()
|
||||
|
||||
# UI setup
|
||||
ui = mcrfpy.sceneUI("anim_demo")
|
||||
ui.append(grid)
|
||||
grid.position = (100, 100)
|
||||
grid.size = (600, 400)
|
||||
|
||||
title = mcrfpy.Caption("Animation Demo - Grid Center & Entity Movement", 200, 20)
|
||||
title.fill_color = mcrfpy.Color(255, 255, 255)
|
||||
ui.append(title)
|
||||
|
||||
# 1. Position Animation Demo
|
||||
pos_frame = mcrfpy.Frame(50, 100, 80, 80)
|
||||
pos_frame.fill_color = (255, 100, 100)
|
||||
pos_frame.outline = 2
|
||||
ui.append(pos_frame)
|
||||
status = mcrfpy.Caption("Press 1: Move Player | 2: Move Enemy | 3: Perspective Shift | Q: Quit", 100, 50)
|
||||
status.fill_color = mcrfpy.Color(200, 200, 200)
|
||||
ui.append(status)
|
||||
|
||||
pos_label = mcrfpy.Caption((50, 80), "Position Animation", mcrfpy.default_font)
|
||||
pos_label.fill_color = (200, 200, 200)
|
||||
ui.append(pos_label)
|
||||
|
||||
# 2. Size Animation Demo
|
||||
size_frame = mcrfpy.Frame(200, 100, 50, 50)
|
||||
size_frame.fill_color = (100, 255, 100)
|
||||
size_frame.outline = 2
|
||||
ui.append(size_frame)
|
||||
|
||||
size_label = mcrfpy.Caption((200, 80), "Size Animation", mcrfpy.default_font)
|
||||
size_label.fill_color = (200, 200, 200)
|
||||
ui.append(size_label)
|
||||
|
||||
# 3. Color Animation Demo
|
||||
color_frame = mcrfpy.Frame(350, 100, 80, 80)
|
||||
color_frame.fill_color = (255, 0, 0)
|
||||
ui.append(color_frame)
|
||||
|
||||
color_label = mcrfpy.Caption((350, 80), "Color Animation", mcrfpy.default_font)
|
||||
color_label.fill_color = (200, 200, 200)
|
||||
ui.append(color_label)
|
||||
|
||||
# 4. Easing Functions Demo
|
||||
easing_y = 250
|
||||
easing_frames = []
|
||||
easings = ["linear", "easeIn", "easeOut", "easeInOut", "easeInElastic", "easeOutBounce"]
|
||||
|
||||
for i, easing in enumerate(easings):
|
||||
x = 50 + i * 120
|
||||
|
||||
frame = mcrfpy.Frame(x, easing_y, 20, 20)
|
||||
frame.fill_color = (100, 150, 255)
|
||||
ui.append(frame)
|
||||
easing_frames.append((frame, easing))
|
||||
|
||||
label = mcrfpy.Caption((x, easing_y - 20), easing, mcrfpy.default_font)
|
||||
label.size = 12
|
||||
label.fill_color = (200, 200, 200)
|
||||
ui.append(label)
|
||||
|
||||
# 5. Complex Animation Demo
|
||||
complex_frame = mcrfpy.Frame(300, 350, 100, 100)
|
||||
complex_frame.fill_color = (128, 128, 255)
|
||||
complex_frame.outline = 3
|
||||
ui.append(complex_frame)
|
||||
|
||||
complex_label = mcrfpy.Caption((300, 330), "Complex Multi-Property", mcrfpy.default_font)
|
||||
complex_label.fill_color = (200, 200, 200)
|
||||
ui.append(complex_label)
|
||||
|
||||
# Start animations
|
||||
def start_animations(runtime):
|
||||
# 1. Position animation - back and forth
|
||||
x_anim = mcrfpy.Animation("x", 500.0, 3.0, "easeInOut")
|
||||
x_anim.start(pos_frame)
|
||||
|
||||
# 2. Size animation - pulsing
|
||||
w_anim = mcrfpy.Animation("w", 150.0, 2.0, "easeInOut")
|
||||
h_anim = mcrfpy.Animation("h", 150.0, 2.0, "easeInOut")
|
||||
w_anim.start(size_frame)
|
||||
h_anim.start(size_frame)
|
||||
|
||||
# 3. Color animation - rainbow cycle
|
||||
color_anim = mcrfpy.Animation("fill_color", (0, 255, 255, 255), 2.0, "linear")
|
||||
color_anim.start(color_frame)
|
||||
|
||||
# 4. Easing demos - all move up with different easings
|
||||
for frame, easing in easing_frames:
|
||||
y_anim = mcrfpy.Animation("y", 150.0, 2.0, easing)
|
||||
y_anim.start(frame)
|
||||
|
||||
# 5. Complex animation - multiple properties
|
||||
cx_anim = mcrfpy.Animation("x", 500.0, 4.0, "easeInOut")
|
||||
cy_anim = mcrfpy.Animation("y", 400.0, 4.0, "easeOut")
|
||||
cw_anim = mcrfpy.Animation("w", 150.0, 4.0, "easeInElastic")
|
||||
ch_anim = mcrfpy.Animation("h", 150.0, 4.0, "easeInElastic")
|
||||
outline_anim = mcrfpy.Animation("outline", 10.0, 4.0, "linear")
|
||||
|
||||
cx_anim.start(complex_frame)
|
||||
cy_anim.start(complex_frame)
|
||||
cw_anim.start(complex_frame)
|
||||
ch_anim.start(complex_frame)
|
||||
outline_anim.start(complex_frame)
|
||||
|
||||
# Individual color component animations
|
||||
r_anim = mcrfpy.Animation("fill_color.r", 255.0, 4.0, "easeInOut")
|
||||
g_anim = mcrfpy.Animation("fill_color.g", 100.0, 4.0, "easeInOut")
|
||||
b_anim = mcrfpy.Animation("fill_color.b", 50.0, 4.0, "easeInOut")
|
||||
|
||||
r_anim.start(complex_frame)
|
||||
g_anim.start(complex_frame)
|
||||
b_anim.start(complex_frame)
|
||||
|
||||
print("All animations started!")
|
||||
|
||||
# Reverse some animations
|
||||
def reverse_animations(runtime):
|
||||
# Position back
|
||||
x_anim = mcrfpy.Animation("x", 50.0, 3.0, "easeInOut")
|
||||
x_anim.start(pos_frame)
|
||||
|
||||
# Size back
|
||||
w_anim = mcrfpy.Animation("w", 50.0, 2.0, "easeInOut")
|
||||
h_anim = mcrfpy.Animation("h", 50.0, 2.0, "easeInOut")
|
||||
w_anim.start(size_frame)
|
||||
h_anim.start(size_frame)
|
||||
|
||||
# Color cycle continues
|
||||
color_anim = mcrfpy.Animation("fill_color", (255, 0, 255, 255), 2.0, "linear")
|
||||
color_anim.start(color_frame)
|
||||
|
||||
# Easing frames back down
|
||||
for frame, easing in easing_frames:
|
||||
y_anim = mcrfpy.Animation("y", 250.0, 2.0, easing)
|
||||
y_anim.start(frame)
|
||||
|
||||
# Continue color cycle
|
||||
def cycle_colors(runtime):
|
||||
color_anim = mcrfpy.Animation("fill_color", (255, 255, 0, 255), 2.0, "linear")
|
||||
color_anim.start(color_frame)
|
||||
|
||||
# Info text
|
||||
info = mcrfpy.Caption((400, 550), "Watch as different properties animate with various easing functions!", mcrfpy.default_font)
|
||||
info.fill_color = (255, 255, 200)
|
||||
# Note: centered property doesn't exist for Caption
|
||||
info = mcrfpy.Caption("Perspective: Player", 500, 70)
|
||||
info.fill_color = mcrfpy.Color(100, 255, 100)
|
||||
ui.append(info)
|
||||
|
||||
# Schedule animations
|
||||
mcrfpy.setTimer("start", start_animations, 500)
|
||||
mcrfpy.setTimer("reverse", reverse_animations, 4000)
|
||||
mcrfpy.setTimer("cycle", cycle_colors, 2500)
|
||||
# Movement functions
|
||||
def move_player_demo():
|
||||
"""Demo player movement with camera follow"""
|
||||
# Calculate path to a destination
|
||||
path = player.path_to(20, 10)
|
||||
if not path:
|
||||
status.text = "No path available!"
|
||||
return
|
||||
|
||||
status.text = f"Moving player along {len(path)} steps..."
|
||||
|
||||
# Animate along path
|
||||
for i, (x, y) in enumerate(path[:5]): # First 5 steps
|
||||
delay = i * 500 # 500ms between steps
|
||||
|
||||
# Schedule movement
|
||||
def move_step(dt, px=x, py=y):
|
||||
# Animate entity position
|
||||
anim_x = mcrfpy.Animation("x", float(px), 0.4, "easeInOut")
|
||||
anim_y = mcrfpy.Animation("y", float(py), 0.4, "easeInOut")
|
||||
anim_x.start(player)
|
||||
anim_y.start(player)
|
||||
|
||||
# Update visibility
|
||||
player.update_visibility()
|
||||
|
||||
# Animate camera to follow
|
||||
center_x = px * 16 # Assuming 16x16 tiles
|
||||
center_y = py * 16
|
||||
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.4, "easeOut")
|
||||
cam_anim.start(grid)
|
||||
|
||||
mcrfpy.setTimer(f"player_move_{i}", move_step, delay)
|
||||
|
||||
# Exit handler
|
||||
def on_key(key):
|
||||
if key == "Escape":
|
||||
mcrfpy.exit()
|
||||
def move_enemy_demo():
|
||||
"""Demo enemy movement"""
|
||||
# Calculate path
|
||||
path = enemy.path_to(10, 5)
|
||||
if not path:
|
||||
status.text = "Enemy has no path!"
|
||||
return
|
||||
|
||||
status.text = f"Moving enemy along {len(path)} steps..."
|
||||
|
||||
# Animate along path
|
||||
for i, (x, y) in enumerate(path[:5]): # First 5 steps
|
||||
delay = i * 500
|
||||
|
||||
def move_step(dt, ex=x, ey=y):
|
||||
anim_x = mcrfpy.Animation("x", float(ex), 0.4, "easeInOut")
|
||||
anim_y = mcrfpy.Animation("y", float(ey), 0.4, "easeInOut")
|
||||
anim_x.start(enemy)
|
||||
anim_y.start(enemy)
|
||||
enemy.update_visibility()
|
||||
|
||||
# If following enemy, update camera
|
||||
if grid.perspective == 1:
|
||||
center_x = ex * 16
|
||||
center_y = ey * 16
|
||||
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.4, "easeOut")
|
||||
cam_anim.start(grid)
|
||||
|
||||
mcrfpy.setTimer(f"enemy_move_{i}", move_step, delay)
|
||||
|
||||
mcrfpy.keypressScene(on_key)
|
||||
def perspective_shift_demo():
|
||||
"""Demo dramatic perspective shift"""
|
||||
status.text = "Perspective shift in progress..."
|
||||
|
||||
# Phase 1: Zoom out
|
||||
zoom_out = mcrfpy.Animation("zoom", 0.5, 1.5, "easeInExpo")
|
||||
zoom_out.start(grid)
|
||||
|
||||
# Phase 2: Switch perspective at peak
|
||||
def switch_perspective(dt):
|
||||
if grid.perspective == 0:
|
||||
grid.perspective = 1
|
||||
info.text = "Perspective: Enemy"
|
||||
info.fill_color = mcrfpy.Color(255, 100, 100)
|
||||
target = enemy
|
||||
else:
|
||||
grid.perspective = 0
|
||||
info.text = "Perspective: Player"
|
||||
info.fill_color = mcrfpy.Color(100, 255, 100)
|
||||
target = player
|
||||
|
||||
# Update camera to new target
|
||||
center_x = target.x * 16
|
||||
center_y = target.y * 16
|
||||
cam_anim = mcrfpy.Animation("center", (center_x, center_y), 0.5, "linear")
|
||||
cam_anim.start(grid)
|
||||
|
||||
mcrfpy.setTimer("switch_persp", switch_perspective, 1600)
|
||||
|
||||
# Phase 3: Zoom back in
|
||||
def zoom_in(dt):
|
||||
zoom_in_anim = mcrfpy.Animation("zoom", 1.0, 1.5, "easeOutExpo")
|
||||
zoom_in_anim.start(grid)
|
||||
status.text = "Perspective shift complete!"
|
||||
|
||||
mcrfpy.setTimer("zoom_in", zoom_in, 2100)
|
||||
|
||||
print("Animation demo started! Press Escape to exit.")
|
||||
# Input handler
|
||||
def handle_input(key, state):
|
||||
if state != "start":
|
||||
return
|
||||
|
||||
if key == "q":
|
||||
print("Exiting demo...")
|
||||
sys.exit(0)
|
||||
elif key == "1":
|
||||
move_player_demo()
|
||||
elif key == "2":
|
||||
move_enemy_demo()
|
||||
elif key == "3":
|
||||
perspective_shift_demo()
|
||||
|
||||
# Set scene
|
||||
mcrfpy.setScene("anim_demo")
|
||||
mcrfpy.keypressScene(handle_input)
|
||||
|
||||
# Initial setup
|
||||
grid.perspective = 0
|
||||
grid.zoom = 1.0
|
||||
|
||||
# Center on player initially
|
||||
center_x = player.x * 16
|
||||
center_y = player.y * 16
|
||||
initial_cam = mcrfpy.Animation("center", (center_x, center_y), 0.5, "easeOut")
|
||||
initial_cam.start(grid)
|
||||
|
||||
print("Animation Demo Started!")
|
||||
print("======================")
|
||||
print("Press 1: Animate player movement with camera follow")
|
||||
print("Press 2: Animate enemy movement")
|
||||
print("Press 3: Dramatic perspective shift with zoom")
|
||||
print("Press Q: Quit")
|
||||
print()
|
||||
print("Watch how the grid center smoothly follows entities")
|
||||
print("and how perspective shifts create cinematic effects!")
|
Loading…
Reference in New Issue