Talk:Physics Jam/Help
Jump to navigation
Jump to search
Some sample code for 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])