Sprite Rotation Around a Point#
This non-interactive example demonstrates two applications of rotating a sprite around a point:
On the left, a beam spinning around a point in a circle
On the right, a platform rotating around a point while staying flat
Although this behavior is inspired by platformers, it could be useful for other types of games.
The base class used in this example offers circular movement with finer control than the one in Collect Coins that are Moving in a Circle.
For a related example demonstrating how to mix rotation around a point with user input, see Move By Keyboard, Fire Towards Mouse.
1"""
2Rotating Sprites Around Points
3
4Two minimal examples demonstrating how to rotate sprites around points
5and how you might apply them in a game.
6
7Artwork from https://kenney.nl
8
9If Python and Arcade are installed, this example can be run from the command line with:
10python -m arcade.examples.sprite_rotate_around_point
11"""
12from __future__ import annotations
13
14import arcade
15from arcade.math import rotate_point
16
17SCREEN_WIDTH = 800
18SCREEN_HEIGHT = 600
19QUARTER_WIDTH = SCREEN_WIDTH // 4
20HALF_HEIGHT = SCREEN_HEIGHT // 2
21
22
23SCREEN_TITLE = "Rotating Sprites Around Points"
24
25
26class RotatingSprite(arcade.Sprite):
27 """
28 This sprite subclass implements a generic rotate_around_point method.
29 """
30
31 def rotate_around_point(self, point, degrees, change_angle=True):
32 """
33 Rotate the sprite around a point by the set amount of degrees
34
35 You could remove the change_angle keyword and/or angle change
36 if you know that sprites will always or never change angle.
37
38 :param point: The point that the sprite will rotate about
39 :param degrees: How many degrees to rotate the sprite
40 :param change_angle: Whether the sprite's angle should also be adjusted.
41 """
42
43 # If change_angle is true, change the sprite's angle
44 if change_angle:
45 self.angle += degrees
46
47 # Move the sprite along a circle centered on the point by degrees
48 self.position = rotate_point(
49 self.center_x, self.center_y,
50 point[0], point[1], degrees)
51
52
53class ExampleWindow(arcade.Window):
54
55 def __init__(self):
56 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
57
58 self.sprites = arcade.SpriteList()
59
60 # This example is based off spinning lines of fire from Mario games
61 # See https://www.mariowiki.com/Fire_Bar for more information
62 self.left_rotating_laser_sprite = RotatingSprite(
63 ":resources:images/space_shooter/laserBlue01.png",
64 center_x=QUARTER_WIDTH + 26, center_y=HALF_HEIGHT)
65
66 self.laser_base_sprite = arcade.Sprite(
67 ":resources:images/tiles/boxCrate.png", scale=0.25,
68 center_x=QUARTER_WIDTH, center_y=HALF_HEIGHT)
69
70 self.laser_text = arcade.Text(
71 "change_angle = True",
72 QUARTER_WIDTH, SCREEN_HEIGHT // 2 - 150,
73 anchor_x='center')
74
75 # This example demonstrates how to make platforms rotate around a point
76 self.right_rotating_platform_sprite = RotatingSprite(
77 ":resources:images/tiles/grassHalf.png", scale=0.25,
78 center_x=3 * QUARTER_WIDTH + 50, center_y=HALF_HEIGHT)
79
80 self.platform_base_sprite = arcade.Sprite(
81 ":resources:images/tiles/boxCrate.png", scale=0.25,
82 center_x=3 * QUARTER_WIDTH, center_y=HALF_HEIGHT)
83
84 self.platform_text = arcade.Text(
85 "change_angle = False",
86 3 * QUARTER_WIDTH, HALF_HEIGHT - 150,
87 anchor_x='center')
88
89 self.sprites.extend([
90 self.laser_base_sprite,
91 self.left_rotating_laser_sprite,
92 self.platform_base_sprite,
93 self.right_rotating_platform_sprite])
94
95 def on_update(self, delta_time: float):
96 # Rotate the laser sprite and change its angle
97 self.left_rotating_laser_sprite.rotate_around_point(
98 self.laser_base_sprite.position,
99 120 * delta_time)
100
101 # Rotate the platform sprite but don't change its angle
102 self.right_rotating_platform_sprite.rotate_around_point(
103 self.platform_base_sprite.position,
104 60 * delta_time, False)
105
106 def on_draw(self):
107 # Draw the sprite list.
108 self.clear()
109 self.sprites.draw()
110
111 self.laser_text.draw()
112 self.platform_text.draw()
113
114
115def main():
116 window = ExampleWindow()
117 window.run()
118
119
120if __name__ == '__main__':
121 main()