Microsoft Small Basic

Program Listing:
Embed this in your website
' Cue GUI for Billiard 0.1b
' Copyright (c) 2013 Nonki Takahashi. All rights reserved.
'
' History:
' 0.1b 2013-09-26 Created.
'
debug = "False"
Init()
Mouse_Move()
Sub Mouse_Move
  not = "False=True;True=False;"
  semaphore = "False"
  up = "True"
  GraphicsWindow.MouseMove = OnMouseMove
  GraphicsWindow.MouseDown = OnMouseDown
  GraphicsWindow.MouseUp = OnMouseUp
EndSub
Sub Init
  GraphicsWindow.Title = "Billiard 0.1a"
  scale = 1.5 ' [pixel/cm]
  Floor_Init()
  Table_Init()
  Ball_Init()
  Cue_Init()
EndSub
Sub OnMouseDown
  button = "down"
EndSub
Sub OnMouseUp
  button = "up"
  OnMouseMove()
EndSub
Sub OnMouseMove
  semaphore = not[semaphore]
  If semaphore Then
    If Mouse.IsLeftButtonDown = "False" Then
      button = "up"
    EndIf
    If button = "up" Then
      If up = "False" Then
        If debug Then
          Cross_Clear()
          Line_Clear()
        EndIf
        up = "True"
      EndIf
    ElseIf button = "down" Then
      mx = GraphicsWindow.MouseX
      my = GraphicsWindow.MouseY
      If up Then
        If debug Then
          Cross_Draw()
        EndIf
        cue["x0"] = mx
        cue["y0"] = my
        cue["grip"] = "False"
        up = "False"
      Else
        If debug Then
          Line_Draw()
        EndIf
        tx = cue["x0"]
        ty = cue["y0"]
        x = mx - tx
        y = my - ty
        Math_CartesianToPolar()
        If cue["length"] * 0.8 * scale < r Then
          cue["grip"] = "True"
        EndIf
        If cue["grip"] Then
          _a = Math.GetRadians(a)
          tx = mx - cue["length"] * 0.8 * scale * Math.Cos(_a)
          ty = my - cue["length"] * 0.8 * scale * Math.Sin(_a)
        EndIf
        angle = a
        Cue_Move()
      EndIf
    EndIf
  EndIf
  semaphore = not[semaphore]
EndSub
Sub Cross_Draw
  For i = 1 To 2
    If cross[i]["obj"] <> "" Then
      Shapes.Remove(cross[i]["obj"])
    EndIf
  EndFor
  GraphicsWindow.PenWidth = 1
  GraphicsWindow.PenColor = "Black"
  cross[1]["obj"] = Shapes.AddLine(0, 0, 20, 20)
  cross[2]["obj"] = Shapes.AddLine(0, 20, 20, 0)
  Shapes.SetOpacity(cross[1]["obj"], 50)
  Shapes.SetOpacity(cross[2]["obj"], 50)
  Shapes.Move(cross[1]["obj"], mx - 10, my - 10)
  Shapes.Move(cross[2]["obj"], mx - 10, my - 10)
  cross["x"] = mx
  cross["y"] = my
EndSub
Sub Cross_Clear
  For i = 1 To 2
    If cross[i]["obj"] <> "" Then
      Shapes.Remove(cross[i]["obj"])
    EndIf
  EndFor
EndSub
Sub Line_Draw
  If line["obj"] <> "" Then
    Shapes.Remove(line["obj"])
  EndIf
  GraphicsWindow.PenWidth = 1
  GraphicsWindow.PenColor = "Black"
  line["obj"] = Shapes.AddLine(cross["x"], cross["y"], mx, my)
  Shapes.SetOpacity(line["obj"], 50)
EndSub
Sub Line_Clear
  If line["obj"] <> "" Then
    Shapes.Remove(line["obj"])
  EndIf
EndSub
Sub Floor_Init
  gw = 800
  gh = 600
  GraphicsWindow.Width = gw
  GraphicsWindow.Height = gh
  GraphicsWindow.BackgroundColor = "#444444"
  GraphicsWindow.BrushColor = "#333333"
  draw1 = "False"
  For y = 0 To gh Step (25 * scale)
    draw = draw1
    If draw1 Then
      draw1 = "False"
    Else
      draw1 = "True"
    EndIf
    For x = 0 To gw Step (25 * scale)
      If draw Then
        GraphicsWindow.FillRectangle(x, y, 25 * scale, 25 * scale)
        draw = "False"
      Else
        draw = "True"
      EndIf
    EndFor
  EndFor
EndSub
Sub Table_Init
  table["width"] = 300    ' [cm]
  table["height"] = 150   ' [cm]
  table["colorTable"] = "ForestGreen"
  table["colorCushon"] = "Green"
  table["widthCushon"] = 3 ' [cm]
  table["colorRail"] = "#773300"
  table["widthRail"] = 5  ' [cm]
  x = (gw - table["width"] * scale) / 2
  table["x"] = x          ' [pixel]
  y = (gh - table["height"] * scale) / 2
  table["y"] = y          ' [pixel]
  GraphicsWindow.BrushColor = table["colorRail"]
  param["x"] = x - (table["widthRail"] + table["widthCushon"]) * scale
  param["y"] = y - (table["widthRail"] + table["widthCushon"]) * scale
  param["width"] = (table["width"] + table["widthRail"] * 2 + table["widthCushon"] * 2) * scale
  param["height"] =  (table["height"] + table["widthRail"] * 2 + table["widthCushon"] * 2) * scale
  param["border-radius"] = table["widthRail"] * scale / 2
  FillRoundRectangle()
  GraphicsWindow.BrushColor = table["colorCushon"]
  GraphicsWindow.FillRectangle(x - table["widthCushon"] * scale, y - table["widthCushon"] * scale, (table["width"] + table["widthCushon"] * 2) * scale, (table["height"] + table["widthCushon"] * 2) * scale)
  GraphicsWindow.BrushColor = table["colorTable"]
  GraphicsWindow.FillRectangle(x, y, table["width"] * scale, table["height"] * scale)
EndSub
Sub Ball_Init
  ball["diameter"] = 5.7  ' [cm]
  ball["num"] = 1
  ball[1]["color"] = "White"
  GraphicsWindow.PenWidth = 0
  GraphicsWindow.BrushColor = ball[1]["color"]
  d = ball["diameter"] * scale
  ball[1]["obj"] = Shapes.AddEllipse(d, d)
  x = table["x"] + table["width"] * scale * 7 / 8
  ball[1]["x"] = x        ' [pixel]
  y = table["y"] + table["height"] * scale / 2
  ball[1]["y"] = y        ' [pixel]
  Shapes.Move(ball[1]["obj"], x - d / 2, y - d / 2)
EndSub
Sub Cue_Init
  cue["length"] = 145     ' [cm]
  cue["width"] = 1        ' [cm]
  cue["color"] = "GoldenRod"
  cue["angle"] = 90       ' [degree]
  GraphicsWindow.PenWidth = 0
  GraphicsWindow.BrushColor = cue["color"]
  cue["obj"] = Shapes.AddRectangle(cue["length"] * scale, cue["width"] * scale)
  tx = 5 * scale
  ty = 5 * scale
  angle = cue["angle"]
  Cue_Move()
EndSub
Sub Cue_Move
  ' param tx, ty - tip
  ' param angle
  a = Math.GetRadians(angle)
  cx = tx + cue["length"] * scale / 2 * Math.Cos(a)
  cy = ty + cue["length"] * scale / 2 * Math.Sin(a)
  x = cx - cue["length"] * scale / 2
  y = cy - cue["width"] * scale / 2
  Shapes.Move(cue["obj"], x, y)
  Shapes.Rotate(cue["obj"], angle)
EndSub
Sub FillRoundRectangle
  Stack.PushValue("local", param)
  If (param["width"] / 2 < param["border-radius"]) Or (param["height"] / 2 < param["border-radius"]) Then
    param["border-radius"] = Math.Min(param["width"] / 2, param["height"] / 2)
  EndIf
  GraphicsWindow.FillEllipse(param["x"], param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
  GraphicsWindow.FillRectangle(param["x"] + param["border-radius"], param["y"], param["width"] - param["border-radius"] * 2, param["height"])
  GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
  GraphicsWindow.FillRectangle(param["x"], param["y"] + param["border-radius"], param["width"], param["height"] - param["border-radius"] * 2)
  GraphicsWindow.FillEllipse(param["x"], param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
  GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
  param = Stack.PopValue("local")
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
Copyright (c) Microsoft Corporation. All rights reserved.