""" 这是一个动画,它不断地产生物理弹球,弹球掉落在由两段线条组成的L形状上会有反弹效果。 """ import random import pygame from pygame.key import * from pygame.locals import * from pygame.color import * import pymunk import pymunk.pygame_util class BouncyBalls(object): """ 这个类实现一个简单的平台上有着随机掉落的弹球场景。 """ def __init__(self): self._space = pymunk.Space() # 新建重力空间 self._space.gravity = (0.0, -900.0) # 重力加速度 self._dt = 1.0 / 60.0 # 这里应该是60分之一秒更新一次重力空间 # 屏幕每一帧执行的物理刷新次数 self._physics_steps_per_frame = 1 # pygame 初始化 pygame.init() self._screen = pygame.display.set_mode((600, 600)) self._clock = pygame.time.Clock() self._draw_options = pymunk.pygame_util.DrawOptions(self._screen) print(self._draw_options) # 添加棍子,弹球碰到它会反弹 self._add_static_scenery() # 所有的球在这个列表中 self._balls = [] # 主循环逻辑变量与产生球的时隔 self._running = True self._ticks_to_next_ball = 10 def run(self): """ 这里是场景的主要循环 """ while self._running: # 每帧执行几次物理计算过程? for x in range(self._physics_steps_per_frame): self._space.step(self._dt) self._process_events() self._update_balls() self._clear_screen() self._draw_objects() pygame.display.flip() # Delay fixed time between frames self._clock.tick(50) pygame.display.set_caption("fps: " + str(self._clock.get_fps())) pygame.quit() def _add_static_scenery(self): """ 创建静止不动的两根棍子 """ static_body = self._space.static_body static_lines = [pymunk.Segment(static_body, (111.0, 280.0), (407.0, 246.0), 0.0), pymunk.Segment(static_body, (407.0, 246.0), (407.0, 343.0), 0.0)] for line in static_lines: line.elasticity = 0.95 line.friction = 0.9 self._space.add(static_lines) def _process_events(self): """ Handle game and events like keyboard input. Call once per frame only. :return: None """ for event in pygame.event.get(): if event.type == QUIT: self._running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: self._running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(self._screen, "bouncing_balls.png") def _update_balls(self): """ 每帧调用一次,创建球或者移出y坐标小于100的弹球。Create/remove balls as necessary. Call once per frame only. :return: None """ self._ticks_to_next_ball -= 1 if self._ticks_to_next_ball <= 0: self._create_ball() self._ticks_to_next_ball = 100 # Remove balls that fall below 100 vertically balls_to_remove = [ball for ball in self._balls if ball.body.position.y < 100] for ball in balls_to_remove: self._space.remove(ball, ball.body) self._balls.remove(ball) def _create_ball(self): """ 创建一个物理 弹球 """ mass = 10 radius = 25 inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) body = pymunk.Body(mass, inertia) x = random.randint(115, 350) body.position = x, 400 shape = pymunk.Circle(body, radius, (0, 0)) shape.elasticity = 0.95 # 弹性系数 shape.friction = 0.9 # 摩擦系数 self._space.add(body, shape) self._balls.append(shape) def _clear_screen(self): """ 清屏为白色 """ self._screen.fill(THECOLORS["white"]) def _draw_objects(self): """ 画各个物体 """ self._space.debug_draw(self._draw_options) if __name__ == '__main__': game = BouncyBalls() game.run()
以下是函数实现的,不过当小球离开屏幕时并没有把它删除,并且左边掉落的小球为什么会有瞬移现象出现呢?
import sys, random import pygame from pygame.locals import * import pymunk import pymunk.pygame_util def add_static_L(space): body = pymunk.Body(body_type = pymunk.Body.STATIC) # 增加静态实体 body.position = (300, 300) shape1 = pymunk.Segment(body, (-150, 0), (255, 0), 5) # 此坐标是相对于(300,300)为原点的 shape1.elasticity = 0.95 # 弹性系数 shape1.friction = 0.9 # 摩擦系数 shape2 = pymunk.Segment(body, (-150, 0), (-150, 50), 5) # y坐标相反 shape2.elasticity = 0.95 # 弹性系数 shape2.friction = 0.9 # 摩擦系数 space.add(shape1, shape2) # 增加到物理空间 return shape1,shape2 def add_ball(space): mass = 1 radius = 14 moment = pymunk.moment_for_circle(mass, 0, radius) # 求一定质量和半径的小球的转动惯量,返回浮点数 body = pymunk.Body(mass, moment) # 新建刚体 x = random.randint(120, 380) # 随机x坐标 body.position = x, 550 # 定位 shape = pymunk.Circle(body, radius) # 设形状 shape.elasticity = 0.95 # 弹性系数 shape.friction = 0.9 # 摩擦系数 space.add(body, shape) # 放到物理空间 return shape def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) pygame.display.set_caption("自由落体小球") clock = pygame.time.Clock() space = pymunk.Space() space.gravity = (0.0, -900.0) lines = add_static_L(space) balls = [] draw_options = pymunk.pygame_util.DrawOptions(screen) # 设定space内物体的渲染面 ticks_to_next_ball = 10 running = True while running: for event in pygame.event.get(): if event.type in( QUIT,KEYDOWN,K_ESCAPE): running = False break ticks_to_next_ball -= 1 if ticks_to_next_ball <= 0: ticks_to_next_ball = 25 ball_shape = add_ball(space) balls.append(ball_shape) space.step(1/50.0) screen.fill((255,255,255)) space.debug_draw(draw_options) pygame.display.flip() clock.tick(50) pygame.quit() if __name__ == '__main__': main()