Performance Statistics#

Arcade includes performance monitoring tools to help you optimize your game. This example demonstrates the following performance api features:
If you do not want to display graphs in your game window, you can use
arcade.print_timings()
to print out the count and average time for
all dispatched events with the function. The output looks like this:
Event Count Average Time
-------------- ----- ------------
on_activate 1 0.0000
on_resize 1 0.0000
on_show 1 0.0000
on_update 59 0.0000
on_expose 1 0.0000
on_draw 59 0.0021
on_mouse_enter 1 0.0000
on_mouse_motion 100 0.0000
See Performance Information for more information about the performance api.
performance_statistics.py#
1"""
2Performance Statistic Display Example
3
4This example demonstrates how to use a few performance profiling tools
5built into arcade:
6
7* arcade.enable_timings
8* arcade.PerfGraph
9* arcade.get_fps
10* arcade.print_timings
11* arcade.clear_timings
12
13A large number of sprites bounce around the screen to produce load. You
14can adjust the number of sprites by changing the COIN_COUNT constant.
15
16Artwork from https://kenney.nl
17
18If Python and Arcade are installed, this example can be run from the
19command line with:
20python -m arcade.examples.performance_statistics
21"""
22import random
23from typing import Optional
24
25import arcade
26
27# --- Constants ---
28SPRITE_SCALING_COIN = 0.25
29SPRITE_NATIVE_SIZE = 128
30SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING_COIN)
31
32SCREEN_WIDTH = 800
33SCREEN_HEIGHT = 600
34SCREEN_TITLE = "Performance Statistics Display Example"
35
36# Size of performance graphs and distance between them
37GRAPH_WIDTH = 200
38GRAPH_HEIGHT = 120
39GRAPH_MARGIN = 5
40
41COIN_COUNT = 1500
42
43
44# Turn on tracking for the number of event handler
45# calls and the average execution time of each type.
46arcade.enable_timings()
47
48
49class Coin(arcade.BasicSprite):
50 """ Our coin sprite class """
51 def __init__(self, texture: arcade.Texture, scale: float):
52 super().__init__(texture, scale=scale)
53 # Add a velocity to the coin
54 self.change_x = 0
55 self.change_y = 0
56
57 def update(self):
58 """ Update the sprite. """
59 # Setting the position is faster than setting x & y individually
60 self.position = (
61 self.position[0] + self.change_x,
62 self.position[1] + self.change_y
63 )
64
65 # Bounce the coin on the edge of the window
66 if self.position[0] < 0:
67 self.change_x *= -1
68 elif self.position[0] > SCREEN_WIDTH:
69 self.change_x *= -1
70 if self.position[1] < 0:
71 self.change_y *= -1
72 elif self.position[1] > SCREEN_HEIGHT:
73 self.change_y *= -1
74
75
76class MyGame(arcade.Window):
77 """ Our custom Window Class"""
78
79 def __init__(self):
80 """ Initializer """
81 # Call the parent class initializer
82 super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
83
84 # Variables to hold game objects and performance info
85 self.coin_list: Optional[arcade.SpriteList] = None
86 self.perf_graph_list: Optional[arcade.SpriteList] = None
87 self.fps_text: Optional[arcade.Text] = None
88 self.frame_count: int = 0 # for tracking the reset interval
89
90 self.coin_texture = arcade.load_texture(":resources:images/items/coinGold.png")
91 self.background_color = arcade.color.AMAZON
92
93 def add_coins(self, amount):
94
95 # Create the coins
96 for i in range(amount):
97 # Create the coin instance
98 # Coin image from kenney.nl
99 coin = Coin(self.coin_texture, scale=SPRITE_SCALING_COIN)
100
101 # Position the coin
102 coin.position = (
103 random.randrange(SPRITE_SIZE, SCREEN_WIDTH - SPRITE_SIZE),
104 random.randrange(SPRITE_SIZE, SCREEN_HEIGHT - SPRITE_SIZE)
105 )
106
107 coin.change_x = random.randrange(-3, 4)
108 coin.change_y = random.randrange(-3, 4)
109
110 # Add the coin to the lists
111 self.coin_list.append(coin)
112
113 def setup(self):
114 """ Set up the game and initialize the variables. """
115
116 # Sprite lists
117 self.coin_list = arcade.SpriteList(use_spatial_hash=False)
118
119 # Create some coins
120 self.add_coins(COIN_COUNT)
121
122 # Create a sprite list to put the performance graphs into
123 self.perf_graph_list = arcade.SpriteList()
124
125 # Calculate position helpers for the row of 3 performance graphs
126 row_y = self.height - GRAPH_HEIGHT / 2
127 starting_x = GRAPH_WIDTH / 2
128 step_x = GRAPH_WIDTH + GRAPH_MARGIN
129
130 # Create the FPS performance graph
131 graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="FPS")
132 graph.position = starting_x, row_y
133 self.perf_graph_list.append(graph)
134
135 # Create the on_update graph
136 graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="on_update")
137 graph.position = starting_x + step_x, row_y
138 self.perf_graph_list.append(graph)
139
140 # Create the on_draw graph
141 graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="on_draw")
142 graph.position = starting_x + step_x * 2, row_y
143 self.perf_graph_list.append(graph)
144
145 # Create a Text object to show the current FPS
146 self.fps_text = arcade.Text(
147 f"FPS: {arcade.get_fps(60):5.1f}",
148 10, 10, arcade.color.BLACK, 22
149 )
150
151 def on_draw(self):
152 """ Draw everything """
153
154 # Clear the screen
155 self.clear()
156
157 # Draw all the coin sprites
158 self.coin_list.draw()
159
160 # Draw the graphs
161 self.perf_graph_list.draw()
162
163 # Get & draw the FPS for the last 60 frames
164 if arcade.timings_enabled():
165 self.fps_text.value = f"FPS: {arcade.get_fps(60):5.1f}"
166 self.fps_text.draw()
167
168 def on_update(self, delta_time):
169 """ Update method """
170 self.frame_count += 1
171
172 # Print and clear timings every 60 frames
173 if self.frame_count % 60 == 0:
174 arcade.print_timings()
175 arcade.clear_timings()
176
177 # Move the coins
178 self.coin_list.update()
179
180 def on_key_press(self, symbol: int, modifiers: int):
181 if symbol == arcade.key.SPACE:
182 if arcade.timings_enabled():
183 arcade.disable_timings()
184 else:
185 arcade.enable_timings()
186
187
188def main():
189 """ Main function """
190 window = MyGame()
191 window.setup()
192 arcade.run()
193
194
195if __name__ == "__main__":
196 main()