def elasticCollision(self,o): """ Elastic collision with another object This changes the velocity of both objects """ normal = Vector( o.x - self.x, self.y - o.y ) normal.setVector( normal.getUnitVector() ) tangent = Vector( -normal.y, normal.x ) m1 = self.mass m2 = o.mass v1n = normal.dotProduct( self.velocity ) v1t = tangent.dotProduct( self.velocity ) v2n = normal.dotProduct( o.velocity ) v2t = tangent.dotProduct( o.velocity ) v1tPrime = v1t v2tPrime = v2t v1nPrime = (v1n*(m1-m2)+v2n*m2*2)/(m1+m2) v2nPrime = (v2n*(m2-m1)+v1n*m1*2)/(m1+m2) vectorV1nPrime = normal.multiply(v1nPrime) vectorV1tPrime = tangent.multiply(v1tPrime) vectorV2nPrime = normal.multiply(v2nPrime) vectorV2tPrime = tangent.multiply(v2tPrime) self.velocity = vectorV1nPrime.add(vectorV1tPrime).multiply(ELASTIC_COLLISION_DAMPENING) o.velocity = vectorV2nPrime.add(vectorV2tPrime).multiply(ELASTIC_COLLISION_DAMPENING)
def uncollide(self,o): """ moves this object out of the other object which prevents collision detection from changing velocity moar than once DOESN'T CHANGE VELOCITY """ if o.isCircle(): normal = Vector( o.centerx - self.centerx, self.centery - o.centery ) distanceToMove = self.width/2.0 + o.width/2.0 - normal.getMagnitude() normal.setVector( Vector (-normal.x, -normal.y ) ) normal.setVector( normal.getUnitVector() ) # set's to 1 so we can multiply better normal = normal.multiply( distanceToMove ); #gets short vector self.setX( self.x + normal.x) self.setY( self.y - normal.y) else: posRel = self.posRelTo(o) if posRel == 1: self.setY( self.y - ( self.y + self.height - o.y ) ) elif posRel == 2: self.setX( self.x - ( self.x + self.width - o.x ) ) elif posRel == 3: self.setX( self.x + ( o.x + o.width - self.x ) ) elif posRel == 4: self.setY( self.y + ( o.y + o.height - self.y ) ) else: self.setY( self.y - ( self.y + self.height - o.y ) ) #just move it up
def main(): import random pygame.init() window = pygame.display.set_mode((1024,768),0,32) pygame.display.set_caption("Physics Test") player = PhysicsCircle( 250, 250, 50,50,15 ) things = [player] leftPressed = False rightPressed = False downPressed = False upPressed = False fuel = 1024.0 font = pygame.font.Font(None, 15) text = font.render('Fuel', True, (255,255, 255)) textRect = text.get_rect() textRect.x = 20 textRect.y = 0 #something clevar to draw new platforms firstclick = None secondclick = None tempsecondclick = None pewpewpew = pygame.mixer.Sound("lazor.wav") platforms = [PhysicsRect(0,80,80,768-160,.5,.90), PhysicsRect(0,0,1024,80,.5,.90), PhysicsRect(1024-80,80,80,768-160,.5,.90), PhysicsRect(0,768-80,1024,80,.5,.90) #PhysicsRect(1024/2-200,768/2,400,50,.20,.90) ] isRunning = True while isRunning: window.fill(pygame.Color('black')) events = pygame.event.get() for event in events: #if event.type == QUIT: # exit() if event.type == MOUSEBUTTONDOWN: if event.button == 1: newDiam = random.randint(10,30) newVector = Vector((event.pos[0] - player.x)/10.0, (player.y - event.pos[1])/10.0) newNormal = newVector.getUnitVector() newCenterx = player.centerx + newNormal.multiply(player.width/2.0 + newDiam/2.0).x newCentery = player.centery - newNormal.multiply(player.width/2.0 + newDiam/2.0).y newX = newCenterx - newDiam/2.0 newY = newCentery - newDiam/2.0 newThing = PhysicsCircle(newX,newY,newDiam ,newDiam , newDiam/10.0, newVector,(random.randint(0,255),random.randint(0,255),random.randint(0,255))) things.append(newThing) pewpewpew.play() elif event.button == 3: if firstclick == None: firstclick = event.pos else: #clicked two times secondclick = event.pos #no negative rectangles second = False if firstclick[0]>secondclick[0]: secondclick = None firstclick = None tempsecondclick = None break else: width = secondclick[0]-firstclick[0] if firstclick[1]>secondclick[1]: secondclick = None firstclick = None tempsecondclick = None break else: height = secondclick[1]-firstclick[1] platforms.append(PhysicsRect(firstclick[0],firstclick[1],width,height,0,.90)) secondclick = None firstclick = None tempsecondclick = None elif event.type == MOUSEMOTION and firstclick != None: #draw temprect where the platform would be named tempsecondclick = event.pos elif event.type == KEYDOWN: if event.key == K_UP: upPressed = True if event.key == K_LEFT: leftPressed = True if event.key == K_RIGHT: rightPressed = True if event.key == K_DOWN: downPressed = True if event.key == K_ESCAPE: isRunning = False elif event.type == KEYUP: if event.key == K_UP: upPressed = False if event.key == K_LEFT: leftPressed = False if event.key == K_RIGHT: rightPressed = False if event.key == K_DOWN: downPressed = False #move "player" if fuel > 0: if leftPressed: player.addVelocity(Vector(-1.0,0)) fuel = fuel - 2 if downPressed: player.addVelocity(Vector(0.0,-1.0)) fuel = fuel - 2 if rightPressed: player.addVelocity(Vector(1.0,0.0)) fuel = fuel - 2 if upPressed: player.addVelocity(Vector(0.0,1.5)) fuel = fuel - 4 fuel += .5 for i in things: touched = len(i.move(Vector(0,0),things+platforms)) #print "Collision:" + str(j) if( i == player ): fuel += touched*5 i.draw(window) for i in platforms: i.draw(window) if fuel > 1024: fuel = 1024 if fuel > 0: if leftPressed: pygame.draw.rect(window, pygame.Color('orange'), pygame.Rect(player.right,player.centery-5,10,10)) if downPressed: pygame.draw.rect(window, pygame.Color('orange'), pygame.Rect(player.centerx-5,player.top-10,10,10)) if rightPressed: pygame.draw.rect(window, pygame.Color('orange'), pygame.Rect(player.left-10,player.centery-5,10,10)) if upPressed: pygame.draw.rect(window, pygame.Color('orange'), pygame.Rect(player.centerx-7,player.bottom,15,15)) pygame.draw.rect(window, pygame.Color('orange'), pygame.Rect(0,0,fuel,10)) #draw current click if firstclick != None and tempsecondclick != None: pygame.draw.rect(window,pygame.Color('firebrick'),pygame.Rect(firstclick,(tempsecondclick[0] - firstclick[0], tempsecondclick[1] - firstclick[1])),1) window.blit(text, textRect) pygame.display.flip() pygame.time.Clock().tick(30) pygame.display.quit() pygame.quit()