如何使用PyBox2d检测碰撞并使用该信息 [英] How to detect collision using PyBox2d and use that information

查看:120
本文介绍了如何使用PyBox2d检测碰撞并使用该信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过重现此示例来过滤Box2D世界中发生的碰撞: https://github.com/pybox2d/pybox2d/blob/master/examples/collision_filtering.py

I am trying to filter collisions occurring in my Box2D world by reproducing this example: https://github.com/pybox2d/pybox2d/blob/master/examples/collision_filtering.py

我的世界上有四个班级,汽车,车轮,建筑物和行人,我想过滤哪个实例与哪个实例碰撞,并且可能的输出之一是(伪代码)

I have four classes in my world, Car, Wheel, Building, and Pedestrian, I want to filter which instance collided with which and one of the possible outputs is (pseudo-code)

if contact.FixtureA.isinstance(Pedestrian) and contact.FixtureB.isinstance(Car):
    print("You have caused a traffic accident")

我有这组类别


CAR_CATEGORY = 2
PEDESTRIAN_CATEGORY = 4
BUILDING_CATEGORY = 8
box2world = world(gravity =(0.0, 0.0), doSleep =True)

我也尝试过:它不起作用(不执行任何操作)

I also tried this: but it doesn't work (it does nothing)

class myContactListener(b2ContactListener):
    def __init__(self):
        b2ContactListener.__init__(self)
    def BeginContact(self, contact):
        fixture_a = contact.fixtureA
        fixture_b = contact.fixtureB

        body_a, body_b = fixture_a.body, fixture_b.body
        ud_a, ud_b = body_a.userData, body_b.userData
        pedestrian = None
        car = None
        for ud in (body_a, body_b):
            if isinstance(ud, Pedestrian):
                pedestrian = ud
            elif isinstance(ud, Car):
                car = ud

        if car is not None and pedestrian is not None:
            if began:
                print("It does stuff")
            else:
                print("It does something")
    def EndContact(self, contact):
        pass
    def PreSolve(self, contact, oldManifold):
        pass
    def PostSolve(self, contact, impulse):
        pass


box2world = world(contactListener=myContactListener(),gravity =(0.0, 0.0), doSleep =True)

在给定的类中(为简单起见,仅以行人类为例):

and I apply this in given classes (only class Pedestrian shown as example for simplicity):

class Pedestrian():
    def __init__(self,box2world, ped_velocity =25, position =None,):

        if position == None:
            position = [5,5]
        self.ped_velocity = ped_velocity
        self.position = position
        self.box2world = box2world
        self.nearest_building = 0
        self.body = self.box2world.CreateDynamicBody(position = position, 
                                                       angle = 0.0,
                                                       fixtures = b2FixtureDef(
                                                            shape = b2CircleShape(radius = 1),
                                                            density = 2,
                                                            friction = 0.3,
                                                            filter = b2Filter(
                                                                categoryBits=PEDESTRIAN_CATEGORY,
                                                                maskBits=BUILDING_CATEGORY + CAR_CATEGORY,
                                                                groupIndex=0,
                                                                    )))
        self.current_position = [self.body.position]
        self.body.userData = {'obj': self}

然后我绘制身体并使用pygame运行世界

And then I draw the bodies and run the world using pygame

但是我对如何继续感到困惑,如何使用来自t的信息他冲撞过滤器能够例如从上面打印关于事故的句子?

But I am confused about how to continue, how could I use the information from the collisionfilter to be able to for example print the sentence about the accident from above?

非常感谢
编辑:我发现一个链接可以完全解决我想做什么,但是它是用C ++编写的,我不理解它。
http://www.iforce2d.net/b2dtut/collision-callbacks

推荐答案

来回答您的第二条评论更为复杂,因此我将其添加为另一个答案。

to answer your second comment that is more complex so I add it as another answer.

您不能自己处理碰撞,Box2D会为您完成,但是您需要进行设置。

You don't handle collisions yourself, Box2D does it for you but you need to set things up.

-创建您的世界

world = b2.World.new(0, 24, true)

-将听众附加到您的世界(

world:addEventListener(Event.BEGIN_CONTACT, self.onBeginContact, self)
world:addEventListener(Event.END_CONTACT, self.onEndContact, self)
world:addEventListener(Event.PRE_SOLVE, self.onPreSolveContact, self)
world:addEventListener(Event.POST_SOLVE, self.onPostSolveContact, self)

-在游戏循环中,您需要调用Box2D更新

self.world:step(1/60, 1, 1)

-然后在这里答案,您检查那些box2d函数侦听器中每个对象的冲突

- then ANSWER IS HERE you check collisions for each objects in those box2d functions listeners

-- collisions handler
function LF_Bullet:onBeginContact(e)
    local bodyA = e.fixtureA:getBody()
    local bodyB = e.fixtureB:getBody()
    if bodyA.type == 100 or bodyB.type == 100 then
        self.removebullet = true
    end
    if bodyA.type == 200 and bodyB.type == 100 then
        bodyA.isdead = true
    end
    if bodyA.type == 100 and bodyB.type == 200 then
        bodyB.isdead = true
    end
    if bodyA.type == 201 and bodyB.type == 100 then
        bodyA.isdead = true
    end
    if bodyA.type == 100 and bodyB.type == 201 then
        bodyB.isdead = true
    end
end

function LF_Bullet:onPreSolveContact(e)
end

function LF_Bullet:onPostSolveContact(e)
end

function LF_Bullet:onEndContact(e)
end

这是使用 gideros mobile 用LUA编写的快速示例, http:// giderosmobile。 com /

This is a quick example written in LUA using gideros mobile http://giderosmobile.com/.

关于box2d的必选网站当然是:
https://www.iforce2d.net/b2dtut/

A must website regarding box2d is of course: https://www.iforce2d.net/b2dtut/

一个广泛的主题,您可能需要关注一些YouTube教程。即使它不是用py编写的,box2d的工作原理也一样,因此您只需要适应py。
一些可能有用的链接:
https:// www.youtube.com/playlist?list=PLZm85UZQLd2SXQzsF-a0-pPF6IWDDdrXt

It is a vast subject and you may want to follow some youtube tuts. Even if it is not written in py, box2d works the same so you just have to adapt to py. Some links that may help: https://www.youtube.com/playlist?list=PLZm85UZQLd2SXQzsF-a0-pPF6IWDDdrXt

这就是我使用box2d学习的方法。希望有帮助吗?

That's how I learned using box2d. Hope that helps?

这篇关于如何使用PyBox2d检测碰撞并使用该信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆