Microsoft Small Basic

Program Listing: FGM769-5
' Donkey Kong in the Small Basic World 0.7
' Small Basic version written by Nonki Takahashi.
'
' History:
' 0.7 2014-03-24 Changed music. (FGM769-5)
' 0.6 2014-03-24 Added music and ending. (FGM769-4)
' 0.5b 2014-03-14 Added motion of Mario. (FGM769-3)
' 0.4a 2014-03-13 Added Donkey Kong. (FGM769-2)
' 2014-03-13 13:40:50 Donkey Kong generated by Shapes 1.6b.
' 0.3a 2014-03-12 Barrels demo with friction. (FGM769-1)
' 0.2a 2014-03-10 Barrel demo without friction. (FGM769-0)
' 0.1a 2014-03-08 Created only for graphics. (FGM769)
'
GraphicsWindow.Title = "Donkey Kong in the Small Basic World 0.7"
MAXBARREL = 8
Init()
Opening()
g = 9.8 ' [m/s^2]
dt = 1 / 24 ' [s]
pxpm = 50 ' [pixel/m]
pslope[1] = "x1=200;y1=70;x2=400;y2=70;height=16;pitch=10;color=Maroon;"
pslope[2] = "x1=0;y1=130;x2=540;y2=150;height=16;pitch=10;color=Maroon;"
pslope[3] = "x1=60;y1=240;x2=600;y2=220;height=16;pitch=10;color=Maroon;"
pslope[4] = "x1=0;y1=310;x2=540;y2=330;height=16;pitch=10;color=Maroon;"
pslope[5] = "x1=300;y1=412;x2=600;y2=400;height=16;pitch=10;color=Maroon;"
pslope[6] = "x1=0;y1=412;x2=300;y2=412;height=16;pitch=10;color=Maroon;"
ns = Array.GetItemCount(pslope)
For i = 1 To ns
param = pslope[i]
Slope_Add()
EndFor
op = 100
For i = 1 To 10
hx = hx + 2
op = op - 10
Shapes.Move(help, hx, hy)
Shapes.SetOpacity(help, op)
Program.Delay(200)
EndFor
param = "x=10;y=40;m=5000;e=0.56;mu=1;"
Barrel_Add()
lastms = Clock.ElapsedMilliseconds
timeout = "False"
Timer.Interval = dt * 1000
Timer.Tick = OnTick
Sound.PlayMusic("O6C4D8F8R8D8C8D8O5B-8O6C16D16E-16F16G16A16B-2")
GraphicsWindow.KeyDown = OnKeyDown
inGame = "True"
goal = "False"
While inGame
If timeout Then
ms = Clock.ElapsedMilliseconds
If 5000 < ms - lastms Then
param = "x=10;y=40;m=5000;e=0.56;mu=1;"
Barrel_Add()
lastms = ms
If mario["ob"] Then
Mario_Add()
EndIf
EndIf
Barrel_Motion()
Mario_Motion()
timeout = "False"
Else
Program.Delay(dt * 1000)
EndIf
If goal Then
Ending()
EndIf
EndWhile
Closing()
Sub Ending
Shapes.ShowShape(heart)
Sound.PlayMusic("O6R4D4D-8D8R8G8R4G4F8D8R4C4C4F8D-8D8R8O5B-2")
inGame = "False"
EndSub
Sub Closing
GraphicsWindow.Clear()
fs = 40
GraphicsWindow.FontSize = fs
GraphicsWindow.BrushColor = "White"
tw = 267
x = Math.Floor((gw - tw) / 2)
y = Math.Floor((gh - fs) / 2)
GraphicsWindow.DrawText(x, y, "GAME OVER")
EndSub
Sub Init
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BackgroundColor = "Black"
Not = "True=False;False=True;"
EndSub
Sub OnKeyDown
key = GraphicsWindow.LastKey
If mario["landing"] Then
If key = "Left" Then
mario["vx"] = mario["vx"] - 100
mario["vy"] = mario["vy"] - 100
ElseIf key = "Right" Then
mario["vx"] = mario["vx"] + 100
mario["vy"] = mario["vy"] - 100
ElseIf key = "Up" Then
mario["vy"] = mario["vy"] - 160
EndIf
EndIf
EndSub
Sub OnTick
timeout = "True"
EndSub
Sub Opening
' initialize shapes
SB_Workaround()
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FontName = "Arial Black"
GraphicsWindow.FontSize = 40
title = Shapes.AddText("DONKEY KONG")
tw = 336
x = (gw - tw) / 2
Shapes.Move(title, x, 20)
GraphicsWindow.FontSize = 20
subtitle = Shapes.AddText("in the Small Basic World")
tw = 267
x = (gw - tw) / 2
Shapes.Move(subtitle, x, 80)
Shapes_Init()
' add shapes
scale = 1
angle = 0
iMin = 1
iMax = 47
Shapes_Add()
Sound.PlayMusic("O3B2O4R4C#4D2O3B2O4F#16F16F#16F16F#16F16F#16F16F#16F16F#16F16F#16F16F#16F16F#1")
Shapes.Remove(title)
Shapes.Remove(subtitle)
Shapes_Remove()
url = "http://www.nonkit.com/smallbasic.files/"
peach = Shapes.AddImage(url + "Peach96.png")
Shapes.Move(peach, 180, -4)
Shapes.Zoom(peach, 0.6, 0.6)
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FontSize = 12
help = Shapes.AddText("HELP!")
hx = 260
hy = 20
Shapes.Move(help, hx, hy)
' add shapes
scale = 0.3
angle = 0
iMin = 1
iMax = 47
Shapes_Add()
x = 20
y = 48
Shapes_Move()
GraphicsWindow.PenWidth = 2
Mario_Add()
GraphicsWindow.FontSize = 50
GraphicsWindow.BrushColor = "Magenta"
heart = Shapes.AddText("♥")
Shapes.Move(heart, 260, 0)
Shapes.HideShape(heart)
EndSub
Sub Barrel_Add
' param["x"] - left co-ordinate
' param["y"] - top co-ordinate
' param["m"] - mass of barrel [g]
' param["e"] - coefficient of resititution
' param["mu"] - cofficient of friction
n = barrel["num"]
n = n + 1
If MAXBARREL < n Then
Barrel_FindUsed()
Else
barrel["num"] = n
EndIf
barrel[n]["m"] = param["m"]
barrel[n]["e"] = param["e"]
barrel[n]["mu"] = param["mu"]
url = "http://www.nonkit.com/smallbasic.files/Barrel32.png"
x = param["x"]
y = param["y"]
If barrel[n]["obj"] = "" Then
barrel[n]["obj"] = Shapes.AddImage(url)
EndIf
Shapes.SetOpacity(barrel[n]["obj"], 100)
barrel[n]["x"] = x
barrel[n]["y"] = y
Shapes.Move(barrel[n]["obj"], x, y)
barrel[n]["vx"] = 0
barrel[n]["vy"] = 0
barrel[n]["vr"] = 0 ' rotational velocity
barrel[n]["r"] = 0 ' rotation angle
EndSub
Sub Barrel_FindUsed
' return n - index of barrel used
For n = 1 To barrel["num"]
If barrel[n]["x"] < -32 Then
Goto bfu_found
EndIf
EndFor
bfu_found:
EndSub
Sub Barrel_Motion
nb = barrel["num"]
ns = slope["num"]
ax = 0
ay = g * pxpm
For ib = 1 To nb
vx = barrel[ib]["vx"]
vy = barrel[ib]["vy"]
barrel[ib]["vx"] = vx + ax * dt
barrel[ib]["vy"] = vy + ay * dt
barrel[ib]["x"] = barrel[ib]["x"] + (vx + barrel[ib]["vx"]) * dt / 2
barrel[ib]["y"] = barrel[ib]["y"] + (vy + barrel[ib]["vy"]) * dt / 2
xo = barrel[ib]["x"] + 16
yo = barrel[ib]["y"] + 16
e = barrel[ib]["e"]
m = barrel[ib]["m"]
mu = barrel[ib]["mu"]
For is = 1 To ns
a = slope[is]["a"]
b = slope[is]["b"]
c = slope[is]["c"]
d = Math.Abs(a * xo + b * yo + c) / Math.SquareRoot(a * a + b * b)
If d <= 16 And slope[is]["x1"] <= xo And xo <= slope[is]["x2"] Then
x = barrel[ib]["vx"]
y = barrel[ib]["vy"]
Math_CartesianToPolar()
ss = slope[is]["ss"]
a = ss * 2 - a
vx = r * Math.Cos(Math.GetRadians(a))
vy = r * Math.Sin(Math.GetRadians(a))
dv = Math.SquareRoot(Math.Power((vx - x), 2) + Math.Power((vy - y), 2))
a = g * Math.Sin(Math.GetRadians(ss)) * pxpm / 2
If barrel[ib]["vr"] * a < 0 Then
barrel[ib]["vr"] = -0.3 * barrel[ib]["vr"]
EndIf
barrel[ib]["vr"] = barrel[ib]["vr"] + a * dt
dvx = barrel[ib]["vr"] * 16 * Math.Cos(Math.GetRadians(ss))
dvy = barrel[ib]["vr"] * 16 * Math.Sin(Math.GetRadians(ss))
barrel[ib]["vx"] = (vx - x) * e / 2 + (vx + x) / 2
barrel[ib]["vy"] = (vy - y) * e / 2 + (vy + y) / 2
barrel[ib]["x"] = barrel[ib]["x"] + (vx - x) * (16 - d) / dv * e * e
barrel[ib]["y"] = barrel[ib]["y"] + (vy - y) * (16 - d) / dv * e * e
EndIf
EndFor
barrel[ib]["r"] = barrel[ib]["r"] + barrel[ib]["vr"] * dt
Shapes.Rotate(barrel[ib]["obj"], barrel[ib]["r"] * 10)
l = barrel[ib]["x"]
If l < 0 And barrel[ib]["y"] < 290 Then
barrel[ib]["x"] = -l * e * e
barrel[ib]["vx"] = -barrel[ib]["vx"] * e
EndIf
r = barrel[ib]["x"] + 32
If gw < r Then
barrel[ib]["x"] = barrel[ib]["x"] - 2 * (r - gw) * e * e
barrel[ib]["vx"] = -barrel[ib]["vx"] * e
EndIf
h = gh - (barrel[ib]["y"] + 32)
If h < 0 Then
barrel[ib]["y"] = barrel[ib]["y"] + h * e * e
barrel[ib]["vy"] = -barrel[ib]["vy"] * e
EndIf
Shapes.Move(barrel[ib]["obj"], barrel[ib]["x"], barrel[ib]["y"])
EndFor
EndSub
Sub Mario_Add
x = 10
y = gh - 20 - 48
If mario["obj1"] = "" Then
mario["n"] = 3
url = "http://www.nonkit.com/smallbasic.files/"
For i = 1 To mario["n"]
life[i] = Shapes.AddImage(url + "Mario48.png")
Shapes.Move(life[i], gw + (i - 5) * 24, 10)
Shapes.Zoom(life[i], 0.5, 0.5)
EndFor
mario["obj1"] = Shapes.AddImage(url + "Mario48.png")
Shapes.Move(mario["obj1"], x, y)
mario["obj2"] = Shapes.AddImage(url + "Mario48L.png")
mario["obj3"] = Shapes.AddImage(url + "MarioJump48.png")
mario["obj4"] = Shapes.AddImage(url + "MarioJump48L.png")
For i = 1 To 4
Shapes.HideShape(mario["obj" + i])
EndFor
Program.Delay(1000)
Shapes.ShowShape(mario["obj1"])
Shapes.HideShape(life[mario["n"]])
mario["n"] = mario["n"] - 1
ElseIf 0 < mario["n"] Then
Shapes.HideShape(life[mario["n"]])
mario["n"] = mario["n"] - 1
Shapes.Move(mario["obj1"], x, y)
Shapes.Rotate(mario["obj1"], 0)
Shapes.ShowShape(mario["obj1"])
Else
inGame = "False"
EndIf
mario["x"] = x
mario["y"] = y
mario["vx"] = 1
mario["vy"] = 0
mario["r"] = 0
mario["vr"] = 0
mario["lastobj"] = 1
mario["hit"] = "False"
mario["right"] = "True"
mario["ob"] = "False"
EndSub
Sub Mario_Motion
ax = 0
ay = g * pxpm
vx = mario["vx"]
vy = mario["vy"]
mario["vx"] = vx + ax * dt
mario["vy"] = vy + ay * dt
xm = mario["x"] + (vx + mario["vx"]) * dt / 2 + 24
ym = mario["y"] + (vy + mario["vy"]) * dt / 2 + 24
mario["landing"] = "False"
If Not[mario["hit"]] Then
nb = barrel["num"]
For ib = 1 To nb
xb = barrel[ib]["x"] + 16
yb = barrel[ib]["y"] + 16
d = Math.SquareRoot(Math.Power((xb - xm), 2) + Math.Power((yb - ym), 2))
If d < 20 Then
mario["hit"] = "True"
mario["vx"] = 0
ym = ym - 24
mario["vr"] = 720
EndIf
EndFor
ns = slope["num"]
For is = 1 To ns
a = slope[is]["a"]
b = slope[is]["b"]
c = slope[is]["c"]
d = Math.Abs(a * xm + b * ym + c) / Math.SquareRoot(a * a + b * b)
If d <= 24 And slope[is]["x1"] <= xm And xm <= slope[is]["x2"] Then
mario["landing"] = "True"
mario["vx"] = 0
mario["vy"] = 0
ym = -(a * xm + c) / b - 22
Goto mm_break
EndIf
EndFor
mm_break:
EndIf
mario["x"] = xm - 24
mario["y"] = Math.Floor(ym - 24)
l = mario["x"]
If mario["landing"] And is = 1 Then
goal = "True"
EndIf
If l < 0 Then
mario["x"] = -l * e * e
mario["vx"] = -mario["vx"] * e
EndIf
r = mario["x"] + 48
If gw < r Then
mario["x"] = mario["x"] - 2 * (r - gw) * e * e
mario["vx"] = -mario["vx"] * e
EndIf
h = gh - (mario["y"] + 48)
If mario["hit"] Then
If h < -48 Then
mario["ob"] = "True"
EndIf
Else
If h < 0 Then
mario["y"] = mario["y"] + h * e * e
mario["vy"] = -mario["vy"] * e
EndIf
EndIf
If mario["landing"] Then
If 0 < mario["vx"] Then
im = 1
ElseIf mario["vx"] < 0 Then
im = 2
Else
im = Math.Remainder(im - 1, 2) + 1
EndIf
Else
If 0 < mario["vx"] Then
im = 3
ElseIf mario["vx"] < 0 Then
im = 4
Else
im = Math.Remainder(im - 1, 2) + 3
EndIf
EndIf
If mario["lastobj"] <> im Then
Shapes.HideShape(mario["obj" + mario["lastobj"]])
Shapes.ShowShape(mario["obj" + im])
mario["lastobj"] = im
EndIf
mario["r"] = mario["r"] + mario["vr"] * dt
Shapes.Rotate(mario["obj" + im], mario["r"])
Shapes.Move(mario["obj" + im], mario["x"], mario["y"])
EndSub
Sub Math_CartesianToPolar
' Math | convert cartesian coodinate to polar coordinate
' param x, y - cartesian coordinate
' return r, a - polar coordinate
r = Math.SquareRoot(x * x + y * y)
If x = 0 And y > 0 Then
a = 90 ' [degree]
ElseIf x = 0 And y < 0 Then
a = -90
Else
a = Math.ArcTan(y / x) * 180 / Math.Pi
EndIf
If x < 0 Then
a = a + 180
ElseIf x > 0 And y < 0 Then
a = a + 360
EndIf
EndSub
Sub SB_RotateWorkaround
' Small Basic | Rotate workaround for Silverlight
' param x, y - original coordinate
' param alpha - angle [radian]
' returns x, y - workaround coordinate
If shape[i]["func"] = "tri" Then
x1 = -Math.Floor(shape[i]["x3"] / 2)
y1 = -Math.Floor(shape[i]["y3"] / 2)
ElseIf shape[i]["func"] = "line" Then
x1 = -Math.Floor(Math.Abs(shape[i]["x1"] - shape[i]["x2"]) / 2)
y1 = -Math.Floor(Math.Abs(shape[i]["y1"] - shape[i]["y2"]) / 2)
EndIf
ox = x - x1
oy = y - y1
x = x1 * Math.Cos(alpha) - y1 * Math.Sin(alpha) + ox
y = x1 * Math.Sin(alpha) + y1 * Math.Cos(alpha) + oy
EndSub
Sub SB_Workaround
' Small Basic | Workaround for Silverlight
' returns silverlight - "True" if in remote
color = GraphicsWindow.GetPixel(0, 0)
If Text.GetLength(color) > 7 Then
silverlight = "True"
msWait = 300
Else
silverlight = "False"
EndIf
EndSub
Sub Shapes_Add
' Shapes | add shapes as shapes data
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - 1 if same scale
' return shWidth, shHeight - total size of shapes
' return shAngle - current angle of shapes
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
Shapes_CalcWidthAndHeight()
s = scale
For i = iMin To iMax
GraphicsWindow.PenWidth = shape[i]["pw"] * s
If shape[i]["pw"] > 0 Then
GraphicsWindow.PenColor = shape[i]["pc"]
EndIf
If Text.IsSubText("rect|ell|tri|text", shape[i]["func"]) Then
GraphicsWindow.BrushColor = shape[i]["bc"]
EndIf
If shape[i]["func"] = "rect" Then
shape[i]["obj"] = Shapes.AddRectangle(shape[i]["width"] * s, shape[i]["height"] * s)
ElseIf shape[i]["func"] = "ell" Then
shape[i]["obj"] = Shapes.AddEllipse(shape[i]["width"] * s, shape[i]["height"] * s)
ElseIf shape[i]["func"] = "tri" Then
shape[i]["obj"] = Shapes.AddTriangle(shape[i]["x1"] * s, shape[i]["y1"] * s, shape[i]["x2"] * s, shape[i]["y2"] * s, shape[i]["x3"] * s, shape[i]["y3"] * s)
ElseIf shape[i]["func"] = "line" Then
shape[i]["obj"] = Shapes.AddLine(shape[i]["x1"] * s, shape[i]["y1"] * s, shape[i]["x2"] * s, shape[i]["y2"] * s)
ElseIf shape[i]["func"] = "text" Then
If silverlight Then
fs = Math.Floor(shape[i]["fs"] * 0.9)
Else
fs = shape[i]["fs"]
EndIf
GraphicsWindow.FontSize = fs * s
GraphicsWindow.FontName = shape[i]["fn"]
shape[i]["obj"] = Shapes.AddText(shape[i]["text"])
EndIf
x = shape[i]["x"]
y = shape[i]["y"]
shape[i]["rx"] = x
shape[i]["ry"] = y
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
alpha = Math.GetRadians(shape[i]["angle"])
SB_RotateWorkaround()
shape[i]["wx"] = x
shape[i]["wy"] = y
EndIf
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
If Text.IsSubText("rect|ell|tri|text", shape[i]["func"]) And shape[i]["angle"] <> 0 Then
Shapes.Rotate(shape[i]["obj"], shape[i]["angle"])
EndIf
EndFor
shAngle = 0
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub
Sub Shapes_CalcRotatePos
' Shapes | Calculate position for rotated shape
' param["x"], param["y"] - position of a shape
' param["width"], param["height"] - size of a shape
' param ["cx"], param["cy"] - center of rotation
' param ["angle"] - rotate angle
' return x, y - rotated position of a shape
_cx = param["x"] + param["width"] / 2
_cy = param["y"] + param["height"] / 2
x = _cx - param["cx"]
y = _cy - param["cy"]
Math_CartesianToPolar()
a = a + param["angle"]
x = r * Math.Cos(a * Math.Pi / 180)
y = r * Math.Sin(a * Math.Pi / 180)
_cx = x + param["cx"]
_cy = y + param["cy"]
x = _cx - param["width"] / 2
y = _cy - param["height"] / 2
EndSub
Sub Shapes_CalcWidthAndHeight
' Shapes | Calculate total width and height of shapes
' param iMin, iMax - shape indices to add
' return shWidth, shHeight - total size of shapes
For i = iMin To iMax
If shape[i]["func"] = "tri" Or shape[i]["func"] = "line" Then
xmin = shape[i]["x1"]
xmax = shape[i]["x1"]
ymin = shape[i]["y1"]
ymax = shape[i]["y1"]
If shape[i]["x2"] < xmin Then
xmin = shape[i]["x2"]
EndIf
If xmax < shape[i]["x2"] Then
xmax = shape[i]["x2"]
EndIf
If shape[i]["y2"] < ymin Then
ymin = shape[i]["y2"]
EndIf
If ymax < shape[i]["y2"] Then
ymax = shape[i]["y2"]
EndIf
If shape[i]["func"] = "tri" Then
If shape[i]["x3"] < xmin Then
xmin = shape[i]["x3"]
EndIf
If xmax < shape[i]["x3"] Then
xmax = shape[i]["x3"]
EndIf
If shape[i]["y3"] < ymin Then
ymin = shape[i]["y3"]
EndIf
If ymax < shape[i]["y3"] Then
ymax = shape[i]["y3"]
EndIf
EndIf
shape[i]["width"] = xmax - xmin
shape[i]["height"] = ymax - ymin
EndIf
If i = 1 Then
shWidth = shape[i]["x"] + shape[i]["width"]
shHeight = shape[i]["y"] + shape[i]["height"]
Else
If shWidth < shape[i]["x"] + shape[i]["width"] Then
shWidth = shape[i]["x"] + shape[i]["width"]
EndIf
If shHeight < shape[i]["y"] + shape[i]["height"] Then
shHeight = shape[i]["y"] + shape[i]["height"]
EndIf
EndIf
EndFor
EndSub
Sub Shapes_Init
' Shapes | Initialize shapes data for Donkey Kong
' return shX, shY - current position of shapes
' return shape - array of shapes
shX = 150 ' x offset
shY = 120 ' y offset
shape = ""
shape[1] = "func=ell;x=98;y=44;width=110;height=71;bc=#834216;pw=0;"
shape[2] = "func=ell;x=51;y=247;width=75;height=23;angle=348;bc=#FDBC90;pc=#834216;pw=2;"
shape[3] = "func=ell;x=197;y=250;width=74;height=22;angle=11;bc=#FDBC90;pc=#834216;pw=2;"
shape[4] = "func=ell;x=113;y=253;width=20;height=22;bc=#FDBC90;pc=#834216;pw=2;"
shape[5] = "func=ell;x=191;y=255;width=18;height=20;bc=#FDBC90;pc=#834216;pw=2;"
shape[6] = "func=ell;x=40;y=260;width=13;height=16;bc=#FDBC90;pc=#834216;pw=2;"
shape[7] = "func=ell;x=47;y=264;width=16;height=18;bc=#FDBC90;pc=#834216;pw=2;"
shape[8] = "func=ell;x=261;y=267;width=13;height=13;bc=#FDBC90;pc=#834216;pw=2;"
shape[9] = "func=ell;x=252;y=269;width=13;height=15;bc=#FDBC90;pc=#834216;pw=2;"
shape[10] = "func=ell;x=81;y=190;width=36;height=67;angle=332;bc=#834216;pw=0;"
shape[11] = "func=ell;x=200;y=188;width=35;height=67;angle=20;bc=#834216;pw=0;"
shape[12] = "func=ell;x=76;y=175;width=62;height=43;bc=#834216;pw=0;"
shape[13] = "func=ell;x=171;y=178;width=60;height=40;bc=#834216;pw=0;"
shape[14] = "func=ell;x=112;y=139;width=82;height=76;bc=#834216;pw=0;"
shape[15] = "func=ell;x=75;y=99;width=81;height=72;bc=#834216;pw=0;"
shape[16] = "func=ell;x=149;y=96;width=82;height=74;bc=#834216;pw=0;"
shape[17] = "func=ell;x=5;y=87;width=107;height=55;angle=340;bc=#834216;pw=0;"
shape[18] = "func=ell;x=195;y=82;width=109;height=59;angle=25;bc=#834216;pw=0;"
shape[19] = "func=ell;x=0;y=126;width=43;height=76;angle=341;bc=#834216;pw=0;"
shape[20] = "func=ell;x=263;y=126;width=45;height=72;angle=17;bc=#834216;pw=0;"
shape[21] = "func=ell;x=33;y=176;width=39;height=35;bc=#FDBC90;pc=#834216;pw=2;"
shape[22] = "func=ell;x=239;y=176;width=41;height=37;bc=#FDBC90;pc=#834216;pw=2;"
shape[23] = "func=tri;x=113;y=0;x1=37;y1=0;x2=0;y2=76;x3=75;y3=76;bc=#834216;pw=0;"
shape[24] = "func=tri;x=148;y=5;x1=15;y1=0;x2=0;y2=43;x3=31;y3=43;bc=#834216;pw=0;"
shape[25] = "func=ell;x=110;y=46;width=58;height=41;angle=33;bc=#FDBC90;pw=0;"
shape[26] = "func=ell;x=138;y=47;width=61;height=41;angle=318;bc=#FDBC90;pw=0;"
shape[27] = "func=tri;x=119;y=60;x1=33;y1=0;x2=0;y2=41;x3=67;y3=41;angle=180;bc=#000000;pc=#000000;pw=2;"
shape[28] = "func=ell;x=127;y=61;width=28;height=19;angle=349;bc=#FFFFFF;pc=#000000;pw=2;"
shape[29] = "func=ell;x=152;y=62;width=30;height=20;angle=16;bc=#FFFFFF;pc=#000000;pw=2;"
shape[30] = "func=ell;x=135;y=66;width=14;height=15;bc=#000000;pc=#000000;pw=2;"
shape[31] = "func=ell;x=158;y=67;width=14;height=15;bc=#000000;pc=#000000;pw=2;"
shape[32] = "func=ell;x=123;y=140;width=59;height=60;bc=#FCA76E;pc=#834216;pw=2;"
shape[33] = "func=ell;x=150;y=107;width=62;height=55;bc=#FCA76E;pw=0;"
shape[34] = "func=ell;x=94;y=107;width=64;height=53;bc=#FCA76E;pw=0;"
shape[35] = "func=ell;x=96;y=79;width=118;height=69;bc=#FDBC90;pc=#834216;pw=2;"
shape[36] = "func=ell;x=77;y=65;width=35;height=23;angle=38;bc=#FDBC90;pc=#834216;pw=2;"
shape[37] = "func=ell;x=194;y=63;width=36;height=23;angle=317;bc=#FDBC90;pc=#834216;pw=2;"
shape[38] = "func=ell;x=130;y=74;width=22;height=17;angle=15;bc=#FDBC90;pw=0;"
shape[39] = "func=ell;x=156;y=73;width=22;height=18;angle=348;bc=#FDBC90;pw=0;"
shape[40] = "func=tri;x=111;y=90;x1=10;y1=0;x2=0;y2=22;x3=20;y3=22;angle=298;bc=#FFFFFF;pc=#000000;pw=2;"
shape[41] = "func=tri;x=172;y=91;x1=11;y1=0;x2=0;y2=23;x3=22;y3=23;angle=62;bc=#FFFFFF;pc=#000000;pw=2;"
shape[42] = "func=rect;x=125;y=97;width=55;height=21;bc=#FFFFFF;pc=#000000;pw=2;"
shape[43] = "func=ell;x=135;y=78;width=15;height=9;angle=23;bc=#834216;pw=0;"
shape[44] = "func=ell;x=159;y=77;width=15;height=9;angle=339;bc=#834216;pw=0;"
shape[45] = "func=line;x=152;y=97;x1=0;y1=0;x2=0;y2=19;pc=#000000;pw=2;"
shape[46] = "func=line;x=137;y=98;x1=0;y1=0;x2=0;y2=19;pc=#000000;pw=2;"
shape[47] = "func=line;x=167;y=99;x1=0;y1=0;x2=0;y2=18;pc=#000000;pw=2;"
EndSub
Sub Shapes_Move
' Shapes | Move shapes
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - to zoom
' param x, y - position to move
' return shX, shY - new position of shapes
Stack.PushValue("local", i)
s = scale
shX = x
shY = y
For i = iMin To iMax
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
_x = shape[i]["wx"]
_y = shape[i]["wy"]
Else
_x = shape[i]["rx"]
_y = shape[i]["ry"]
EndIf
Shapes.Move(shape[i]["obj"], shX + _x * s, shY + _y * s)
EndFor
i = Stack.PopValue("local")
EndSub
Sub Shapes_Remove
' Shapes | Remove shapes
' param iMin, iMax - shapes indices to remove
' param shape - array of shapes
Stack.PushValue("local", i)
For i = iMin To iMax
Shapes.Remove(shape[i]["obj"])
EndFor
i = Stack.PopValue("local")
EndSub
Sub Shapes_Rotate
' Shapes | Rotate shapes
' param iMin, iMax - shapes indices to rotate
' param shape - array of shapes
' param scale - to zoom
' param angle - to rotate
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
s = scale
param["angle"] = angle
param["cx"] = shWidth / 2
param["cy"] = shHeight / 2
For i = iMin To iMax
param["x"] = shape[i]["x"]
param["y"] = shape[i]["y"]
param["width"] = shape[i]["width"]
param["height"] = shape[i]["height"]
Shapes_CalcRotatePos()
shape[i]["rx"] = x
shape[i]["ry"] = y
If silverlight And Text.IsSubText("tri|line", shape[i]["func"]) Then
alpha = Math.GetRadians(angle + shape[i]["angle"])
SB_RotateWorkAround()
shape[i]["wx"] = x
shape[i]["wy"] = y
EndIf
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
Shapes.Rotate(shape[i]["obj"], angle + shape[i]["angle"])
EndFor
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub
Sub Slope_Add
' param["x1"] - top-left x co-ordinate
' param["y1"] - top-left y co-ordinate
' param["x2"] - top-right x co-ordinate
' param["y2"] - top-right y co-ordinate
' param["height"] - height of slope
' param["pitch"] - x pitch for diagonal brace
' param["color"] - color of slop
' return slope
n = slope["num"]
n = n + 1
slope["num"] = n
GraphicsWindow.PenColor = param["color"]
x1 = param["x1"]
y1 = param["y1"]
x2 = param["x2"]
y2 = param["y2"]
GraphicsWindow.DrawLine(x1, y1, x2, y2)
slope[n]["x1"] = x1
slope[n]["y1"] = y1
slope[n]["x2"] = x2
slope[n]["y2"] = y2
x = x2 - x1
y = y2 - y1
Math_CartesianToPolar()
slope[n]["ss"] = a
slope[n]["a"] = y
slope[n]["b"] = -x
slope[n]["c"] = -y * x1 + x * y1
x3 = x1
y3 = y1 + param["height"]
x4 = x2
y4 = y2 + param["height"]
GraphicsWindow.DrawLine(x3, y3, x4, y4)
slope[n]["x3"] = x3
slope[n]["y3"] = y3
slope[n]["x4"] = x4
slope[n]["y4"] = y4
pitch = param["pitch"]
up = "False"
For x5 = x1 To x2 - pitch Step pitch
x6 = x5 + pitch
If up Then
y5 = y1 + (y2 - y1) * (x5 - x1) / (x2 - x1)
y6 = y3 + (y4 - y3) * (x6 - x3) / (x4 - x3)
Else
y5 = y3 + (y4 - y3) * (x5 - x3) / (x4 - x3)
y6 = y1 + (y2 - y1) * (x6 - x1) / (x2 - x1)
EndIf
GraphicsWindow.DrawLine(x5, y5, x6, y6)
up = Not[up]
EndFor
EndSub