diff --git a/doc/tutorials/card_game/drag_drop_cards_full.py b/doc/tutorials/card_game/drag_drop_cards_full.py index 04ce68baa..c8b72a092 100644 --- a/doc/tutorials/card_game/drag_drop_cards_full.py +++ b/doc/tutorials/card_game/drag_drop_cards_full.py @@ -172,9 +172,7 @@ def setup(self): self.card_list.append(card) # Shuffle the cards - for pos1 in range(len(self.card_list)): - pos2 = random.randrange(len(self.card_list)) - self.card_list[pos1], self.card_list[pos2] = self.card_list[pos2], self.card_list[pos1] + self.card_list.shuffle() # Create a list of lists, each holds a pile of cards. self.piles = [[] for _ in range(PILE_COUNT)] @@ -216,11 +214,11 @@ def pull_to_top(self, card): """ Pull card to top of rendering order (last to render, looks on-top) """ # Find the index of the card index = self.card_list.index(card) - # Loop and pull all the other cards down towards the zero end + + # Repeatedly swap cards until the chosen card draws on top (last) for i in range(index, len(self.card_list) - 1): - self.card_list[i] = self.card_list[i + 1] - # Put this card at the right-side/top/size of list - self.card_list[len(self.card_list) - 1] = card + # Exchange the drawing order of the cards at i and i + 1 + self.card_list.swap(i, i+1) def on_key_press(self, symbol: int, modifiers: int): """ User presses key """ diff --git a/doc/tutorials/compute_shader/main.py b/doc/tutorials/compute_shader/main.py index 76d435e95..487e5510c 100644 --- a/doc/tutorials/compute_shader/main.py +++ b/doc/tutorials/compute_shader/main.py @@ -67,15 +67,15 @@ def __init__(self): # --- Create shaders - # Load in the shader source code - file = open("shaders/compute_shader.glsl") - compute_shader_source = file.read() - file = open("shaders/vertex_shader.glsl") - vertex_shader_source = file.read() - file = open("shaders/fragment_shader.glsl") - fragment_shader_source = file.read() - file = open("shaders/geometry_shader.glsl") - geometry_shader_source = file.read() + # Load in the shader source code safely & auto-close files + with open("shaders/compute_shader.glsl") as file: + compute_shader_source = file.read() + with open("shaders/vertex_shader.glsl") as file: + vertex_shader_source = file.read() + with open("shaders/fragment_shader.glsl") as file: + fragment_shader_source = file.read() + with open("shaders/geometry_shader.glsl") as file: + geometry_shader_source = file.read() # Create our compute shader. # Search/replace to set up our compute groups diff --git a/doc/tutorials/crt_filter/bloom_filter_example.py b/doc/tutorials/crt_filter/bloom_filter_example.py index 5c3f22f2e..d046c7c4a 100644 --- a/doc/tutorials/crt_filter/bloom_filter_example.py +++ b/doc/tutorials/crt_filter/bloom_filter_example.py @@ -1,15 +1,13 @@ -from pathlib import Path import arcade from arcade.experimental import BloomFilter import random -from arcade.color import * +from arcade.color import RED, YELLOW, ORANGE, GREEN, BLUEBERRY, AMETHYST # Do the math to figure out our screen dimensions SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 SCREEN_TITLE = "ShaderToy Demo" -RESOURCE_DIR = Path(__file__).parent class MyGame(arcade.Window): @@ -27,8 +25,9 @@ def __init__(self, width, height, title): self.sprite_list = arcade.SpriteList() for y in range(10, self.height, 50): - color = random.choice([RED, YELLOW, ORANGE, GREEN, BLUEBERRY, AMETHYST]) - my_sprite = arcade.SpriteCircle(random.randrange(40), color) + color = random.choice( + [RED, YELLOW, ORANGE, GREEN, BLUEBERRY, AMETHYST]) + my_sprite = arcade.SpriteCircle(random.randrange(1, 40), color) self.sprite_list.append(my_sprite) my_sprite.change_x = random.random() * 5 my_sprite.center_y = y @@ -39,7 +38,8 @@ def on_draw(self): self.bloom_filter.use() self.bloom_filter.clear() self.sprite_list.draw() - # arcade.draw_lrbt_rectangle_outline(0, self.width - 25, 0, self.height - 5, arcade.color.WHITE, 5) + # arcade.draw_lrbt_rectangle_outline( + # 0, self.width - 25, 0, self.height - 5, arcade.color.WHITE, 5) # Switch back to our window and draw the CRT filter do # draw its stuff to the screen diff --git a/doc/tutorials/crt_filter/crt_filter_example.py b/doc/tutorials/crt_filter/crt_filter_example.py index 4b0f02687..23bba6835 100644 --- a/doc/tutorials/crt_filter/crt_filter_example.py +++ b/doc/tutorials/crt_filter/crt_filter_example.py @@ -1,14 +1,12 @@ -from pathlib import Path import arcade from arcade.experimental.crt_filter import CRTFilter from pyglet.math import Vec2 -# Do the math to figure out our screen dimensions +# Store our screen dimensions & title in a convenient place SCREEN_WIDTH = 800 SCREEN_HEIGHT = 1100 SCREEN_TITLE = "ShaderToy Demo" -RESOURCE_DIR = Path(__file__).parent class MyGame(arcade.Window): @@ -21,7 +19,7 @@ def __init__(self, width, height, title): resolution_down_scale=6.0, hard_scan=-8.0, hard_pix=-3.0, - display_warp = Vec2(1.0 / 32.0, 1.0 / 24.0), + display_warp=Vec2(1.0 / 32.0, 1.0 / 24.0), mask_dark=0.5, mask_light=1.5) @@ -30,33 +28,37 @@ def __init__(self, width, height, title): # Create some stuff to draw on the screen self.sprite_list = arcade.SpriteList() - full = arcade.Sprite(RESOURCE_DIR / "Pac-man.png") + full = arcade.Sprite("Pac-man.png") full.center_x = width / 2 full.center_y = height / 2 full.scale = width / full.width self.sprite_list.append(full) - my_sprite = arcade.Sprite(RESOURCE_DIR / "pac_man_sprite_sheet.png", - scale=5, image_x=4, image_y=65, image_width=13, image_height=15) + my_sprite = arcade.Sprite( + "pac_man_sprite_sheet.png", + scale=5, image_x=4, image_y=65, image_width=13, image_height=15) my_sprite.change_x = 1 self.sprite_list.append(my_sprite) my_sprite.center_x = 100 my_sprite.center_y = 300 - my_sprite = arcade.Sprite(RESOURCE_DIR / "pac_man_sprite_sheet.png", - scale=5, image_x=4, image_y=81, image_width=13, image_height=15) + my_sprite = arcade.Sprite( + "pac_man_sprite_sheet.png", + scale=5, image_x=4, image_y=81, image_width=13, image_height=15) my_sprite.change_x = -1 self.sprite_list.append(my_sprite) my_sprite.center_x = 800 my_sprite.center_y = 200 my_sprite = arcade.AnimatedTimeBasedSprite() - texture = arcade.load_texture(RESOURCE_DIR / "pac_man_sprite_sheet.png", x=4, y=1, width=13, height=15) + texture = arcade.load_texture( + "pac_man_sprite_sheet.png", x=4, y=1, width=13, height=15) frame = arcade.AnimationKeyframe(tile_id=0, duration=150, texture=texture) my_sprite.frames.append(frame) - texture = arcade.load_texture(RESOURCE_DIR / "pac_man_sprite_sheet.png", x=20, y=1, width=13, height=15) + texture = arcade.load_texture( + "pac_man_sprite_sheet.png", x=20, y=1, width=13, height=15) frame = arcade.AnimationKeyframe(tile_id=1, duration=150, texture=texture) @@ -76,8 +78,8 @@ def on_draw(self): self.crt_filter.clear() self.sprite_list.draw() - # Next, switch back to the screen and dump the contents of the CRT filter - # to it. + # Next, switch back to the screen and dump the contents of + # the CRT filter to it. self.use() self.clear() self.crt_filter.draw() diff --git a/doc/tutorials/framebuffer/step_01.py b/doc/tutorials/framebuffer/step_01.py index 01e4b291c..776808551 100644 --- a/doc/tutorials/framebuffer/step_01.py +++ b/doc/tutorials/framebuffer/step_01.py @@ -55,7 +55,6 @@ def on_draw(self): self.clear() self.filter.clear() self.filter.use() - print(self.width / 2) arcade.draw_circle_filled(self.width / 2, self.height / 2, 100, arcade.color.RED) arcade.draw_circle_filled(400, 300, 100, arcade.color.GREEN) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_02.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_02.py index 1474d7ecf..63c178a2f 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_02.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_02.py @@ -3,6 +3,7 @@ """ from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -68,10 +69,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f', - ['in_pos']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f', + ['in_pos']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_03.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_03.py index 30b3827ba..1699e981c 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_03.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_03.py @@ -5,6 +5,7 @@ import time from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -31,7 +32,7 @@ def __init__(self): # Program to visualize the points self.program = self.ctx.load_program( - vertex_shader="vertex_shader_v1.glsl", + vertex_shader="vertex_shader_v2.glsl", fragment_shader="fragment_shader.glsl", ) @@ -81,10 +82,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f', - ['in_pos', 'in_vel']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f', + ['in_pos', 'in_vel']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_04.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_04.py index e08f0c008..4f01bb8e7 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_04.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_04.py @@ -6,6 +6,7 @@ import math from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -84,10 +85,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f', - ['in_pos', 'in_vel']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f', + ['in_pos', 'in_vel']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_05.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_05.py index cf4250e1c..d4354d030 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_05.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_05.py @@ -6,6 +6,7 @@ import math from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -84,10 +85,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f', - ['in_pos', 'in_vel']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f', + ['in_pos', 'in_vel']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_06.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_06.py index b07eb0ada..70fe6ed19 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_06.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_06.py @@ -6,6 +6,7 @@ import math from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -90,10 +91,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f 3f', - ['in_pos', 'in_vel', 'in_color']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f 3f', + ['in_pos', 'in_vel', 'in_color']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_07.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_07.py index 34173768c..40243df18 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_07.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_07.py @@ -6,6 +6,7 @@ import math from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -66,8 +67,7 @@ def on_update(self, dt): temp_list = self.burst_list.copy() for burst in temp_list: if time.time() - burst.start_time > MAX_FADE_TIME: - self.burst_list.remove(burst) - + self.burst_list.remove(burst) def on_mouse_press(self, x: float, y: float, button: int, modifiers: int): """ User clicks mouse """ @@ -82,7 +82,8 @@ def _gen_initial_data(initial_x, initial_y): red = random.uniform(0.5, 1.0) green = random.uniform(0, red) blue = 0 - fade_rate = random.uniform(1 / MAX_FADE_TIME, 1 / MIN_FADE_TIME) + fade_rate = random.uniform( + 1 / MAX_FADE_TIME, 1 / MIN_FADE_TIME) yield initial_x yield initial_y @@ -104,13 +105,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f 3f f', - ['in_pos', - 'in_vel', - 'in_color', - 'in_fade_rate']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f 3f f', + ['in_pos', 'in_vel', 'in_color', 'in_fade_rate']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_08.py b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_08.py index ee93c907b..2fa05af80 100644 --- a/doc/tutorials/gpu_particle_burst/gpu_particle_burst_08.py +++ b/doc/tutorials/gpu_particle_burst/gpu_particle_burst_08.py @@ -6,6 +6,7 @@ import math from array import array from dataclasses import dataclass + import arcade import arcade.gl @@ -81,7 +82,8 @@ def _gen_initial_data(initial_x, initial_y): red = random.uniform(0.5, 1.0) green = random.uniform(0, red) blue = 0 - fade_rate = random.uniform(1 / MAX_FADE_TIME, 1 / MIN_FADE_TIME) + fade_rate = random.uniform( + 1 / MAX_FADE_TIME, 1 / MIN_FADE_TIME) yield initial_x yield initial_y @@ -103,13 +105,12 @@ def _gen_initial_data(initial_x, initial_y): # Create a buffer with that data buffer = self.ctx.buffer(data=array('f', initial_data)) - # Create a buffer description that says how the buffer data is formatted. - buffer_description = arcade.gl.BufferDescription(buffer, - '2f 2f 3f f', - ['in_pos', - 'in_vel', - 'in_color', - 'in_fade_rate']) + # Create a buffer description specifying the buffer's data format + buffer_description = arcade.gl.BufferDescription( + buffer, + '2f 2f 3f f', + ['in_pos', 'in_vel', 'in_color', 'in_fade_rate']) + # Create our Vertex Attribute Object vao = self.ctx.geometry([buffer_description]) diff --git a/doc/tutorials/gpu_particle_burst/index.rst b/doc/tutorials/gpu_particle_burst/index.rst index 9ad50a1b3..9be956171 100644 --- a/doc/tutorials/gpu_particle_burst/index.rst +++ b/doc/tutorials/gpu_particle_burst/index.rst @@ -38,7 +38,7 @@ Imports First, we'll import some more items for our program: .. literalinclude:: gpu_particle_burst_02.py - :lines: 4-7 + :lines: 4-8 Burst Dataclass ~~~~~~~~~~~~~~~ @@ -165,7 +165,7 @@ update call. Imports ~~~~~~~ -First, we'll import both the random and time libraries: +First, we'll add imports for both the ``random`` and ``time`` libraries: .. literalinclude:: gpu_particle_burst_03.py :lines: 4-5 @@ -176,7 +176,7 @@ Constants Then we need to create a constant that contains the number of particles to create: .. literalinclude:: gpu_particle_burst_03.py - :lines: 15 + :lines: 16 Burst Dataclass ~~~~~~~~~~~~~~~ @@ -208,7 +208,7 @@ Finally, our burst object needs to track the time we created the burst. .. literalinclude:: gpu_particle_burst_03.py :pyobject: MyWindow.on_mouse_press - :emphasize-lines: 6-12, 27-28, 33 + :emphasize-lines: 6-12, 28-29, 35 :linenos: Set Time in on_draw @@ -299,7 +299,7 @@ Another option is to use a gaussian function to produce more of a 'splat' look: .. literalinclude:: gpu_particle_burst_05.py - :lines: 66 + :lines: 69 Program Listings ~~~~~~~~~~~~~~~~ @@ -318,12 +318,13 @@ need to generate it for each particle. Shaders take colors in the form of RGB floats, so we'll generate a random number for red, and add in some green to get our yellows. Don't add more green than red, or else you get a green tint. -Finally, pass in the three floats as ``in_color`` to the shader buffer (VBO). +Finally, make sure to update the shader buffer description (VBO) to accept +the three color channel floats (``3f``) under the name ``in_color``. .. literalinclude:: gpu_particle_burst_06.py :pyobject: MyWindow.on_mouse_press :linenos: - :emphasize-lines: 11-13, 18-20, 34-36 + :emphasize-lines: 11-13, 18-20, 36-37 Then, update the shader to use the color instead of always using white: @@ -353,11 +354,11 @@ Once a burst has faded out, let's remove it from ``burst_list``. Constants ~~~~~~~~~ -First, let's add a couple constants to control the minimum and maximum tile to -fade a particle: +First, let's add a couple constants to control the minimum and maximum times +to fade a particle: .. literalinclude:: gpu_particle_burst_07.py - :lines: 18-19 + :lines: 19-20 Update Init ~~~~~~~~~~~ @@ -372,12 +373,12 @@ back to the ``__init__`` method and update the ``enable_only`` call to: Add Fade Rate to Buffer ~~~~~~~~~~~~~~~~~~~~~~~ -Next, add the fade rate to the VBO: +Next, add the fade rate float to the VBO: .. literalinclude:: gpu_particle_burst_07.py :pyobject: MyWindow.on_mouse_press :linenos: - :emphasize-lines: 14, 23, 37-42 + :emphasize-lines: 14-15, 24, 40-41 Update Shader ~~~~~~~~~~~~~ diff --git a/doc/tutorials/pymunk_platformer/index.rst b/doc/tutorials/pymunk_platformer/index.rst index 9d7916cca..e69b5d6f3 100644 --- a/doc/tutorials/pymunk_platformer/index.rst +++ b/doc/tutorials/pymunk_platformer/index.rst @@ -176,7 +176,7 @@ First, add some constants for our physics. Here we are setting: .. literalinclude:: pymunk_demo_platformer_05.py :caption: Add Constants for Physics :linenos: - :lines: 28-47 + :lines: 27-46 Second, add the following attributer in the ``__init__`` method to hold our physics engine: @@ -184,7 +184,7 @@ physics engine: .. literalinclude:: pymunk_demo_platformer_05.py :caption: Add Physics Engine Attribute :linenos: - :lines: 72-73 + :lines: 71-72 Third, in the ``setup`` method we create the physics engine and add the sprites. The player, walls, and dynamic items all have different properties so they are @@ -193,14 +193,14 @@ added individually. .. literalinclude:: pymunk_demo_platformer_05.py :caption: Add Sprites to Physics Engine in 'setup' Method :linenos: - :lines: 103-153 + :lines: 102-152 Fourth, in the ``on_update`` method we call the physics engine's ``step`` method. .. literalinclude:: pymunk_demo_platformer_05.py :caption: Add Sprites to Physics Engine in 'setup' Method :linenos: - :lines: 166-168 + :lines: 165-167 If you run the program, and you have dynamic items that are up in the air, you should see them fall when the game starts. @@ -220,7 +220,7 @@ We'll apply a different force later, if the player happens to be airborne. .. literalinclude:: pymunk_demo_platformer_06.py :caption: Add Player Movement - Constants and Attributes :linenos: - :lines: 49-72 + :lines: 48-71 :emphasize-lines: 1-2, 22-24 We need to track if the left/right keys are held down. To do this we define @@ -230,7 +230,7 @@ appropriate values in the key press and release handlers. .. literalinclude:: pymunk_demo_platformer_06.py :caption: Handle Key Up and Down Events :linenos: - :lines: 160-174 + :lines: 159-173 :emphasize-lines: 4-7, 12-15 Finally, we need to apply the correct force in ``on_update``. Force is specified @@ -242,7 +242,7 @@ We also set the friction when we are moving to zero, and when we are not moving .. literalinclude:: pymunk_demo_platformer_06.py :caption: Apply Force to Move Player :linenos: - :lines: 176-197 + :lines: 175-196 :emphasize-lines: 4-19 * :ref:`pymunk_demo_platformer_06` @@ -271,14 +271,14 @@ For the code changes, first we'll define some constants: .. literalinclude:: pymunk_demo_platformer_07.py :caption: Add Player Jumping - Constants :linenos: - :lines: 52-56 + :lines: 51-55 We'll add logic that will apply the impulse force when we jump: .. literalinclude:: pymunk_demo_platformer_07.py :caption: Add Player Jumping - Jump Force :linenos: - :lines: 167-179 + :lines: 166-178 :emphasize-lines: 8-13 Then we will adjust the left/right force depending on if we are grounded or not: @@ -286,7 +286,7 @@ Then we will adjust the left/right force depending on if we are grounded or not: .. literalinclude:: pymunk_demo_platformer_07.py :caption: Add Player Jumping - Left/Right Force Selection :linenos: - :lines: 189-215 + :lines: 188-214 :emphasize-lines: 4, 7-11, 16-20 * :ref:`pymunk_demo_platformer_07` @@ -358,7 +358,7 @@ in our ``__init__`` method: .. literalinclude:: pymunk_demo_platformer_08.py :caption: Add Player Animation - Creating the Player Class - :lines: 161-162 + :lines: 159-160 @@ -436,8 +436,8 @@ it instead of the plain ``arcade.Sprite`` class. .. literalinclude:: pymunk_demo_platformer_10.py :caption: Destroy Bullets - Bullet Sprite :linenos: - :lines: 315-319 - :emphasize-lines: 4 + :lines: 315-320 + :emphasize-lines: 1 Handle Collisions ~~~~~~~~~~~~~~~~~ @@ -455,7 +455,7 @@ the texture depending on its health. .. literalinclude:: pymunk_demo_platformer_10.py :caption: Destroy Bullets - Collision Handlers :linenos: - :lines: 240-251 + :lines: 242-253 * :ref:`pymunk_demo_platformer_10` @@ -497,13 +497,13 @@ an attribute for ``moving_sprites_list``: .. literalinclude:: pymunk_demo_platformer_11.py :caption: Moving Platforms - Adding the sprite list - :lines: 189 + :lines: 186 In the ``setup`` method, load in the sprite list from the tmx layer. .. literalinclude:: pymunk_demo_platformer_11.py :caption: Moving Platforms - Adding the sprite list - :lines: 214-217 + :lines: 227 Also in the ``setup`` method, we need to add these sprites to the physics engine. In this case we'll add the sprites as ``KINEMATIC``. Static sprites don't move. @@ -512,7 +512,7 @@ Kinematic sprites do move, but aren't affected by other objects. .. literalinclude:: pymunk_demo_platformer_11.py :caption: Moving Platforms - Loading the sprites - :lines: 299-301 + :lines: 294-296 We need to draw the moving platform sprites. After adding this line, you should be able to run the program and see the sprites from this layer, even if they don't @@ -544,7 +544,7 @@ so we'll convert. .. literalinclude:: pymunk_demo_platformer_11.py :caption: Moving Platforms - Moving the sprites - :lines: 407-427 + :lines: 404-428 * :ref:`pymunk_demo_platformer_11` * :ref:`pymunk_demo_platformer_11_diff` @@ -564,7 +564,7 @@ to track some more items: :caption: Add Ladders - PlayerSprite class :linenos: :pyobject: PlayerSprite.__init__ - :emphasize-lines: 2, 33-36, 54-55 + :emphasize-lines: 2, 33-36, 51-52 Next, in our ``pymunk_moved`` method we need to change physics when we are on a ladder, and to update our player texture. @@ -593,7 +593,8 @@ Then load the ladder layer in ``setup``: .. literalinclude:: pymunk_demo_platformer_12.py :caption: Add Ladders - Game Window Setup - :lines: 265-266 + :lines: 256-260 + :emphasize-lines: 4 Also, pass the ladder list to the player class: @@ -623,7 +624,7 @@ Next, change our update with new updates for the ladder. .. literalinclude:: pymunk_demo_platformer_12.py :caption: Add Ladders - Game Window On Update :linenos: - :lines: 430-465 + :lines: 426-462 :emphasize-lines: 7, 16, 23-36 And, of course, don't forget to draw the ladders: diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer.py index d518d7c7f..3d9f6cff7 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer.py @@ -52,14 +52,6 @@ RIGHT_FACING = 0 LEFT_FACING = 1 -def load_texture_pair(filename): - """ - Load a texture pair, with the second being a mirror image. - """ - return [ - arcade.load_texture(filename), - arcade.load_texture(filename, flipped_horizontally=True) - ] class PlayerSprite(arcade.Sprite): def __init__(self): @@ -78,14 +70,14 @@ def __init__(self): # main_path = ":resources:images/animated_characters/robot/robot" # Load textures for idle standing - self.idle_texture_pair = load_texture_pair(f"{main_path}_idle.png") - self.jump_texture_pair = load_texture_pair(f"{main_path}_jump.png") - self.fall_texture_pair = load_texture_pair(f"{main_path}_fall.png") + self.idle_texture_pair = arcade.load_texture_pair(f"{main_path}_idle.png") + self.jump_texture_pair = arcade.load_texture_pair(f"{main_path}_jump.png") + self.fall_texture_pair = arcade.load_texture_pair(f"{main_path}_fall.png") # Load textures for walking self.walk_textures = [] for i in range(8): - texture = load_texture_pair(f"{main_path}_walk{i}.png") + texture = arcade.load_texture_pair(f"{main_path}_walk{i}.png") self.walk_textures.append(texture) # Load textures for climbing @@ -101,7 +93,7 @@ def __init__(self): # Hit box will be set based on the first image used. If you want to specify # a different hit box, you can do it like the code below. # self.set_hit_box([[-22, -64], [22, -64], [22, 28], [-22, 28]]) - self.set_hit_box(self.texture.hit_box_points) + # self.set_hit_box(self.texture.hit_box_points) # Default to face-right self.character_face_direction = RIGHT_FACING @@ -218,12 +210,11 @@ def setup(self): map_name = ":resources:/tiled_maps/pymunk_test_map.json" # Read in the tiled map - my_map = arcade.tilemap.read_map(map_name) + my_map = arcade.load_tilemap(map_name, SPRITE_SCALING_TILES) # --- Read in layers --- - self.wall_list = arcade.tilemap.process_layer(my_map, 'Platforms', SPRITE_SCALING_TILES) - self.item_list = arcade.tilemap.process_layer(my_map, 'Dynamic Items', SPRITE_SCALING_TILES) - + self.wall_list = my_map.sprite_lists["Platforms"] + self.item_list = my_map.sprite_lists["Dynamic Items"] # --- Pymunk Physics Engine Setup --- # The default damping for every object controls the percent of velocity @@ -258,7 +249,7 @@ def item_hit_handler(bullet_sprite, item_sprite, arbiter, space, data): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of intertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -268,7 +259,7 @@ def item_hit_handler(bullet_sprite, item_sprite, arbiter, space, data): friction=1.0, damping=0.4, mass=2, - moment=PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) @@ -293,7 +284,7 @@ def item_hit_handler(bullet_sprite, item_sprite, arbiter, space, data): def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ - bullet = arcade.SpriteSolidColor(20, 5, arcade.color.DARK_YELLOW) + bullet = arcade.SpriteSolidColor(width=20, height=5, color=arcade.color.DARK_YELLOW) self.bullet_list.append(bullet) # Position the bullet at the player's current location diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_05.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_05.py index d67dd174e..d89341a72 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_05.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_05.py @@ -1,7 +1,6 @@ """ Example of Pymunk Physics Engine Platformer """ -import math from typing import Optional import arcade @@ -124,7 +123,7 @@ def setup(self): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -133,7 +132,7 @@ def setup(self): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_06.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_06.py index 11d2821b0..29847d961 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_06.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_06.py @@ -1,7 +1,6 @@ """ Example of Pymunk Physics Engine Platformer """ -import math from typing import Optional import arcade @@ -126,7 +125,7 @@ def setup(self): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -135,7 +134,7 @@ def setup(self): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_07.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_07.py index 3786f3dda..acf86426d 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_07.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_07.py @@ -1,7 +1,6 @@ """ Example of Pymunk Physics Engine Platformer """ -import math from typing import Optional import arcade @@ -133,7 +132,7 @@ def setup(self): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -142,7 +141,7 @@ def setup(self): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_08.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_08.py index fb6ea16e3..582df00dd 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_08.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_08.py @@ -1,7 +1,6 @@ """ Example of Pymunk Physics Engine Platformer """ -import math from typing import Optional import arcade @@ -98,9 +97,6 @@ def __init__(self): # Set the initial texture self.texture = self.idle_texture_pair[0] - # Hit box will be set based on the first image used. - self.hit_box = self.texture.hit_box_points - # Default to face-right self.character_face_direction = RIGHT_FACING @@ -228,7 +224,7 @@ def setup(self): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -237,7 +233,7 @@ def setup(self): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_09.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_09.py index 3ea44d56f..d9f223cfa 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_09.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_09.py @@ -107,9 +107,6 @@ def __init__(self): # Set the initial texture self.texture = self.idle_texture_pair[0] - # Hit box will be set based on the first image used. - self.hit_box = self.texture.hit_box_points - # Default to face-right self.character_face_direction = RIGHT_FACING @@ -237,7 +234,7 @@ def setup(self): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -246,7 +243,7 @@ def setup(self): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) @@ -293,7 +290,7 @@ def on_key_release(self, key, modifiers): def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ - bullet = arcade.SpriteSolidColor(20, 5, arcade.color.DARK_YELLOW) + bullet = arcade.SpriteSolidColor(width=20, height=5, color=arcade.color.DARK_YELLOW) self.bullet_list.append(bullet) # Position the bullet at the player's current location diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_10.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_10.py index fdcbfaaa9..775192ef4 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_10.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_10.py @@ -107,9 +107,6 @@ def __init__(self): # Set the initial texture self.texture = self.idle_texture_pair[0] - # Hit box will be set based on the first image used. - self.hit_box = self.texture.hit_box_points - # Default to face-right self.character_face_direction = RIGHT_FACING @@ -259,7 +256,7 @@ def item_hit_handler(bullet_sprite, item_sprite, _arbiter, _space, _data): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -268,7 +265,7 @@ def item_hit_handler(bullet_sprite, item_sprite, _arbiter, _space, _data): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) @@ -315,7 +312,7 @@ def on_key_release(self, key, modifiers): def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ - bullet = BulletSprite(20, 5, arcade.color.DARK_YELLOW) + bullet = BulletSprite(width=20, height=5, color=arcade.color.DARK_YELLOW) self.bullet_list.append(bullet) # Position the bullet at the player's current location diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_11.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_11.py index baf63b4fc..4b3aac1fa 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_11.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_11.py @@ -107,9 +107,6 @@ def __init__(self): # Set the initial texture self.texture = self.idle_texture_pair[0] - # Hit box will be set based on the first image used. - self.hit_box = self.texture.hit_box_points - # Default to face-right self.character_face_direction = RIGHT_FACING @@ -227,9 +224,7 @@ def setup(self): self.player_list.append(self.player_sprite) # Moving Sprite - self.moving_sprites_list = arcade.tilemap.process_layer(my_map, - 'Moving Platforms', - SPRITE_SCALING_TILES) + self.moving_sprites_list = tile_map.sprite_lists['Moving Platforms'] # --- Pymunk Physics Engine Setup --- @@ -265,7 +260,7 @@ def item_hit_handler(bullet_sprite, item_sprite, _arbiter, _space, _data): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of inertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -274,7 +269,7 @@ def item_hit_handler(bullet_sprite, item_sprite, _arbiter, _space, _data): self.physics_engine.add_sprite(self.player_sprite, friction=PLAYER_FRICTION, mass=PLAYER_MASS, - moment=arcade.PymunkPhysicsEngine.MOMENT_INF, + moment_of_inertia=arcade.PymunkPhysicsEngine.MOMENT_INF, collision_type="player", max_horizontal_velocity=PLAYER_MAX_HORIZONTAL_SPEED, max_vertical_velocity=PLAYER_MAX_VERTICAL_SPEED) @@ -325,7 +320,7 @@ def on_key_release(self, key, modifiers): def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ - bullet = BulletSprite(20, 5, arcade.color.DARK_YELLOW) + bullet = BulletSprite(width=20, height=5, color=arcade.color.DARK_YELLOW) self.bullet_list.append(bullet) # Position the bullet at the player's current location diff --git a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_12.py b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_12.py index 96cc4bdd5..c07c38100 100644 --- a/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_12.py +++ b/doc/tutorials/pymunk_platformer/pymunk_demo_platformer_12.py @@ -117,9 +117,6 @@ def __init__(self, # Set the initial texture self.texture = self.idle_texture_pair[0] - # Hit box will be set based on the first image used. - self.hit_box = self.texture.hit_box_points - # Default to face-right self.character_face_direction = RIGHT_FACING @@ -307,7 +304,7 @@ def item_hit_handler(bullet_sprite, item_sprite, _arbiter, _space, _data): # For the player, we set the damping to a lower value, which increases # the damping rate. This prevents the character from traveling too far # after the player lets off the movement keys. - # Setting the moment to PymunkPhysicsEngine.MOMENT_INF prevents it from + # Setting the moment of intertia to PymunkPhysicsEngine.MOMENT_INF prevents it from # rotating. # Friction normally goes between 0 (no friction) and 1.0 (high friction) # Friction is between two objects in contact. It is important to remember @@ -375,7 +372,7 @@ def on_key_release(self, key, modifiers): def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ - bullet = BulletSprite(20, 5, arcade.color.DARK_YELLOW) + bullet = BulletSprite(width=20, height=5, color=arcade.color.DARK_YELLOW) self.bullet_list.append(bullet) # Position the bullet at the player's current location diff --git a/doc/tutorials/raycasting/example.py b/doc/tutorials/raycasting/example.py index d010da430..404b8fad6 100644 --- a/doc/tutorials/raycasting/example.py +++ b/doc/tutorials/raycasting/example.py @@ -1,4 +1,5 @@ import random + import arcade from arcade.experimental import Shadertoy @@ -71,8 +72,7 @@ def generate_sprites(self): self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list) def load_shader(self): - file_name = "example.glsl" - file = open(file_name) + file = open("example.glsl") shader_sourcecode = file.read() size = self.width, self.height diff --git a/doc/tutorials/raycasting/index.rst b/doc/tutorials/raycasting/index.rst index bb45c5052..7a4e1d593 100644 --- a/doc/tutorials/raycasting/index.rst +++ b/doc/tutorials/raycasting/index.rst @@ -42,7 +42,7 @@ We'll modify our prior program to import the Shadertoy class: .. literalinclude:: step_01.py :caption: Import Shadertoy - :lines: 5 + :lines: 4 Next, we'll need some shader-related variables. In addition to a variable to hold the shader, we are also going to need to keep track of a couple **frame buffer objects** (FBOs). You can store image data in an @@ -64,7 +64,7 @@ We will use the ``channel1`` variable to hold the ground, bombs, or anything we want to be hidden by shadows. .. literalinclude:: step_01.py - :caption: Create shader variables + :caption: Create & initialize shader variables :pyobject: MyGame.__init__ :emphasize-lines: 4-8 @@ -390,10 +390,11 @@ What if you need to resize the window? First enable resizing: You'll need to enable resizing in the window's ``__init__``: .. literalinclude:: step_07.py + :pyobject: MyGame.__init__ :caption: Enable resizing :language: python - :lines: 24-27 - :emphasize-lines: 4 + :lines: 1-2 + :emphasize-lines: 2 Then we need to override the ``Window.resize`` method to also resize the shadertoy: @@ -420,8 +421,8 @@ screen as something for the GUI. :emphasize-lines: 17-19, 23-24 Next up, we need to draw and use the cameras. This complicates our shader as it doesn't -care about the scrolling, so we have to pass it a position not effected by the camera position. -Thus we subtract it out. +care about the scrolling, so we have to pass it a position not affected by the camera position. +Therefore, we subtract it out. .. literalinclude:: step_08.py :caption: MyGame.on_draw @@ -437,7 +438,17 @@ When we update, we need to scroll the camera to where the user is: :linenos: :emphasize-lines: 7-8 -We need that new function: +We need to implement the ``scroll_to_player`` method ourselves. + +First, we import pyglet's :class:`~pyglet.math.Vec2` class to +make the math faster to implement: + +.. literalinclude:: step_08.py + :caption: Import pyglet's 2D vector class to help with math + :lines: 1-5 + :emphasize-lines: 2 + +Then, we implement the ``MyGame.scroll_to_player`` method: .. literalinclude:: step_08.py :caption: MyGame.scroll_to_player diff --git a/doc/tutorials/raycasting/step_01.py b/doc/tutorials/raycasting/step_01.py index 839f1c45f..730b595a0 100644 --- a/doc/tutorials/raycasting/step_01.py +++ b/doc/tutorials/raycasting/step_01.py @@ -1,5 +1,4 @@ import random -from pathlib import Path import arcade from arcade.experimental import Shadertoy @@ -42,14 +41,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_01.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_01.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_03.py b/doc/tutorials/raycasting/step_03.py index a7acebf52..57ac7a276 100644 --- a/doc/tutorials/raycasting/step_03.py +++ b/doc/tutorials/raycasting/step_03.py @@ -1,5 +1,4 @@ import random -from pathlib import Path import arcade from arcade.experimental import Shadertoy @@ -42,14 +41,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_03.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_03.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_04.py b/doc/tutorials/raycasting/step_04.py index e6eadff80..af6308934 100644 --- a/doc/tutorials/raycasting/step_04.py +++ b/doc/tutorials/raycasting/step_04.py @@ -1,5 +1,4 @@ import random -from pathlib import Path import arcade from arcade.experimental import Shadertoy @@ -42,14 +41,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_04.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_04.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_05.py b/doc/tutorials/raycasting/step_05.py index 853169327..dadfe7728 100644 --- a/doc/tutorials/raycasting/step_05.py +++ b/doc/tutorials/raycasting/step_05.py @@ -1,5 +1,4 @@ import random -from pathlib import Path import arcade from arcade.experimental import Shadertoy @@ -42,14 +41,12 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_05.glsl") # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_05.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_06.py b/doc/tutorials/raycasting/step_06.py index 3fb73eb71..e21631442 100644 --- a/doc/tutorials/raycasting/step_06.py +++ b/doc/tutorials/raycasting/step_06.py @@ -1,6 +1,4 @@ import random -from pathlib import Path -from pyglet.math import Vec2 import arcade from arcade.experimental import Shadertoy @@ -43,14 +41,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_06.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_06.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_07.py b/doc/tutorials/raycasting/step_07.py index 4ed8b173f..d889ec9d9 100644 --- a/doc/tutorials/raycasting/step_07.py +++ b/doc/tutorials/raycasting/step_07.py @@ -1,6 +1,4 @@ import random -from pathlib import Path -from pyglet.math import Vec2 import arcade from arcade.experimental import Shadertoy @@ -43,14 +41,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_06.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_06.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/raycasting/step_08.py b/doc/tutorials/raycasting/step_08.py index d03f7110c..cb425ad85 100644 --- a/doc/tutorials/raycasting/step_08.py +++ b/doc/tutorials/raycasting/step_08.py @@ -1,5 +1,4 @@ import random -from pathlib import Path from pyglet.math import Vec2 import arcade @@ -51,14 +50,11 @@ def __init__(self, width, height, title): self.background_color = arcade.color.ARMY_GREEN def load_shader(self): - # Where is the shader file? Must be specified as a path. - shader_file_path = Path("step_06.glsl") - # Size of the window window_size = self.get_size() - # Create the shader toy - self.shadertoy = Shadertoy.create_from_file(window_size, shader_file_path) + # Create the shader toy, passing in a path for the shader source + self.shadertoy = Shadertoy.create_from_file(window_size, "step_06.glsl") # Create the channels 0 and 1 frame buffers. # Make the buffer the size of the window, with 4 channels (RGBA) diff --git a/doc/tutorials/shader_toy_glow/index.rst b/doc/tutorials/shader_toy_glow/index.rst index 66726adf4..735342cf9 100644 --- a/doc/tutorials/shader_toy_glow/index.rst +++ b/doc/tutorials/shader_toy_glow/index.rst @@ -48,7 +48,7 @@ This program will load a GLSL program and display it. We'll write our shader in .. literalinclude:: shadertoy_demo_2.py :caption: Run a shader :linenos: - :emphasize-lines: 2, 11-14, 18 + :emphasize-lines: 2, 12-15, 19 .. note:: @@ -155,7 +155,7 @@ We can also change our color to orange. :caption: Adjusts fade speed :language: glsl :linenos: - :emphasize-lines: 15-16, 18-19 + :emphasize-lines: 19-20, 22-23 .. image:: circle_4.png :width: 60% @@ -171,7 +171,7 @@ look better. :caption: Tone mapping :language: glsl :linenos: - :emphasize-lines: 21-22 + :emphasize-lines: 25-26 .. image:: circle_5.png :width: 60% @@ -191,7 +191,7 @@ Python program: .. literalinclude:: shadertoy_demo_3.py :caption: Run a shader :linenos: - :emphasize-lines: 17-19 + :emphasize-lines: 17-20 Then we can use those uniforms in our shader: @@ -199,7 +199,7 @@ Then we can use those uniforms in our shader: :caption: Glow follows mouse, and color can be changed. :language: glsl :linenos: - :emphasize-lines: 1-2, 8, 11, 23 + :emphasize-lines: 3-4, 12, 15, 27 .. image:: circle_6.png :width: 60% diff --git a/doc/tutorials/shader_toy_glow/shadertoy_demo_2.py b/doc/tutorials/shader_toy_glow/shadertoy_demo_2.py index 1d979ea79..d89c3449b 100644 --- a/doc/tutorials/shader_toy_glow/shadertoy_demo_2.py +++ b/doc/tutorials/shader_toy_glow/shadertoy_demo_2.py @@ -1,6 +1,7 @@ import arcade from arcade.experimental import Shadertoy + # Derive an application window from Arcade's parent Window class class MyGame(arcade.Window): diff --git a/doc/tutorials/shader_toy_glow/shadertoy_demo_3.py b/doc/tutorials/shader_toy_glow/shadertoy_demo_3.py index 5a691f9aa..b0b1ed2f7 100644 --- a/doc/tutorials/shader_toy_glow/shadertoy_demo_3.py +++ b/doc/tutorials/shader_toy_glow/shadertoy_demo_3.py @@ -1,6 +1,7 @@ import arcade from arcade.experimental import Shadertoy + # Derive an application window from Arcade's parent Window class class MyGame(arcade.Window): diff --git a/tests/integration/examples/run_all_examples.py b/tests/integration/examples/run_all_examples.py index e7ac47d5a..2e293294a 100644 --- a/tests/integration/examples/run_all_examples.py +++ b/tests/integration/examples/run_all_examples.py @@ -8,7 +8,7 @@ import os import glob -EXAMPLE_SUBDIR = "../../arcade/examples" +EXAMPLE_SUBDIR = "../../../arcade/examples" def _get_short_name(fullpath): diff --git a/tests/integration/examples/test_all_examples.py b/tests/integration/examples/test_all_examples.py index adf8a6ce7..437fec4ec 100644 --- a/tests/integration/examples/test_all_examples.py +++ b/tests/integration/examples/test_all_examples.py @@ -2,9 +2,8 @@ Run All Examples If Python and Arcade are installed, this example can be run from the command line with: -python -m tests.test_examples.run_all_examples +python -m tests.test_examples.test_all_examples """ -import pyglet import glob import os import subprocess diff --git a/tests/integration/tutorials/__init__.py b/tests/integration/tutorials/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/integration/tutorials/run_all_tutorials.py b/tests/integration/tutorials/run_all_tutorials.py new file mode 100644 index 000000000..3abd1c36f --- /dev/null +++ b/tests/integration/tutorials/run_all_tutorials.py @@ -0,0 +1,67 @@ +""" +Run All tutorials + +If Python and Arcade are installed, this tutorial can be run from the command line with: +python -m tests.test_tutorials.run_all_tutorials +""" +import glob +import subprocess +import os +from pathlib import Path + +TUTORIAL_SUBDIR = "../../../doc/tutorials/" + + +def _get_short_name(fullpath): + return os.path.splitext(os.path.basename(fullpath))[0] + +def _get_tutorials(start_path): + query_path = os.path.join(start_path, "*.py") + tutorials = glob.glob(query_path) + tutorials = [_get_short_name(e) for e in tutorials] + tutorials = [e for e in tutorials if e != "run_all_tutorials"] + tutorials = [e for e in tutorials if not e.startswith('_')] + tutorials = [f"doc.tutorials.{start_path.name}." + e for e in tutorials if not e.startswith('_')] + return tutorials + +def run_tutorials(indices_in_range = None, index_skip_list = None): + """Run all tutorials in the doc/tutorials directory""" + for tutorial_subdir in [path for path in list(Path.cwd().joinpath(TUTORIAL_SUBDIR).iterdir()) if path.is_dir()]: + tutorials = _get_tutorials(tutorial_subdir) + tutorials.sort() + print(f"Found {len(tutorials)} tutorials in {tutorial_subdir}") + + file_path = os.path.dirname(os.path.abspath(__file__)) + print(file_path) + os.chdir(file_path+"/../..") + # run tutorials + for (idx, tutorial) in enumerate(tutorials): + if indices_in_range is not None and idx not in indices_in_range: + continue + if index_skip_list is not None and idx in index_skip_list: + continue + print(f"=================== tutorial {idx + 1:3} of {len(tutorials)}: {tutorial}") + # print('%s %s (index #%d of %d)' % ('=' * 20, tutorial, idx, len(tutorials) - 1)) + + # Directly call venv, necessary for github action runner + cmd = 'python -m ' + tutorial + + # print(cmd) + result = subprocess.check_output(cmd, shell=True) + if result: + print(f"ERROR: Got a result of: {result}.") + +def all_tutorials(): + file_path = os.path.dirname(os.path.abspath(__file__)) + os.chdir(file_path) + + # Set an environment variable that will just run on_update() and on_draw() + # once, then quit. + os.environ['ARCADE_TEST'] = "TRUE" + + indices_in_range = None + index_skip_list = None + run_tutorials(indices_in_range, index_skip_list) + + +all_tutorials() diff --git a/tests/integration/tutorials/test_all_tutoirals.py b/tests/integration/tutorials/test_all_tutoirals.py new file mode 100644 index 000000000..aeb94419b --- /dev/null +++ b/tests/integration/tutorials/test_all_tutoirals.py @@ -0,0 +1,76 @@ +""" +Run All tutorials + +If Python and Arcade are installed, this tutorial can be run from the command line with: +python -m tests.test_tutorials.test_all_tutorials +""" +import glob +import os +import subprocess +from pathlib import Path + +import pytest + +TUTORIAL_SUBDIR = "../../../doc/tutorials/" +# These tutorials are allowed to print to stdout +ALLOW_STDOUT = set() + +def _get_short_name(fullpath): + return os.path.splitext(os.path.basename(fullpath))[0] + +def _get_tutorials(start_path): + query_path = os.path.join(start_path, "*.py") + tutorials = glob.glob(query_path) + tutorials = [_get_short_name(e) for e in tutorials] + tutorials = [e for e in tutorials if e != "run_all_tutorials"] + tutorials = [e for e in tutorials if not e.startswith('_')] + tutorials = [f"{e}.py" for e in tutorials if not e.startswith('_')] + return tutorials + +def find_tutorials(indices_in_range, index_skip_list): + """List all tutorials in the doc/tutorials directory""" + file_dir = Path(__file__).parent + for tutorial_subdir in [path for path in list((file_dir / TUTORIAL_SUBDIR).iterdir()) if path.is_dir()]: + tutorials = _get_tutorials(tutorial_subdir) + tutorials.sort() + print(f"Found {len(tutorials)} tutorials in {tutorial_subdir}") + if len(tutorials) == 0: + continue + print(tutorial_subdir) + # os.chdir(tutorial_subdir) + for (idx, tutorial) in enumerate(tutorials): + if indices_in_range is not None and idx not in indices_in_range: + continue + if index_skip_list is not None and idx in index_skip_list: + continue + + allow_stdout = tutorial in ALLOW_STDOUT + yield f'python {tutorial}', allow_stdout, tutorial_subdir + # os.chdir("../") + + +def list_tutorials(indices_in_range, index_skip_list): + file_path = os.path.dirname(os.path.abspath(__file__)) + os.chdir(file_path) + + return list(find_tutorials(indices_in_range, index_skip_list)) + + +@pytest.mark.parametrize( + "cmd, allow_stdout, tutorial_subdir", + argvalues=list_tutorials( + indices_in_range=None, + index_skip_list=None + ) +) +def test_all(cmd, allow_stdout, tutorial_subdir): + # Set an environment variable that will just run on_update() and on_draw() + # once, then quit. + import pyglet + test_env = os.environ.copy() + test_env["ARCADE_TEST"] = "TRUE" + os.chdir(tutorial_subdir) + result = subprocess.check_output(cmd, shell=True, env=test_env) + if result and not allow_stdout: + print(f"ERROR: Got a result of: {result}.") + assert not result