Easing Example 1
easing_example_1.py
1"""
2Easing Example 1
3
4Demonstrate the different easing functions available in :py:mod:`arcade.anim`.
5Each ball uses a different easing curve to travel from left to right, making it
6easy to compare the visual character of each curve.
7
8If Python and Arcade are installed, this example can be run from the command line with:
9python -m arcade.examples.easing_example_1
10"""
11
12import arcade
13from arcade.anim import ease, Easing
14
15# --- Constants ---
16WINDOW_WIDTH = 1280
17WINDOW_HEIGHT = 720
18WINDOW_TITLE = "Easing Example 1"
19
20X_START = 40
21X_END = 1200
22Y_INTERVAL = 60
23BALL_RADIUS = 13
24LINE_WIDTH = 1.0
25TRAVEL_TIME = 3.0
26
27BACKGROUND_COLOR = arcade.types.Color.from_hex_string("#F5D167")
28TEXT_COLOR = arcade.types.Color.from_hex_string("#4B1DF2")
29BALL_COLOR = arcade.types.Color.from_hex_string("#42B5EB")
30LINE_COLOR = arcade.types.Color.from_hex_string("#45E6D0")
31
32# Each entry is (label, easing function).
33EASING_LIST = [
34 ("LINEAR", Easing.LINEAR),
35 ("QUAD_OUT", Easing.QUAD_OUT),
36 ("QUAD_IN", Easing.QUAD_IN),
37 ("SINE", Easing.SINE),
38 ("QUAD", Easing.QUAD),
39 ("ELASTIC_OUT", Easing.ELASTIC_OUT),
40 ("BACK_IN", Easing.BACK_IN),
41 ("BACK_OUT", Easing.BACK_OUT),
42 ("SINE_IN", Easing.SINE_IN),
43 ("SINE_OUT", Easing.SINE_OUT),
44 ("BOUNCE_OUT", Easing.BOUNCE_OUT),
45]
46
47
48class EasingCircle(arcade.SpriteCircle):
49 """A ball that eases along the x-axis using a specific curve."""
50
51 def __init__(self, radius: int, color: arcade.types.RGBOrA255,
52 ease_function: Easing):
53 super().__init__(radius, color)
54 self.ease_function = ease_function
55 self.start_time = 0.0
56
57
58class GameView(arcade.View):
59 """Main view showing all easing balls."""
60
61 def __init__(self):
62 super().__init__()
63 self.background_color = BACKGROUND_COLOR
64 self.ball_list: arcade.SpriteList[EasingCircle] | None = None
65 self.time_elapsed = 0.0
66
67 def setup(self):
68 """Create one ball per easing function."""
69 self.ball_list = arcade.SpriteList()
70 self.time_elapsed = 0.0
71
72 for index, (label, ease_func) in enumerate(EASING_LIST):
73 ball = EasingCircle(BALL_RADIUS, BALL_COLOR, ease_func)
74 ball_y = WINDOW_HEIGHT - (index + 1) * Y_INTERVAL
75 ball.center_x = X_START
76 ball.center_y = ball_y
77 ball.start_time = 0.0
78 self.ball_list.append(ball)
79
80 def on_draw(self):
81 """Render the scene."""
82 self.clear()
83
84 for index, (label, _ease_func) in enumerate(EASING_LIST):
85 ball_y = WINDOW_HEIGHT - (index + 1) * Y_INTERVAL
86
87 # Horizontal guide line
88 arcade.draw_line(X_START, ball_y, X_END, ball_y, LINE_COLOR, LINE_WIDTH)
89
90 # Label for this easing function
91 arcade.draw_text(
92 label,
93 X_END + 10,
94 ball_y,
95 color=TEXT_COLOR,
96 font_size=10,
97 anchor_y="center",
98 )
99
100 # Draw all balls
101 self.ball_list.draw()
102
103 # Instructions
104 arcade.draw_text(
105 "Click to restart",
106 WINDOW_WIDTH // 2,
107 20,
108 color=TEXT_COLOR,
109 font_size=14,
110 anchor_x="center",
111 anchor_y="center",
112 )
113
114 def on_update(self, delta_time: float):
115 """Update ball positions using the easing functions."""
116 self.time_elapsed += delta_time
117
118 for ball in self.ball_list:
119 eased_x = ease(
120 X_START, X_END,
121 ball.start_time, ball.start_time + TRAVEL_TIME,
122 self.time_elapsed,
123 func=ball.ease_function,
124 )
125 ball.center_x = eased_x
126
127 def on_mouse_press(self, x: int, y: int, button: int, modifiers: int):
128 """Restart the animation on click."""
129 for ball in self.ball_list:
130 ball.start_time = self.time_elapsed
131
132
133def main():
134 """Main function."""
135 window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
136 game = GameView()
137 game.setup()
138 window.show_view(game)
139 arcade.run()
140
141
142if __name__ == "__main__":
143 main()