Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion arcade/geometry.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os

shapely_exists = False

try:
Expand All @@ -6,8 +8,10 @@
except ImportError:
pass

use_shapely = shapely_exists and not os.environ.get("DISABLE_SHAPELY")
print("Use shapely: " + str(use_shapely))

if shapely_exists:
if use_shapely:
from .geometry_shapely import are_polygons_intersecting # noqa: F401
from .geometry_shapely import is_point_in_polygon # noqa: F401
else:
Expand Down
11 changes: 10 additions & 1 deletion arcade/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@
Classic A-star algorithm for path finding.
"""
import sys
import os
from arcade.types import Point
from arcade import check_for_collision_with_list, SpriteList, Sprite
from typing import Union, List, Tuple, Set, Optional

if 'shapely' in sys.modules:
shapely_exists = False
try:
import shapely # noqa: F401
shapely_exists = True
except ImportError:
pass
use_shapely = shapely_exists and not os.environ.get("DISABLE_SHAPELY")
print("Use shapely for has_line_of_sight: " + str(use_shapely))
if use_shapely:
from .paths_shapely import has_line_of_sight # noqa: F401
else:
from .paths_python import has_line_of_sight # noqa: F401
Expand Down
3 changes: 3 additions & 0 deletions arcade/paths_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def has_line_of_sight(point_1: Point,
distance = get_distance(point_1[0], point_1[1],
point_2[0], point_2[1])
steps = int(distance // check_resolution)
if distance == 0:
sprite_list = get_sprites_at_point(point_1, walls)
return not (len(sprite_list) > 0)
for step in range(steps + 1):
step_distance = step * check_resolution
u = step_distance / distance
Expand Down
7 changes: 7 additions & 0 deletions benchmarks/bench-shapely-helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

if [ "$2" == "disabled" ]
then
export DISABLE_SHAPELY=true
fi
python -m benchmarks.$1.bench
18 changes: 18 additions & 0 deletions benchmarks/bench-shapely.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# On windows, can run via the bash you get with git:
# C:\Program Files\Git\bin\bash.exe

__dirname="$(CDPATH= cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$__dirname"
cd ..

bench_name="$1"

python.exe --version

hyperfine \
--show-output \
--export-markdown benchmarks/results.md \
--warmup 1 --runs 2 \
--parameter-list shapely 'enabled,disabled' \
'bash ./benchmarks/bench-shapely-helper.sh '"$bench_name"' {shapely}'
2 changes: 1 addition & 1 deletion benchmarks/collisions/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# like something I might create in a game.
rng.seed(2)
for i in range(0, WALLS_COUNT):
wall = arcade.SpriteSolidColor(rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), arcade.color.BLACK)
wall = arcade.SpriteSolidColor(rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), color=arcade.color.BLACK)
wall.position = rng.randint(0, SCREEN_WIDTH), rng.randint(0, SCREEN_HEIGHT)
walls.append(wall)

Expand Down
60 changes: 60 additions & 0 deletions benchmarks/line-of-sight/bench.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import math
import arcade
import pyglet
import random
import time

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

WALL_DIM_MIN = 10
WALL_DIM_MAX = 200
WALLS_COUNT = 10

SIMULATE_MINUTES = 0.1
SIMULATE_FPS = 60

# Predictable randomization so that each benchmark is identical
rng = random.Random(0)

walls = arcade.SpriteList(use_spatial_hash=True)

window = arcade.Window()

# Seed chosen manually to create a wall distribution that looked good enough,
# like something I might create in a game.
rng.seed(2)
for i in range(0, WALLS_COUNT):
wall = arcade.SpriteSolidColor(rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), rng.randint(WALL_DIM_MIN, WALL_DIM_MAX), color=arcade.color.BLACK)
wall.position = rng.randint(0, SCREEN_WIDTH), rng.randint(0, SCREEN_HEIGHT)
walls.append(wall)

# Check for line-of-sight
def check_ray():
x = rng.randint(0, SCREEN_WIDTH)
y = rng.randint(0, SCREEN_HEIGHT)
hit = arcade.has_line_of_sight(origin, (x, y), walls)
return x, y, hit

origin = (SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)
rays = []
for i in range(0, int(SIMULATE_MINUTES * 60 * SIMULATE_FPS)):
pyglet.clock.tick()

window.switch_to()
window.dispatch_events()

rays[:] = [check_ray() for x in range(1000)]

window.dispatch_event('on_draw')

window.clear(color=arcade.color.WHITE)
walls.draw()

# only draw a few:
# A) so the benchmark isn't dominated by slow draw_line calls
# B) to validate that the line-of-sight checks are accurate
# C) so you get a visual indicator of framerate
for ray in rays[:10]:
arcade.draw_line(origin[0], origin[1], ray[0], ray[1], arcade.color.BLUE if ray[2] else arcade.color.RED, 2)
window.flip()