def draw_cg(self): """Draw the center of gravity.""" screen = pygame.display.get_surface() for b in App.current.space.bodies: cg = b.position + b.center_of_gravity p = to_pygame(cg, screen) pygame.draw.circle(screen, BLUE, p, 5, 1)
def DrawEverything(self,flag=0): ### Write Everything On The Game Window ### img = pygame.image.load("./assets/intel.jpg") x, y = 580,550 AdjustedImagePosition = (x-50,y+50) screen.blit(img,to_pygame(AdjustedImagePosition,screen)) if(flag==0 and self.DetectCrash == 0): (self.BotRect.x,self.BotRect.y) = self.Bot.position[0],600-self.Bot.position[1] self.CircleRect = pygame.draw.circle(screen, (169,169,169), (self.BotRect.x,self.BotRect.y), 20, 0) ## If Collision Detected Draw Green elif(flag==0 and self.DetectCrash >= 1): (self.BotRect.x,self.BotRect.y) = self.Bot.position[0],600-self.Bot.position[1] self.CircleRect = pygame.draw.circle(screen, (0,255,0), (self.BotRect.x,self.BotRect.y), 20, 0) ## If Collision Detected Draw Red else: (self.BotRect.x,self.BotRect.y) = self.Bot.position[0],600-self.Bot.position[1] self.CircleRect = pygame.draw.circle(screen, (255,0,0), (self.BotRect.x,self.BotRect.y), 20, 0) img = pygame.image.load("./assets/spherelight.png") offset = Vec2d(img.get_size()) / 2. x, y = self.Bot.position y = 600.0 -y AdjustedImagePosition = (x,y) - offset screen.blit(img,AdjustedImagePosition) for ob in self.WallRects: pygame.draw.rect(screen, (169,169, 169), ob)
def draw_everything(self,flag=0): img = pygame.image.load("./assets/intel.jpg") x, y = 580,550 adjusted_img_position = (x-50,y+50) screen.blit(img,to_pygame(adjusted_img_position,screen)) if(flag==0 and self.detect_crash == 0): (self.bot_rect.x,self.bot_rect.y) = self.bot.position[0],600-self.bot.position[1] self.circle_rect = pygame.draw.circle(screen, (169,169,169), (self.bot_rect.x,self.bot_rect.y), 20, 0) elif(flag==0 and self.detect_crash >= 1): (self.bot_rect.x,self.bot_rect.y) = self.bot.position[0],600-self.bot.position[1] self.circle_rect = pygame.draw.circle(screen, (0,255,0), (self.bot_rect.x,self.bot_rect.y), 20, 0) else: (self.bot_rect.x,self.bot_rect.y) = self.bot.position[0],600-self.bot.position[1] self.circle_rect = pygame.draw.circle(screen, (255,0,0), (self.bot_rect.x,self.bot_rect.y), 20, 0) img = pygame.image.load("./assets/spherelight.png") offset = Vec2d(img.get_size()) / 2. x, y = self.bot.position y = 600.0 -y adjusted_img_position = (x,y) - offset screen.blit(img,adjusted_img_position) for ob in self.wall_rects: pygame.draw.rect(screen, (169,169, 169), ob)
def hitbox(self, attack, pos, radius, damage, source): numHit = 0 pygame.draw.circle(self.screen, pygame.color.THECOLORS['pink'], to_pygame(pos, self.screen), radius) for entity in self.entities: if entity != source: if pos.get_distance(entity.position) < radius: numHit += 1 entity.onDamaged(attack, damage) return numHit
def draw(self, screen, tile_id, position): if not tile_id: return # There was nothing to be drawn tile_id -= 1 # we're 1-indexed in Tiled tiles_wide = self.img.get_width() // self.tile_width source_x = (tile_id % tiles_wide) * self.tile_width source_y = (tile_id // tiles_wide) * self.tile_height screen.blit(self.img, to_pygame(position, screen), (source_x, source_y, self.tile_width, self.tile_height))
def updateCamera(screen, game, center, space, draw_options): x, y = screen.get_size() c_x, c_y = pygame_util.to_pygame(center, game) dest = max(c_x - x // 2, 0), max(c_y - y // 2, 0) print((x, y), (c_x, c_y), dest) screen.fill((0, 0, 0)) graph.drawStars(screen, center) game.blit(screen, dest) space.debug_draw(draw_options) screen.blit(game, (0, 0), pg.Rect(dest[0], dest[1], x, y))
def draw_polygon(self, verts, radius, outline_color, fill_color): ps = [ppu.to_pygame(v, self.surface) for v in verts] ps += [ps[0]] pygame.draw.polygon(self.surface, fill_color, ps) if radius < 1 and False: pygame.draw.lines(self.surface, outline_color, False, ps) else: pygame.draw.lines(self.surface, outline_color, False, ps, int(radius * 2))
def draw_build_hint(self, graph, r=8, linewidth=1): ''' Метод для рисования подсказки на экране во время строительства. Подсказка разная для двух случаев (аналогичны случаям при строительстве, см. метод build в ShapeCreator): Если подходящие для строительства узлы не соседи друг другу, то рисуем линию между ними. Если подходящие для строительства узлы соседи друг другу, то рисуем круг, там где будет новый узел, и 2 линии. Аргументы: ---------- graph : Graph Объект, который даст нам доступ к фиксированным Ду, подходящим для строительства. r : int Радиус рисуемого круга. ''' if len(graph.fixed_doo_for_build) == 2: if graph.fixed_doo_for_build[0] in graph[graph.fixed_doo_for_build[1]]: pg.draw.line(self, (0, 200, 0), to_pygame(graph.fixed_doo_for_build[0].body.position, self), to_pygame(self.shape_being_dragged.body.position, self), linewidth) pg.draw.line(self, (0, 200, 0), to_pygame(graph.fixed_doo_for_build[1].body.position, self), to_pygame(self.shape_being_dragged.body.position, self), linewidth) pg.draw.circle(self, (0, 200, 0), to_pygame(self.shape_being_dragged.body.position, self), r) else: pg.draw.line(self, (0, 200, 0), to_pygame(graph.fixed_doo_for_build[0].body.position, self), to_pygame(graph.fixed_doo_for_build[1].body.position, self))
def draw(self, DEBUG): for s in self.soldiers: s.draw(DEBUG) if DEBUG: # DRAW CONVEX HULL inf_simplices, fight_simplices = self.formation.get_hulls(for_draw=True) for p1, p2 in inf_simplices: pygame.draw.line( self.game.screen, (0, 0, 0), (p1[0], p2[0]), (p1[1], p2[1]) ) for p1, p2 in fight_simplices: pygame.draw.line( self.game.screen, (0, 0, 0), (p1[0], p2[0]), (p1[1], p2[1]) ) # DRAW DIRECTION center, direction = self.pos_direction p1 = to_pygame(center, self.game.screen) p2 = to_pygame(center + direction*30, self.game.screen) pygame.draw.aalines(self.game.screen, GREEN, False, [p1,p2], 10)
def draw(self, DEBUG): pos = to_pygame(self.body.position, self.game.screen) pygame.draw.circle(self.game.screen, self.col, pos, self.radius) if self.unit.is_selected: pygame.draw.circle(self.game.screen, BLACK, pos, self.radius - 1) if DEBUG: # if self.unit.is_selected: # pygame.draw.circle(self.game.screen, BLACK, pos, self.radius - 1) # DRAW ARROW TO TARGET p1 = to_pygame(self.body.position, self.game.screen) p2 = to_pygame(self.target_position, self.game.screen) pygame.draw.aalines(self.game.screen, BLUE, False, [p1, p2]) # DRAW VELOCITY # p1 = to_pygame(self.body.position, self.game.screen) # p2 = to_pygame(self.body.position + self.body.velocity.normalized() * 100, self.game.screen) # pygame.draw.aalines(self.game.screen, BLUE, False, [p1,p2]) # DRAW COORDINATES # draw_text(f"{self.coord[0]},{self.coord[1]}", self.game.screen, self.game.font, self.body.position, # np.pi) pass
def draw_circle(self, r=12, width=1): ''' Метод для рисования окружности около Ду, находящегося под курсором мыши. Перед рисованием находим координаты центра Ду в координатной системе поверхности world. Так как окружность рисуем именно на этой поверхности. Аргументы: ---------- r : int Радиус окружности в пикселях. width : int Толщина окружности в пикселях. ''' if self.free_doo_under_cursor != None: doo_center = to_pygame(self.free_doo_under_cursor.body.position, self) pg.draw.circle(self, [200,0,0], doo_center, r, width)
def draw(self, screen, camera): # match sprite to the physics object position = self.body.position - camera + SCREEN_HALF position = Vec2d(to_pygame(position, screen)) # play different animations depending on what's going on # TODO: These are all screwed up flip = self.current_facing == self.left_key if self.health <= 0: self.death_sequence.draw(screen, position, flip) if self.death_sequence.done: # respawn self.health = self.max_health self.body.position = Vec2d(100, 100) elif self.landed and abs(self.feet.surface_velocity.x) > 1: # walking self.walk_loop.draw(screen, position, flip) elif self.landed: # idle self.idle_loop.draw(screen, position, flip) elif self.remaining_jumps > 0: # falling self.jump_loop.draw(screen, position, flip) elif self.remaining_jumps == 0: # spinning self.spin_loop.draw(screen, position, flip) else: # I dunno what else to do self.idle_loop.draw(screen, position, flip) # Draw health bar health_percent = max(float(self.health) / self.max_health, 0) if health_percent: rect = (position.x, position.y - 35, 30 * health_percent, 5) pygame.draw.rect(screen, (255, 0, 0, 0), rect) # Did we land? if self.landed_hard: self.fall_sound.play() # Draw our bullets for bullet in self.bullets: bullet.draw(screen, camera)
def get_hulls(self, for_draw=False): points = np.array(self.unit.get_soldiers_pos(False)) if for_draw: for i in range(len(points)): points[i] = to_pygame(list(points[i]), self.unit.game.screen) center = points.mean(0) inf_hull_ = ConvexHull(points) inf_hull = Polygon(points[inf_hull_.vertices]) expanded = [] for ind1, ind2 in zip( inf_hull_.vertices, inf_hull_.vertices[1:].tolist() + [inf_hull_.vertices[0]]): v1 = Vec2d(list(points[ind1])) v2 = Vec2d(list(points[ind2])) p_norm = (v1 - v2).perpendicular_normal() * self.melee_range if (v1 + p_norm - center).length < (v1 - center).length: p_norm = -p_norm v1 = v1 + p_norm v2 = v2 + p_norm expanded.append(v1) expanded.append(v2) expanded = np.array([list(p) for p in expanded]) hull = ConvexHull(expanded) fight_hull = Polygon(expanded[hull.vertices]) if not for_draw: # we only need polygons if we are not drawing return inf_hull, fight_hull inf_simplices = [] for simplex in inf_hull_.simplices: inf_simplices.append( (points[simplex, 0].tolist(), points[simplex, 1].tolist())) fight_simplices = [] for simplex in hull.simplices: fight_simplices.append( (expanded[simplex, 0].tolist(), expanded[simplex, 1].tolist())) return inf_simplices, fight_simplices
def draw(self, screen, camera): # match sprite to the physics object position = self.body.position - camera + SCREEN_HALF position = Vec2d(to_pygame(position, screen)) # play different animations depending on what's going on # TODO: These are all screwed up flip = self.current_facing == self.left_key if self.health <= 0: self.death_sequence.draw(screen, position, flip) elif self.landed and abs(self.feet.surface_velocity.x) > 1: # walking self.walk_loop.draw(screen, position, flip) elif self.landed: # idle self.idle_loop.draw(screen, position, flip) elif self.remaining_jumps > 0: # falling self.jump_loop.draw(screen, position, flip) elif self.remaining_jumps == 0: # spinning self.spin_loop.draw(screen, position, flip) else: # I dunno what else to do self.idle_loop.draw(screen, position, flip) # Draw health bar health_percent = max(float(self.health) / self.max_health, 0) if health_percent: rect = (position.x, position.y - 35, 30 * health_percent, 5) pygame.draw.rect(screen, (255, 0, 0, 0), rect) # Did we land? if self.landed_hard: self.fall_sound.play() # Draw our bullets for bullet in self.bullets: bullet.draw(screen, camera)
def draw_dot(self, size, pos, color): p = ppu.to_pygame(pos, self.surface) pygame.draw.circle(self.surface, color, p, int(size), 0)
motor_speed -= acc * dt motor_speed = max(motor_speed, -max_speed) elif keys[K_a]: motor_speed += acc * dt motor_speed = min(motor_speed, max_speed) else: sign = math.copysign(1, motor_speed) motor_speed += (dec * dt) * -sign if math.copysign(1, motor_speed) != sign: motor_speed = 0 for m in motors: m.rate = motor_speed space.step(dt) scroll = Vec2d(screen_rect.center) - to_pygame(car.position, screen) screen.fill(pygame.color.THECOLORS["white"]) for body, shape in sprites: if isinstance(shape, pymunk.Circle): screen_center = to_pygame(body.position, screen) + scroll pygame.draw.circle(screen, (0, 0, 0), screen_center, shape.radius) edge = to_pygame( body.position + Vec2d(shape.radius, 0).rotated(body.angle), screen) + scroll pygame.draw.line(screen, (255, 255, 255), screen_center, edge) elif isinstance(shape, pymunk.Poly): vertices = shape.get_vertices() transformed_vertices = [ v.rotated(body.angle) + body.position for v in vertices
def draw_fat_segment(self, a, b, radius, outline_color, fill_color): p1 = ppu.to_pygame(a, self.surface) p2 = ppu.to_pygame(b, self.surface) r = int(max(1, radius * 2)) pygame.draw.lines(self.surface, fill_color, False, [p1, p2], r)
def draw_segment(self, a, b, color): p1 = ppu.to_pygame(a, self.surface) p2 = ppu.to_pygame(b, self.surface) pygame.draw.aalines(self.surface, color, False, [p1, p2])
def draw_circle(self, pos, angle, radius, outline_color, fill_color): p = ppu.to_pygame(pos, self.surface) pygame.draw.circle(self.surface, fill_color, p, int(radius), 0)
trajectory = np.array(game.mouse_traj) trajectory = trajectory + np.random.randn(len(trajectory), 2) * 0.0001 selected_unit.set_spline_formation_trajectory( start_dir, final_dir, trajectory, True) game.mouse_traj = [] game.draw(DEBUG) for u in units: u.draw(DEBUG) # for cur_traj_form in traj_form: if not selected_unit is None: traj_form = selected_unit.traj for i in range(len(traj_form) - 1): p1 = to_pygame(traj_form[i], game.screen) p2 = to_pygame(traj_form[i + 1], game.screen) pygame.draw.aalines(game.screen, (0, 0, 0), False, [p1, p2]) pygame.display.flip() game.clock.tick(game.fps) if game.record: arr = pygame.surfarray.array3d(game.screen).swapaxes(1, 0) game.video.append(arr.astype(np.uint8)) # %% OLD CODE FOR TRAJECTORY SPLINE NOW IMPLEMENTED IN THE UNIT # angle_th = 50 # SPLINE_DISTANCE_POINT = 50
def draw(self, screen, camera): if not self.active: return position = to_pygame(self.body.position - camera + SCREEN_HALF, screen) pygame.draw.circle(screen, (0, 0, 0, 0), position, self.radius)
def main(): ### PyGame init pygame.init() clock = pygame.time.Clock() running = True ### Physics stuff space.gravity = 0,-980 static= [pymunk.Segment(space.static_body, (10, 50), (10, 590), 5), pymunk.Segment(space.static_body, (500, 200), (900,200), 5), pymunk.Segment(space.static_body, (500, 100), (900,100), 5), pymunk.Segment(space.static_body, (500, 300), (900,300), 5), pymunk.Segment(space.static_body, (500, 100), (450,150), 5), pymunk.Segment(space.static_body, (10, 590), (890, 590), 5) ] for s in static: s.friction = 1. s.group = 1 space.add(static) # "Cannon" that can fire arrows cannon_body = pymunk.Body(10, 10) cannon_shape = pymunk.Circle(cannon_body, .1) cannon_shape.ignore_draw=True #~ cannon_shape.sensor = True cannon_body.position = 100,150 #~ space.add(cannon_shape) ball_body,ball_shape = create_ball() pig_body,pig_shape = create_pig() #~ ball_shape.ignore_draw=True while running: start=Vec2d (100,300) for event in pygame.event.get(): mp=from_pygame( (pygame.mouse.get_pos()), screen ) if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False elif pygame.mouse.get_pressed()[1]: pig_body.position=mp space.add(pig_body) space.add(pig_shape) pig_body, pig_shape = create_pig() print len(space.shapes) break elif event.type == pygame.MOUSEMOTION and pygame.mouse.get_pressed()[0]: cannon_body.position =Vec2d (mp[0],mp[1]) print cannon_body.position elif event.type == pygame.MOUSEBUTTONUP and pygame.mouse.get_pressed()[1]==False: diff = -1*(Vec2d(mp) - start) print("abs="+str(diff)) cannon_body.position =start impulse = diff* 75 ball_body.apply_impulse(impulse.rotated(ball_body.angle)) space.add(ball_body) #~ ball_shape.ignore_draw=True ball_body, ball_shape = create_ball() space.add(ball_shape) mouse_position = from_pygame( Vec2d(pygame.mouse.get_pos()), screen ) cannon_body.angle = (mouse_position - cannon_body.position).angle # move the unfired ball together with the cannon ball_body.position = cannon_body.position ball_body.angle = cannon_body.angle ### Clear screen screen.fill(pygame.color.THECOLORS["white"]) ### Draw stuff background = os.path.join("bgsl.png") background_surface = pygame.image.load(background) screen.blit(background_surface, (0,0)) #~ animation_offset = 32*0 col=[] pigs=[] for x in space.shapes: if x.body.mass>1: col.append(x) else: pigs.append(x) #~ print len(col) for x in col: tem=x.body.position tem=list(tem) pos=tem[0]-20,tem[1]+20 #~ position=5 #~ print (s) screen.blit(img, to_pygame(pos, screen)) for x in pigs: tem=x.body.position tem=list(tem) pos=tem[0]-30,tem[1]+20 #~ position=5 #~ print (s) screen.blit(pigimg, to_pygame(pos, screen)) draw_space(screen, space) pygame.display.flip() ### Update physics fps = 60 dt = 1./fps space.step(dt) clock.tick(fps)
def main(): pygame.init() pygame.font.init() screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() tunings = (27, 2, 10) pid = PID(*tunings, output_limits=(-8000, 8000), proportional_on_measurement=True) pid.sample_time = 1 / REFRESH draw_options = DrawOptions(screen) pymunk.pygame_util.positive_y_is_up = True font = pygame.font.SysFont('Lucida Console', 11) space = pymunk.Space() space.gravity = 0, -100 x = random.randint(120, 380) drone = Drone((x, 450), space) ground = Ground(space) setpoint = 450 ticks = 0 while True: for event in pygame.event.get(): # print(event) if event.type == pygame.QUIT: sys.exit(0) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: setpoint += 5 elif event.key == pygame.K_DOWN: setpoint -= 5 elif event.key == pygame.K_ESCAPE: sys.exit(0) elif event.key == pygame.K_1: p, i, d = pid.tunings pid.tunings = (p + 0.5, i, d) elif event.key == pygame.K_q: p, i, d = pid.tunings pid.tunings = (p - 0.5, i, d) elif event.key == pygame.K_2: p, i, d = pid.tunings pid.tunings = (p, i + 0.5, d) elif event.key == pygame.K_w: p, i, d = pid.tunings pid.tunings = (p, i - 0.5, d) elif event.key == pygame.K_3: p, i, d = pid.tunings pid.tunings = (p, i, d + 0.5) elif event.key == pygame.K_e: p, i, d = pid.tunings pid.tunings = (p, i, d - 0.5) elif event.type == pygame.MOUSEBUTTONUP: setpoint = 600 - event.pos[1] # ticks=0 screen.fill((0, 0, 0)) error = drone.body.position.y - setpoint output = pid(error) space.debug_draw(draw_options) # if drone.shape.body.position.y < setpoint: if True: # output > 0: # drone.shape.body.apply_force_at_local_point((0, 340), (0, 0)) drone.shape.body.apply_force_at_local_point((0, output), (0, 0)) c = to_pygame(drone.body.position, screen) pygame.draw.aaline(screen, (0, 128, 255, .75), c, (c[0], c[1] - output // 10)) pygame.draw.aaline(screen, (128, 255, 128, .125), to_pygame((50, setpoint), screen), to_pygame((600 - 50, setpoint), screen)) # pygame.draw.aaline(screen, (255, 255, 255, .5), to_pygame((0,0), screen), to_pygame((100,100), screen)) textsurface = font.render( f"pos:{drone.body.position.y:7.1f} set:{setpoint} error:{error:7.1f} o:{output:7.1f}", False, WHITE) screen.blit(textsurface, (10, 10)) textsurface = font.render( f"pid:{['{:7.1f}'.format(p) for p in pid.components]}", False, WHITE) screen.blit(textsurface, (10, 25)) textsurface = font.render( f"tun:{['{:7.1f}'.format(p) for p in pid.tunings]}", False, WHITE) screen.blit(textsurface, (10, 40)) textsurface = font.render(f"ticks:{ticks}", False, WHITE) screen.blit(textsurface, (10, 55)) space.step(1 / REFRESH) pygame.display.update() clock.tick(REFRESH) pygame.display.set_caption(f"{drone.body.position.y:.1f} {setpoint}") ticks += 1
def draw_text(t, screen, font, pos, angle, col=YELLOW): pos = to_pygame(pos, screen) text = font.render(t, True, col) text = pygame.transform.rotate(text, angle) text_rect = text.get_rect(center=pos) screen.blit(text, text_rect)
def main(): ### PyGame init pygame.init() screen = pygame.display.set_mode((width,height)) clock = pygame.time.Clock() running = True font = pygame.font.SysFont("Arial", 16) sound = pygame.mixer.Sound("sfx.wav") img = pygame.image.load("xmasgirl1.png") ### Physics stuff space = pymunk.Space() space.gravity = 0,-1000 # box walls static = [pymunk.Segment(space.static_body, (10, 50), (300, 50), 5) , pymunk.Segment(space.static_body, (300, 50), (325, 50), 5) , pymunk.Segment(space.static_body, (325, 50), (350, 50), 5) , pymunk.Segment(space.static_body, (350, 50), (375, 50), 5) , pymunk.Segment(space.static_body, (375, 50), (680, 50), 5) , pymunk.Segment(space.static_body, (680, 50), (680, 370), 5) , pymunk.Segment(space.static_body, (680, 370), (10, 370), 5) , pymunk.Segment(space.static_body, (10, 370), (10, 50), 5) ] static[1].color = pygame.color.THECOLORS['red'] static[2].color = pygame.color.THECOLORS['green'] static[3].color = pygame.color.THECOLORS['red'] # rounded shape rounded = [pymunk.Segment(space.static_body, (500, 50), (520, 60), 5) , pymunk.Segment(space.static_body, (520, 60), (540, 80), 5) , pymunk.Segment(space.static_body, (540, 80), (550, 100), 5) , pymunk.Segment(space.static_body, (550, 100), (550, 150), 5) ] # static platforms platforms = [pymunk.Segment(space.static_body, (170, 50), (270, 150), 5) #, pymunk.Segment(space.static_body, (270, 100), (300, 100), 5) , pymunk.Segment(space.static_body, (400, 150), (450, 150), 5) , pymunk.Segment(space.static_body, (400, 200), (450, 200), 5) , pymunk.Segment(space.static_body, (220, 200), (300, 200), 5) , pymunk.Segment(space.static_body, (50, 250), (200, 250), 5) , pymunk.Segment(space.static_body, (10, 370), (50, 250), 5) ] for s in static + platforms+rounded: s.friction = 1. s.group = 1 space.add(static, platforms+rounded) # moving platform platform_path = [(650,100),(600,200),(650,300)] platform_path_index = 0 platform_body = pymunk.Body(pymunk.inf, pymunk.inf) platform_body.position = 650,100 s = pymunk.Segment(platform_body, (-25, 0), (25, 0), 5) s.friction = 1. s.group = 1 s.color = pygame.color.THECOLORS["blue"] space.add(s) # pass through platform passthrough = pymunk.Segment(space.static_body, (270, 100), (320, 100), 5) passthrough.color = pygame.color.THECOLORS["yellow"] passthrough.friction = 1. passthrough.collision_type = 2 passthrough.layers = passthrough.layers ^ 0b1000 space.add(passthrough) def passthrough_handler(space, arbiter): if arbiter.shapes[0].body.velocity.y < 0: return True else: return False space.add_collision_handler(1,2, begin=passthrough_handler) # player body = pymunk.Body(5, pymunk.inf) body.position = 100,100 head = pymunk.Circle(body, 10, (0,5)) head2 = pymunk.Circle(body, 10, (0,13)) feet = pymunk.Circle(body, 10, (0,-5)) head.layers = head2.layers = 0b1000 feet.collision_type = 1 feet.ignore_draw = head.ignore_draw = head2.ignore_draw = True space.add(body, head, feet,head2) direction = 1 remaining_jumps = 2 landing = {'p':Vec2d.zero(), 'n':0} frame_number = 0 landed_previous = False while running: grounding = { 'normal' : Vec2d.zero(), 'penetration' : Vec2d.zero(), 'impulse' : Vec2d.zero(), 'position' : Vec2d.zero(), 'body' : None } # find out if player is standing on ground def f(arbiter): n = -arbiter.contacts[0].normal if n.y > grounding['normal'].y: grounding['normal'] = n grounding['penetration'] = -arbiter.contacts[0].distance grounding['body'] = arbiter.shapes[1].body grounding['impulse'] = arbiter.total_impulse grounding['position'] = arbiter.contacts[0].position body.each_arbiter(f) well_grounded = False if grounding['body'] != None and abs(grounding['normal'].x/grounding['normal'].y) < feet.friction: well_grounded = True remaining_jumps = 2 ground_velocity = Vec2d.zero() if well_grounded: ground_velocity = grounding['body'].velocity for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "platformer.png") elif event.type == KEYDOWN and event.key == K_d: feet.ignore_draw = not feet.ignore_draw head.ignore_draw = not head.ignore_draw head2.ignore_draw = not head2.ignore_draw elif event.type == KEYDOWN and event.key == K_UP: if well_grounded or remaining_jumps > 0: jump_v = math.sqrt(2.0 * JUMP_HEIGHT * abs(space.gravity.y)) body.velocity.y = ground_velocity.y + jump_v; remaining_jumps -=1 elif event.type == KEYUP and event.key == K_UP: body.velocity.y = min(body.velocity.y, JUMP_CUTOFF_VELOCITY) # Target horizontal velocity of player target_vx = 0 if body.velocity.x > .01: direction = 1 elif body.velocity.x < -.01: direction = -1 keys = pygame.key.get_pressed() if (keys[K_LEFT]): direction = -1 target_vx -= PLAYER_VELOCITY if (keys[K_RIGHT]): direction = 1 target_vx += PLAYER_VELOCITY if (keys[K_DOWN]): direction = -3 feet.surface_velocity = target_vx,0 if grounding['body'] != None: feet.friction = -PLAYER_GROUND_ACCEL/space.gravity.y head.friciton = HEAD_FRICTION else: feet.friction,head.friction = 0,0 # Air control if grounding['body'] == None: body.velocity.x = cpflerpconst(body.velocity.x, target_vx + ground_velocity.x, PLAYER_AIR_ACCEL*dt) body.velocity.y = max(body.velocity.y, -FALL_VELOCITY) # clamp upwards as well? # Move the moving platform destination = platform_path[platform_path_index] current = Vec2d(platform_body.position) distance = current.get_distance(destination) if distance < PLATFORM_SPEED: platform_path_index += 1 platform_path_index = platform_path_index % len(platform_path) t = 1 else: t = PLATFORM_SPEED / distance new = current.interpolate_to(destination, t) platform_body.position = new platform_body.velocity = (new - current) / dt ### Clear screen screen.fill(pygame.color.THECOLORS["black"]) ### Helper lines for y in [50,100,150,200,250,300]: color = pygame.color.THECOLORS['darkgrey'] pygame.draw.line(screen, color, (10,y), (680,y), 1) ### Draw stuff draw(screen, space) if feet.ignore_draw: direction_offset = 48+(1*direction+1)/2 * 48 if grounding['body'] != None and abs(target_vx) > 1: animation_offset = 32 * (frame_number / 8 % 4) elif grounding['body'] is None: animation_offset = 32*1 else: animation_offset = 32*0 position = body.position +(-16,28) screen.blit(img, to_pygame(position, screen), (animation_offset, direction_offset, 32, 48)) # Did we land? if abs(grounding['impulse'].y) / body.mass > 200 and not landed_previous: sound.play() landing = {'p':grounding['position'],'n':5} landed_previous = True else: landed_previous = False if landing['n'] > 0: pygame.draw.circle(screen, pygame.color.THECOLORS['yellow'], to_pygame(landing['p'], screen), 5) landing['n'] -= 1 # Info and flip screen screen.blit(font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0,0)) screen.blit(font.render("Move with Left/Right, jump with Up, press again to double jump", 1, THECOLORS["darkgrey"]), (5,height - 35)) screen.blit(font.render("Press D to toggle sprite draw, ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5,height - 20)) pygame.display.flip() frame_number += 1 ### Update physics space.step(dt) clock.tick(fps)