From 4f37c56a5574b7e905e708b34aded2fb595594e0 Mon Sep 17 00:00:00 2001 From: pushfoo <36696816+pushfoo@users.noreply.github.com> Date: Sun, 7 Apr 2024 22:39:01 -0400 Subject: [PATCH 1/4] Remove SimpleCamera from arcade.camera's __init__.py --- arcade/camera/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/arcade/camera/__init__.py b/arcade/camera/__init__.py index d4aaf545b2..f1d5d40d5a 100644 --- a/arcade/camera/__init__.py +++ b/arcade/camera/__init__.py @@ -14,7 +14,6 @@ from arcade.camera.orthographic import OrthographicProjector from arcade.camera.perspective import PerspectiveProjector -from arcade.camera.simple_camera import SimpleCamera from arcade.camera.camera_2d import Camera2D import arcade.camera.grips as grips @@ -28,7 +27,6 @@ 'OrthographicProjector', 'PerspectiveProjectionData', 'PerspectiveProjector', - 'SimpleCamera', 'Camera2D', 'grips' ] From 69e86b174bbea8fa8995016581f35171b7bb669c Mon Sep 17 00:00:00 2001 From: pushfoo <36696816+pushfoo@users.noreply.github.com> Date: Sun, 7 Apr 2024 22:39:42 -0400 Subject: [PATCH 2/4] Remove arcade/camera/simple_camera.py --- arcade/camera/simple_camera.py | 410 --------------------------------- 1 file changed, 410 deletions(-) delete mode 100644 arcade/camera/simple_camera.py diff --git a/arcade/camera/simple_camera.py b/arcade/camera/simple_camera.py deleted file mode 100644 index 4fb7f6a16a..0000000000 --- a/arcade/camera/simple_camera.py +++ /dev/null @@ -1,410 +0,0 @@ -from typing import TYPE_CHECKING, Optional, Tuple, Iterator -from warnings import warn -from contextlib import contextmanager -from math import atan2, cos, sin, degrees, radians - -from pyglet.math import Vec3 - -from arcade.camera.data_types import Projector, CameraData, OrthographicProjectionData -from arcade.camera.orthographic import OrthographicProjector - -from arcade.window_commands import get_window -if TYPE_CHECKING: - from arcade import Window - - -__all__ = [ - 'SimpleCamera' -] - - -class SimpleCamera: - """ - A simple camera which uses an orthographic camera and a simple 2D Camera Controller. - It also implements an update method that allows for an interpolation between two points - - Written to be backwards compatible with the old SimpleCamera. - - Initialize a Simple Camera Instance with either Camera PoDs or individual arguments - - .. depreciated:: 3.0 - use :cls:`.Camera2D` instead - - :param window: The Arcade Window to bind the camera to. - Defaults to the currently active window. - :param viewport: A 4-int tuple which defines the pixel bounds which the camera with project to. - :param position: The 2D position of the camera in the XY plane. - :param up: The 2D unit vector which defines the +Y-axis of the camera space. - :param zoom: A scalar value which is inversely proportional to the size of the camera projection. - i.e. a zoom of 2.0 halves the size of the projection, doubling the perceived size of objects. - :param projection: A 4-float tuple which defines the world space - bounds which the camera projects to the viewport. - :param near: The near clipping plane of the camera. - :param far: The far clipping place of the camera. - :param camera_data: A CameraData PoD which describes the viewport, position, up, and zoom - :param projection_data: A OrthographicProjectionData PoD which describes the left, right, top, - bottom, far, near planes for an orthographic projection. - """ - def __init__(self, *, - window: Optional["Window"] = None, - viewport: Optional[Tuple[int, int, int, int]] = None, - projection: Optional[Tuple[float, float, float, float]] = None, - position: Optional[Tuple[float, float]] = None, - up: Optional[Tuple[float, float]] = None, - zoom: Optional[float] = None, - near: Optional[float] = None, - far: Optional[float] = None, - camera_data: Optional[CameraData] = None, - projection_data: Optional[OrthographicProjectionData] = None - ): - warn("arcade.camera.SimpleCamera has been depreciated please use arcade.camera.Camera2D instead", - DeprecationWarning) - - self._window = window or get_window() - - if any((viewport, projection, position, up, zoom, near, far)) and any((camera_data, projection_data)): - raise ValueError("Provided both data structures and raw values." - "Only supply one or the other") - - if any((viewport, projection, position, up, zoom, near, far)): - _pos = position or (0.0, 0.0) - _up = up or (0.0, 1.0) - self._view = CameraData( - (_pos[0], _pos[1], 0.0), - (_up[0], _up[1], 0.0), - (0.0, 0.0, -1.0), - zoom or 1.0 - ) - _projection = projection or ( - 0.0, self._window.width, - 0.0, self._window.height - ) - self._projection = OrthographicProjectionData( - _projection[0] or 0.0, _projection[1] or self._window.width, # Left, Right - _projection[2] or 0.0, _projection[3] or self._window.height, # Bottom, Top - near or -100, far or 100, # Near, Far - viewport or (0, 0, self._window.width, self._window.height), # Viewport - ) - else: - self._view = camera_data or CameraData( - (0.0, 0.0, 0.0), # Position - (0, 1.0, 0.0), # Up - (0.0, 0.0, -1.0), # Forward - 1.0 # Zoom - ) - self._projection = projection_data or OrthographicProjectionData( - 0.0, self._window.width, # Left, Right - 0.0, self._window.height, # Bottom, Top - -100, 100, # Near, Far - (0, 0, self._window.width, self._window.height), # Viewport - ) - - self._camera = OrthographicProjector( - window=self._window, - view=self._view, - projection=self._projection - ) - - self._easing_speed: float = 0.0 - self._position_goal: Tuple[float, float] = self.position - - # Basic properties for modifying the viewport and orthographic projection - - @property - def viewport_width(self) -> int: - """ Returns the width of the viewport """ - return self._projection.viewport[2] - - @property - def viewport_height(self) -> int: - """ Returns the height of the viewport """ - return self._projection.viewport[3] - - @property - def viewport(self) -> Tuple[int, int, int, int]: - """ The pixel area that will be drawn to while this camera is active (left, bottom, width, height) """ - return self._projection.viewport - - @viewport.setter - def viewport(self, viewport: Tuple[int, int, int, int]) -> None: - """ Set the viewport (left, bottom, width, height) """ - self.set_viewport(viewport) - - def set_viewport(self, viewport: Tuple[int, int, int, int]) -> None: - self._projection.viewport = viewport - - @property - def projection(self) -> Tuple[float, float, float, float]: - """ - The dimensions that will be projected to the viewport. (left, right, bottom, top). - """ - return self._projection.left, self._projection.right, self._projection.bottom, self._projection.top - - @projection.setter - def projection(self, projection: Tuple[float, float, float, float]) -> None: - """ - Update the orthographic projection of the camera. (left, right, bottom, top). - """ - self._projection.left = projection[0] - self._projection.right = projection[1] - self._projection.bottom = projection[2] - self._projection.top = projection[3] - - # Methods for retrieving the viewport - projection ratios. Originally written by Alejandro Casanovas. - @property - def viewport_to_projection_width_ratio(self) -> float: - """ - The ratio of viewport width to projection width. - A value of 1.0 represents that an object that moves one unit will move one pixel. - A value less than one means that one pixel is equivalent to more than one unit (Zoom out). - """ - return (self.viewport_width * self.zoom) / (self._projection.left - self._projection.right) - - @property - def viewport_to_projection_height_ratio(self) -> float: - """ - The ratio of viewport height to projection height. - A value of 1.0 represents that an object that moves one unit will move one pixel. - A value less than one means that one pixel is equivalent to more than one unit (Zoom out). - """ - return (self.viewport_height * self.zoom) / (self._projection.bottom - self._projection.top) - - @property - def projection_to_viewport_width_ratio(self) -> float: - """ - The ratio of projection width to viewport width. - A value of 1.0 represents that an object that moves one unit will move one pixel. - A value less than one means that one pixel is equivalent to less than one unit (Zoom in). - """ - return (self._projection.left - self._projection.right) / (self.zoom * self.viewport_width) - - @property - def projection_to_viewport_height_ratio(self) -> float: - """ - The ratio of projection height to viewport height. - A value of 1.0 represents that an object that moves one unit will move one pixel. - A value less than one means that one pixel is equivalent to less than one unit (Zoom in). - """ - return (self._projection.bottom - self._projection.top) / (self.zoom * self.viewport_height) - - # Control methods (movement, zooming, rotation) - @property - def position(self) -> Tuple[float, float]: - """ - The position of the camera based on the bottom left coordinate. - """ - return self._view.position[0], self._view.position[1] - - @position.setter - def position(self, pos: Tuple[float, float]) -> None: - """ - Set the position of the camera based on the bottom left coordinate. - """ - self._view.position = (pos[0], pos[1], self._view.position[2]) - - @property - def zoom(self) -> float: - """ - A scaler which adjusts the size of the orthographic projection. - A higher zoom value means larger pixels. - For best results keep the zoom value an integer to an integer or an integer to the power of -1. - """ - return self._view.zoom - - @zoom.setter - def zoom(self, zoom: float) -> None: - """ - A scaler which adjusts the size of the orthographic projection. - A higher zoom value means larger pixels. - For best results keep the zoom value an integer to an integer or an integer to the power of -1. - """ - self._view.zoom = zoom - - @property - def up(self) -> Tuple[float, float]: - """ - A 2D normalised vector which defines which direction corresponds to the +Y axis. - """ - return self._view.up[0], self._view.up[1] - - @up.setter - def up(self, up: Tuple[float, float]) -> None: - """ - A 2D normalised vector which defines which direction corresponds to the +Y axis. - generally easier to use the `rotate` and `rotate_to` methods as they use an angle value. - """ - _up = Vec3(up[0], up[1], 0.0).normalize() - self._view.up = (_up[0], _up[1], _up[2]) - - @property - def angle(self) -> float: - """ - An alternative way of setting the up vector of the camera. - The angle value goes clock-wise starting from (0.0, 1.0). - """ - return degrees(atan2(self.up[0], self.up[1])) - - @angle.setter - def angle(self, angle: float) -> None: - """ - An alternative way of setting the up vector of the camera. - The angle value goes clock-wise starting from (0.0, 1.0). - """ - rad = radians(angle) - self.up = ( - sin(rad), - cos(rad) - ) - - def move_to(self, vector: Tuple[float, float], speed: float = 1.0) -> None: - """ - Sets the goal position of the camera. - - The camera will lerp towards this position based on the provided speed, - updating its position every time the use() function is called. - - Args: - vector: The 2D vector position to move the camera towards (in the XY plane) - speed: How fast to move the camera, 1.0 is instant, 0.1 moves slowly - """ - self._position_goal = vector - self._easing_speed = speed - - def move(self, vector: Tuple[float, float]) -> None: - """ - Moves the camera with a speed of 1.0, aka instant move - - This is equivalent to calling move_to(my_pos, 1.0) - """ - self.move_to(vector, 1.0) - - def center(self, vector: Tuple[float, float], speed: float = 1.0) -> None: - """ - Centers the camera. Allows for a linear lerp like the move_to() method. - """ - viewport_center = self.viewport_width / 2, self.viewport_height / 2 - - adjusted_vector = ( - vector[0] * self.viewport_to_projection_width_ratio, - vector[1] * self.viewport_to_projection_height_ratio - ) - - target = ( - adjusted_vector[0] - viewport_center[0], - adjusted_vector[1] - viewport_center[1] - ) - - self.move_to(target, speed) - - # General Methods - - def update(self): - """ - Update the camera's position. - """ - if self._easing_speed > 0.0: - x_a = self.position[0] - x_b = self._position_goal[0] - - y_a = self.position[1] - y_b = self._position_goal[1] - - self.position = ( - x_a + (x_b - x_a) * self._easing_speed, # Linear Lerp X position - y_a + (y_b - y_a) * self._easing_speed # Linear Lerp Y position - ) - if self.position == self._position_goal: - self._easing_speed = 0.0 - - def use(self) -> None: - """ - Sets the active camera to this object. - Then generates the view and projection matrices. - Finally, the gl context viewport is set, as well as the projection and view matrices. - This method also calls the update method. This can cause the camera to move faster than expected - if the camera is used multiple times in a single frame. - """ - - # Updated the position - self.update() - - # set matrices - self._camera.use() - - @contextmanager - def activate(self) -> Iterator[Projector]: - """ - A context manager version of Camera2DOrthographic.use() which allows for the use of - `with` blocks. For example, `with camera.activate() as cam: ...`. - """ - previous_projector = self._window.current_camera - try: - self.use() - yield self - finally: - previous_projector.use() - - def map_coordinate(self, screen_coordinate: Tuple[float, float], depth: float = 0.0) -> Tuple[float, float]: - """ - Take in a pixel coordinate from within - the range of the viewport and returns - the world space coordinates. - - .. deprecated:: 3.0 - Use :meth:`.map_screen_to_world_coordinate` instead. - - Essentially reverses the effects of the projector. - - Args: - screen_coordinate: A 2D position in pixels from the bottom left of the screen. - This should ALWAYS be in the range of 0.0 - screen size. - depth: The depth value which is mapped along with the screen coordinates. Because of how - Orthographic perspectives work this does not impact how the screen_coordinates are mapped. - Returns: - A 2D vector (Along the XY plane) in world space (same as sprites). - perfect for finding if the mouse overlaps with a sprite or ui element irrespective - of the camera. - """ - - return self._camera.map_screen_to_world_coordinate(screen_coordinate, depth)[:2] - - def map_screen_to_world_coordinate( - self, - screen_coordinate: Tuple[float, float], - depth: Optional[float] = 0.0 - ) -> Tuple[float, float]: - """ - Take in a pixel coordinate from within - the range of the window size and returns - the world space coordinates. - - Essentially reverses the effects of the projector. - - Args: - screen_coordinate: A 2D position in pixels from the bottom left of the screen. - This should ALWAYS be in the range of 0.0 - screen size. - depth: The depth value which is mapped along with the screen coordinates. Because of how - Orthographic perspectives work this does not impact how the screen_coordinates are mapped. - Returns: - A 2D vector (Along the XY plane) in world space (same as sprites). - perfect for finding if the mouse overlaps with a sprite or ui element irrespective - of the camera. - """ - - return self._camera.map_screen_to_world_coordinate(screen_coordinate, depth)[:2] - - def resize(self, viewport_width: int, viewport_height: int, *, - resize_projection: bool = True) -> None: - """ - Resize the camera's viewport. Call this when the window resizes. - - Args: - viewport_width: Width of the viewport. - viewport_height: Height of the viewport. - resize_projection: If True the projection will also be resized. - """ - new_viewport = (self.viewport[0], self.viewport[1], viewport_width, viewport_height) - self.set_viewport(new_viewport) - if resize_projection: - self.projection = (self._projection.left, viewport_width, - self._projection.bottom, viewport_height) From adaa44435b682760f0df4f4979a41236cdb77ee0 Mon Sep 17 00:00:00 2001 From: pushfoo <36696816+pushfoo@users.noreply.github.com> Date: Mon, 8 Apr 2024 06:27:43 -0400 Subject: [PATCH 3/4] Update platformer tutorial step 7's .rst to account for Camera2D changes --- doc/tutorials/platform_tutorial/step_07.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/doc/tutorials/platform_tutorial/step_07.rst b/doc/tutorials/platform_tutorial/step_07.rst index e6bfb56fa5..119889f019 100644 --- a/doc/tutorials/platform_tutorial/step_07.rst +++ b/doc/tutorials/platform_tutorial/step_07.rst @@ -7,9 +7,8 @@ Now that our player can move and jump around, we need to give them a way to expl beyond the original window. If you've ever played a platformer game, you might be familiar with the concept of the screen scrolling to reveal more of the map as the player moves. -To achieve this, we can use a Camera, Arcade provides :class:`arcade.SimpleCamera` and :class:`arcade.Camera`. -They both do the same base thing, but Camera has a bit of extra functionality that SimpleCamera doesn't. -For now, we will just use the SimpleCamera. +To achieve this, we can use a Camera. Since we are making a 2D game, `arcade.camera.Camera2D` will +be easiest. To start with, let's go ahead and add a variable in our ``__init__`` function to hold it: @@ -21,16 +20,15 @@ Next we can go to our setup function, and initialize it like so: .. code-block:: - self.camera = arcade.SimpleCamera(viewport=(0, 0, self.width, self.height)) + self.camera = arcade.camera.Camera2D() -The ``viewport`` parameter here defines the size of the camera. In most circumstances, you will want this -to be the size of your window. So we specify the bottom and left coordinates of our camera viewport as -(0, 0), and provide it the width and height of our window. +Since we're drawing to the entire screen, we can use ``Camera2D``'s default settings. +In other circumstances, we can create or adjust the camera so it has a different viewport. In order to use our camera when drawing things to the screen, we only need to add one line to our ``on_draw`` function. This line should typically come before anything you want to draw with the camera. In later chapters, we'll explore using multiple cameras to draw things in different positions. Go ahead and add this line before -drawing our SpriteLists +drawing our SpriteLists: .. code-block:: @@ -49,7 +47,7 @@ consideration. .. code-block:: - self.camera.center(self.player_sprite.position) + self.camera.position = self.player_sprite.position Source Code ~~~~~~~~~~~ From 2eecfaeee425ca21e8cd6a0353999a2fbcddfc55 Mon Sep 17 00:00:00 2001 From: pushfoo <36696816+pushfoo@users.noreply.github.com> Date: Mon, 8 Apr 2024 06:33:46 -0400 Subject: [PATCH 4/4] Use consistent code style for the class in step 7 --- doc/tutorials/platform_tutorial/step_07.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorials/platform_tutorial/step_07.rst b/doc/tutorials/platform_tutorial/step_07.rst index 119889f019..27a29ccf4c 100644 --- a/doc/tutorials/platform_tutorial/step_07.rst +++ b/doc/tutorials/platform_tutorial/step_07.rst @@ -7,7 +7,7 @@ Now that our player can move and jump around, we need to give them a way to expl beyond the original window. If you've ever played a platformer game, you might be familiar with the concept of the screen scrolling to reveal more of the map as the player moves. -To achieve this, we can use a Camera. Since we are making a 2D game, `arcade.camera.Camera2D` will +To achieve this, we can use a Camera. Since we are making a 2D game, ``arcade.camera.Camera2D`` will be easiest. To start with, let's go ahead and add a variable in our ``__init__`` function to hold it: