Arcade Draw Moving Shapes Source Code

draw_shapes.py
  1"""
  2Moving Sprites Stress Test
  3"""
  4
  5import random
  6import os
  7import arcade
  8from performance_timing import PerformanceTiming
  9
 10# Set up the constants
 11SCREEN_WIDTH = 1800
 12SCREEN_HEIGHT = 1000
 13SCREEN_TITLE = "Arcade - Moving Shapes Non-Buffered"
 14
 15RECT_WIDTH = 50
 16RECT_HEIGHT = 50
 17
 18
 19class Shape:
 20    """ Generic base shape class """
 21    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
 22                 delta_angle, color):
 23        self.x = x
 24        self.y = y
 25        self.width = width
 26        self.height = height
 27        self.angle = angle
 28        self.delta_x = delta_x
 29        self.delta_y = delta_y
 30        self.delta_angle = delta_angle
 31        self.color = color
 32
 33    def move(self):
 34        self.x += self.delta_x
 35        self.y += self.delta_y
 36        self.angle += self.delta_angle
 37        if self.x < 0 and self.delta_x < 0:
 38            self.delta_x *= -1
 39        if self.y < 0 and self.delta_y < 0:
 40            self.delta_y *= -1
 41        if self.x > SCREEN_WIDTH and self.delta_x > 0:
 42            self.delta_x *= -1
 43        if self.y > SCREEN_HEIGHT and self.delta_y > 0:
 44            self.delta_y *= -1
 45
 46
 47class Ellipse(Shape):
 48
 49    def draw(self):
 50        arcade.draw_ellipse_filled(self.x, self.y, self.width, self.height,
 51                                   self.color, self.angle)
 52
 53
 54class Rectangle(Shape):
 55
 56    def draw(self):
 57        arcade.draw_rectangle_filled(self.x, self.y, self.width, self.height,
 58                                     self.color, self.angle)
 59
 60
 61class Line(Shape):
 62
 63    def draw(self):
 64        arcade.draw_line(self.x, self.y,
 65                         self.x + self.width, self.y + self.height,
 66                         self.color, 2)
 67
 68
 69class ShapeBuffered:
 70    """ Generic base shape class """
 71
 72    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
 73                 delta_angle, color):
 74        self.x = x
 75        self.y = y
 76        self.width = width
 77        self.height = height
 78        self.angle = angle
 79        self.delta_x = delta_x
 80        self.delta_y = delta_y
 81        self.delta_angle = delta_angle
 82        self.color = color
 83        self.shape_list = None
 84
 85    def move(self):
 86        self.x += self.delta_x
 87        self.y += self.delta_y
 88        if self.delta_angle:
 89            self.angle += self.delta_angle
 90        if self.x < 0 and self.delta_x < 0:
 91            self.delta_x *= -1
 92        if self.y < 0 and self.delta_y < 0:
 93            self.delta_y *= -1
 94        if self.x > SCREEN_WIDTH and self.delta_x > 0:
 95            self.delta_x *= -1
 96        if self.y > SCREEN_HEIGHT and self.delta_y > 0:
 97            self.delta_y *= -1
 98
 99    def draw(self):
100        self.shape_list.center_x = self.x
101        self.shape_list.center_y = self.y
102        # self.shape_list.angle = self.angle
103        self.shape_list.draw()
104
105
106class EllipseBuffered(ShapeBuffered):
107
108    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
109                 delta_angle, color):
110
111        super().__init__(x, y, width, height, angle, delta_x, delta_y,
112                         delta_angle, color)
113
114        shape = arcade.create_ellipse_filled(0, 0,
115                                             self.width, self.height,
116                                             self.color, self.angle)
117        self.shape_list = arcade.ShapeElementList()
118        self.shape_list.append(shape)
119
120
121class RectangleBuffered(ShapeBuffered):
122
123    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
124                 delta_angle, color):
125
126        super().__init__(x, y, width, height, angle, delta_x, delta_y,
127                         delta_angle, color)
128
129        shape = arcade.shape_list.create_rectangle_filled(0, 0,
130                                               self.width, self.height,
131                                               self.color, self.angle)
132        self.shape_list = arcade.shape_list.ShapeElementList()
133        self.shape_list.append(shape)
134
135
136class LineBuffered(ShapeBuffered):
137
138    def __init__(self, x, y, width, height, angle, delta_x, delta_y,
139                 delta_angle, color):
140
141        super().__init__(x, y, width, height, angle, delta_x, delta_y,
142                         delta_angle, color)
143
144        shape = arcade.shape_list.create_line(0, 0,
145                                   self.width, self.height,
146                                   self.color, 2)
147        self.shape_list = arcade.shape_list.ShapeElementList()
148        self.shape_list.append(shape)
149
150
151class MyGame(arcade.Window):
152    """ Main application class. """
153
154    def __init__(self, buffered):
155        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
156
157        self.shape_list = None
158        self.buffered = buffered
159
160        # Set the working directory (where we expect to find files) to the same
161        # directory this .py file is in. You can leave this out of your own
162        # code, but it is needed to easily run the examples using "python -m"
163        # as mentioned at the top of this program.
164        file_path = os.path.dirname(os.path.abspath(__file__))
165        os.chdir(file_path)
166
167        if self.buffered:
168            self.results_file = "../../result_data/arcade/moving_shapes_buffered.csv"
169            self.results_image = "../../result_data/arcade/moving_shapes_buffered.png"
170        else:
171            self.results_file = "../../result_data/arcade/moving_shapes_unbuffered.csv"
172            self.results_image = "../../result_data/arcade/moving_shapes_unbuffered.png"
173
174        self.performance_timing = PerformanceTiming(results_file=self.results_file,
175                                                    start_n=0,
176                                                    increment_n=20,
177                                                    end_time=60)
178
179    def setup(self):
180        """ Set up the game and initialize the variables. """
181        self.shape_list = []
182
183    def add_shapes(self, amount):
184        for i in range(amount):
185            x = random.randrange(0, SCREEN_WIDTH)
186            y = random.randrange(0, SCREEN_HEIGHT)
187            width = random.randrange(10, 30)
188            height = random.randrange(10, 30)
189            # angle = random.randrange(0, 360)
190            angle = 0
191
192            d_x = random.randrange(-3, 4)
193            d_y = random.randrange(-3, 4)
194            # d_angle = random.randrange(-3, 4)
195            d_angle = 0
196
197            red = random.randrange(256)
198            green = random.randrange(256)
199            blue = random.randrange(256)
200            alpha = random.randrange(256)
201
202            shape_type = random.randrange(1)
203            shape_type = 0
204
205            if not self.buffered:
206                if shape_type == 0:
207                    shape = Rectangle(x, y, width, height, angle, d_x, d_y,
208                                      d_angle, (red, green, blue, alpha))
209                elif shape_type == 1:
210                    shape = Ellipse(x, y, width, height, angle, d_x, d_y,
211                                d_angle, (red, green, blue, alpha))
212                elif shape_type == 2:
213                    shape = Line(x, y, width, height, angle, d_x, d_y,
214                                 d_angle, (red, green, blue, alpha))
215            else:
216                if shape_type == 0:
217                    shape = RectangleBuffered(x, y, width, height, angle, d_x, d_y,
218                                      d_angle, (red, green, blue, alpha))
219                elif shape_type == 1:
220                    shape = EllipseBuffered(x, y, width, height, angle, d_x, d_y,
221                                d_angle, (red, green, blue, alpha))
222                elif shape_type == 2:
223                    shape = LineBuffered(x, y, width, height, angle, d_x, d_y,
224                                 d_angle, (red, green, blue, alpha))
225
226            self.shape_list.append(shape)
227
228    def on_update(self, dt):
229        """ Move everything """
230
231        # Start update timer
232        self.performance_timing.start_timer('update')
233
234        for shape in self.shape_list:
235            shape.move()
236
237        # Stop timing the update
238        self.performance_timing.stop_timer('update')
239
240        # Figure out if we need more coins
241        if self.performance_timing.target_n > len(self.shape_list):
242            new_coin_amount = self.performance_timing.target_n - len(self.shape_list)
243            self.add_shapes(new_coin_amount)
244
245        # End the program run
246        if self.performance_timing.end_run():
247            # Save screenshot
248            image = arcade.get_image()
249            image.save(self.results_image, 'PNG')
250            self.close()
251
252    def on_draw(self):
253        """
254        Render the screen.
255        """
256        # Start timing how long this takes
257        self.performance_timing.start_timer('draw')
258
259        arcade.start_render()
260
261        for shape in self.shape_list:
262            shape.draw()
263
264        # Stop timing how long this takes
265        self.performance_timing.stop_timer('draw')
266
267
268def main(buffered):
269    window = MyGame(buffered)
270    window.setup()
271    arcade.run()
272
273
274if __name__ == "__main__":
275    # main(True)
276    main(False)