Issue
I am trying to draw colliders of Box2D. Now I have only physics in this example without graphics for simplicity. The DrawSegment()
method must be called to print hello
. I inherited the DebugDrawer
class from the b2Draw
class:
debug_drawer.py
from Box2D import b2Draw
class DebugDrawer(b2Draw):
def DrawSegment(self, p1, p2, color):
print("hello")
def DrawSolidPolygon(self, vertices, color):
pass
def DrawPoint(self, p, size, color):
pass
def DrawPolygon(self, vertices, color):
pass
def DrawCircle(self, center, radius, color, drawwidth=1):
pass
def DrawSolidCircle(self, center, radius, axis, color):
pass
def DrawTransform(self, xf):
pass
I created one object with the box shape. I have the animationLoop()
method that I call with timer. Inside of the animationLoop()
method I the self.world.Step()
method and I call the paintGL()
method by calling the self.update()
method. Inside of the paintGL()
method I call the self.world.DrawDebugData()
method. I expect that the DrawSegment()
will be called but it does not happen.
widget.py
from Box2D import (b2_staticBody, b2Body, b2BodyDef, b2FixtureDef,
b2PolygonShape, b2Vec2, b2World)
from OpenGL import GL as gl
from PyQt6.QtCore import QElapsedTimer, QSize, QTimer
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
from debug_drawer import DebugDrawer
class Widget(QOpenGLWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Box2D, OpenGL3, PyQt6")
self.setFixedSize(QSize(500, 500))
self.deltaTime = 0
self.WORLD_SCALE = 30.0
self.world = b2World(gravity=b2Vec2(0.0, 9.8))
def initializeGL(self):
gl.glClearColor(0.2, 0.2, 0.2, 1.0)
gl.glEnable(gl.GL_DEPTH_TEST)
self.debugDrawer = DebugDrawer()
self.world.renderer = self.debugDrawer
self.debugDrawer.flags = { 'drawShapes': True,
'drawJoints': True, 'drawAABBs': True, 'drawPairs': True }
# print(self.debugDrawer.flags)
shape = b2PolygonShape()
shape.SetAsBox(50.0 / self.WORLD_SCALE, 50.0 / self.WORLD_SCALE)
bodyDef = b2BodyDef()
bodyDef.type = b2_staticBody
self.body: b2Body = self.world.CreateBody(bodyDef)
fixtureDef = b2FixtureDef()
fixtureDef.shape = shape
fixtureDef.density = 2
self.body.CreateFixture(fixtureDef)
self.timer = QTimer()
self.timer.timeout.connect(self.animationLoop)
self.elapsedTimer = QElapsedTimer()
self.elapsedTimer.start()
self.timer.start(1000//60)
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
self.world.DrawDebugData()
def resizeGL(self, w: int, h: int):
gl.glViewport(0, 0, w, h)
def animationLoop(self):
self.deltaTime = self.elapsedTimer.elapsed() / 1000.0
self.elapsedTimer.restart()
self.world.Step(self.deltaTime, 8, 3)
self.update()
main.py
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QSurfaceFormat
from PyQt6.QtWidgets import QApplication
from widget import Widget
def main():
QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
app = QApplication(sys.argv)
format = QSurfaceFormat()
format.setSamples(8)
w = Widget()
w.setFormat(format)
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Solution
I should use DrawPolygon
to draw segments of colliders when I use boxes to draw borders around game objects. DrawSegment()
will be called when an instance of b2EdgeShape
is created:
edgeShape = b2EdgeShape()
edgeShape.vertices = [(0.0, 0.0), (1.0, 0.0)]
self.edgeBody: b2Body = self.world.CreateBody(bodyDef)
edgeFixtureDef = b2FixtureDef()
edgeFixtureDef.shape = edgeShape
edgeFixtureDef.density = 2
self.edgeBody.CreateFixture(edgeFixtureDef)
Answered By - 8Observer8
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.