[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Limited Range?



On Wed, Nov 04, 2009 at 05:23:42PM +0000, Kris Schnee wrote:
> On Wed, 4 Nov 2009 09:21:58 -0800, James Paige <Bob@xxxxxxxxxxxxxxxxxxx>
> wrote:
> > A quick test with the timeit module suggest that the ** operator is not
> > slower.
> 
> > Here is how I would write the distance check:
> > 
> > def is_in_range(enemy, tower):
> >   return (enemy.x-tower.x)**2 + (enemy.y-tower.y)**2 <= tower.range**2
> 
> If speed is important, how about trying a cruder orthogonal method?
> 
> def IsInRange(enemy,tower):
>     return (enemy.x-tower.x) + (enemy.y-tower.y) <= tower.range

Did you mean?:

def IsInRange(enemy,tower):
    return abs(enemy.x-tower.x) + abs(enemy.y-tower.y) <= tower.range

That gives you a diamond-shaped range instead of a round range, which 
would be fine for some games, but maybe not a tower defence game.

I was curious how much faster it would be, so I ran some tests:

james@rhinoctopus:~/tmp$ ./timeit.py -n 10000000 'import range1'
15 10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . # . . . . . . . . . . . . . . 
. . . . . . . . . . . . # # # # # # # . . . . . . . . . . . 
. . . . . . . . . . # # # # # # # # # # # . . . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . # # # # # # # # X # # # # # # # # . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . . . # # # # # # # # # # # . . . . . . . . . 
. . . . . . . . . . . . # # # # # # # . . . . . . . . . . . 
. . . . . . . . . . . . . . . # . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
10000000 loops, best of 3: 0.976 usec per loop
james@rhinoctopus:~/tmp$ ./timeit.py -n 10000000 'import range2'
15 10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . # . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . # # # . . . . . . . . . . . . . 
. . . . . . . . . . . . . # # # # # . . . . . . . . . . . . 
. . . . . . . . . . . . # # # # # # # . . . . . . . . . . . 
. . . . . . . . . . . # # # # # # # # # . . . . . . . . . . 
. . . . . . . . . . # # # # # # # # # # # . . . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . # # # # # # # # X # # # # # # # # . . . . . . 
. . . . . . . . # # # # # # # # # # # # # # # . . . . . . . 
. . . . . . . . . # # # # # # # # # # # # # . . . . . . . . 
. . . . . . . . . . # # # # # # # # # # # . . . . . . . . . 
. . . . . . . . . . . # # # # # # # # # . . . . . . . . . . 
. . . . . . . . . . . . # # # # # # # . . . . . . . . . . . 
. . . . . . . . . . . . . # # # # # . . . . . . . . . . . . 
. . . . . . . . . . . . . . # # # . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . # . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
10000000 loops, best of 3: 0.969 usec per loop

So I think the difference is too small to be worth it.

range1 and range2 are just two copies of this script, with one of the 
tests commented out at the end:


#!/usr/bin/env python

width = 30
height = 20

center_x = int(width / 2)
center_y = int(height / 2)

radius = 8

print center_x, center_y

def in_range(x1, y1, x2, y2, r):
  return (x1 - x2)**2 + (y1 - y2)**2 <= r**2

def in_ortho_range(x1, y1, x2, y2, r):
  return abs(x1 - x2) + abs(y1 - y2) <= r

def draw_field(dist_func):
  for y in xrange(height):
    for x in xrange(width):
      if x == center_x and y == center_y:
        print "X",
      elif dist_func(x, y, center_x, center_y, radius):
        print "#",
      else:
        print ".",
    print ""

draw_field(in_range)
draw_field(in_ortho_range)