Talk:Physics Jam/Help

From OLPC
< Talk:Physics Jam
Revision as of 14:49, 30 August 2008 by 18.85.18.34 (talk) (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)...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, 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])