batframework 1.0.8a13__py3-none-any.whl → 1.0.9a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batFramework/__init__.py +11 -15
- batFramework/animatedSprite.py +1 -1
- batFramework/camera.py +1 -1
- batFramework/character.py +1 -1
- batFramework/constants.py +10 -0
- batFramework/cutscene.py +10 -10
- batFramework/drawable.py +75 -0
- batFramework/dynamicEntity.py +2 -4
- batFramework/entity.py +93 -56
- batFramework/enums.py +1 -0
- batFramework/fontManager.py +3 -3
- batFramework/gui/__init__.py +2 -2
- batFramework/gui/{dialogueBox.py → animatedLabel.py} +18 -36
- batFramework/gui/button.py +30 -0
- batFramework/gui/clickableWidget.py +6 -1
- batFramework/gui/constraints/constraints.py +90 -1
- batFramework/gui/container.py +84 -93
- batFramework/gui/debugger.py +1 -1
- batFramework/gui/indicator.py +3 -2
- batFramework/gui/interactiveWidget.py +43 -24
- batFramework/gui/label.py +43 -49
- batFramework/gui/layout.py +378 -42
- batFramework/gui/root.py +2 -9
- batFramework/gui/shape.py +2 -0
- batFramework/gui/textInput.py +115 -78
- batFramework/gui/toggle.py +1 -4
- batFramework/gui/widget.py +50 -38
- batFramework/manager.py +65 -53
- batFramework/particle.py +1 -1
- batFramework/scene.py +1 -34
- batFramework/sceneManager.py +6 -34
- batFramework/scrollingSprite.py +1 -1
- batFramework/sprite.py +2 -2
- batFramework/{time.py → timeManager.py} +0 -2
- batFramework/utils.py +118 -19
- {batframework-1.0.8a13.dist-info → batframework-1.0.9a1.dist-info}/METADATA +1 -1
- batframework-1.0.9a1.dist-info/RECORD +63 -0
- {batframework-1.0.8a13.dist-info → batframework-1.0.9a1.dist-info}/WHEEL +1 -1
- batFramework/object.py +0 -123
- batframework-1.0.8a13.dist-info/RECORD +0 -63
- {batframework-1.0.8a13.dist-info → batframework-1.0.9a1.dist-info}/LICENCE +0 -0
- {batframework-1.0.8a13.dist-info → batframework-1.0.9a1.dist-info}/top_level.txt +0 -0
@@ -598,6 +598,95 @@ class MarginRight(Constraint):
|
|
598
598
|
other.margin == self.margin
|
599
599
|
)
|
600
600
|
|
601
|
+
class RectMarginBottom(Constraint):
|
602
|
+
def __init__(self, margin: float):
|
603
|
+
super().__init__()
|
604
|
+
self.margin = margin
|
605
|
+
|
606
|
+
def evaluate(self, parent_widget, child_widget):
|
607
|
+
return (
|
608
|
+
child_widget.rect.bottom == parent_widget.rect.bottom - self.margin
|
609
|
+
)
|
610
|
+
|
611
|
+
def apply_constraint(self, parent_widget, child_widget):
|
612
|
+
child_widget.set_position(
|
613
|
+
child_widget.rect.x,
|
614
|
+
parent_widget.rect.bottom- child_widget.rect.h - self.margin,
|
615
|
+
)
|
616
|
+
|
617
|
+
def __eq__(self,other:"Constraint")->bool:
|
618
|
+
if not isinstance(other,self.__class__):
|
619
|
+
return False
|
620
|
+
return (
|
621
|
+
other.name == self.name and
|
622
|
+
other.margin == self.margin
|
623
|
+
)
|
624
|
+
|
625
|
+
class RectMarginTop(Constraint):
|
626
|
+
def __init__(self, margin: float):
|
627
|
+
super().__init__()
|
628
|
+
self.margin = margin
|
629
|
+
|
630
|
+
def evaluate(self, parent_widget, child_widget):
|
631
|
+
return child_widget.rect.top == parent_widget.rect.top + self.margin
|
632
|
+
|
633
|
+
def apply_constraint(self, parent_widget, child_widget):
|
634
|
+
child_widget.set_position(
|
635
|
+
child_widget.rect.x, parent_widget.rect.top + self.margin
|
636
|
+
)
|
637
|
+
|
638
|
+
def __eq__(self,other:"Constraint")->bool:
|
639
|
+
if not isinstance(other,self.__class__):
|
640
|
+
return False
|
641
|
+
return (
|
642
|
+
other.name == self.name and
|
643
|
+
other.margin == self.margin
|
644
|
+
)
|
645
|
+
|
646
|
+
class RectMarginLeft(Constraint):
|
647
|
+
def __init__(self, margin: float):
|
648
|
+
super().__init__()
|
649
|
+
self.margin = margin
|
650
|
+
|
651
|
+
def evaluate(self, parent_widget, child_widget):
|
652
|
+
return child_widget.rect.left == parent_widget.rect.left + self.margin
|
653
|
+
|
654
|
+
def apply_constraint(self, parent_widget, child_widget):
|
655
|
+
if not self.evaluate(parent_widget, child_widget):
|
656
|
+
child_widget.set_position(
|
657
|
+
parent_widget.rect.left + self.margin, child_widget.rect.y
|
658
|
+
)
|
659
|
+
|
660
|
+
def __eq__(self,other:"Constraint")->bool:
|
661
|
+
if not isinstance(other,self.__class__):
|
662
|
+
return False
|
663
|
+
return (
|
664
|
+
other.name == self.name and
|
665
|
+
other.margin == self.margin
|
666
|
+
)
|
667
|
+
|
668
|
+
class RectMarginRight(Constraint):
|
669
|
+
def __init__(self, margin: float):
|
670
|
+
super().__init__()
|
671
|
+
self.margin = margin
|
672
|
+
|
673
|
+
def evaluate(self, parent_widget, child_widget):
|
674
|
+
return child_widget.rect.right == parent_widget.rect.right - self.margin
|
675
|
+
|
676
|
+
def apply_constraint(self, parent_widget, child_widget):
|
677
|
+
child_widget.set_position(
|
678
|
+
parent_widget.rect.right - child_widget.rect.w - self.margin,
|
679
|
+
child_widget.rect.y,
|
680
|
+
)
|
681
|
+
|
682
|
+
def __eq__(self,other:"Constraint")->bool:
|
683
|
+
if not isinstance(other,self.__class__):
|
684
|
+
return False
|
685
|
+
return (
|
686
|
+
other.name == self.name and
|
687
|
+
other.margin == self.margin
|
688
|
+
)
|
689
|
+
|
601
690
|
class PercentageMarginBottom(Constraint):
|
602
691
|
def __init__(self, margin: float):
|
603
692
|
super().__init__()
|
@@ -812,4 +901,4 @@ class PercentageRectMarginRight(Constraint):
|
|
812
901
|
return (
|
813
902
|
other.name == self.name and
|
814
903
|
other.margin == self.margin
|
815
|
-
)
|
904
|
+
)
|
batFramework/gui/container.py
CHANGED
@@ -11,181 +11,172 @@ from pygame.math import Vector2
|
|
11
11
|
class Container(Shape, InteractiveWidget):
|
12
12
|
def __init__(self, layout: Layout = None, *children: Widget) -> None:
|
13
13
|
super().__init__()
|
14
|
-
self.
|
14
|
+
self.dirty_layout: bool = False
|
15
15
|
self.set_debug_color("green")
|
16
|
-
self.layout
|
17
|
-
self.scroll = Vector2(0, 0)
|
18
|
-
if not self.layout:
|
19
|
-
self.layout = Column()
|
16
|
+
self.layout = layout if layout else Column()
|
20
17
|
self.layout.set_parent(self)
|
18
|
+
self.scroll = Vector2(0, 0)
|
21
19
|
self.add(*children)
|
22
20
|
|
23
21
|
def __str__(self) -> str:
|
24
22
|
return f"Container({self.uid},{len(self.children)})"
|
25
23
|
|
26
24
|
def get_min_required_size(self):
|
27
|
-
if self.layout
|
28
|
-
return self.layout.get_auto_size()
|
29
|
-
return self.rect.size
|
25
|
+
return self.layout.get_auto_size() if self.layout else self.rect.size
|
30
26
|
|
31
27
|
def reset_scroll(self) -> Self:
|
28
|
+
if self.scroll == (0,0):
|
29
|
+
return self
|
32
30
|
self.scroll.update(0, 0)
|
33
|
-
self.
|
31
|
+
self.dirty_layout = True
|
34
32
|
return self
|
35
33
|
|
36
34
|
def set_scroll(self, value: tuple) -> Self:
|
35
|
+
if (self.scroll.x,self.scroll.y) == value:
|
36
|
+
return self
|
37
37
|
self.scroll.update(value)
|
38
|
-
self.
|
38
|
+
self.clamp_scroll()
|
39
|
+
self.dirty_layout = True
|
39
40
|
return self
|
40
41
|
|
41
42
|
def scrollX_by(self, x: float | int) -> Self:
|
43
|
+
if x == 0:
|
44
|
+
return self
|
42
45
|
self.scroll.x += x
|
43
|
-
self.
|
46
|
+
self.clamp_scroll()
|
47
|
+
self.dirty_layout = True
|
44
48
|
return self
|
45
49
|
|
46
50
|
def scrollY_by(self, y: float | int) -> Self:
|
51
|
+
if y == 0:
|
52
|
+
return self
|
47
53
|
self.scroll.y += y
|
48
|
-
self.
|
54
|
+
self.clamp_scroll()
|
55
|
+
self.dirty_layout = True
|
49
56
|
return self
|
50
57
|
|
51
58
|
def scroll_by(self, value: tuple[float | int, float | int]) -> Self:
|
59
|
+
if value[0] == 0 and value[1] == 0:
|
60
|
+
return self
|
52
61
|
self.scroll += value
|
53
|
-
self.
|
62
|
+
self.clamp_scroll()
|
63
|
+
self.dirty_layout = True
|
54
64
|
return self
|
55
65
|
|
56
66
|
def clamp_scroll(self) -> Self:
|
57
67
|
if not self.children:
|
58
|
-
return
|
68
|
+
return self
|
59
69
|
r = self.get_padded_rect()
|
60
|
-
size = self.children[0].rect.unionall(self.children[1:]).size
|
70
|
+
size = self.children[0].rect.unionall([child.rect for child in self.children[1:]]).size
|
61
71
|
|
62
|
-
# Calculate the maximum scroll values
|
63
72
|
max_scroll_x = max(0, size[0] - r.width)
|
64
73
|
max_scroll_y = max(0, size[1] - r.height)
|
65
74
|
|
66
|
-
# Clamp the scroll values
|
67
75
|
self.scroll.x = max(0, min(self.scroll.x, max_scroll_x))
|
68
76
|
self.scroll.y = max(0, min(self.scroll.y, max_scroll_y))
|
69
|
-
|
70
|
-
self.dirty_children = True
|
77
|
+
self.dirty_layout = True
|
71
78
|
return self
|
72
79
|
|
73
80
|
def set_layout(self, layout: Layout) -> Self:
|
74
81
|
tmp = self.layout
|
75
82
|
self.layout = layout
|
76
83
|
if self.layout != tmp:
|
77
|
-
|
84
|
+
tmp.set_parent(None)
|
85
|
+
self.layout.set_parent(self)
|
86
|
+
self.dirty_layout = True
|
78
87
|
return self
|
79
88
|
|
80
89
|
def get_interactive_children(self) -> list[InteractiveWidget]:
|
81
|
-
return [
|
82
|
-
child
|
83
|
-
for child in self.children
|
84
|
-
if isinstance(child, InteractiveWidget) and child.allow_focus_to_self()
|
85
|
-
]
|
86
|
-
|
87
|
-
def focus_next_child(self) -> None:
|
88
|
-
self.layout.focus_next_child()
|
89
|
-
|
90
|
-
def focus_prev_child(self) -> None:
|
91
|
-
self.layout.focus_prev_child()
|
90
|
+
return [child for child in self.children if isinstance(child, InteractiveWidget) and not isinstance(child,Container) and child.allow_focus_to_self()]
|
92
91
|
|
93
92
|
def clear_children(self) -> None:
|
94
93
|
self.children.clear()
|
95
|
-
self.
|
94
|
+
self.dirty_layout = True
|
96
95
|
|
97
96
|
def add(self, *child: Widget) -> Self:
|
98
97
|
super().add(*child)
|
99
|
-
self.
|
98
|
+
self.dirty_shape = True
|
99
|
+
self.clamp_scroll()
|
100
100
|
return self
|
101
101
|
|
102
102
|
def remove(self, *child: Widget) -> Self:
|
103
103
|
super().remove(*child)
|
104
|
-
self.
|
104
|
+
self.dirty_shape = True
|
105
|
+
self.clamp_scroll()
|
105
106
|
return self
|
106
107
|
|
107
|
-
def resolve_constraints(self) -> None:
|
108
|
-
super().resolve_constraints()
|
109
|
-
|
110
108
|
def top_at(self, x: float | int, y: float | int) -> "None|Widget":
|
111
109
|
if self.visible and self.rect.collidepoint(x, y):
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
return r
|
110
|
+
for child in reversed(self.children):
|
111
|
+
result = child.top_at(x, y)
|
112
|
+
if result is not None:
|
113
|
+
return result
|
117
114
|
return self
|
118
115
|
return None
|
119
116
|
|
120
117
|
def get_focus(self) -> bool:
|
121
|
-
|
122
|
-
if not res:
|
118
|
+
if not super().get_focus():
|
123
119
|
return False
|
124
|
-
|
125
|
-
if not
|
120
|
+
interactive_children = self.get_interactive_children()
|
121
|
+
if not interactive_children:
|
126
122
|
return True
|
127
|
-
self.focused_index = min(self.focused_index, len(
|
128
|
-
return
|
123
|
+
self.focused_index = min(self.focused_index, len(interactive_children) - 1)
|
124
|
+
return interactive_children[self.focused_index].get_focus()
|
129
125
|
|
130
|
-
def do_handle_event(self, event):
|
131
|
-
self.
|
126
|
+
def do_handle_event(self, event) -> None:
|
127
|
+
if any(child.is_focused for child in self.get_interactive_children()):
|
128
|
+
self.layout.handle_event(event)
|
132
129
|
|
133
130
|
def set_focused_child(self, child: InteractiveWidget) -> bool:
|
134
|
-
|
131
|
+
interactive_children = self.get_interactive_children()
|
135
132
|
try:
|
136
|
-
|
133
|
+
index = interactive_children.index(child)
|
134
|
+
self.focused_index = index
|
135
|
+
return True
|
137
136
|
except ValueError:
|
138
137
|
return False
|
139
|
-
if i >= 0:
|
140
|
-
self.focused_index = i
|
141
|
-
return True
|
142
|
-
return False
|
143
138
|
|
144
139
|
def allow_focus_to_self(self) -> bool:
|
145
|
-
return
|
140
|
+
return bool(self.get_interactive_children()) and self.visible
|
146
141
|
|
147
|
-
|
148
|
-
|
142
|
+
|
143
|
+
def apply_updates(self):
|
144
|
+
if any(child.dirty_shape for child in self.children):
|
145
|
+
self.dirty_layout = True # Mark layout as dirty if any child changed size
|
146
|
+
|
147
|
+
if self.dirty_constraints:
|
148
|
+
self.resolve_constraints() # Finalize positioning based on size
|
149
|
+
|
150
|
+
# Step 1: Build shape if needed
|
149
151
|
if self.dirty_shape:
|
150
|
-
self.
|
151
|
-
self.
|
152
|
-
self.dirty_surface = True
|
153
|
-
self.
|
152
|
+
self.build() # Finalize size of the container
|
153
|
+
self.dirty_shape = False
|
154
|
+
self.dirty_surface = True # Mark surface for repaint
|
155
|
+
self.dirty_layout = True # Mark layout for arrangement
|
156
|
+
# Flag all children to update constraints after size is finalized
|
154
157
|
for child in self.children:
|
155
158
|
child.dirty_constraints = True
|
156
|
-
self.dirty_shape = False
|
157
159
|
|
160
|
+
for child in self.children:
|
161
|
+
child.apply_updates()
|
162
|
+
|
163
|
+
# Step 2: Arrange layout if marked as dirty
|
164
|
+
if self.dirty_layout:
|
165
|
+
self.layout.arrange()
|
166
|
+
self.dirty_surface = True
|
167
|
+
self.dirty_layout = False
|
168
|
+
# Constraints may need to adjust based on the layout change
|
169
|
+
self.dirty_constraints = True
|
170
|
+
|
171
|
+
# Step 3: Resolve constraints now that size and layout are finalized
|
158
172
|
if self.dirty_constraints:
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
if not self.dirty_children:
|
164
|
-
self.dirty_children = any(c.dirty_shape for c in self.children)
|
165
|
-
if self.dirty_children:
|
166
|
-
if self.layout:
|
167
|
-
self.layout.arrange()
|
168
|
-
self.dirty_children = False
|
169
|
-
|
170
|
-
if constraints_down:
|
171
|
-
self.visit(lambda c: c.resolve_constraints())
|
173
|
+
self.resolve_constraints() # Finalize positioning based on size
|
174
|
+
for child in self.children:
|
175
|
+
child.dirty_constraints = True # Children inherit updated positioning
|
176
|
+
self.dirty_constraints = False
|
172
177
|
|
178
|
+
# Step 4: Paint the surface if marked as dirty
|
173
179
|
if self.dirty_surface:
|
180
|
+
# print("PAINT !!")
|
174
181
|
self.paint()
|
175
182
|
self.dirty_surface = False
|
176
|
-
|
177
|
-
bf.Entity.draw(self, camera)
|
178
|
-
|
179
|
-
if self.clip_children:
|
180
|
-
new_clip = camera.world_to_screen(self.get_padded_rect())
|
181
|
-
old_clip = camera.surface.get_clip()
|
182
|
-
new_clip = new_clip.clip(old_clip)
|
183
|
-
camera.surface.set_clip(new_clip)
|
184
|
-
# Draw children with adjusted positions
|
185
|
-
_ = [
|
186
|
-
child.draw(camera)
|
187
|
-
for child in sorted(self.children, key=lambda c: c.render_order)
|
188
|
-
]
|
189
|
-
|
190
|
-
if self.clip_children:
|
191
|
-
camera.surface.set_clip(old_clip)
|
batFramework/gui/debugger.py
CHANGED
@@ -72,7 +72,7 @@ class Debugger(Label):
|
|
72
72
|
def update(self, dt: float) -> None:
|
73
73
|
if not self.parent_scene:
|
74
74
|
return
|
75
|
-
if
|
75
|
+
if bf.ResourceManager().get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
|
76
76
|
self.set_visible(False)
|
77
77
|
return
|
78
78
|
self.set_visible(True)
|
batFramework/gui/indicator.py
CHANGED
@@ -29,11 +29,11 @@ class Indicator(Shape):
|
|
29
29
|
|
30
30
|
class ToggleIndicator(Indicator):
|
31
31
|
def __init__(self, default_value: bool) -> None:
|
32
|
+
super().__init__((20, 20))
|
32
33
|
self.value: bool = default_value
|
33
34
|
self.callback = lambda val: self.set_color("green" if val else "red")
|
34
|
-
super().__init__((20, 20))
|
35
35
|
self.set_value(default_value)
|
36
|
-
|
36
|
+
self.callback(default_value)
|
37
37
|
# TODO aspect ratio would be good right about here
|
38
38
|
# self.add_constraint(ConstraintAspectRatio(1))
|
39
39
|
|
@@ -55,3 +55,4 @@ class ToggleIndicator(Indicator):
|
|
55
55
|
if r is self:
|
56
56
|
return None
|
57
57
|
return r
|
58
|
+
|
@@ -2,13 +2,13 @@ from .widget import Widget
|
|
2
2
|
from typing import Self
|
3
3
|
from typing import TYPE_CHECKING
|
4
4
|
import pygame
|
5
|
-
from math import cos
|
5
|
+
from math import cos,floor,ceil
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
8
8
|
from .container import Container
|
9
9
|
import batFramework as bf
|
10
10
|
|
11
|
-
def children_has_focus(widget):
|
11
|
+
def children_has_focus(widget)->bool:
|
12
12
|
if isinstance(widget,InteractiveWidget) and widget.is_focused:
|
13
13
|
return True
|
14
14
|
for child in widget.children:
|
@@ -56,6 +56,8 @@ class InteractiveWidget(Widget):
|
|
56
56
|
|
57
57
|
def on_get_focus(self) -> None:
|
58
58
|
self.is_focused = True
|
59
|
+
if isinstance(self.parent,bf.Container):
|
60
|
+
self.parent.layout.scroll_to_widget(self)
|
59
61
|
self.do_on_get_focus()
|
60
62
|
|
61
63
|
def on_lose_focus(self) -> None:
|
@@ -84,7 +86,7 @@ class InteractiveWidget(Widget):
|
|
84
86
|
i_children[index + 1].get_focus()
|
85
87
|
return
|
86
88
|
|
87
|
-
if self.parent:
|
89
|
+
if self.parent and isinstance(self.parent,InteractiveWidget):
|
88
90
|
self.parent.focus_next_tab(self)
|
89
91
|
|
90
92
|
def focus_prev_tab(self, previous_widget):
|
@@ -108,30 +110,18 @@ class InteractiveWidget(Widget):
|
|
108
110
|
i_children[index - 1].get_focus()
|
109
111
|
return
|
110
112
|
|
111
|
-
if self.parent:
|
113
|
+
if self.parent and isinstance(self.parent,InteractiveWidget):
|
112
114
|
self.parent.focus_prev_tab(self)
|
113
115
|
|
114
|
-
def focus_next_sibling(self) -> None:
|
115
|
-
if isinstance(self.parent, bf.Container):
|
116
|
-
self.parent.focus_next_child()
|
117
|
-
|
118
|
-
def focus_prev_sibling(self) -> None:
|
119
|
-
if isinstance(self.parent, bf.Container):
|
120
|
-
self.parent.focus_prev_child()
|
121
|
-
|
122
116
|
def on_key_down(self, key) -> bool:
|
123
|
-
if key == pygame.
|
124
|
-
self.focus_next_sibling()
|
125
|
-
elif key == pygame.K_UP:
|
126
|
-
self.focus_prev_sibling()
|
127
|
-
elif key == pygame.K_TAB and self.parent:
|
117
|
+
if key == pygame.K_TAB and self.parent:
|
128
118
|
keys = pygame.key.get_pressed()
|
129
119
|
if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
|
130
120
|
|
131
121
|
self.focus_prev_tab(self)
|
132
122
|
else:
|
133
123
|
self.focus_next_tab(self)
|
134
|
-
|
124
|
+
return True
|
135
125
|
else:
|
136
126
|
|
137
127
|
return self.do_on_key_down(key)
|
@@ -192,10 +182,39 @@ class InteractiveWidget(Widget):
|
|
192
182
|
pass
|
193
183
|
|
194
184
|
def draw_focused(self, camera: bf.Camera) -> None:
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
185
|
+
|
186
|
+
proportion = 16
|
187
|
+
surface = pygame.Surface(self.rect.inflate(proportion,proportion).size)
|
188
|
+
surface.fill("black")
|
189
|
+
|
190
|
+
delta = proportion*0.75 - int(proportion * cos(pygame.time.get_ticks() / 100) /4)
|
191
|
+
delta = delta//2 * 2
|
192
|
+
# Base rect centered in tmp surface
|
193
|
+
base_rect = surface.get_frect()
|
194
|
+
|
195
|
+
# Expanded white rectangle for border effect
|
196
|
+
white_rect = base_rect.inflate(-delta,-delta)
|
197
|
+
white_rect.center = base_rect.center
|
198
|
+
pygame.draw.rect(surface, "white", white_rect, 2, *self.border_radius)
|
199
|
+
|
200
|
+
# Black cutout rectangles to create the effect around the edges
|
201
|
+
black_rect_1 = white_rect.copy()
|
202
|
+
black_rect_1.w -= proportion
|
203
|
+
black_rect_1.centerx = white_rect.centerx
|
204
|
+
|
205
|
+
black_rect_2 = white_rect.copy()
|
206
|
+
black_rect_2.h -= proportion
|
207
|
+
black_rect_2.centery = white_rect.centery
|
208
|
+
|
209
|
+
surface.fill("black", black_rect_1)
|
210
|
+
surface.fill("black", black_rect_2)
|
211
|
+
|
212
|
+
base_rect.center = self.rect.center
|
213
|
+
|
214
|
+
surface.set_colorkey("black")
|
215
|
+
|
216
|
+
# Blit the tmp surface onto the camera surface with adjusted position
|
217
|
+
camera.surface.blit(
|
218
|
+
surface,
|
219
|
+
base_rect.move(-camera.rect.x, -camera.rect.y),
|
201
220
|
)
|