viblo / pymunk

Pymunk is a easy-to-use pythonic 2d physics library that can be used whenever you need 2d rigid body physics from Python
http://www.pymunk.org
MIT License
933 stars 190 forks source link

Objects only reacting to certain objects #210

Open eschan145 opened 2 years ago

eschan145 commented 2 years ago

I am in the process of making this battle simulator game where two armies battle each other when they are in ranks. Of course, the soldiers shoot arrows at the enemy, but a problem with this is that the soldiers' arrows on one side hit other soldiers on the same side. This propels them forward, so they look like this:

image

Blue is on one side and red is another side. The arrows propel the soldiers in front of them forwards as they hit them. How can I make it that the arrows only hit a specific side and go through the soldiers that fired them?

For example, an airplane would fly over and go through a building, not reacting to it or the building moving, but a missile could destroy that same building. Changing the body types of these objects to KINEMATIC, STATIC, or DYNAMIC doesn't work.

viblo commented 2 years ago

There are a couple of ways to do this with Pymunk, depending on exactly what you need. You wrote that arrows from a friendly soldier should not collide with other friendly soldiers.

The easiest solution would be to use a custom ShapeFilter on the shapes (the 'filter' property). If its ok for no collision to happen between friendly arrows, friendly soldiers then put all blue team in ShapeFilter.group 1 and red team in group 2. The ShapeFilter is documented here: http://www.pymunk.org/en/latest/pymunk.html#pymunk.ShapeFilter

There are also more complex setups possible, but then you need to describe exactly how it should work :) Two questions to narrow it down:

  1. Should arrows collide with other arrows?
  2. Should soldiers collide with other soldiers?
eschan145 commented 2 years ago

Arrows should not collide with other arrows. Soldiers might collide with other soldiers in melee attacks. It would be nice if a soldier could have knockback when hit with an arrow. BTW I am using the Python arcade library for this. I have no idea how to plug this into my code.

viblo commented 2 years ago

Alright. Then you can do it by putting read team soldiers in one category, red team arrows in one category, blue team soldiers in one category and finally blue team arrows in one category. Then just specify the mask on each category what other they should collide with. I recently wrote an answer on SO that explains it: https://stackoverflow.com/questions/72795180/how-to-use-pymunk-categories-and-masks/72807516#72807516