pymunk icon indicating copy to clipboard operation
pymunk copied to clipboard

Wildcard collision handler

Open davidrahd opened this issue 6 years ago • 5 comments

for the lack of a better place to ask. I don't know if it is a issue or i'm doing things wrong but a wildcard collision handler isn't supposed to be called every time a certain type of shape collides? I've done something like that :

myshape = pymunk.Circle(mybody, radius) myshape.collision_type = 0 space.add(mybody, myshape)

def mybegin(): print('collision confirmed') return true

myhandler = space.add_wildcard_collision_handler(0) myhandler.begin = mybegin

with no results, the shapes collides as they do normally, but i never get the message 'collision confirmed'. Also when I use something like:

myhandler = space.add_collision_handler(0, 0) myhandler.begin = mybegin

I get the message 'collision confirmed' every time myshape collides with anything else, instead of only when 2 of myshape collide, the behavior I was expecting, because when using:

myshape1 = pymunk.Circle(mybody1, radius) myshape1.collision_type = 1 space.add(mybody1, myshape1)

myhandler = space.add_collision_handler(0, 1) myhandler.begin = mybegin

I only get the message 'collision confirmed' when myshape collides with myshape1, the behavior I assume is the intended.

davidrahd avatar Apr 11 '18 16:04 davidrahd

Its difficult to say without more code. See this example that will print out wildcard collision

import pymunk

space = pymunk.Space()

b1 = pymunk.Body(1,2)
c1 = pymunk.Circle(b1, 10)
c1.collision_type = 0
space.add(b1,c1)

b2 = pymunk.Body(1,2)
c2 = pymunk.Circle(b2, 10)
c2.collision_type = 1
space.add(b2,c2)

h = space.add_wildcard_collision_handler(0)
def f(*args):
    print('wildcard collision')
    return True

h.begin = f
space.step(1)

viblo avatar Apr 12 '18 21:04 viblo

your example worked, I tried a few different scenarios, and i think I know what I'm doing that is causing the issue. The issue only happens when i use a default_collision_handler with an wildcard_collision_handler in the same space:

import pyglet import pymunk from pymunk.pyglet_util import DrawOptions

window = pyglet.window.Window(600, 600, 'pymunk test') options = DrawOptions()

space = pymunk.Space() space.gravity = 0, -500

line = pymunk.Segment(space.static_body, (0, 10), (600, 10), 2) line.elasticity = 0.7 line.friction = 0.5 line.collision_type = 1 space.add(line)

circle_body = pymunk.Body(1, 999) circle_body.position = (300, 500) circle_shape = pymunk.Circle(circle_body, 50) circle_shape.elasticity = 0.7 circle_shape.friction = 0.9 circle_shape.collision_type = 0 space.add(circle_body, circle_shape)

circle_body = pymunk.Body(1, 999) circle_body.position = (300, 300) circle_shape = pymunk.Circle(circle_body, 50) circle_shape.elasticity = 0.7 circle_shape.friction = 0.9 circle_shape.collision_type = 0 space.add(circle_body, circle_shape)

def collision_begin(arbiter, space, data): print('a collision happen') return True

def circle_begin(arbiter, space, data): print('a circle collided') return True

def circle_circle_begin(arbiter, space, data): print('two circles collided') return True

#handler = space.add_default_collision_handler() #handler.begin = collision_begin circle_handler = space.add_wildcard_collision_handler(0) circle_handler.begin = circle_begin circle_circle_handler = space.add_collision_handler(0,0) circle_circle_handler.begin = circle_circle_begin

@window.event def on_draw(): window.clear() space.debug_draw(options)

def update(dt): space.step(dt)

if name == 'main' : pyglet.clock.schedule_interval(update, 1/60.0) pyglet.app.run()

this code returns:

a circle collided two circles collided a circle collided a circle collided a circle collided two circles collided two circles collided two circles collided two circles collided

uncommenting the two lines it returns:

a collision happen two circles collided a collision happen two circles collided a collision happen a collision happen a collision happen two circles collided a collision happen a collision happen two circles collided a collision happen two circles collided a collision happen

davidrahd avatar Apr 15 '18 06:04 davidrahd

Ah, ok, now I get the same result as you. I will do some more investigation as to why,

viblo avatar Apr 18 '18 06:04 viblo

I have a question that relates to this issue, dunno if it's worth opening another issue for so I'll leave a comment here for now. I'm trying to add both a wildcard collision handler for type 1 and a specific handler for types 1 and 2, but I want the wildcard handler to always be called. Currently, the specific handler overrides the wildcard when a shape of type 2 is involved. In the doc, it says you need to call the wildcard yourself using Arbiter.call_wildcard*() - however, this is the only mention of this function anywhere - it doesn't show up anywhere else in the docs or in the source code AFAICT. How should i call the wildcard from the specific handler?

russ-smith avatar Jun 26 '18 05:06 russ-smith

Oh, well spotted. It must be a leftover in the docs. I will update them when I have the chance. I think the best way to do what you want is to just call it manually like any other function.

viblo avatar Jun 26 '18 10:06 viblo