Как обнаружить столкновение с помощью PyBox2d и использовать эту информацию - PullRequest
0 голосов
/ 05 ноября 2019

Привет, у меня есть этот простой код для проверки работы со столкновениями в Box2d, это просто прямоугольник, падающий на заданную высоту относительно тела земли, и возникла интересная проблема, когда тело поворачивается на 45 градусов влево / вправо (это означает, что оно касаетсяназемный корпус с его углом) он просто останавливается там и не падает, как ожидалось.

import pygame
import numpy as np
from Box2D.b2 import world, polygonShape, circleShape,edgeShape, staticBody, dynamicBody, kinematicBody, revoluteJoint, wheelJoint, contact
from Box2D import b2Vec2, b2FixtureDef,b2PolygonShape, b2CircleShape, b2Dot,b2EdgeShape, b2Contact,b2ContactFilter,b2Filter, b2ContactListener


pygame.init()

PPM = 15
SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480
pos_X = SCREEN_WIDTH/PPM/3
pos_Y = SCREEN_HEIGHT/PPM

Box_2_World = world(gravity = (0.0, -9.81), doSleep = True)

Rectangle = Box_2_World.CreateDynamicBody(position = (pos_X+5, pos_Y + 5),
                                    angle = np.pi/4,
                                    fixtures = b2FixtureDef(
                                        shape = b2PolygonShape(box= (5,5)),
                                        density = 1000,
                                        friction = 1000,
                                                            ))
Ground = Box_2_World.CreateStaticBody(position = [0,0],
                                    angle = 0,
                                    fixtures = b2FixtureDef(
                                        shape = b2PolygonShape(box= (50,1)),
                                        density = 1000,
                                        friction = 1000,
                                                            ))


screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
colors = {dynamicBody: (133, 187, 101, 0),  staticBody: (15, 0, 89, 0)}
FPS = 24
TIME_STEP = 1.0 / FPS
running = True

def my_draw_polygon(polygon, body, fixture):
    vertices = [(body.transform * v) * PPM for v in polygon.vertices]
    vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]
    pygame.draw.polygon(screen, colors[body.type], vertices)
polygonShape.draw = my_draw_polygon

while running:
    # Draw the world
    screen.fill((255, 255, 255, 255))

    for body in Box_2_World.bodies:
        for fixture in body.fixtures:
            fixture.shape.draw(body, fixture)

    # Simulate dynamic equation in each step
    TIME_STEP = 1.0 / FPS
    Box_2_World.Step(TIME_STEP, 10, 10)

        # Flip the screen and try to keep at the target FPS
    pygame.display.flip() # Update the full display Surface to the screen
    pygame.time.Clock().tick(FPS)

pygame.quit()

РЕДАКТИРОВАТЬ: Основная тема была решена, так что теперь я могу перейти к другой проблеме (которая для меня важнее)

Я работаю над более сложной игрой, но я застрял в обнаружении столкновений около недели, поэтому я написал этот простой сценарий, чтобы узнать о столкновениях более эффективно, но я все еще застрял. Я не знаю, как установить contactListener или как определить, столкнулись ли два тела или нет. Я гуглил его, искал учебники, но ничего не помогло (в основном потому, что эти учебники не были написаны на python).

Итак ... Я был бы более чем благодарен, если бы вы показали мне, например, в моем сценарии, как изменитьцвет прямоугольника, когда он падает на землю (я не показываю вам то, что я уже пробовал, потому что были разные способы, например, места в памяти, и я хочу сделать этот пример максимально простым.

Спасибо ОЧЕНЬмного для любого ответа. Я не могу двигаться вперед в моей игре без этого ...

РЕДАКТИРОВАТЬ: Я нашел ссылку, которая решает именно то, что я хочу сделать, но она написана на C ++, и я не понимаю,это http://www.iforce2d.net/b2dtut/collision-callbacks

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

эй, я только что ответил на ваш вопрос о stackexchange: -)

Для коллизий это просто:

local filterData = {
   categoryBits = player,
   maskBits = wall + nme + platform,
   groupIndex = 0
}
fixture:setFilterData(filterData)

игрок , стена , nme , ... являются целочисленными переменными (должны быть степенью 2 числа):

player = 1
wall = 2
nme = 4
... = 16, 32, 64, 128, 256, ...

categoryBits = основной объект, для которого вы хотите проверить столкновения на

maskBits = вы добавьте (с +) все числа, с которыми может столкнуться главный объект.

В противном случае лучше хранить числа как переменныебудет выглядеть так:

local filterData = {
   categoryBits = 1,
   maskBits = 2 + 4 + 8 + 16 ...,
   groupIndex = 0
}
fixture:setFilterData(filterData)

: -)

0 голосов
/ 05 ноября 2019

Интересно, насколько просто решение, мне просто нужно добавить новый класс:

class myContactListener(b2ContactListener):
    def __init__(self):
        b2ContactListener.__init__(self)
    def BeginContact(self, contact):
        print('FUNGUJE')
        Box_2_World.gravity = (0.0, 9.81)
    def EndContact(self, contact):
        print('MUHEHEHA')
    def PreSolve(self, contact, oldManifold):
        pass
    def PostSolve(self, contact, impulse):
        pass

Box_2_World = world(contactListener=myContactListener(), gravity = (0.0, -9.81), doSleep = True)

Теперь мне, скорее всего, нужно будет как-то отфильтровать эти коллизии, но это вопрос для другого времени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...