Microsoft Small Basic

Program Listing: HMP803-3
' Dragon vs Turtle
' Copyright © 2015 Nonki Takahashi. The MIT License.
' Version 0.4a
' Last update 2015-05-19
' Program ID HMP803-3
' Update:
' Added fire balls and stars.
'
title = "Dragon vs Turtle"
version = "0.4a"
GraphicsWindow.Title = title
SB_Workaround()
folder = "http://www.nonkit.com/smallbasic.files"
GraphicsWindow.BackgroundColor = "YellowGreen"
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.FontName = "Trebuchet MS"
GraphicsWindow.BrushColor = "White"
GraphicsWindow.DrawText(8, gh - 22, title + " " + version)
InitTurtle()
InitStar()
InitDragon()
InitFire()
mouseDown = "False"
GraphicsWindow.MouseDown = OnMouseDown
t = Clock.ElapsedMilliseconds / 1000
tf = t ' time fired
While "True"
Program.Delay(100) '1000/30)
t1 = t
t = Clock.ElapsedMilliseconds / 1000
dt = t - t1
mx = GraphicsWindow.MouseX
my = GraphicsWindow.MouseY
MoveTurtle()
MoveDragon()
If mouseDown Then
AddStar()
mouseDown = "False"
EndIf
MoveStar()
If 3 <= t - tf Then
AddFire()
tf = t
EndIf
MoveFire()
EndWhile
Sub OnMouseDown
mouseDown = "True"
EndSub
Sub AddFire
nFire = nFire + 1
GraphicsWindow.BrushColor = "Red"
GraphicsWindow.PenWidth = 0
fire[nFire] = Shapes.AddEllipse(dw, dw)
fx[nFire] = bx[ih]
fy[nFire] = by[ih]
Shapes.Move(fire[nFire], fx[nFire] - dw / 2, fy[nFire] - dw / 2)
fo[nFire] = 100 ' opacity
_a = Math.GetRadians(ba[ih])
dfx[nFire] = Math.Cos(_a) * dw * 1.5
dfy[nFire] = Math.Sin(_a) * dw * 1.5
EndSub
Sub MoveFire
iFire = Array.GetAllIndices(fire)
n = Array.GetItemCount(fire)
For i = 1 To n
fo[iFire[i]] = fo[iFire[i]] - 6
If fo[iFire[i]] <= 0 Then
Shapes.Remove(fire[iFire[i]])
fire[iFire[i]] = ""
Else
Shapes.SetOpacity(fire[iFire[i]], fo[iFire[i]])
fx[iFire[i]] = fx[iFire[i]] + dfx[iFire[i]]
fy[iFire[i]] = fy[iFire[i]] + dfy[iFire[i]]
Shapes.Move(fire[iFire[i]], fx[iFire[i]] - dw / 2, fy[iFire[i]] - dw / 2)
EndIf
EndFor
EndSub
Sub AddStar
nStar = nStar + 1
img = folder + "/star.png"
star[nStar] = Shapes.AddImage(img)
If silverlight Then
Program.Delay(msWait)
EndIf
sx[nStar] = tx
sy[nStar] = ty
Shapes.Move(star[nStar], sx[nStar] - 5, sy[nStar] - 5)
dist = Math.SquareRoot(Math.Power(mx - sx[nStar], 2) + Math.Power(my - sy[nStar], 2))
dsx[nStar] = (mx - sx[nStar]) / dist * 5
dsy[nStar] = (my - sy[nStar]) / dist * 5
sa[nStar] = 0
EndSub
Sub MoveStar
For i = 1 To nStar
sx[i] = sx[i] + dsx[i]
sy[i] = sy[i] + dsy[i]
Shapes.Move(star[i], sx[i] - 5, sy[i] - 5)
sa[i] = sa[i] + 30
If 360 <= sa[i] Then
sa[i] = sa[i] - 360
EndIf
Shapes.Rotate(star[i], sa[i])
EndFor
EndSub
Sub MoveTurtle
tx = Turtle.X
ty = Turtle.Y
x = mx - tx
y = my - ty
Math_CartesianToPolar()
Turtle.Angle = a + 90
Turtle.Move(4)
EndSub
Sub MoveDragon
tx = Turtle.X
ty = Turtle.Y
x = tx - bx[ih]
y = ty - by[ih]
Math_CartesianToPolar()
da = a - ba[ih]
While da <= -180
da = da + 360
EndWhile
While 180 < da
da = da - 360
EndWhile
maxDa = 5
If da < -maxDa Then
da = -maxDa
ElseIf maxDa < da Then
da = maxDa
EndIf
' move head
ba[ih2] = ba[ih] + da
_a = Math.GetRadians(ba[ih2])
bx[ih2] = bx[ih] + dw * Math.Cos(_a)
by[ih2] = by[ih] + dw * Math.Sin(_a)
Shapes.Move(head, bx[ih2] - dw / 2, by[ih2] - dw / 2)
Shapes.Rotate(head, ba[ih2])
' move tail
Shapes.Move(body[it], bx[in2] - dw / 2, by[in2] - dw / 2)
body[in2] = body[it]
body[it] = ""
' move legs
Shapes.Move(legs, bx[il2] - dw * 1.5 - 1, by[il2] - 2 * dw - 1)
Shapes.Rotate(legs, ba[il2])
' move arms
Shapes.Move(arms, bx[ia2] - dw * 1.5 - 1, by[ia2] - 2 * dw - 1)
Shapes.Rotate(arms, ba[ia2])
ih = ih2
CalcIndex()
EndSub
Sub InitTurtle
Turtle.PenUp()
Turtle.TurnRight()
Turtle.Move(220)
Turtle.TurnLeft()
Turtle.TurnLeft()
EndSub
Sub InitStar
nStar = 0
EndSub
Sub CalcIndex
' index for head
ih2 = ih + 1
If h < ih2 Then
ih2 = ih2 - h
EndIf
' index for legs
il = ih + 7
If h < il Then
il = il - h
EndIf
il2 = il + 1
If h < il2 Then
il2 = il2 - h
EndIf
' index for arms
ia = ih + 15
If h < ia Then
ia = ia - h
EndIf
ia2 = ia + 1
If h < ia2 Then
ia2 = ia2 - h
EndIf
' index for tail
it = ih2
' index for neck (to)
in2 = ih
EndSub
Sub InitDragon
interval = 3 ' sec
dc = "OrangeRed"
dw = 12
GraphicsWindow.PenColor = "Black"
GraphicsWindow.BrushColor = dc
h = 22
ih = h
CalcIndex()
bx[it] = 60 ' for tail
by[it] = 200
img = folder + "/dragonarm.png"
body[it] = Shapes.AddEllipse(dw, dw)
Shapes.Move(body[it], bx[it] - dw / 2, by[it] - dw / 2)
ba[it] = 0 ' body angle
ang = Math.GetRandomNumber(10) - 5
If ang < 1 Then
ang = ang - 1
EndIf
For i = 2 To h - 1
UpdateAngle()
_a = Math.GetRadians(ba[i])
bx[i] = bx[i - 1] + dw * Math.Cos(_a)
by[i] = by[i - 1] + dw * Math.Sin(_a)
If i = il Then
legs = Shapes.AddImage(img)
If silverlight Then
Program.Delay(msWait)
EndIf
Shapes.Move(legs, bx[i] - dw * 1.5 - 1, by[i] - 2 * dw - 1)
Shapes.Rotate(legs, ba[i])
Shapes.HideShape(legs)
EndIf
If i = ia Then
arms = Shapes.AddImage(img)
If silverlight Then
Program.Delay(msWait)
EndIf
Shapes.Move(arms, bx[i] - dw * 1.5 - 1, by[i] - 2 * dw - 1)
Shapes.Rotate(arms, ba[i])
Shapes.HideShape(arms)
EndIf
EndFor
For i = 2 To h - 1
body[i] = Shapes.AddEllipse(dw, dw)
Shapes.Move(body[i], bx[i] - dw / 2, by[i] - dw / 2)
If i = il Then
Shapes.ShowShape(legs)
EndIf
If i = ia Then
Shapes.ShowShape(arms)
EndIf
Program.Delay(100)
EndFor
UpdateAngle()
_a = Math.GetRadians(ba[i])
bx[i] = bx[i - 1] + dw * Math.Cos(_a)
by[i] = by[i - 1] + dw * Math.Sin(_a)
head = Shapes.AddRectangle(dw, dw)
Shapes.Move(head, bx[i] - dw / 2, by[i] - dw / 2)
Shapes.Rotate(head, ba[i])
EndSub
Sub InitFire
nFire = 0
EndSub
Sub UpdateAngle
da = Math.Sin((i - 1) / 25 * 2 * Math.Pi) * ang
ba[i] = ba[i - 1] + da
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_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