# http://kobazlab.main.jp/2017/01/26/wxpython%E8%87%AA%E7%94%B1%E8%90%BD%E4%B8%8B%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/
#wxPython自由落下アニメーション
#wxPython自由落下アニメーション
をしていたが、「自由落下」でなかったので、pyodeと組み合わせ(スレッド)
自由落下をしてみた。
pyodeの動きにwxpythonの動きをスレッドでリンク。
上サイトのコードに著作権があるのか、またこのページでは引用になるのかわからないが
無断で借用させていただいた。
vpython と wxpython の各大きさはカット&トライで決定。もともと大きさの単位が
わからないため。
vpyton pyode 側コード
E:\MyBackups\goolgedrive\myprg_main\python_my_prg\wxpython\ball_bound.py
# coding: UTF-8
#ボールの自由落下による 地面とのバウンドから停止まで
#ボールの自由落下による 地面とのバウンドから停止まで
#以下のようなコードにすると文法どおりだがやりにくい
#E:\goolgedrive\myprg_main\python_my_prg\ode_prg\ball_bound1.py
#このコードのほうがいいのか
#E:\goolgedrive\myprg_main\python_my_prg\ode_prg\ball_bound1.py
#このコードのほうがいいのか
import ode
from visual import *
#以下の変数をグローバル的に使いたくてリストとする
#そうでないといちいちglobalと宣言するハメになる
field = [""]
ball = [""]
ball_pos = [0]
dt = [0]
#そうでないといちいちglobalと宣言するハメになる
field = [""]
ball = [""]
ball_pos = [0]
dt = [0]
class Field:
#scene = display(forward=visual.norm((0,1,-4)), center= (0,-1, 0))
scene = display(width=500, height=600)
#scene.senter=(0,-1,0)
#物理世界を作成
world=ode.World()
world.setGravity((0, -9.81, 0))
#自由落下させたいなら worldのコメントアウトのほうを生かし
# 最後の方の ball.body.addForce((0,-1000,0)) を殺す
#world.setGravity((0, 0, 0))
#地平面を作成?
space=ode.Space()
#scene = display(forward=visual.norm((0,1,-4)), center= (0,-1, 0))
scene = display(width=500, height=600)
#scene.senter=(0,-1,0)
#物理世界を作成
world=ode.World()
world.setGravity((0, -9.81, 0))
#自由落下させたいなら worldのコメントアウトのほうを生かし
# 最後の方の ball.body.addForce((0,-1000,0)) を殺す
#world.setGravity((0, 0, 0))
#地平面を作成?
space=ode.Space()
#衝突関係
jointgroup=ode.JointGroup()
ode_floor=ode.GeomPlane(space,(0,1,0),0)
#()なかの引数 上の例ではy軸方向に重力が発生
#多分 spaceの最後の引数が y軸の座標を示す
ode_floor.setCategoryBits(1)
ode_floor.setCollideBits(3)
ode_floor.viz=box(
pos=(0,-0.03,0),
width=10,length=10,height=0.06,color=(0.5,0.5,1.0))
jointgroup=ode.JointGroup()
ode_floor=ode.GeomPlane(space,(0,1,0),0)
#()なかの引数 上の例ではy軸方向に重力が発生
#多分 spaceの最後の引数が y軸の座標を示す
ode_floor.setCategoryBits(1)
ode_floor.setCollideBits(3)
ode_floor.viz=box(
pos=(0,-0.03,0),
width=10,length=10,height=0.06,color=(0.5,0.5,1.0))
#タイム関係
#30に変更
target_fps=30
#target_fps=30だから1秒間に30回の処理をする
dt[0]=1.0/target_fps
#30に変更
target_fps=30
#target_fps=30だから1秒間に30回の処理をする
dt[0]=1.0/target_fps
def near_callback(self,args,geom1,geom2):
for c in ode.collide(geom1,geom2):
#接触ジョイント (Contact joint)
#mu 摩擦係数 (摩擦方向1) mu2 摩擦係数 (摩擦方向2)
#bounce 反発係数
c.setBounce(0.97)
c.setMu(50)
c.setMu2(50)
j=ode.ContactJoint(self.world,self.jointgroup,c)
j.attach(geom1.getBody(),geom2.getBody())
def tick(self):
#ballはグローバル変数でもないのにupdateができるのが不思議
ball[0].update()
time.sleep(0.03)
self.space.collide((),self.near_callback)
#self.dtの間隔で世界を動かしていく
self.world.step(dt[0])
self.jointgroup.empty()
return True
#ballはグローバル変数でもないのにupdateができるのが不思議
ball[0].update()
time.sleep(0.03)
self.space.collide((),self.near_callback)
#self.dtの間隔で世界を動かしていく
self.world.step(dt[0])
self.jointgroup.empty()
return True
class Ball:
def __init__(self,field):
self.body=ode.Body(field.world)
M=ode.Mass()
M.setSphere(1, 1)
self.body.setMass(M)
self.geom=ode.GeomSphere(
space=field.space,
radius=0.3
)
#このradiusが実際のバウンドを決める
#多分 sphereの座標が0で radiusが0.3だから
#posが0.3ぐらいのバウンド点になる
self.geom.setCategoryBits(1)
self.geom.setCollideBits(3)
#上は Boxのジオメトリを作成
self.geom.setBody(self.body)
# 剛体にジオメトリをセット
self.vball=sphere(
radius=0.3,
color=color.red)
def __init__(self,field):
self.body=ode.Body(field.world)
M=ode.Mass()
M.setSphere(1, 1)
self.body.setMass(M)
self.geom=ode.GeomSphere(
space=field.space,
radius=0.3
)
#このradiusが実際のバウンドを決める
#多分 sphereの座標が0で radiusが0.3だから
#posが0.3ぐらいのバウンド点になる
self.geom.setCategoryBits(1)
self.geom.setCollideBits(3)
#上は Boxのジオメトリを作成
self.geom.setBody(self.body)
# 剛体にジオメトリをセット
self.vball=sphere(
radius=0.3,
color=color.red)
def update(self):
#boxのジオメトリの位置を得る
pos=self.geom.getPosition()
#boxのジオメトリの位置を得る
pos=self.geom.getPosition()
# ここに余計な処理を書くとアニメがスムーズでなくなるので
# こめんとアウトする
# #ボールの位置を表示す
# #round:引数の2 小数点第3位を四捨五入
# #ljust:文字列を5桁で表示し足らなければ右側を0で埋める
# #こうするとvpythonでposをラベルで表示したとき、
# #周りの四角の囲みがぶれなくていい
# x_lj = str(round(pos[0],2)).ljust(5,'0')
# y_lj = str(round(pos[1],2)).ljust(5,'0')
# z_lj = str(round(pos[2],2)).ljust(5,'0')
# ball_pos_txt = x_lj + " " + y_lj + " " + z_lj
# label(pos=(0,-5,0), text=ball_pos_txt)
# こめんとアウトする
# #ボールの位置を表示す
# #round:引数の2 小数点第3位を四捨五入
# #ljust:文字列を5桁で表示し足らなければ右側を0で埋める
# #こうするとvpythonでposをラベルで表示したとき、
# #周りの四角の囲みがぶれなくていい
# x_lj = str(round(pos[0],2)).ljust(5,'0')
# y_lj = str(round(pos[1],2)).ljust(5,'0')
# z_lj = str(round(pos[2],2)).ljust(5,'0')
# ball_pos_txt = x_lj + " " + y_lj + " " + z_lj
# label(pos=(0,-5,0), text=ball_pos_txt)
self.vball.pos = pos
ball_pos[0] = pos
#print ball_pos[0]
ball_pos[0] = pos
#print ball_pos[0]
def main():
field[0] = Field()
ball[0]=Ball(field[0])
ball[0].body.setPosition((0,10,0))
Field#ball[0].body.addForce((0,-1000,0))
while True:
field[0].tick()
#最後の数行 main()にまとめて
#if __name__ == '__main__':
# main()
# などとしたいけれど 変数にglobalをいくつも
#いれないと だめなようだ。
if __name__ =="__main__":
main()
field[0].tick()
#最後の数行 main()にまとめて
#if __name__ == '__main__':
# main()
# などとしたいけれど 変数にglobalをいくつも
#いれないと だめなようだ。
if __name__ =="__main__":
main()
wxpython 側コード ほとんど拝借
E:\MyBackups\goolgedrive\myprg_main\python_my_prg\wxpython\anime_ball_down_simple.
py
py
# coding: UTF-8
# http://kobazlab.main.jp/2017/01/26/wxpython%E8%87%AA%E7%94%B1%E8%90%BD%E4%B8%8B%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3/
#wxPython自由落下アニメーション
#wxPython自由落下アニメーション
# 元コード Panelをつかっていたが動作しないため
# 以下のように改変した
# 以下のように改変した
import wx
import ball_bound
import ball_bound
ball_pos_txt = ["","",""]
class myPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(500,600))
#self.panel = wx.Panel(self, size=(300,600))
self.SetBackgroundColour('WHITE')
self.InitBuffer()
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.createTimer()
self.counter = 0
self.ball = Ball(10)
def __init__(self, parent):
wx.Panel.__init__(self, parent, size=(500,600))
#self.panel = wx.Panel(self, size=(300,600))
self.SetBackgroundColour('WHITE')
self.InitBuffer()
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.createTimer()
self.counter = 0
self.ball = Ball(10)
def InitBuffer(self):
size = self.GetClientSize()
self.buffer = wx.EmptyBitmap(max(1, size.width), max(1, size.height))
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush( self.GetBackgroundColour()))
dc.Clear()
dc.SetBrush(wx.Brush(wx.Colour(0,255,0)))
dc.DrawRectangle(0,300, 500, 5)
def createTimer(self):
t = ball_bound.dt[0] * 1000
self.timer = wx.Timer(self)
self.timer.Start(t)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
t = ball_bound.dt[0] * 1000
self.timer = wx.Timer(self)
self.timer.Start(t)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
def onTimer(self, event):
self.InitBuffer()
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
#dc.Clear()
self.InitBuffer()
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
#dc.Clear()
dc.BeginDrawing()
dc.SetPen(wx.Pen("black", 3, wx.SOLID))
self.ball.Fall(dc)
str = ball_pos_txt[0] + " " + ball_pos_txt[1] + " " + ball_pos_txt[2]
dc.DrawText(str , 100,500)
#dc.DrawText(ball_pos_txt[0], 20,20)
dc.EndDrawing()
dc.SetPen(wx.Pen("black", 3, wx.SOLID))
self.ball.Fall(dc)
str = ball_pos_txt[0] + " " + ball_pos_txt[1] + " " + ball_pos_txt[2]
dc.DrawText(str , 100,500)
#dc.DrawText(ball_pos_txt[0], 20,20)
dc.EndDrawing()
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self.buffer)
dc = wx.BufferedPaintDC(self, self.buffer)
class Ball:
def __init__(self, R):
self.r = R
self.v = 0
self.x = 0
self.y = 0
self.z = 0
#vpythonは(0,0)がウィンドウセンターにあるので調整する
self.x0 = 500/2
self.y0 = 600/2
self.z0 = 0
def __init__(self, R):
self.r = R
self.v = 0
self.x = 0
self.y = 0
self.z = 0
#vpythonは(0,0)がウィンドウセンターにあるので調整する
self.x0 = 500/2
self.y0 = 600/2
self.z0 = 0
def Fall(self, dc):
#wxpythonのyは下に行くほど数値が高くなる
#vpytonは逆
self.x = self.x0 + ball_bound.ball_pos[0][0]
self.y = self.y0 + -ball_bound.ball_pos[0][1]*30
self.z = self.z0 + ball_bound.ball_pos[0][2]
#wxpythonのyは下に行くほど数値が高くなる
#vpytonは逆
self.x = self.x0 + ball_bound.ball_pos[0][0]
self.y = self.y0 + -ball_bound.ball_pos[0][1]*30
self.z = self.z0 + ball_bound.ball_pos[0][2]
x_lj = str(round(self.x,2)).ljust(7,'0')
y_lj = str(round(self.y,2)).ljust(7,'0')
z_lj = str(round(self.z,2)).ljust(7,'0')
ball_pos_txt[0] = x_lj
ball_pos_txt[1] = y_lj
ball_pos_txt[2] = z_lj
#self.v += 0.5
#self.y += self.v / 2
#if self.y > 600:
# self.y = 0
# self.v = 0
dc.SetPen(wx.Pen(wx.Colour(255,165,0)))
#領域をブラシを使って赤で塗りつぶす
dc.SetBrush(wx.Brush(wx.Colour(255,0,0)))
dc.DrawCircle(self.x, self.y, self.r)
y_lj = str(round(self.y,2)).ljust(7,'0')
z_lj = str(round(self.z,2)).ljust(7,'0')
ball_pos_txt[0] = x_lj
ball_pos_txt[1] = y_lj
ball_pos_txt[2] = z_lj
#self.v += 0.5
#self.y += self.v / 2
#if self.y > 600:
# self.y = 0
# self.v = 0
dc.SetPen(wx.Pen(wx.Colour(255,165,0)))
#領域をブラシを使って赤で塗りつぶす
dc.SetBrush(wx.Brush(wx.Colour(255,0,0)))
dc.DrawCircle(self.x, self.y, self.r)
class MainFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title)
myPanel(self)
#MainFrameをmyPanelの大きさにあわせる
self.Fit()
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title)
myPanel(self)
#MainFrameをmyPanelの大きさにあわせる
self.Fit()
def main():
app = wx.PySimpleApp()
frame = MainFrame(None, "Free Fall")
frame.Show(True)
app.MainLoop()
app = wx.PySimpleApp()
frame = MainFrame(None, "Free Fall")
frame.Show(True)
app.MainLoop()
if __name__ =="__main__":
main()
main()
メインコード スレッド
E:\MyBackups\goolgedrive\myprg_main\python_my_prg\wxpython\anime_ball_down_ode.py
# coding: UTF-8
# ball_bound.pyとanime_ball_down_simple.py
# をスレッドする
# をスレッドする
import anime_ball_down_simple
import ball_bound
import threading
import ball_bound
import threading
#import printmy
#今まで何気なくimportしてきたが、モジュールに実行できる
#文、命令があるとimportされた側のファイルを実行すると
# モジュール側の命令文なども、実行されてしまう。
# たとえ モジュール.命令文 の形をとらなくても。
#今まで何気なくimportしてきたが、モジュールに実行できる
#文、命令があるとimportされた側のファイルを実行すると
# モジュール側の命令文なども、実行されてしまう。
# たとえ モジュール.命令文 の形をとらなくても。
class ThreadWx(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def __init__(self):
threading.Thread.__init__(self)
def run(self):
anime_ball_down_simple.main()
anime_ball_down_simple.main()
class ThreadOde(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
ball_bound.main()
ball_bound.main()
if __name__ == '__main__':
t1 = ThreadWx()
t2 = ThreadOde()
t1.start()
t2.start()
t1.join()
t2.join()
print "end"
0 件のコメント:
コメントを投稿