1 說明:
=====
1.1 中英文介紹:
Pymunk is a easy-to-use pythonic 2d physics library
pymunk是一個易於使用的pythonic 2d物理庫
1.2 多基於pygame和pyglet的動畫。
1.3 官網示意圖:
2 準備:
=====
2.1 官網:
<code>http://www.pymunk.org/en/latest/ https://pypi.org/project/pymunk/ https://github.com/viblo/pymunk/<code>
2.2 環境:
華為筆記本電腦、深度deepin-linux操作系統、谷歌瀏覽器、python3.8和微軟vscode編輯器。
2.3 安裝:
<code>pip install pymunk #本機安裝,且推薦國內源安裝 sudo pip3.8 install pymunk -i https://mirrors.aliyun.com/pypi/simple/<code>
3 官方example:
4 拿官網的動畫gif來講解:
======================
4.1 圖1:index_video.gif,也可以實現,代碼量太多了,省略,屬於example。
4.2 蜘蛛網:spiderweb.py對代碼進行修改,註釋,bug改進。
5 spiderweb.py代碼:
===============
提前看看效果圖:
5.1 第1步:導入模塊
<code>import math, random import pyglet import pymunk from pymunk.vec2d import Vec2d/<code>
5.2 第2步:初始化參數設定
<code>config = pyglet.gl.Config(sample_buffers=1, samples=2, double_buffer=True) window = pyglet.window.Window(config=config, vsync = False, #窗口大小和標題名設定 width=800, height=800, caption="spiderweb", resizable=True) #pymunk物理參數設定 space = pymunk.Space() space.gravity = 0,-900 space.damping = .999 #中心點座標 c = Vec2d(window.width /2., window.height / 2.) #WEB參數 web_group = 1 bs = [] dist = .3 cb = pymunk.Body(1,1) cb.position = c #位置中心點座標 s = pymunk.Circle(cb, 15) # to have something to grab s.filter = pymunk.ShapeFilter(group = web_group) s.ignore_draw = True space.add(cb, s)/<code>
5.3 第3步:織網
<code>#generate each crossing in the net for x in range(0,101): b = pymunk.Body(1, 1) v = Vec2d.unit() v.angle_degrees = x*18 scale = window.height / 2. / 6. * .5 dist += 1/18. dist = dist ** 1.005 offset = 0 offset = [0.0, -0.80, -1.0, -0.80][((x*18) % 360)//18 % 4] offset = .8 + offset offset *= dist**2.8 / 100. v.length = scale * (dist + offset) b.position = c + v s = pymunk.Circle(b, 15) s.filter = pymunk.ShapeFilter(group = web_group) s.ignore_draw = True space.add(b,s) bs.append(b) #連接線 def add_joint(a,b): rl = a.position.get_distance(b.position) * 0.9 stiffness = 5000. damping = 100 j = pymunk.DampedSpring(a, b, (0,0), (0,0), rl, stiffness, damping) j.max_bias = 1000 j.max_force = 50000 space.add(j) for b in bs[:20]: add_joint(cb,b) for i in range(len(bs)-1): add_joint(bs[i], bs[i+1]) i2 = i+20 if len(bs) > i2: add_joint(bs[i], bs[i2]) /<code>
5.4 網和點的關係
<code>static_bs = [] for b in bs[-17::4]: static_body = pymunk.Body(body_type = pymunk.Body.STATIC) static_body.position = b.position static_bs.append(static_body) j = pymunk.PivotJoint(static_body, b, static_body.position) j = pymunk.DampedSpring(static_body, b, (0,0), (0,0), 0, 0, 0) j.damping = 100 j.stiffness = 20000 space.add(j) #更新 def update(dt): r = 10 for x in range(r): space.step(1./30./r) pyglet.clock.schedule_interval(update, 1/30.) selected = None selected_joint = None mouse_body = pymunk.Body(body_type = pymunk.Body.KINEMATIC)/<code>
5.5 第5步:窗口事件綁定和運行
<code>#第5步:窗口時間綁定 @window.event def on_mouse_press(x, y, button, modifiers): mouse_body.position = x,y hit = space.point_query_nearest((x,y), 10, pymunk.ShapeFilter()) if hit != None: global selected body = hit.shape.body rest_length = mouse_body.position.get_distance(body.position) stiffness = 1000 damping = 10 selected = pymunk.DampedSpring(mouse_body, body, (0,0), (0,0), rest_length, stiffness, damping) space.add(selected) @window.event def on_mouse_release(x, y, button, modifiers): global selected if selected != None: space.remove(selected) selected = None @window.event def on_mouse_drag(x, y, dx, dy, buttons, modifiers): mouse_body.position = x,y @window.event def on_key_press(symbol, modifiers): #保存設置,當按p就是保存 if symbol == pyglet.window.key.P: pyglet.image.get_buffer_manager().get_color_buffer().save('spiderweb.png') fps_display = pyglet.window.FPSDisplay(window) @window.event def on_draw(): #窗口背景顏色設置,默認為黑色(0,0,0,255),最後一個255為透明度 #pyglet.gl.glClearColor(240,240,240,255) #白色 #pyglet.gl.glClearColor(0,0,0,255) #黑色,不設置也是黑色 window.clear() fps_display.draw() # static attach points pyglet.gl.glColor3f(1,0,1) pyglet.gl.glPointSize(6) a = [] for b in static_bs: a += [b.position.x, b.position.y] pyglet.graphics.draw(len(a)//2, pyglet.gl.GL_POINTS, ('v2f',a)) # web crossings / bodies pyglet.gl.glColor3f(.8,.8,.8) a = [] for b in bs: a += [b.position.x, b.position.y] pyglet.gl.glPointSize(4) pyglet.graphics.draw(len(a)//2, pyglet.gl.GL_POINTS, ('v2f',a)) # web net / constraints a = [] for j in space.constraints: a += [j.a.position.x, j.a.position.y, j.b.position.x, j.b.position.y] pass pyglet.graphics.draw(len(a)//2, pyglet.gl.GL_LINES, ('v2f',a)) pyglet.app.run() /<code>
關注我,不迷路。
學習你學不到的python知識,作為你編程的補充。