2015FALL CPA 協同作業主頁面 (課程已經結束)

在網際頁面上, 用 Python 執行動態模擬!

以下利用 Brython 在網頁中進行具彈性的 20 個小球彈跳模擬! 換言之, 若採用相同的程式技巧與流程, 耶誕卡上的所有繪圖物件, 都可以製作成動畫!!!

上列繪圖的程式碼:

<!-- 導入 brython.js -->

<script type="text/javascript" src="http://brython.info/src/brython_dist.js"></script>

<!-- 啟動 brython() -->

<script>
window.onload=function(){
brython(1);
}
</script>

<!-- 以下利用 Brython 程式執行繪圖 -->

<canvas id="plotarea" width="600" height="400"></canvas>

<script type="text/python3">
# 導入 browser 模組中的 document, 並設為 doc 變數
from browser import document as doc
# 導入數學模組
import math
# 產生各小球的亂數速度用
import random
# 導入 browser 中的計時器, 建立動畫用
import browser.timer

# 準備繪圖畫布
canvas = doc["plotarea"]
ctx = canvas.getContext("2d")

# 取畫布的寬與高度
width = canvas.width
height = canvas.height

n = 20
# 已知數列內容個數, 先分別與 None 對應
x = [None]*n
y = [None]*n
vy = [None]*n
vx = [None]*n
# 重力加速度, Y 方向向下為正
g = 0.05
# 空氣的黏滯阻尼係數
cor = 0.7 
# 球的彈力係數
fr = 0.95
# 球的半徑
r = 5

for i in range(n):
    x[i] = 300
    y[i] = 100
    # random.random() 將會產生介於 0  1 的浮點亂數
    vx[i] = 2*(random.random()-.5)
    vy[i] = 2*(random.random()-.5)

# 更新第 i  Y 座標的運算邏輯
def updateY(i):
    if ((y[i]+r) < height):
        #y = height
        vy[i] += g
    else:
        vy[i] = -vy[i]*cor
        vx[i] *= fr
    y[i] += vy[i]
    if ((y[i]+r) > height):
        y[i] = height-r

# 更新第 i  X 座標的運算邏輯
def updateX(i):
    if ((x[i]+r) >= width or (x[i]-r) <= 0):
        vx[i] = -vx[i]*cor
    x[i] += vx[i]
    if ((x[i]+r) > width):
        x[i] = width-r
    elif ((x[i]-r) < 0):
        x[i] = r

# 畫圓函式
def circle(x,y,r):
    ctx.beginPath()
    ctx.arc(x, y, r, 0, math.pi*2, True)
    ctx.fill()

# 寫字函式
def text(s):
    ctx.fillStyle = "#ff0000"
    ctx.font = "30px sans-serif"
    ctx.textBaseline = "bottom"
    ctx.fillText(s,0,height)

# 每隔特定時間, 進行動畫繪製
def animate():
    # 刷新畫布
    ctx.clearRect(0, 0, width, height)
    # 逐一重新繪製小球
    ctx.fillStyle = "#000000"
    for i in range(n):
        updateY(i)
        updateX(i)
        circle(x[i],y[i],r)

text("Click me!")

# 畫布點擊後執行的函式
def on_canvas_click(ev):
    browser.timer.set_interval(animate,0)

# 只要使用者點擊在畫布上任何地方, 即執行 on_canvas_click 函式
canvas.bind('click', on_canvas_click, False)
</script>

Comments