I have this pymunk universe. How can I make the box slowly push up from one of its corners with a set intensity for a set amount of time? (like pushes up with 50% effort (or something like that) for 2-3ish seconds?)
import pygame
import pymunk
import pymunk.pygame_util
import math
pygame.init()
WIDTH, HEIGHT = 1280, 720
window = pygame.display.set_mode((WIDTH, HEIGHT))
def draw(space, window, draw_options):
window.fill('white')
space.debug_draw(draw_options)
pygame.display.update()
def create_invisible_border(space, width, height, collision_type, friction=0.4, elasticity=0.9, thickness=100):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = (width/2, height/2)
space.add(body)
top_border = pymunk.Segment(body, (-width/2, height/2 + thickness), (width/2, height/2 + thickness), thickness)
bottom_border = pymunk.Segment(body, (-width/2, -height/2 - thickness), (width/2, -height/2 - thickness), thickness)
left_border = pymunk.Segment(body, (-width/2 - thickness, height/2), (-width/2 - thickness, -height/2), thickness)
right_border = pymunk.Segment(body, (width/2 + thickness, height/2), (width/2 + thickness, -height/2), thickness)
top_border.collision_type = collision_type
bottom_border.collision_type = collision_type
left_border.collision_type = collision_type
right_border.collision_type = collision_type
top_border.friction = friction
bottom_border.friction = friction
left_border.friction = friction
right_border.friction = friction
top_border.elasticity = elasticity
bottom_border.elasticity = elasticity
left_border.elasticity = elasticity
right_border.elasticity = elasticity
space.add(top_border, bottom_border, left_border, right_border)
def create_static_circle(space, x_pos, y_pos, collision_type, radius):
body = pymunk.Body(body_type=pymunk.Body.STATIC)
body.position = x_pos, y_pos
space.add(body)
shape = pymunk.Circle(body, radius)
shape.collision_type = collision_type
space.add(shape)
return body
def create_object(space, mass, size, x, y, collision_type, friction = 0.4, elasticity = 0.9):
moment = pymunk.moment_for_box(mass, size)
body = pymunk.Body(mass, moment)
body.position = x, y
shape = pymunk.Poly.create_box(body, size)
shape.elasticity = elasticity
shape.friction = friction
shape.collision_type = collision_type
space.add(body, shape)
return body
def run(window, width, height):
run = True
clock = pygame.time.Clock()
fps = 60
dt = 1/fps
space = pymunk.Space()
space.gravity = (0, 981)
create_invisible_border(space, width, height, 2)
create_static_circle(space, 1050, 160, 3, 25)
object = create_object(space, 1, (100, 100), 300, 300, 1, elasticity = 0.2)
draw_options = pymunk.pygame_util.DrawOptions(window)
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
break
draw(space, window, draw_options)
space.step(dt)
clock.tick(fps)
pygame.quit()
if __name__ == '__main__':
run(window, WIDTH, HEIGHT)
I tried playing with impulses and came to this code, but it is nothing like how I want it to work, though I think it is a step in the right direction.
def jump(body, angle, strength):
x = strength * math.cos(math.radians(angle))
y = strength * math.sin(math.radians(angle))
body.apply_impulse_at_local_point((x, y))
def jump_if_collided(arbiter, space, data, body, degrees, intensity):
if arbiter.shapes[0].collision_type == 1 and arbiter.shapes[1].collision_type == 2:
jump(body, degrees, intensity)
return True
Then, this was called in the run function
space.add_collision_handler(1, 2).begin = lambda arbiter, space, data: jump_if_collided(arbiter, space, data, object, 135, 1000)