pymunk物理引擎之掉落的弹球

Python海龟宝典含200多个原创的用turtle模块制作的创意程序,原名《Python趣味编程200例》。准备参加全国创意编程与智能设计大赛的同学们可以用来做参考。

""" 这是一个动画,它不断地产生物理弹球,弹球掉落在由两段线条组成的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()

 

本站所有作品,教程等皆为原创,版权所有。只供个人及单位内部研究使用,对外展示或传播必需经本站同意,且注明来自本站。培训机构等用本站资源培训学生,需经本站授权。一旦付款,表示同意本站知识付费原则:数字商品,不支持退款。亦可直接向微信号scratch8付款购买。入住QQ群:225792826 和爱好者共同交流,并且能下载免费提供的Python资源(需提供真实姓名才可入群)
李兴球的博客_Python创意编程技术前沿_pygame » pymunk物理引擎之掉落的弹球

李兴球Python微信公众号文章列表

Python游戏海龟模块教程说明书与案例若干免费发放

爱的纪念_Python创意情景动画源代码解析

少儿Python编程到底学些什么?这些代码或许回答了问题.

Python编程家长会花絮_萍乡中小学Python家长会现场

火星路上等着你_少儿从小学什么最好呢?

国家大力整顿教育培训机构,Scratch或Python少儿编程还有得教吗?

鸿蒙系统支持Python开发_可视化编程特别兴趣小组

Scratch作品转Python作品_小猴接桃

python海龟数据可视化。第七次全国人口普查历年数据图表

你的孩子Python编程学到哪个阶段了?给孩子报编程的家长,务必仔细一读。

五一神女来对话,看看她们聊什么?赠Python教案等。

五一快乐有大礼,告诉大家我是如何上Python课的。

Python名堂多,趣味到处有,劈开机械手,帧帧是图片。速算达人之猫狮大战正在进行。 逐字动画不独享,自动生成皆有它。2行代码自动生成字幕gif动画。 Python之潮来临,我在安源区教师科技创新能力的Python讲座

小心你的Python程序,它会是你的一面镜子。小方块闯迷宫.py源代码简析。送Scratch算法集。?

铃儿响钉铛_音效怎能忘_Python配音之Pygame混音器

人面桃花相映红_winsound模块简介

《Python昨晚我想你了》_开源的游戏海龟模块实例案例浅析

《八猫联动初体验》_来自游戏海龟模块的问候

喜爱春天的人儿啊 心地纯洁的人_Python逐行像素显示

旋转之三叶炫彩扇_蟒蛇与海龟的表演

彩虹欢迎字幕_三模合体滚图形

《Python海龟宝典》简介

100%错误的算法还在用,明明没有错别字,说我有11个错别字

奇怪的Python代码,谁能帮我解释一下??

人造地球系统让人类文明充满整个宇宙之Python32768版

深夜,是什么把你的大脑搞成一团浆糊!再谈少儿编程!

5线城市萍乡的少儿Python寒假班学的是什么内容?

关于纯少儿编程课程进化的自然选择

Python海龟画图经典作品_国庆中秋双重喜庆源代码免费下载

海龟为什么要自杀!turtle制作游戏秘籍之一

朋友,你是否知道我在仰望着你_Python神笔马良案例集

酷酷的爆炸效果_Python海龟画图不仅仅是画图

虫子满屏爬_三bug多线程示例程序浅析 少儿Python视频课程A级简介

给的gif图片加文字水印_拆帧与合帧(免费下载180个Python创意源码

用Python制作酷炫图形之如意金箍棒_颜色增加模块应用

简单的用Python做酷炫图形与动画

sb3转exe,sb3素材提取器,编程小子apk, 未公开的pygame游戏集/scratch/python少儿编程免费下载集合

夜幕下的霓虹

学本领,探索更大的世界!

李兴球博客 风火轮编程主页