プログラミング言語「Python」で制作 Part119 | Photoshop CC Tutorials

今回はプログラミング言語の「Python」を使って作成しました。

 

下記の本のサンプル「二つの物体につながれた、ばねのシミュレーション」をPygameで動くように移植しました。

 

■ プログラム

import traceback

try:
    import sys
    import math
    import random
    import pygame
    from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_SPACE, Rect

    def array(N1, N2=0, N3=0):
        if N2 == 0 and N3==0: return [0 for i in range(N1)]
        elif N3 == 0: return [[0 for i in range(N2)] for j in range(N1)]
        else: return [[[0 for i in range(N3)] for j in range(N2)]
                      for k in range(N1)]
    PI=math.pi
    V1=0; X1=50; L1= 50; H1=50; M1=1.0; Myu1=0.005 # 物体 1 データ
    V2=0; X2=300; L2=100; H2=50; M2=1.5; Myu2=0.005 # 物体 2 データ
    DT=0.01; DTH=PI*DT; Kfact=1                    # 実行用パラメータ
    Hist=array(400,2); IHist=0; iDsp=2           # 履歴表示用

    # Pygame初期設定
    pygame.init()
    SURFACE = pygame.display.set_mode((480, 400))
    FPSCLOCK = pygame.time.Clock()
    fps = 60

    #--------------------------------------------------------------
    # 履歴表示
    #--------------------------------------------------------------
    def history(SURFACE):
        global Hist,IHist, X1, X2

        Hist[IHist][0]=X1-100; Hist[IHist][1]=X2-300;IHist+=1
        if IHist>=400: IHist=0
        GH=200; GH1=GH-30; GH2=GH+30
        ip=IHist;GX1=Hist[ip][0]+GH; GX2=Hist[ip][1]+GH
        pygame.draw.line(SURFACE, (0, 255, 0), (50,GH), (450, GH))

        for i in range(399):
            ip+=1
            if ip>=400: ip=0
            GN1=Hist[ip][0]+GH; GN2=Hist[ip][1]+GH
            if ip % 100==0:
                pygame.draw.line(SURFACE, (0, 255, 0), (i+50,GH1), (i+50, GH2))
            pygame.draw.line(SURFACE, (255, 0, 0), (i+50,GX1), (i+51, GN1))
            pygame.draw.line(SURFACE, (0, 0, 255), (i+50,GX2), (i+51, GN2))
            GX1=GN1; GX2=GN2

    #--------------------------------------------------------------
    # 計算
    #--------------------------------------------------------------
    def calc(F):
        global M1,M2, Myu1,Myu2,X1,V1,X2,V2,Kfact

        FS=(X2-X1-200)*Kfact
        Acc=(F+FS)/M1; V1=(V1+Acc*DT)*(1-Myu1); X1+=V1*DT
        Acc=-FS/M1; V2=(V2+Acc*DT)*(1-Myu2); X2+=V2*DT

    #--------------------------------------------------------------
    # 物体初期表示
    #--------------------------------------------------------------
    def initDraw(SURFACE,X,L,H,C):
        LL=L;
        pygame.draw.rect(SURFACE, C, (X-LL,100, LL, 100-H))

    #--------------------------------------------------------------
    # バネを直線で描く
    #--------------------------------------------------------------
    def initLine(SURFACE,X1, X2,H,C):
        HH=100-H/2;
        pygame.draw.line(SURFACE, C, (X1,HH*2 - H/2), (X2, HH*2 - H/2))

    #--------------------------------------------------------------
    # 物体の表示(座標位置変更)
    #--------------------------------------------------------------
    def Draw(SURFACE, X, L, H, C):
        LL=L
        pygame.draw.rect(SURFACE, C, ((X-LL,100), (LL, 100-H)))
        pygame.draw.rect(SURFACE, (0, 0, 0), ((X-LL,100), (LL, 100-H)), 3)

    #--------------------------------------------------------------
    # バネの表示(座標位置変更)
    #--------------------------------------------------------------
    def DrawLine(SURFACE,X1, X2, H, C):
        HH=100-H/2
        pygame.draw.line(SURFACE, C, (X1,HH*2 - H/2), (X2, HH*2 - H/2), 2)

    LID = initLine(SURFACE, X1, X2, H1, (0, 0, 0))
    ID1 = initDraw(SURFACE, X1, L1, H1, (255, 0, 0))
    ID2 = initDraw(SURFACE, X2, L2, H2, (0, 0, 255))
    TH=0;N=0

    #--------------------------------------------------------------
    # ループ処理
    #--------------------------------------------------------------
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        #-----------------------------------------------------------
        # 描画処理
        #-----------------------------------------------------------
        SURFACE.fill((255, 255, 255))

        calc(200*math.sin(TH)); TH+=DTH
        DrawLine(SURFACE, X1, X2, H1, (0, 0, 0)) # ばね
        Draw(SURFACE, X1, L1, H1, (255, 0,   0)) # 赤物体
        Draw(SURFACE, X2, L2, H2, (  0, 0, 255)) # 青物体
        N+=10
        if N % iDsp==0:
            history(SURFACE)

        pygame.display.update()
        FPSCLOCK.tick(fps)

except Exception as e:
    print("エラー情報\n" + traceback.format_exc())

input()

 

■ 参考書

「Python 3.6 による 力学シミュレーション 第7巻: 複合運動」

 

■ ゲーム用ライブラリ

「Pygame」

 

■ プログラミング言語

「Python」