Easing Example 1#

Easing Example

Source#

easing_example.py#
  1"""
  2Example showing how to use the easing functions for position.
  3
  4See:
  5https://easings.net/
  6...for a great guide on the theory behind how easings can work.
  7
  8See example 2 for how to use easings for angles.
  9
 10If Python and Arcade are installed, this example can be run from the command line with:
 11python -m arcade.examples.easing_example_1
 12"""
 13from __future__ import annotations
 14
 15import arcade
 16from arcade import easing
 17from arcade.types import Color
 18
 19SPRITE_SCALING = 0.5
 20
 21SCREEN_WIDTH = 800
 22SCREEN_HEIGHT = 600
 23SCREEN_TITLE = "Easing Example"
 24
 25BACKGROUND_COLOR = "#F5D167"
 26TEXT_COLOR = "#4B1DF2"
 27BALL_COLOR = "#42B5EB"
 28LINE_COLOR = "#45E6D0"
 29LINE_WIDTH = 3
 30
 31X_START = 40
 32X_END = 760
 33Y_INTERVAL = 50
 34BALL_RADIUS = 13
 35TIME = 3.0
 36
 37
 38class EasingCircle(arcade.SpriteCircle):
 39    """ Player class """
 40
 41    def __init__(self, radius, color):
 42        """ Set up the player """
 43
 44        # Call the parent init
 45        super().__init__(radius, color)
 46
 47        self.easing_x_data = None
 48        self.easing_y_data = None
 49
 50    def on_update(self, delta_time: float = 1 / 60):
 51        if self.easing_x_data is not None:
 52            done, self.center_x = easing.ease_update(self.easing_x_data, delta_time)
 53            if done:
 54                x = X_START
 55                if self.center_x < SCREEN_WIDTH / 2:
 56                    x = X_END
 57                ex, ey = easing.ease_position(self.position,
 58                                              (x, self.center_y),
 59                                              rate=180,
 60                                              ease_function=self.easing_x_data.ease_function)
 61                self.easing_x_data = ex
 62
 63        if self.easing_y_data is not None:
 64            done, self.center_y = easing.ease_update(self.easing_y_data, delta_time)
 65            if done:
 66                self.easing_y_data = None
 67
 68
 69class MyGame(arcade.Window):
 70    """ Main application class. """
 71
 72    def __init__(self, width, height, title):
 73        """ Initializer """
 74
 75        # Call the parent class initializer
 76        super().__init__(width, height, title)
 77
 78        # Set the background color
 79        self.background_color = Color.from_hex_string(BACKGROUND_COLOR)
 80
 81        self.ball_list = None
 82        self.text_list = []
 83        self.lines = None
 84
 85    def setup(self):
 86        """ Set up the game and initialize the variables. """
 87
 88        # Sprite lists
 89        self.ball_list = arcade.SpriteList()
 90        self.lines = arcade.shape_list.ShapeElementList()
 91
 92        def create_ball(ball_y, ease_function):
 93            ball = EasingCircle(BALL_RADIUS, Color.from_hex_string(BALL_COLOR))
 94            ball.position = X_START, ball_y
 95            p1 = ball.position
 96            p2 = (X_END, ball_y)
 97            ex, ey = easing.ease_position(p1, p2, time=TIME, ease_function=ease_function)
 98            ball.ease_function = ease_function
 99            ball.easing_x_data = ex
100            ball.easing_y_data = ey
101            return ball
102
103        def create_line(line_y):
104            line = arcade.shape_list.create_line(
105                X_START, line_y - BALL_RADIUS - LINE_WIDTH,
106                X_END, line_y - BALL_RADIUS,
107                line_color, line_width=LINE_WIDTH,
108            )
109            return line
110
111        def create_text(text_string):
112            text = arcade.Text(text_string, X_START, y - BALL_RADIUS, color=text_color, font_size=14)
113            return text
114
115        def add_item(item_y, ease_function, text):
116            ball = create_ball(item_y, ease_function)
117            self.ball_list.append(ball)
118            text = create_text(text)
119            self.text_list.append(text)
120            line = create_line(item_y)
121            self.lines.append(line)
122
123        text_color = Color.from_hex_string(TEXT_COLOR)
124        line_color = Color.from_hex_string(LINE_COLOR)
125
126        y = Y_INTERVAL
127        add_item(y, easing.linear, "Linear")
128
129        y += Y_INTERVAL
130        add_item(y, easing.ease_out, "Ease out")
131
132        y += Y_INTERVAL
133        add_item(y, easing.ease_in, "Ease in")
134
135        y += Y_INTERVAL
136        add_item(y, easing.smoothstep, "Smoothstep")
137
138        y += Y_INTERVAL
139        add_item(y, easing.ease_in_out, "Ease in/out")
140
141        y += Y_INTERVAL
142        add_item(y, easing.ease_out_elastic, "Ease out elastic")
143
144        y += Y_INTERVAL
145        add_item(y, easing.ease_in_back, "Ease in back")
146
147        y += Y_INTERVAL
148        add_item(y, easing.ease_out_back, "Ease out back")
149
150        y += Y_INTERVAL
151        add_item(y, easing.ease_in_sin, "Ease in sin")
152
153        y += Y_INTERVAL
154        add_item(y, easing.ease_out_sin, "Ease out sin")
155
156        y += Y_INTERVAL
157        add_item(y, easing.ease_in_out_sin, "Ease in out sin")
158
159    def on_draw(self):
160        """ Render the screen. """
161
162        # This command has to happen before we start drawing
163        self.clear()
164
165        self.lines.draw()
166
167        # Draw all the sprites.
168        self.ball_list.draw()
169
170        for text in self.text_list:
171            text.draw()
172
173    def on_update(self, delta_time):
174        """ Movement and game logic """
175
176        # Call update on all sprites (The sprites don't do much in this
177        # example though.)
178        self.ball_list.on_update(delta_time)
179
180
181def main():
182    """ Main function """
183    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
184    window.setup()
185    arcade.run()
186
187
188if __name__ == "__main__":
189    main()