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