Skip to content

Commit f3de4d9

Browse files
MiCurryeruvanos
andauthored
Raise TypeError if Viewport is not a Rect and make Viewport (#2790)
* Make viewport a property/setter and raise TypeError if not a Rect This commit makes viewport a property of Camera2D and adds a setter for it. In the setter, and in __init__, we check that Viewport is a Rect and raise a TypeError if it is not. Without this check, an error will be raised after either calling `Camera2D.equalise()` or in `Camera2D.use()`, which may confuse users as to why the error is occurring. Backtrace when calling `Camera2D.equalise()` with a non-rect viewport: ``` File "E:\Projects\SpaceGame\SpaceGame\gamemodes\basegame.py", line 128, in setup_two_player_cameras player_one_camera.equalise() File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 336, in equalise self._projection_data.rect = XYWH(x, y, self.viewport_width, self.viewport_height) ^^^^^^^^^^^^^^^^^^^ File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 751, in viewport_width return int(self._viewport.width) ``` Backtrace when calling `Camera2D.use()` with a non-rect viewport: ``` File "E:\Projects\SpaceGame\SpaceGame\gamemodes\pvp.py", line 139, in on_draw self.cameras[player].use() File "E:\Programs\python-arcade\arcade\camera\camera_2d.py", line 271, in use self._window.ctx.viewport = self._viewport.lbwh_int ``` * Refactor viewport assignment and type check in camera_2d.py --------- Co-authored-by: Maic Siemering <[email protected]>
1 parent 4b9d515 commit f3de4d9

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

arcade/camera/camera_2d.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ def __init__(
122122
render_target = render_target or self._window.ctx.screen
123123
viewport = viewport or LBWH(*render_target.viewport)
124124

125+
if not isinstance(viewport, Rect):
126+
raise TypeError("viewport must be a Rect type,use arcade.LBWH or arcade.types.Viewport")
127+
125128
if aspect is None:
126129
width, height = viewport.size
127130
elif aspect == 0.0:
@@ -135,6 +138,7 @@ def __init__(
135138
width = viewport.width
136139
height = viewport.width / aspect
137140
viewport = XYWH(viewport.x, viewport.y, width, height)
141+
138142
half_width = width / 2
139143
half_height = height / 2
140144

@@ -173,7 +177,8 @@ def __init__(
173177
left=left, right=right, top=top, bottom=bottom, near=near, far=far
174178
)
175179

176-
self.viewport: Rect = viewport
180+
self.viewport = viewport
181+
177182
"""
178183
A rect which describes how the final projection should be mapped
179184
from unit-space. defaults to the size of the render_target or window
@@ -289,7 +294,7 @@ def use(self) -> None:
289294
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
290295
_view = generate_view_matrix(self.view_data)
291296

292-
self._window.ctx.viewport = self.viewport.lbwh_int
297+
self._window.ctx.viewport = self._viewport.lbwh_int
293298
self._window.ctx.scissor = None if not self.scissor else self.scissor.lbwh_int
294299
self._window.projection = _projection
295300
self._window.view = _view
@@ -322,7 +327,7 @@ def project(self, world_coordinate: Point) -> Vec2:
322327

323328
return project_orthographic(
324329
world_coordinate,
325-
self.viewport.lbwh_int,
330+
self._viewport.lbwh_int,
326331
_view,
327332
_projection,
328333
)
@@ -345,7 +350,9 @@ def unproject(self, screen_coordinate: Point) -> Vec3:
345350

346351
_projection = generate_orthographic_matrix(self.projection_data, self.zoom)
347352
_view = generate_view_matrix(self.view_data)
348-
return unproject_orthographic(screen_coordinate, self.viewport.lbwh_int, _view, _projection)
353+
return unproject_orthographic(
354+
screen_coordinate, self._viewport.lbwh_int, _view, _projection
355+
)
349356

350357
def equalize(self) -> None:
351358
"""
@@ -470,8 +477,7 @@ def update_values(
470477
h = value.width / aspect
471478
value = XYWH(value.x, value.y, w, h)
472479

473-
if viewport:
474-
self.viewport = value
480+
self.viewport = value
475481

476482
if projection:
477483
x, y = self._projection_data.rect.x, self._projection_data.rect.y
@@ -498,7 +504,7 @@ def aabb(self) -> Rect:
498504
ux, uy, *_ = up
499505
rx, ry = uy, -ux # up x Z'
500506

501-
l, r, b, t = self.viewport.lrbt
507+
l, r, b, t = self._viewport.lrbt
502508
x, y = self.position
503509

504510
x_points = (
@@ -881,89 +887,100 @@ def projection_far(self) -> float:
881887
def projection_far(self, new_far: float) -> None:
882888
self._projection_data.far = new_far
883889

890+
@property
891+
def viewport(self) -> Rect:
892+
return self._viewport
893+
894+
@viewport.setter
895+
def viewport(self, viewport: Rect) -> None:
896+
if not isinstance(viewport, Rect):
897+
raise TypeError("viewport must be a Rect type,use arcade.LBWH or arcade.types.Viewport")
898+
899+
self._viewport = viewport
900+
884901
@property
885902
def viewport_width(self) -> int:
886903
"""
887904
The width of the viewport.
888905
Defines the number of pixels drawn too horizontally.
889906
"""
890-
return int(self.viewport.width)
907+
return int(self._viewport.width)
891908

892909
@viewport_width.setter
893910
def viewport_width(self, new_width: int) -> None:
894-
self.viewport = self.viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
911+
self._viewport = self._viewport.resize(new_width, anchor=Vec2(0.0, 0.0))
895912

896913
@property
897914
def viewport_height(self) -> int:
898915
"""
899916
The height of the viewport.
900917
Defines the number of pixels drawn too vertically.
901918
"""
902-
return int(self.viewport.height)
919+
return int(self._viewport.height)
903920

904921
@viewport_height.setter
905922
def viewport_height(self, new_height: int) -> None:
906-
self.viewport = self.viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
923+
self._viewport = self._viewport.resize(height=new_height, anchor=Vec2(0.0, 0.0))
907924

908925
@property
909926
def viewport_left(self) -> int:
910927
"""
911928
The left most pixel drawn to on the X axis.
912929
"""
913-
return int(self.viewport.left)
930+
return int(self._viewport.left)
914931

915932
@viewport_left.setter
916933
def viewport_left(self, new_left: int) -> None:
917934
"""
918935
Set the left most pixel drawn to.
919936
This moves the position of the viewport, and does not change the size.
920937
"""
921-
self.viewport = self.viewport.align_left(new_left)
938+
self._viewport = self._viewport.align_left(new_left)
922939

923940
@property
924941
def viewport_right(self) -> int:
925942
"""
926943
The right most pixel drawn to on the X axis.
927944
"""
928-
return int(self.viewport.right)
945+
return int(self._viewport.right)
929946

930947
@viewport_right.setter
931948
def viewport_right(self, new_right: int) -> None:
932949
"""
933950
Set the right most pixel drawn to.
934951
This moves the position of the viewport, and does not change the size.
935952
"""
936-
self.viewport = self.viewport.align_right(new_right)
953+
self._viewport = self._viewport.align_right(new_right)
937954

938955
@property
939956
def viewport_bottom(self) -> int:
940957
"""
941958
The bottom most pixel drawn to on the Y axis.
942959
"""
943-
return int(self.viewport.bottom)
960+
return int(self._viewport.bottom)
944961

945962
@viewport_bottom.setter
946963
def viewport_bottom(self, new_bottom: int) -> None:
947964
"""
948965
Set the bottom most pixel drawn to.
949966
This moves the position of the viewport, and does not change the size.
950967
"""
951-
self.viewport = self.viewport.align_bottom(new_bottom)
968+
self._viewport = self._viewport.align_bottom(new_bottom)
952969

953970
@property
954971
def viewport_top(self) -> int:
955972
"""
956973
The top most pixel drawn to on the Y axis.
957974
"""
958-
return int(self.viewport.top)
975+
return int(self._viewport.top)
959976

960977
@viewport_top.setter
961978
def viewport_top(self, new_top: int) -> None:
962979
"""
963980
Set the top most pixel drawn to.
964981
This moves the position of the viewport, and does not change the size.
965982
"""
966-
self.viewport = self.viewport.align_top(new_top)
983+
self._viewport = self._viewport.align_top(new_top)
967984

968985
@property
969986
def up(self) -> Vec2:

0 commit comments

Comments
 (0)