forked from pythonarcade/arcade
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
1,054 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
""" | ||
Use Pymunk physics engine. | ||
For more info on Pymunk see: | ||
http://www.pymunk.org/en/latest/ | ||
To install pymunk: | ||
pip install pymunk | ||
Artwork from http://kenney.nl | ||
If Python and Arcade are installed, this example can be run from the command line with: | ||
python -m arcade.examples.pymunk_box_stacks | ||
Click and drag with the mouse to move the boxes. | ||
""" | ||
|
||
import arcade | ||
import pymunk | ||
import timeit | ||
import math | ||
import os | ||
|
||
SCREEN_WIDTH = 1800 | ||
SCREEN_HEIGHT = 800 | ||
|
||
|
||
class PhysicsSprite(arcade.Sprite): | ||
def __init__(self, pymunk_shape, filename): | ||
super().__init__(filename, center_x=pymunk_shape.body.position.x, center_y=pymunk_shape.body.position.y) | ||
self.pymunk_shape = pymunk_shape | ||
|
||
|
||
class CircleSprite(PhysicsSprite): | ||
def __init__(self, pymunk_shape, filename): | ||
super().__init__(pymunk_shape, filename) | ||
self.width = pymunk_shape.radius * 2 | ||
self.height = pymunk_shape.radius * 2 | ||
|
||
|
||
class BoxSprite(PhysicsSprite): | ||
def __init__(self, pymunk_shape, filename, width, height): | ||
super().__init__(pymunk_shape, filename) | ||
self.width = width | ||
self.height = height | ||
|
||
|
||
class MyGame(arcade.Window): | ||
""" Main application class. """ | ||
|
||
def __init__(self, width, height): | ||
super().__init__(width, height) | ||
|
||
# Set the working directory (where we expect to find files) to the same | ||
# directory this .py file is in. You can leave this out of your own | ||
# code, but it is needed to easily run the examples using "python -m" | ||
# as mentioned at the top of this program. | ||
file_path = os.path.dirname(os.path.abspath(__file__)) | ||
os.chdir(file_path) | ||
|
||
arcade.set_background_color(arcade.color.DARK_SLATE_GRAY) | ||
|
||
# -- Pymunk | ||
self.space = pymunk.Space() | ||
self.space.iterations = 35 | ||
self.space.gravity = (0.0, -900.0) | ||
|
||
# Lists of sprites or lines | ||
self.sprite_list = arcade.SpriteList() | ||
self.static_lines = [] | ||
|
||
# Used for dragging shapes around with the mouse | ||
self.shape_being_dragged = None | ||
self.last_mouse_position = 0, 0 | ||
|
||
self.draw_time = 0 | ||
self.processing_time = 0 | ||
|
||
# Create the floor | ||
floor_height = 80 | ||
body = pymunk.Body(body_type=pymunk.Body.STATIC) | ||
shape = pymunk.Segment(body, [0, floor_height], [SCREEN_WIDTH, floor_height], 0.0) | ||
shape.friction = 10 | ||
self.space.add(shape) | ||
self.static_lines.append(shape) | ||
|
||
# Create the stacks of boxes | ||
for row in range(10): | ||
for column in range(10): | ||
size = 32 | ||
mass = 1.0 | ||
x = 500 + column * 32 | ||
y = (floor_height + size / 2) + row * size | ||
moment = pymunk.moment_for_box(mass, (size, size)) | ||
body = pymunk.Body(mass, moment) | ||
body.position = pymunk.Vec2d(x, y) | ||
shape = pymunk.Poly.create_box(body, (size, size)) | ||
shape.elasticity = 0.2 | ||
shape.friction = 0.9 | ||
self.space.add(body, shape) | ||
# body.sleep() | ||
|
||
sprite = BoxSprite(shape, "images/boxCrate_double.png", width=size, height=size) | ||
self.sprite_list.append(sprite) | ||
|
||
def on_draw(self): | ||
""" | ||
Render the screen. | ||
""" | ||
|
||
# This command has to happen before we start drawing | ||
arcade.start_render() | ||
|
||
# Start timing how long this takes | ||
draw_start_time = timeit.default_timer() | ||
|
||
# Draw all the sprites | ||
self.sprite_list.draw() | ||
|
||
# Draw the lines that aren't sprites | ||
for line in self.static_lines: | ||
body = line.body | ||
|
||
pv1 = body.position + line.a.rotated(body.angle) | ||
pv2 = body.position + line.b.rotated(body.angle) | ||
arcade.draw_line(pv1.x, pv1.y, pv2.x, pv2.y, arcade.color.WHITE, 2) | ||
|
||
# Display timings | ||
output = f"Processing time: {self.processing_time:.3f}" | ||
arcade.draw_text(output, 20, SCREEN_HEIGHT - 20, arcade.color.WHITE, 12) | ||
|
||
output = f"Drawing time: {self.draw_time:.3f}" | ||
arcade.draw_text(output, 20, SCREEN_HEIGHT - 40, arcade.color.WHITE, 12) | ||
|
||
self.draw_time = timeit.default_timer() - draw_start_time | ||
|
||
def on_mouse_press(self, x, y, button, modifiers): | ||
if button == arcade.MOUSE_BUTTON_LEFT: | ||
self.last_mouse_position = x, y | ||
# See if we clicked on anything | ||
shape_list = self.space.point_query((x, y), 1, pymunk.ShapeFilter()) | ||
|
||
# If we did, remember what we clicked on | ||
if len(shape_list) > 0: | ||
self.shape_being_dragged = shape_list[0] | ||
|
||
elif button == arcade.MOUSE_BUTTON_RIGHT: | ||
# With right mouse button, shoot a heavy coin fast. | ||
mass = 60 | ||
radius = 10 | ||
inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) | ||
body = pymunk.Body(mass, inertia) | ||
body.position = x, y | ||
body.velocity = 2000, 0 | ||
shape = pymunk.Circle(body, radius, pymunk.Vec2d(0, 0)) | ||
shape.friction = 0.3 | ||
self.space.add(body, shape) | ||
|
||
sprite = CircleSprite(shape, "images/coin_01.png") | ||
self.sprite_list.append(sprite) | ||
|
||
def on_mouse_release(self, x, y, button, modifiers): | ||
if button == arcade.MOUSE_BUTTON_LEFT: | ||
# Release the item we are holding (if any) | ||
self.shape_being_dragged = None | ||
|
||
def on_mouse_motion(self, x, y, dx, dy): | ||
if self.shape_being_dragged is not None: | ||
# If we are holding an object, move it with the mouse | ||
self.last_mouse_position = x, y | ||
self.shape_being_dragged.shape.body.position = self.last_mouse_position | ||
self.shape_being_dragged.shape.body.velocity = dx * 20, dy * 20 | ||
|
||
def update(self, delta_time): | ||
start_time = timeit.default_timer() | ||
|
||
# Check for balls that fall off the screen | ||
for sprite in self.sprite_list: | ||
if sprite.pymunk_shape.body.position.y < 0: | ||
# Remove balls from physics space | ||
self.space.remove(sprite.pymunk_shape, sprite.pymunk_shape.body) | ||
# Remove balls from physics list | ||
sprite.kill() | ||
|
||
# Update physics | ||
# Use a constant time step, don't use delta_time | ||
# See "Game loop / moving time forward" | ||
# http://www.pymunk.org/en/latest/overview.html#game-loop-moving-time-forward | ||
self.space.step(1 / 60.0) | ||
|
||
# If we are dragging an object, make sure it stays with the mouse. Otherwise | ||
# gravity will drag it down. | ||
if self.shape_being_dragged is not None: | ||
self.shape_being_dragged.shape.body.position = self.last_mouse_position | ||
self.shape_being_dragged.shape.body.velocity = 0, 0 | ||
|
||
# Move sprites to where physics objects are | ||
for sprite in self.sprite_list: | ||
sprite.center_x = sprite.pymunk_shape.body.position.x | ||
sprite.center_y = sprite.pymunk_shape.body.position.y | ||
sprite.angle = math.degrees(sprite.pymunk_shape.body.angle) | ||
|
||
# Save the time it took to do this. | ||
self.processing_time = timeit.default_timer() - start_time | ||
|
||
|
||
def main(): | ||
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT) | ||
|
||
arcade.run() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import arcade | ||
|
||
class MyGame(arcade.Window): | ||
""" Our custom Window Class""" | ||
|
||
def __init__(self): | ||
super().__init__(800, 600, "Moving Sprite Stress Test") | ||
|
||
self.coin_list = arcade.SpriteList() | ||
|
||
arcade.set_background_color(arcade.color.AMAZON) | ||
|
||
def on_draw(self): | ||
arcade.start_render() | ||
|
||
|
||
MyGame() | ||
arcade.run() |
Oops, something went wrong.