Talk:Physics Jam/Help: Difference between revisions
Jump to navigation
Jump to search
(New page: Some sample code for binding sprites and bodies: <pre> import pygame from Box2D2 import * import sys from math import * class BodySprite(pygame.sprite.Sprite): blankColor = (0, 0, 0)...) |
No edit summary |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
= Non-screen flipping graphics = |
|||
Some sample code for binding sprites and bodies: |
|||
<pre> |
|||
import pygame |
|||
from pygame.locals import * |
|||
from pygame.color import * |
|||
import Box2D2 as box2d |
|||
from math import * |
|||
global SCENERY |
|||
global ROLLCAT_WHEEL |
|||
global ROLLCAT_BODY |
|||
(SCENERY, ROLLCAT_WHEEL, ROLLCAT_BODY) = (0,1,2) |
|||
global contactList |
|||
contactList = [] |
|||
class X2OGame: |
|||
def __init__(self, screen): |
|||
self.pixelsPerMeter = 20 |
|||
self.updateList = [] |
|||
self.screen = screen |
|||
# get everything set up |
|||
self.clock = pygame.time.Clock() |
|||
#self.font = pygame.font.Font(None, 24) # font object |
|||
#self.canvas = olpcgames.ACTIVITY.canvas |
|||
#self.joystickobject = None |
|||
self.debug = True |
|||
self.initializeWorld() |
|||
self.screen.fill((0,0,0)) |
|||
self.leftLPress = False |
|||
self.leftRPress = False |
|||
# create the name --> instance map for components |
|||
def worldToScreen(self, worldX, worldY): |
|||
return (worldX * self.pixelsPerMeter, - worldY * self.pixelsPerMeter) |
|||
def screenToWorld(self, screenX, screenY): |
|||
return (screenX / self.pixelsPerMeter, - screenY / self.pixelsPerMeter) |
|||
def initializeWorld(self): |
|||
worldAABB = box2d.b2AABB() |
|||
worldAABB.lowerBound.Set(- 100, - 100) |
|||
worldAABB.upperBound.Set(100, 100) |
|||
gravity = box2d.b2Vec2(0, - 10) |
|||
doSleep = True |
|||
self.world = box2d.b2World(worldAABB, gravity, doSleep) |
|||
bodyDef2 = box2d.b2BodyDef() |
|||
bodyDef2.position.Set(10, - 20) |
|||
body2 = self.world.CreateBody(bodyDef2) |
|||
shapeDef2 = box2d.b2PolygonDef() |
|||
shapeDef2.SetAsBox(50, .2) |
|||
body2.CreateShape(shapeDef2) |
|||
body2.SetXForm(body2.GetXForm().position,-.02) |
|||
BodySprite(body2, 'pic2.png',100,.4,0,0,self.worldToScreen, self.screenToWorld) |
|||
body2.type = SCENERY |
|||
self.updateList.append(RollCat(self,(10,0))) |
|||
self.updateList.append(RollCat(self,(13,0))) |
|||
self.updateList.append(RollCat(self,(16,0))) |
|||
self.updateList.append(RollCat(self,(19,0))) |
|||
self.updateList.append(RollCat(self,(22,0))) |
|||
self.updateList.append(RollCat(self,(25,0))) |
|||
print body2.type |
|||
def run(self): |
|||
self.running = True |
|||
while self.running: |
|||
for event in pygame.event.get(): |
|||
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): |
|||
self.running = False |
|||
if (event.type == KEYDOWN and event.key == K_a): |
|||
self.leftLPress = True |
|||
if (event.type == KEYUP and event.key == K_a): |
|||
self.leftLPress = False |
|||
if (event.type == KEYDOWN and event.key == K_d): |
|||
self.leftRPress = True |
|||
if (event.type == KEYUP and event.key == K_d): |
|||
self.leftRPress = False |
|||
#self.currentTool.handleEvents(event) |
|||
# Clear Display |
|||
#self.screen.fill((0,0,0)) #255 for white |
|||
contactList = [] |
|||
self.world.Step(1.0/60,10) |
|||
for updatable in self.updateList: |
|||
updatable.update() |
|||
#Print all the text on the screen |
|||
#text = self.font.render("Current Tool: "+self.currentTool.name, True, (0,0,0)) |
|||
#textpos = text.get_rect(left=700,top=7) |
|||
#self.screen.blit(text,textpos) |
|||
for char in BodySprite.bodySpriteList: |
|||
char.update() |
|||
for char in BodySprite.bodySpriteList: |
|||
self.screen.blit(char.blank, char.old) |
|||
for char in BodySprite.bodySpriteList: |
|||
self.screen.blit(char.image, char.rect) |
|||
for char in BodySprite.bodySpriteList: |
|||
pygame.display.update([char.old, char.rect]) |
|||
# Flip Display |
|||
#pygame.display.flip() |
|||
# Try to stay at 30 FPS |
|||
self.clock.tick(60) # originally 50 |
|||
class BodySprite(pygame.sprite.Sprite): |
|||
blankColor = (0, 0, 0) |
|||
bodySpriteList = [] |
|||
def __init__(self, body, imageName, imageWidthMeters, imageHeightMeters, imageOffsetXMeters, imageOffsetYMeters, worldToScreenFunction, screenToWorldFunction): |
|||
pygame.sprite.Sprite.__init__(self) |
|||
BodySprite.bodySpriteList.append(self) |
|||
# Save a copy of the screen's rectangle |
|||
self.screen = pygame.display.get_surface().get_rect() |
|||
self.w2s = worldToScreenFunction |
|||
self.s2w = screenToWorldFunction |
|||
self.body = body |
|||
newWidth = self.w2s(imageWidthMeters, imageHeightMeters)[0] - self.w2s(0, 0)[0] |
|||
newHeight = self.w2s(imageWidthMeters, imageHeightMeters)[1] - self.w2s(0, 0)[1] |
|||
self.offsetX = imageOffsetXMeters |
|||
self.offsetY = imageOffsetYMeters |
|||
if newWidth < 0: |
|||
newWidth *= - 1 |
|||
if newHeight < 0: |
|||
newHeight *= - 1 |
|||
# Create a variable to store the previous position of the sprite |
|||
self.old = (0, 0, 0, 0) |
|||
self.angle = 0 |
|||
self.originalImage = pygame.transform.scale(pygame.image.load(imageName).convert_alpha(), (newWidth, newHeight)) |
|||
self.image = pygame.transform.rotate(self.originalImage, self.angle) |
|||
self.rect = self.image.get_rect() |
|||
# Create a Surface the size of our character |
|||
self.blank = pygame.Surface((self.rect.width * 2, self.rect.height * 2), 0, self.screen) |
|||
self.blank.fill(BodySprite.blankColor) |
|||
self.alreadyRendered = False |
|||
# self. |
|||
def update(self): |
|||
if ((self.body.IsStatic() or self.body.IsSleeping()) and self.alreadyRendered): |
|||
return |
|||
self.alreadyRendered = True |
|||
# Make a copy of the current rectangle for use in erasing |
|||
self.old = self.rect |
|||
angle = self.body.GetAngle() |
|||
self.image = pygame.transform.rotate(self.originalImage, angle * 180 / 3.1415) |
|||
# Move the rectangle by the specified amount |
|||
self.rect = self.image.get_rect() |
|||
cosAngle = cos(- angle) |
|||
sinAngle = sin(- angle) |
|||
vrotx = - (cosAngle * self.offsetX - sinAngle * self.offsetY) |
|||
vroty = (sinAngle * self.offsetX + cosAngle * self.offsetY) |
|||
(self.x, self.y) = self.w2s(self.body.GetXForm().position.x + vrotx, self.body.GetXForm().position.y + vroty) |
|||
self.rect.center = (self.x, self.y) |
|||
class myContactListener(box2d.b2ContactListener): |
|||
def __init__(self): super(myContactListener, self).__init__() |
|||
def Add(self, point): |
|||
pass |
|||
def Persist(self, point): |
|||
contact |
|||
def Remove(self, point): |
|||
pass |
|||
def Result(self, point): |
|||
pass |
|||
class RollCat: |
|||
def __init__(self, game, location): |
|||
self.game = game |
|||
self.world = game.world |
|||
bodyDef = box2d.b2BodyDef() |
|||
bodyDef.position.Set(location[0], location[1]+1) |
|||
#bodyDef.fixedRotation = True |
|||
body = self.world.CreateBody(bodyDef) |
|||
shapeDef = box2d.b2PolygonDef() |
|||
shapeDef.SetAsBox(1, 1) |
|||
shapeDef.density = 1 |
|||
shapeDef.restitution = 0.5 |
|||
shapeDef.friction = 1.0 |
|||
body.CreateShape(shapeDef) |
|||
body.SetMassFromShapes() |
|||
self.torso = body |
|||
self.torso.type = ROLLCAT_BODY |
|||
bodyDef3 = box2d.b2BodyDef() |
|||
bodyDef3.position.Set(location[0],location[1]) |
|||
body3 = self.world.CreateBody(bodyDef3) |
|||
shapeDef3 = box2d.b2CircleDef() |
|||
shapeDef3.radius = 1.0 |
|||
shapeDef3.density = 1 |
|||
shapeDef3.restitution = 0.5 |
|||
shapeDef3.friction = 1.0 |
|||
body3.CreateShape(shapeDef3) |
|||
body3.SetMassFromShapes() |
|||
self.wheel = body3 |
|||
self.wheel.type = ROLLCAT_WHEEL |
|||
sensorDef = box2d.b2CircleDef() |
|||
sensorDef.radius = 0.5 |
|||
sensorDef.isSensor = True |
|||
sensorDef.localPosition = box2d.b2Vec2(0,-2) |
|||
sensorShape = self.torso.CreateShape(sensorDef) |
|||
jd = box2d.b2RevoluteJointDef() |
|||
jd.Initialize(body, body3, box2d.b2Vec2(location[0],location[1])) |
|||
revJoint = self.world.CreateJoint(jd).getAsType() |
|||
self.axle = revJoint |
|||
revJoint.EnableMotor(True) |
|||
revJoint.SetMotorSpeed(0) |
|||
revJoint.SetMaxMotorTorque(5000) |
|||
self.motorSpeed = 0 |
|||
self.targetAngle = 0 |
|||
BodySprite(body3,'Rollcats_bottom.png',2, 2, 0, 0, self.game.worldToScreen, self.game.screenToWorld) |
|||
BodySprite(body,'Rollcats_top.png',2, 2, 0, 0,self.game.worldToScreen, self.game.screenToWorld) |
|||
#def canJump(self): |
|||
def update(self): |
|||
moveSpeed = .1 |
|||
moveForce = 100 |
|||
angle = self.torso.GetAngle() - self.targetAngle |
|||
angVel = self.torso.GetAngularVelocity() |
|||
if (self.game.leftLPress): |
|||
self.targetAngle = .95*self.targetAngle + .05 * .4 |
|||
self.wheel.ApplyForce(box2d.b2Vec2(-moveForce,0),self.wheel.GetWorldCenter()) |
|||
elif (self.game.leftRPress): |
|||
self.targetAngle = .95*self.targetAngle - .05 * .4 |
|||
self.wheel.ApplyForce(box2d.b2Vec2(moveForce,0),self.wheel.GetWorldCenter()) |
|||
else: |
|||
vx = self.wheel.GetLinearVelocity().x |
|||
self.targetAngle = .9*self.targetAngle |
|||
self.wheel.ApplyForce(box2d.b2Vec2(-.1*moveForce*vx,0),self.wheel.GetWorldCenter()) |
|||
while (angle > 3.1415): |
|||
angle -= 2*3.1415 |
|||
while (angle < -3.1415): |
|||
angle += 2*3.1415 |
|||
correctionFactor = 2 |
|||
correctionDragFactor = .1 |
|||
#torque = -correctionFactor*angle - correctionDragFactor*angVel |
|||
#self.torso.ApplyTorque(torque) |
|||
self.motorSpeed += correctionFactor*angle + correctionDragFactor*angVel |
|||
self.axle.SetMotorSpeed(self.motorSpeed) |
|||
def main(): |
|||
pygame.init() |
|||
pygame.display.init() |
|||
x, y = (1200,800)#pygame.display.list_modes()[0] |
|||
#toolbarheight = 10 |
|||
#tabheight = 10 |
|||
screen = pygame.display.set_mode((x, y)) |
|||
# create an instance of the game |
|||
game = X2OGame(screen) |
|||
# start the main loop |
|||
game.run() |
|||
# function for loading sounds (mostly borrowed from Pete Shinners pygame tutorial) |
|||
def loadSound(name): |
|||
# if the mixer didn't load, then create an empy class that has an empty play method |
|||
# this way the program will run if the mixer isn't present (sans sound) |
|||
class NoneSound: |
|||
def play(self): pass |
|||
def set_volume(self): pass |
|||
if not pygame.mixer: |
|||
return NoneSound() |
|||
try: |
|||
sound = pygame.mixer.Sound(name) |
|||
except: |
|||
print "error with sound: " + name |
|||
return NoneSound() |
|||
return sound |
|||
# make sure that main get's called |
|||
if __name__ == '__main__': |
|||
main() |
|||
</pre> |
|||
= Binding sprites and bodies: = |
|||
Latest revision as of 00:33, 31 August 2008
Non-screen flipping graphics
import pygame from pygame.locals import * from pygame.color import * import Box2D2 as box2d from math import * global SCENERY global ROLLCAT_WHEEL global ROLLCAT_BODY (SCENERY, ROLLCAT_WHEEL, ROLLCAT_BODY) = (0,1,2) global contactList contactList = [] class X2OGame: def __init__(self, screen): self.pixelsPerMeter = 20 self.updateList = [] self.screen = screen # get everything set up self.clock = pygame.time.Clock() #self.font = pygame.font.Font(None, 24) # font object #self.canvas = olpcgames.ACTIVITY.canvas #self.joystickobject = None self.debug = True self.initializeWorld() self.screen.fill((0,0,0)) self.leftLPress = False self.leftRPress = False # create the name --> instance map for components def worldToScreen(self, worldX, worldY): return (worldX * self.pixelsPerMeter, - worldY * self.pixelsPerMeter) def screenToWorld(self, screenX, screenY): return (screenX / self.pixelsPerMeter, - screenY / self.pixelsPerMeter) def initializeWorld(self): worldAABB = box2d.b2AABB() worldAABB.lowerBound.Set(- 100, - 100) worldAABB.upperBound.Set(100, 100) gravity = box2d.b2Vec2(0, - 10) doSleep = True self.world = box2d.b2World(worldAABB, gravity, doSleep) bodyDef2 = box2d.b2BodyDef() bodyDef2.position.Set(10, - 20) body2 = self.world.CreateBody(bodyDef2) shapeDef2 = box2d.b2PolygonDef() shapeDef2.SetAsBox(50, .2) body2.CreateShape(shapeDef2) body2.SetXForm(body2.GetXForm().position,-.02) BodySprite(body2, 'pic2.png',100,.4,0,0,self.worldToScreen, self.screenToWorld) body2.type = SCENERY self.updateList.append(RollCat(self,(10,0))) self.updateList.append(RollCat(self,(13,0))) self.updateList.append(RollCat(self,(16,0))) self.updateList.append(RollCat(self,(19,0))) self.updateList.append(RollCat(self,(22,0))) self.updateList.append(RollCat(self,(25,0))) print body2.type def run(self): self.running = True while self.running: for event in pygame.event.get(): if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): self.running = False if (event.type == KEYDOWN and event.key == K_a): self.leftLPress = True if (event.type == KEYUP and event.key == K_a): self.leftLPress = False if (event.type == KEYDOWN and event.key == K_d): self.leftRPress = True if (event.type == KEYUP and event.key == K_d): self.leftRPress = False #self.currentTool.handleEvents(event) # Clear Display #self.screen.fill((0,0,0)) #255 for white contactList = [] self.world.Step(1.0/60,10) for updatable in self.updateList: updatable.update() #Print all the text on the screen #text = self.font.render("Current Tool: "+self.currentTool.name, True, (0,0,0)) #textpos = text.get_rect(left=700,top=7) #self.screen.blit(text,textpos) for char in BodySprite.bodySpriteList: char.update() for char in BodySprite.bodySpriteList: self.screen.blit(char.blank, char.old) for char in BodySprite.bodySpriteList: self.screen.blit(char.image, char.rect) for char in BodySprite.bodySpriteList: pygame.display.update([char.old, char.rect]) # Flip Display #pygame.display.flip() # Try to stay at 30 FPS self.clock.tick(60) # originally 50 class BodySprite(pygame.sprite.Sprite): blankColor = (0, 0, 0) bodySpriteList = [] def __init__(self, body, imageName, imageWidthMeters, imageHeightMeters, imageOffsetXMeters, imageOffsetYMeters, worldToScreenFunction, screenToWorldFunction): pygame.sprite.Sprite.__init__(self) BodySprite.bodySpriteList.append(self) # Save a copy of the screen's rectangle self.screen = pygame.display.get_surface().get_rect() self.w2s = worldToScreenFunction self.s2w = screenToWorldFunction self.body = body newWidth = self.w2s(imageWidthMeters, imageHeightMeters)[0] - self.w2s(0, 0)[0] newHeight = self.w2s(imageWidthMeters, imageHeightMeters)[1] - self.w2s(0, 0)[1] self.offsetX = imageOffsetXMeters self.offsetY = imageOffsetYMeters if newWidth < 0: newWidth *= - 1 if newHeight < 0: newHeight *= - 1 # Create a variable to store the previous position of the sprite self.old = (0, 0, 0, 0) self.angle = 0 self.originalImage = pygame.transform.scale(pygame.image.load(imageName).convert_alpha(), (newWidth, newHeight)) self.image = pygame.transform.rotate(self.originalImage, self.angle) self.rect = self.image.get_rect() # Create a Surface the size of our character self.blank = pygame.Surface((self.rect.width * 2, self.rect.height * 2), 0, self.screen) self.blank.fill(BodySprite.blankColor) self.alreadyRendered = False # self. def update(self): if ((self.body.IsStatic() or self.body.IsSleeping()) and self.alreadyRendered): return self.alreadyRendered = True # Make a copy of the current rectangle for use in erasing self.old = self.rect angle = self.body.GetAngle() self.image = pygame.transform.rotate(self.originalImage, angle * 180 / 3.1415) # Move the rectangle by the specified amount self.rect = self.image.get_rect() cosAngle = cos(- angle) sinAngle = sin(- angle) vrotx = - (cosAngle * self.offsetX - sinAngle * self.offsetY) vroty = (sinAngle * self.offsetX + cosAngle * self.offsetY) (self.x, self.y) = self.w2s(self.body.GetXForm().position.x + vrotx, self.body.GetXForm().position.y + vroty) self.rect.center = (self.x, self.y) class myContactListener(box2d.b2ContactListener): def __init__(self): super(myContactListener, self).__init__() def Add(self, point): pass def Persist(self, point): contact def Remove(self, point): pass def Result(self, point): pass class RollCat: def __init__(self, game, location): self.game = game self.world = game.world bodyDef = box2d.b2BodyDef() bodyDef.position.Set(location[0], location[1]+1) #bodyDef.fixedRotation = True body = self.world.CreateBody(bodyDef) shapeDef = box2d.b2PolygonDef() shapeDef.SetAsBox(1, 1) shapeDef.density = 1 shapeDef.restitution = 0.5 shapeDef.friction = 1.0 body.CreateShape(shapeDef) body.SetMassFromShapes() self.torso = body self.torso.type = ROLLCAT_BODY bodyDef3 = box2d.b2BodyDef() bodyDef3.position.Set(location[0],location[1]) body3 = self.world.CreateBody(bodyDef3) shapeDef3 = box2d.b2CircleDef() shapeDef3.radius = 1.0 shapeDef3.density = 1 shapeDef3.restitution = 0.5 shapeDef3.friction = 1.0 body3.CreateShape(shapeDef3) body3.SetMassFromShapes() self.wheel = body3 self.wheel.type = ROLLCAT_WHEEL sensorDef = box2d.b2CircleDef() sensorDef.radius = 0.5 sensorDef.isSensor = True sensorDef.localPosition = box2d.b2Vec2(0,-2) sensorShape = self.torso.CreateShape(sensorDef) jd = box2d.b2RevoluteJointDef() jd.Initialize(body, body3, box2d.b2Vec2(location[0],location[1])) revJoint = self.world.CreateJoint(jd).getAsType() self.axle = revJoint revJoint.EnableMotor(True) revJoint.SetMotorSpeed(0) revJoint.SetMaxMotorTorque(5000) self.motorSpeed = 0 self.targetAngle = 0 BodySprite(body3,'Rollcats_bottom.png',2, 2, 0, 0, self.game.worldToScreen, self.game.screenToWorld) BodySprite(body,'Rollcats_top.png',2, 2, 0, 0,self.game.worldToScreen, self.game.screenToWorld) #def canJump(self): def update(self): moveSpeed = .1 moveForce = 100 angle = self.torso.GetAngle() - self.targetAngle angVel = self.torso.GetAngularVelocity() if (self.game.leftLPress): self.targetAngle = .95*self.targetAngle + .05 * .4 self.wheel.ApplyForce(box2d.b2Vec2(-moveForce,0),self.wheel.GetWorldCenter()) elif (self.game.leftRPress): self.targetAngle = .95*self.targetAngle - .05 * .4 self.wheel.ApplyForce(box2d.b2Vec2(moveForce,0),self.wheel.GetWorldCenter()) else: vx = self.wheel.GetLinearVelocity().x self.targetAngle = .9*self.targetAngle self.wheel.ApplyForce(box2d.b2Vec2(-.1*moveForce*vx,0),self.wheel.GetWorldCenter()) while (angle > 3.1415): angle -= 2*3.1415 while (angle < -3.1415): angle += 2*3.1415 correctionFactor = 2 correctionDragFactor = .1 #torque = -correctionFactor*angle - correctionDragFactor*angVel #self.torso.ApplyTorque(torque) self.motorSpeed += correctionFactor*angle + correctionDragFactor*angVel self.axle.SetMotorSpeed(self.motorSpeed) def main(): pygame.init() pygame.display.init() x, y = (1200,800)#pygame.display.list_modes()[0] #toolbarheight = 10 #tabheight = 10 screen = pygame.display.set_mode((x, y)) # create an instance of the game game = X2OGame(screen) # start the main loop game.run() # function for loading sounds (mostly borrowed from Pete Shinners pygame tutorial) def loadSound(name): # if the mixer didn't load, then create an empy class that has an empty play method # this way the program will run if the mixer isn't present (sans sound) class NoneSound: def play(self): pass def set_volume(self): pass if not pygame.mixer: return NoneSound() try: sound = pygame.mixer.Sound(name) except: print "error with sound: " + name return NoneSound() return sound # make sure that main get's called if __name__ == '__main__': main()
Binding sprites and bodies:
import pygame from Box2D2 import * import sys from math import * class BodySprite(pygame.sprite.Sprite): blankColor = (0, 0, 0) bodySpriteList = [] def __init__(self, body, imageName, imageWidthMeters, imageHeightMeters, imageOffsetXMeters, imageOffsetYMeters, worldToScreenFunction, screenToWorldFunction): pygame.sprite.Sprite.__init__(self) BodySprite.bodySpriteList.append(self) # Save a copy of the screen's rectangle self.screen = pygame.display.get_surface().get_rect() self.w2s = worldToScreenFunction self.s2w = screenToWorldFunction self.body = body newWidth = self.w2s(imageWidthMeters,imageHeightMeters)[0] - self.w2s(0,0)[0] newHeight = self.w2s(imageWidthMeters,imageHeightMeters)[1] - self.w2s(0,0)[1] self.offsetX = imageOffsetXMeters self.offsetY = imageOffsetYMeters if newWidth < 0: newWidth *= -1 if newHeight < 0: newHeight *= -1 # Create a variable to store the previous position of the sprite self.old = (0, 0, 0, 0) self.angle = 0 self.originalImage = pygame.transform.scale(pygame.image.load(imageName).convert_alpha(),(newWidth,newHeight)) self.image = pygame.transform.rotate(self.originalImage,self.angle) self.rect = self.image.get_rect() # Create a Surface the size of our character self.blank = pygame.Surface((self.rect.width*2, self.rect.height*2),0,screen) self.blank.fill(BodySprite.blankColor) # self. def update(self): # Make a copy of the current rectangle for use in erasing self.old = self.rect angle = self.body.GetAngle() self.image = pygame.transform.rotate(self.originalImage,angle * 180 / 3.1415) # Move the rectangle by the specified amount self.rect = self.image.get_rect() cosAngle = cos(-angle) sinAngle = sin(-angle) vrotx = -(cosAngle * self.offsetX - sinAngle * self.offsetY) vroty = (sinAngle * self.offsetX + cosAngle * self.offsetY) (self.x, self.y) = self.w2s(self.body.GetXForm().position.x + vrotx, self.body.GetXForm().position.y + vroty) self.rect.center = (self.x, self.y) global pixelsPerMeter pixelsPerMeter = 20 #screen to world conversion def s2w(screenX, screenY): return (screenX / pixelsPerMeter, -screenY / pixelsPerMeter) #world to screen conversion def w2s(worldX, worldY): return (worldX * pixelsPerMeter, -worldY * pixelsPerMeter) pygame.init() screen = pygame.display.set_mode((640, 480)) pygame.display.set_caption('Body + Sprite Example') screen.fill((159, 182, 205)) worldAABB = b2AABB() worldAABB.lowerBound.Set(-100,-100) worldAABB.upperBound.Set(100,100) gravity = b2Vec2(0, -10) doSleep = True world = b2World(worldAABB, gravity, doSleep) bodyDef = b2BodyDef() bodyDef.position.Set(10,-10) bodyDef.fixedRotation = True body = world.CreateBody(bodyDef) body.SetLinearVelocity(b2Vec2(1.0,0.0)) shapeDef = b2PolygonDef() shapeDef.SetAsBox(1, 1) shapeDef.density = 1 shapeDef.restitution = 0.5 shapeDef.friction = 1.0 body.CreateShape(shapeDef) body.SetMassFromShapes() bodyDef2 = b2BodyDef() bodyDef2.position.Set(10,-20) body2 = world.CreateBody(bodyDef2) shapeDef2 = b2PolygonDef() shapeDef2.SetAsBox(50,.2) body2.CreateShape(shapeDef2) bodyDef3 = b2BodyDef() bodyDef3.position.Set(10,-11) body3 = world.CreateBody(bodyDef3) shapeDef3 = b2CircleDef() shapeDef3.radius = 1.0 shapeDef3.density = 1 shapeDef3.restitution = 0.5 shapeDef3.friction = 1.0 body3.CreateShape(shapeDef3) body3.SetMassFromShapes() jd = b2RevoluteJointDef() jd.Initialize(body, body3, b2Vec2(10,-11)) revJoint = world.CreateJoint(jd) BodySprite(body3,'wheel.png',2, 2, 0, 0, w2s, s2w) BodySprite(body,'pic2.png',2, 2, 0, 0,w2s,s2w) BodySprite(body2, 'pic2.png',100,.4,0,0,w2s,s2w) pygame.display.update() while True: count = 0 world.Step(1.0/60.0, 10) for event in pygame.event.get(): 0 for char in BodySprite.bodySpriteList: char.update() # Erase the old position by putting our blank Surface on it for char in BodySprite.bodySpriteList: screen.blit(char.blank, char.old) for char in BodySprite.bodySpriteList: screen.blit(char.image, char.rect) for char in BodySprite.bodySpriteList: pygame.display.update([char.old, char.rect])