Microsoft Small Basic

Program Listing: JDR564-8
' Spring 0.41
' Copyright (c) 2012 Nonki Takahashi. All rights reserved.
'
' History:
' 0.41 2012/10/15 Fixed to be worked on Silverlight. (JDR564-8)
' 0.32 2012/10/14 Work on the web too + restart option by GoToLoop. (JDR564-6)
' 0.31 2012/10/14 Minor change. (JDR564-2)
' 0.3 2012/10/14 Changed to use image. (JDR564-1)
' 0.2 2012/10/13 Timer event mod by GoToLoop. (JDR564-0)
' 0.1 2012/10/13 Created. (JDR564)
'
title = "Spring 0.41"
msg = " - Hit space key to start/pause, R key to restart, or other key to quit."
GraphicsWindow.Title = title + msg

scale = 3139 ' [dot/m]

l = .05 ' spring length [m]
w = .006 ' spring width [m]
le = .006 ' spring edge length [m]
k = 20 ' spring constant [N/m]
m = .01 ' mass of weight [kg]
d = .01 ' diameter of weight [m]
g = 9.8 ' acceleration of gravity [m/(s^2)]
xs = .1 ' stationary point from left [m]
ys = 0 ' stationary point from top [m]

x0 = xs - d / 2
y0 = ys + l
v0 = 0
InitParam()

fps = 12 ' frame rate [FPS (frames per second)]
time = Math.Round(1000 / fps)
dt = time / 1000

InitWeight()

Timer.Tick = OnTick
Timer.Interval = time
Timer.Pause()
isPaused = "True"
GraphicsWindow.KeyDown = OnKeyDown
tick = "False"
continue = "True"
key = ""

While continue
If tick Then
Animation()
tick = "False"
ElseIf key = "Space" Then
If isPaused Then
isPaused = "False"
Timer.Resume()
Else
isPaused = "True"
Timer.Pause()
EndIf
key = ""
ElseIf key = "R" Then
InitParam()
ShowWeight()
key = ""
ElseIf key <> "" Then
continue = "False"
Else
Program.Delay(time / 10)
EndIf
EndWhile

Sound.PlayClickAndWait()
Program.End()

Sub Animation
ShowWeight()
dv = (m * g - (y - y0) * k) * dt
v = v + dv
dy = (2 * v + dv) * dt / 2
y = y + dy
EndSub

Sub OnTick
tick = "True"
EndSub

Sub OnKeyDown
key = GraphicsWindow.LastKey
EndSub

Sub InitParam
y = y0 + .05 ' initial position of weight
v = v0 ' initial velocity of weight
EndSub

Sub InitWeight
url = "http://www.nonkit.com/smallbasic.files/spring.png"
img = ImageList.LoadImage(url)
ld = ImageList.GetHeightOfImage(img) ' spring length (without edges) [dot]
If ld < 1 Then ' patch to make it work on Silverlight
ld = 276
spring = Shapes.AddImage(url)
Else
spring = Shapes.AddImage(img)
EndIf

GraphicsWindow.PenColor = "DimGray"
edge0 = Shapes.AddLine(0, 0, 0, le * scale)

GraphicsWindow.PenColor = "DimGray"
edge1 = Shapes.AddLine(0, 0, 0, le * scale)

pw = GraphicsWindow.PenWidth
GraphicsWindow.PenWidth = 0
GraphicsWindow.BrushColor = "Black"
weight = Shapes.AddEllipse(d * scale, d * scale)

Shapes.Move(edge0, xs * scale, ys * scale)
ShowWeight()
EndSub

Sub ShowWeight
' param y
Shapes.Move(weight, x0 * scale, y * scale)

Shapes.Move(spring, (xs - w / 2) * scale, ((y - y0 + l - 2 * le) / 2 + le + ys) * scale - ld / 2)
Shapes.Zoom(spring, 1, (y - y0 + l - 2 * le) * scale / ld)

Shapes.Move(edge1, xs * scale, (y - le + ys) * scale)
EndSub