Top Down Racer - pymunk for collisions?

272 views
Skip to first unread message

dorzey

unread,
Aug 7, 2009, 7:31:47 PM8/7/09
to pyglet-users
I'm trying to create my first game and after some research it seems
pymunk might be a nice way to add some physics to my top down racing
game; or at least take care of collisions for me.

However, my attempt (http://pastebin.com/m6d5a81c1) to use it has
faltered. Whilst the body, shape and sprite all seem to be having
their position updated correctly my program fails to recognise, and
then handle, the collision. What am I doing wrong?

I'm probably missing something really obvious, but google and the
pymunk api don't seem to hold the answer.

I'd also be interested in links to any tutorials/examples on using
pymunk with pyglet.

Thanks,

Dorzey

Steve Johnson

unread,
Aug 7, 2009, 11:40:53 PM8/7/09
to pyglet-users
My unfinished work in progress Gluball uses pyglet extensively. I'm
afraid I don't have the time or energy to document it, but feel free
to peek at the source. In particular, check out gamelib/util/
physics.py, gamelib.body.SingleBody and gamelib.unit.Unit. I think
your problem is probably that you need to set your shapes'
collision_type or layer attributes. I don't remember which.

http://www.github.com/irskep/gluball

dorzey

unread,
Aug 8, 2009, 4:02:40 AM8/8/09
to pyglet-users
Setting the Shape's collision_type and layer attributes doesn't fix
the problem. I must be missing something else.

I'll study your code in more detail. I shall also try something a
little more basic in pymunk as well.

Thanks for the help,

Dorzey

Tartley

unread,
Aug 8, 2009, 5:09:46 AM8/8/09
to pyglet-users
As I recall, your polygon's in pymunk must be defined with the correct
winding. I forget if they should all be clockwise, or all anti-
clockwise, but getting it wrong makes things not work. Also, I seem to
recall that whichever way it specifies in the pymunk documentation, is
only accurate so long as you consider your Y axis to be pointing
downwards. In the opengl world we tend to think of Y-axis as pointing
up, so you must reverse the winding. (ie. if pymunk docs say 'use
clockwise', then you must actually use anti-clockwise)

viblo

unread,
Aug 9, 2009, 4:37:20 PM8/9/09
to pyglet-users
The main problem is that you set an offset to the body, even when you
have changed the image to have its center in the middle. If you remove
the offset from the body you will get collisions when the circles
overlap. (You had collisions all the time, just that they didn't occur
where you would expect :)

Another problem is that as soon as the two circles collide they will
move in the "physics world" but you never update their pyglet
positions based on this fact. If you don't want them to move, you can
return false from the collision callback function (then pymunk wont
move the bodies to resolve the collision). Otherwise you have to
update the pyglet car sprite positions from the bodies.

I don't know if you have seen it but there is one very small pyglet
example included with pymunk (the src dist). However, I don't think it
will give you much help as it draws the screen directly from the
pymunk objects and doesnt use pyglet sprites at all.

note: With the newest release pymunk will automatically reorder the
vertices if they are in the wrong order (unless its told not to).
Another useful tip If you are uncertain about the polygon winding is
to use pymunk.util.is_clockwise(..) or even simpler, just reverse the
list and see if things improve :)

/vb

dorzey

unread,
Aug 10, 2009, 11:39:46 AM8/10/09
to pyglet-users
I do indeed have collisions! The pymunk example you pointed to was
very useful; especially for drawing the body so I can see where it is.

However, I'm still struggling with updating the sprites when a
collision happens. I've updated the pastebin(http://pastebin.com/
f3ae6b483) with my latest effort. I can successfully update the
sprite and body from user input, but not when a collision occurs as
the bodies become 'detached' from the sprite.

Dorzey

viblo

unread,
Aug 12, 2009, 10:02:01 AM8/12/09
to pyglet-users
Some hints:
1. You still have offset on the circle shape (I see that I wrote
offset on the body and not on the shape in my previous post, sorry).
Its not needed and will just confuse you, so just send in (0,0)
instead

2. You will have to decide if you want pymunk to resolve collisions
for you or if you just want pymunk to detect them. If you _do not
want_ pymunk to actually resolve collisions you should return False
from the callback (or otherwise make sure pymunk never tries to
resolve a collision). For the next pointers I will assume you _want_
pymunk to resolve collisions for you.

3. The move function is very strange, it doesnt even do anything with
the x and y it gets as parameters! :) I suggest you remove it
completely as I don't understand why you need it. And remove those
old_x/old_y variables as well. And change the update function to only
synchronize the body position in the pymunk world with the sprite
position in the pyglet world:
def update(self): x,y = self.body.position

4. You don't need to do anything in the collision callback function.
Remove it (or keep it and just use it to print info for debugging).
pymunk will move the shapes/bodies for you

Later on you will want to use another way to move the car by player
input and not just -+ on the position, but I think its good if you
straighten out the other stuff first :) There are some threads on the
chipmunk forum (http://www.slembcke.net/forums/viewforum.php?f=1) that
deals with top down cars that might be usefull to get this part right.
(just search on it for topdown and "top down" and you will find them).
Another thing I noticed is that you create pymunk vectors before you
send them in to functions. This is usually not needed so you can save
some space with writing it as a normal python tuple instead ((x,y)
instead of pymunk.Vec2d(x,y)). And I see that you got some spaces
mixed with tabs when you added the debug code. Its usually a very good
idea to keep to one form, either tabs or spaces, not both. But you
probably know that already :)

Maybe I can put together some simple example when I get home today,
but I can't promise anything.

/vb
(Now when I see your code I see that I forgot the moon buggy example,
but it looks like you found it. When I said pyglet example I meant
box2d_pyramid.py (or something like that) :))

Tartley

unread,
Aug 12, 2009, 12:36:22 PM8/12/09
to pyglet-users
On Aug 9, 9:37 pm, viblo <v...@viblo.se> wrote:
> note: With the newest release pymunk will automatically reorder the
> vertices if they are in the wrong order (unless its told not to).

Hooray! You rock! This is actually of direct relevance to me - I just
added an if statement last night, to modify windings on loading
graphics from SVG in order to make pymunk happy, and it confuses my
subsequent tessellation code that sends the same data to pyglet. Let
me unleash some pip/virtualenv-fu in order to take advantage of your
latest release. Thanks!

viblo

unread,
Aug 13, 2009, 4:10:51 AM8/13/09
to pyglet-users
Intersting. Actually I was beginning to have second thoughts about
this feature :) I mean, it might be confusing for the user if pymunk
automatically reverse the vertices, i.e. the order of the vertices is
different when you call poly.get_points(..) than it was when the
polygon was created. Then again this might be such a small problem
that its worth it anyway, and as you say, its a useful feature in many
cases, and it is possible to turn it off for those who don't like it.

Tartley

unread,
Aug 13, 2009, 7:40:57 AM8/13/09
to pyglet-users
I see. I guess, on reflection, if you *hadn't* implemented this, then
my solution would simply have been to conditionally reverse the verts
I send to pymunk, rather than conditionally reversing the verts I load
from svg and then use for everythin. So while news of your feature
made me happy, if you decide to ditch it for simplicity and
predictability reasons, then I guess I'd be ok after all.

Best regards, and many thanks for pymunk. I'm now generating collision
shapes (and pyglet batches) from loaded SVG and it's really really
great. :-)

Tartley

unread,
Aug 13, 2009, 7:42:27 AM8/13/09
to pyglet-users
On further reflection, I think it's a good feature. The surprise
developers might experience on seeing their verts have been reversed
is smaller and less critical than the relatively frequent surprise of
newbies who find their shapes don't collide.

dorzey

unread,
Aug 13, 2009, 8:55:00 AM8/13/09
to pyglet-users
On Aug 12, 3:02 pm, viblo <v...@viblo.se> wrote:
> Some hints:
> 1. You still have offset on the circle shape (I see that I wrote
> offset on the body and not on the shape in my previous post, sorry).
> Its not needed and will just confuse you, so just send in (0,0)
> instead
>

Thanks, I was most definitely being confused by the offsets!

<snip/>
> 3. The move function is very strange, it doesnt even do anything with
> the x and y it gets as parameters! :) I suggest you remove it
> completely as I don't understand why you need it. And remove those
> old_x/old_y variables as well. And change the update function to only
> synchronize the body position in the pymunk world with the sprite
> position in the pyglet world:
> def update(self): x,y = self.body.position
>

Indeed it was very strange. I think it was largely a product of me
trying everything and anything I could think of.

<snip/>
> Later on you will want to use another way to move the car by player
> input and not just -+ on the position, but I think its good if you
> straighten out the other stuff first :) There are some threads on the
> chipmunk forum (http://www.slembcke.net/forums/viewforum.php?f=1) that
> deals with top down cars that might be usefull to get this part right.
<snip/>

Thanks for the link. Now I have the basic bit working (working code
here: http://pastebin.com/f216a1170) I can actually attempt to make
the game!

Dorzey
Reply all
Reply to author
Forward
0 new messages