Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wildcard collision handler #136

Open
davidrahd opened this issue Apr 11, 2018 · 5 comments
Open

Wildcard collision handler #136

davidrahd opened this issue Apr 11, 2018 · 5 comments

Comments

@davidrahd
Copy link

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.

@viblo
Copy link
Owner

viblo commented Apr 12, 2018

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)

@davidrahd
Copy link
Author

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

@viblo
Copy link
Owner

viblo commented Apr 18, 2018

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

@russ-smith
Copy link

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?

@viblo
Copy link
Owner

viblo commented Jun 26, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants