İstanbul,
22°C
az bulutlu
Small Basic Oyun Kodları ile çeşitli bir çok oyunu nasıl yapabileceğinizi öğrenebilirsiniz. Hazır kodlardan yola çıkarak kendinizi geliştirecek ve sıfırdan bir oyun yapacak donanıma sahip olabilmek için işinize yarayacak bazı oyun kodlarını sizlere sunuyoruz.
'Code Copyright Noah Buscher 2012
'Image Copyright Mojang
'Thank You to Mojang for Images
'This Game and/or Noah Buscher is Not Affliated with Minecraft or Mojang in Any Way
'Sets Up Board to Play
GraphicsWindow.title = "MineTag"
GraphicsWindow.CanResize = "False"
GraphicsWindow.BackgroundColor = "Green"
GraphicsWindow.Height = 500
GraphicsWindow.Width = 500
GraphicsWindow.FontName = "Neuropol"
GraphicsWindow.FontSize = "24"
GraphicsWindow.BrushColor = "White"
touch = "False"
score = 0
mex = 430
mey = 10
ox = 10
oy = 430
Player = Shapes.AddImage("http://i47.tinypic.com/nx2h4w.jpg")
Shapes.Move(Player, mex, mey)
Zombie = Shapes.AddImage("http://i49.tinypic.com/2gvsk6r.jpg")
Shapes.Move(Zombie, ox, oy)
scoreDisp = Shapes.AddText(score)
'Refreshes the Screen every .0020 seconds and Checks for Touch
Timer.interval = 20
Timer.resume()
Timer.Tick = Tock
Sub Tock
score = score + 0.0020
Shapes.SetText(scoreDisp, score)
If ox = mex And oy = mey Then
Shapes.Remove(Player)
Sound.PlayClick()
Timer.pause()
touch = "True"
GraphicsWindow.ShowMessage("Your Score Was " + score , "You Lost")
Program.End()
EndIf
EndSub
'This Sub Controls How the Human Player Moves
GraphicsWindow.TextInput = PlayerMove
Sub PlayerMove
If GraphicsWindow.LastText = "w" Then
mey = mey - 10
Shapes.Move(Player, mex, mey)
EndIf
If GraphicsWindow.LastText = "a" Then
mex = mex - 10
Shapes.Move(Player, mex, mey)
EndIf
If GraphicsWindow.LastText= "s" Then
mey = mey + 10
Shapes.Move(Player, mex, mey)
EndIf
If GraphicsWindow.LastText = "d" Then
mex = mex + 10
Shapes.Move(Player, mex, mey)
EndIf
'Makes the Board Inf.
If mex > 500 Then
mex = 0
endif
If mey > 500 Then
mey = 0
EndIf
If mex < 0 Then
mex = 500
endif
If mey < 0 Then
mey = 500
EndIf
EndSub
'Controls AI Movement
While touch = "False"
If ox < mex Then
ox = ox + 10
Shapes.Move(Zombie, ox, oy)
Program.Delay(80)
endif
If ox > mex Then
ox = ox - 10
Shapes.Move(Zombie, ox, oy)
Program.Delay(80)
endif
If oy < mey Then
oy = oy + 10
Shapes.Move(Zombie, ox, oy)
Program.Delay(80)
endif
If oy > mey Then
oy = oy - 10
Shapes.Move(Zombie, ox, oy)
Program.Delay(80)
endif
EndWhile
' 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
'***************************************************
' Small Basic Chomper (SBC) v 1.0
' Pacman-style game (BETA)
'Version 1.3.7.13 (online version)
'
' Software designed & written in BASIC by Anthony Yarrell (QBasicLover in the SB forums)
' Designed for Microsoft Small Basic 1.0
' March 2013
'
'Sprites created using Microsoft Paint
'Maze designed using Microsoft Excel
'
'My Research Sources:
'===============
'Sprite Management & Animation: "Visual Basic Game Programming for Teens", Jonathan S. Harbour;
'"Video Game Programming for Teens", Jonathan S. Harbour; Microsoft Small Basic Forums.
'Pacman Sprite Behavior: "The Pacman Dossier" http://home.comcast.net/~jpittman2/pacman/pacmandossier.html;
'Creating a Pacman Maze: http://stackoverflow.com/questions/622471/pacman-maze-in-java;
'
'***************************************************
'These variables control game play:
BRAND_NEW_GAME = 0
PLAY_LEVEL = 1
ADVANCE_LEVEL = 2
REPLAY_LEVEL = 3
GAME_OVER = 4
gameState = BRAND_NEW_GAME
'Initialization:
mazeScale = 8 'Size of maze and distance between tiles. The game runs better when
'the mazeScale is 2 x the number of animation frames. I set the total animation frames
'to 4 because it gave the best performance while making the math easier.
gameScreenHeight = 375
gamescreenWidth = 225
monsterEatenCtr = 0 'Counts the number of monsters eaten in succession per energizer (4= bonus)
monsterBonusPts = 1000 'Pts given to player for eating 4 monsters in succession.
monsterPts = 200 'Points player gets when he/she eats a monster.
monsterPtsMuliplier = 2 'Causes player to get bonus points when monsters are eaten in succession.
monstersEatenPerLevel = 0'Counts the number of mosters eaten per level. SBC gets a life if he eats 16 monsters per level.
gameSpeed = 20'<-- Decrease if game runs too slowly
gameScore = 0
gameLevel = 0
pelletScore = 25
energizerScore = 100
hasReached50K = "False" 'Flag to track if score reaches 50,000. Player gets extra life.
initialCountDownTime = 80 'Amount of time (cycles) the monsters stay "frightened"
globalCycleCtr = 0 'Used for syncronization and scheduling.
'**********************************
'Game loop
'***********************************
While (gameState <> GAME_OVER)
keyPressed = GraphicsWindow.LastKey
start = Clock.ElapsedMilliseconds
globalCycleCtr = globalCycleCtr + 1
If (gameState = BRAND_NEW_GAME) Then
InitializeLookupTables()
SetupGraphicsWindow()
LoadBitmaps()
InitializeSprites()
SpriteArray[SBC][Lives] = 3
gameState = ADVANCE_LEVEL
ElseIf (gameState = ADVANCE_LEVEL) Then
globalCycleCtr = 0
monstersEatenPerLevel = 0
selectedRotation = 0 ' SBC goes through 4 max rotations.
sbcDirection = Dir_R ' SBC moves to the right when level starts.
SmallDelay()
UpdateLevelState()
ConstructGameElements()
splashText = "L E V E L : "+ gameLevel
DisplayLevelSplash()
gameState = PLAY_LEVEL
ElseIf (gameState = PLAY_LEVEL) Then
LeaveMonsterPenOneByOne()
'Each sprite has a counter that it uses to track when it reaches a tile when moving though the maze.
'When this counter reaches mazeScale, the sprite updates it info and draws.
'Each sprite also has a spritespeed variable that it uses to set its movement speed. For example,
'if spritespeed = 1 then updates will be done on each tick of the global counter. If spritespeed = 2 then
'updates will be done on every 2nd tick, which will slow down that sprite, etc.
For Sprites = firstSprite to lastSprite
IF Math.Remainder(globalCycleCtr,SpriteArray[Sprites][spriteSpeed])=0 Then
Update()
Draw()
EndIf
Endfor
ElseIf (gameState = REPLAY_LEVEL) Then
sbcDirection = Dir_R
Sprites=1
SpriteArray[SBC][Lives] = SpriteArray[sbc][Lives] - 1
SpriteArray[SBC][State] = NORMAL
globalCycleCtr = 0
SmallDelay()
ClearSpritesFromaze()
InitializeSprites()
PositionSpritesInMaze()
DrawSprites() '<---BUG FIX. A call to DrawSprites( ) fixes an issue where SBC dissapears when level restarts.
SmallDelay()
gameState = PLAY_LEVEL
If (SpriteArray[SBC][Lives] = 0) Then
gameState = GAME_OVER
splashText = "Game Over"
DisplayLevelSplash()
Endif
Endif
delay = gameSpeed - (Clock.ElapsedMilliseconds-start)
If (delay > 0) Then
Program.Delay(delay)
EndIf
KeyboardHandler()
EndWhile 'End of main state machine
'***********************************************************************************
Sub SmallDelay
Program.Delay(500)
EndSub
'*******************************************************************************************
'Updates various games elements (eg maze color, game speed, etc) as the player advances to a new level:
'- gameSpeed: Overall speed of game. Game gets faster on each level.
'- initialCountDownTime: amount of time that monsters stay afraid. Decreases on each level.
Sub UpdateLevelState
If math.Remainder(gameLevel,4) = 1 Then
mazeBorderColor = "Cyan"
ElseIf math.Remainder(gameLevel,4) = 2 then
mazeBorderColor = "Red"
Elseif math.Remainder(gameLevel,4) = 3 then
mazeBorderColor = "midnightblue"
Elseif math.Remainder(gameLevel,4) = 0 then
mazeBorderColor = "magenta"
EndIf
gameLevel = gameLevel + 1
gameSpeed = gameSpeed - 2
If (gameSpeed <= 0) Then
gameSpeed = 0
EndIf
'Give the player a new life on levels 4 and 8:
If (gameLevel = 4 Or gameLevel = 8) Then
SpriteArray[sbc][Lives]=SpriteArray[sbc][Lives] + 1
EndIf
'Reduce the amount of time that the monsters stay "Frightened" as game progresses.
'At much higher levels, the monsters won't stay frighened at all:
initialCountDownTime = initialCountDownTime - 2
If initialCountDownTime <= 0 Then
initialCountDownTime = 0
EndIf
EndSub
'*******************************************************************************************
'Dsplays a splash screen at the start of each level:
Sub DisplayLevelSplash
GraphicsWindow.FontSize=14
GraphicsWindow.BrushColor="white"
l=Shapes.AddText(splashText)
Shapes.Move(l,-200,205)
Shapes.Animate(l,80,205,1000)
SmallDelay()
SmallDelay()
SmallDelay()
Shapes.Animate(l,-200,205,1000)
EndSub
'*******************************************************************************************
'The variables Dir_L, Dir_U, Dir_R, Dir_D are used as indexes into the xModifier and yModifier lookup tables.
'For example, xModifier[L] & yModifier[L] produces -1 and 0 respectively. When added to XY or RC values this will cause
'the sprite to go left, etc:
Sub KeyboardHandler
Dir_L = 1
Dir_U = 2
Dir_R = 3
Dir_D = 4
If (keyPressed = "Left") Then
sbcDirection = Dir_L
Elseif (keyPressed = "Right") Then
sbcDirection = Dir_R
Elseif (keyPressed = "Up") Then
sbcDirection = Dir_U
Elseif (keyPressed = "Down") Then
sbcDirection = Dir_D
Elseif (keyPressed = "Escape") Then
gameState = GAME_OVER
Endif
EndSub
'*******************************************************************************************
Sub MoveSBC
'This routine moves SBC around the screen and causes SBC to stop at borders.It checks the maze
'locations adjacent to SBC's current location aganist the direction chosen by an arrow key press.
'If the new direction is possible (eg no borders in the way) SBC will go in the new direction. If
'the new direction is not possible, but the previous direction is, SBC will continue traveling in the
'direction it was moving in prior to the arrow key press. If neither direction is possible, SBC
'will stop moving:
If Sprites=SBC Then
canMoveInOldDirection = "False"
canMoveInNewDirection = "False"
'Get maze data ahead of SBC:
aheadDirX = SpriteArray[SBC][mazeCol] + SpriteArray[SBC][DX]
aheadDirY = SpriteArray[SBC][mazeRow] + SpriteArray[SBC][DY]
aheadDirData = Maze[aheadDirY][aheadDirX]
'Get maze data at location based on arrow key press:
newDirX = SpriteArray[SBC][mazeCol] + xModifier[SbcDirection]
newDirY = SpriteArray[SBC][mazeRow] + yModifier[SbcDirection]
newDirData = Maze[newDirY][newDirX]
'The mazeTokens array holds data that represent ares that are NOT blocked by borders.
For a = firstToken To lastToken
If (mazeTokens[a] = newDirData) Then
canMoveInNewDirection = "True"
Goto _XIT_4Loop_Early
EndIf
If (mazeTokens[a] = aheadDirData) Then
canMoveInOldDirection = "True"
EndIf
EndFor
_XIT_4Loop_Early:
'If the new direction is possible, go in new direction:
If (canMoveInNewDirection = "True") Then
SpriteArray[SBC][DX] = xModifier[sbcDirection]
SpriteArray[SBC][DY] = yModifier[sbcDirection]
selectedRotation = rotationLookupTable[sbcDirection]
EndIf
'If neither old nor new directions are possible, come to a stop:
If (canMoveInNewDirection = "False" And canMoveInOldDirection = "False") Then
SpriteArray[SBC][DX] = 0
SpriteArray[SBC][DY] = 0
EndIf
SpriteArray[SBC][mazeCol] = SpriteArray[SBC][mazeCol] + SpriteArray[SBC][DX]
SpriteArray[SBC][mazeRow] = SpriteArray[SBC][mazeRow] + SpriteArray[SBC][DY]
EatPellet()
EndIf
EndSub
'*******************************************************************************************
Sub MoveMonstersTowardTarget
'This routine moves the monsters toward a target while allowing them to navigate around the maze
'borders. LL is a temporary array:
INVALID = 9999 '9999 is used as an invalid flag because the total distance across the maze is
'much lower than 9999 pixels. Later, when the code calculates the distance
'between source to target, anything marked 9999 won't be considered.
If (Sprites <> SBC) Then '<--SBC has his own movement routine (see MoveSBC)
For a = 1 To 4 'step through XY/RC modifier table:
SourceX = SpriteArray[Sprites][mazeCol] + xModifier[a]
SourceY = SpriteArray[Sprites][mazeRow] + yModifier[a]
targetX = SpriteArray[Sprites][targetCol]
targetY = SpriteArray[Sprites][targetRow]
For b = firstToken To lastToken
'If the maze area being examined is not a border then calculate the distance from that maze area
' to the target using the Manhattan Distance formula (SourceX-targetCol)+(SourceY-targetRow)...
If mazeTokens[b]=Maze[SpriteArray[Sprites][mazeRow] + yModifier[a]][SpriteArray[Sprites][mazeCol]+ xModifier[a]] Then
LL[a] = 1+(math.Abs(Sourcex-targetx) + math.Abs(Sourcey-targety))
Goto _XIT4
'...otherwise mark it as invalid because it's a border :
Else
LL[a] = INVALID
EndIf
EndFor
_XIT4:
EndFor
'For each maze area stored in the LL array, check to see if that was visited by the monster during previous
'game loop cycle. If so mark it INVALID, then save the monster's current maze location
'in VX, VY. These two steps will force the monster to travel in forward directions only (no reversing direction):
For c = 1 To 4
If SpriteArray[Sprites][mazeCol] + xModifier[c] = SpriteArray[Sprites][VX] Then
If SpriteArray[Sprites][mazeRow] + yModifier[c] = SpriteArray[Sprites][VY] Then
LL[c] = INVALID
EndIf
EndIf
EndFor
SpriteArray[Sprites][VX] = SpriteArray[Sprites][mazeCol]
SpriteArray[Sprites][VY] = SpriteArray[Sprites][mazeRow]
'Get the smallest number in temporary LL array, which will represent the direction to move in
'1 = go left, 2 = go up, 3 = to right, 4 = go down:
initialValue = LL[1]
For ictr = 1 TO 4
If initialValue >= LL[ictr] THEN
initialValue = LL[ictr]
elementfound = ictr
EndIf
EndFor
'Set the movement direction. The xModifier/yModifier lookup tables eliminate the need for If/Then tests here:
SpriteArray[Sprites][DX] = xModifier[elementfound]
SpriteArray[Sprites][DY] = yModifier[elementfound]
'** There is at least one circumstance where the monster finds a dead end - when the monster is in the
'monster pen at level start. In this instance, the monster's L, D, & R adjacent areas will be invalid
'due to being blocked by visible and invisible borders, and U is blocked because it will be added to the
'VX/VY variables after the first game cycle. When this happens the VX/VY variables must be deleted
'and on the next game cycle the monster will move out of dead end.
'
if LL[elementfound] = INVALID Then
SpriteArray[Sprites][DX] = 0
SpriteArray[Sprites][DY] = 0
SpriteArray[Sprites][VX] = 0
SpriteArray[Sprites][VY] = 0
EndIf
'Finally, move toward target:
SpriteArray[Sprites][mazeCol] = (SpriteArray[Sprites][mazeCol] + SpriteArray[Sprites][dx])
SpriteArray[Sprites][mazeRow] = (SpriteArray[Sprites][mazeRow] + SpriteArray[Sprites][dy])
EndIf
Endsub
'*******************************************************************************************
'Detects when sprites touch each other and when sprites enter special areas of the maze:
Sub CollisionDetect
If Sprites <> SBC Then
CheckRectangles()
If isTouching = "True" Then
isTouching = "False"
'Monster dies if touching SBC while fightened and then monster returns to the monster pen:
If SpriteArray[Sprites][State] = FRIGHT then
ShowEatSplash()
SpriteArray[Sprites][State] = DIE
hasEatenMonster = "True"
ScoreAndBonusManager()
'SBC dies if touching monster when energizer is not active:
ElseIf SpriteArray[Sprites][State] = CHASE then
SpriteArray[SBC][State] = DIE
gameState = REPLAY_LEVEL
EndIf
hasEatenMonster = "False"
EndIf
'When monster reaches monster pen, get body back and leave:
If SpriteArray[Sprites][mazeCol] = MonsterPenX and SpriteArray[Sprites][mazeRow]= MonsterPenY Then
If SpriteArray[Sprites][State] = DIE then
SpriteArray[Sprites][State] = EMERGE
EndIf
EndIf
'When monster has left monster pen, go back to chasing SBC:
If SpriteArray[Sprites][mazeCol] = emergeX and SpriteArray[Sprites][mazeRow] = emergeY Then
If SpriteArray[Sprites][State] = EMERGE then
SpriteArray[Sprites][State] = CHASE
EndIf
EndIf
EndIf
'***BUG FIX: If a monster is in the monster pen when an energizer is eaten it will switch from whatever mode its in to
'FRIGHT mode. However, FRIGHT mode closes to doors when causes the monster to get trapped. This is a side effect -
'my intention was to keep the monsters from re-entering the pen prematurely. The fix below checks to see if a monster
'is in the pen and is the wrong mode. If so, it is switched to EMERGE mode so that it can properly emerge from the pen:
If (SpriteArray[Sprites][mazeCol] = MonsterPenX) and (SpriteArray[Sprites][mazeRow] = MonsterPenY) Then
If (SpriteArray[Sprites][State] <> DIE) Or (SpriteArray[Sprites][State] <> EMERGE) then
SpriteArray[Sprites][State] = EMERGE
EndIf
EndIf
EndSub
'*******************************************************************************************
'Sets the targets that the monsters will move towards:
Sub SetupMonsterTargets
IF (Sprites <>SBC) then
'Sets ghosts to meander around the screen after SBC eats a power pellet:
If SpriteArray[Sprites][State] = FRIGHT Then
SpriteArray[Sprites][targetRow] = math.GetRandomNumber(maxMazeRows)
SpriteArray[Sprites][targetCol] = math.GetRandomNumber(maxMazeCols)
'Sends the monsters back to monster pen after being eaten by SBC:
ElseIf SpriteArray[Sprites][State] = DIE Then
SpriteArray[Sprites][targetCol] = MonsterPenX
SpriteArray[Sprites][targetRow] = MonsterPenY
'Makes the monsters leave home base:
ElseIf SpriteArray[Sprites][State] = EMERGE Then
SpriteArray[Sprites][targetCol] = emergeX
SpriteArray[Sprites][targetRow] = emergeY
Elseif SpriteArray[Sprites][State] = CHASE Then
If Sprites = RedMonster Then
'Red monster pursues directly:
SpriteArray[RedMonster][targetCol] = SpriteArray[SBC][mazeCol]
SpriteArray[RedMonster][targetRow] = SpriteArray[SBC][mazeRow]
ElseIf Sprites = PinkMonster Then
'Pink monster tries to ambush (***TO DO: needs to be fixed***):
SpriteArray[PinkMonster][targetCol] = SpriteArray[SBC][mazeCol] + (SpriteArray[SBC][DX]-1)
SpriteArray[PinkMonster][targetRow] = SpriteArray[SBC][mazeRow] + (SpriteArray[SBC][DY]-1)
ElseIf Sprites = OrangeMonster Then
'Orange monster wanders around
SpriteArray[OrangeMonster][targetCol] = math.GetRandomNumber(maxMazeCols)
SpriteArray[OrangeMonster][targetRow] = math.GetRandomNumber(maxMazeRows)
ElseIf Sprites = BlueMonster Then
'Blue monster considers red monster's coordinates and SBC's coordinates wheb determining how to move:
SpriteArray[BlueMonster][targetCol] = math.abs(SpriteArray[SBC][mazeCol] + SpriteArray[RedMonster][mazeCol])
SpriteArray[BlueMonster][targetRow] = math.abs(SpriteArray[SBC][mazeRow] + SpriteArray[RedMonster][mazeRow])
EndIf
EndIf
ENDIF
EndSub
'*******************************************************************************************
'Animation manager. The animation frames are stored in the ImageArray 2D array. This routine
'sets the indexes into that array. FrameCtr + Offset is used as the index into ImageArray.
'When Offset = zero all sprites go through the normal 4-cycle animation sequence. When
'offset = 5, the monsters turn purple (Fright Mode), and when the offset = 6 the monsters turn dark gray
'(Die Mode).
Sub SetupAnimationSequence
SpriteArray[SBC][LastFrame] = 4
SpriteArray[SBC][FirstFrame] = 1
SpriteArray[SBC][offset] = 0
If (Sprites <> SBC) Then
If SpriteArray[Sprites][State] = CHASE Then
SpriteArray[Sprites][offset] = 0
SpriteArray[Sprites][LastFrame] = 4
SpriteArray[Sprites][FirstFrame] = 1
ElseIf SpriteArray[Sprites][State] = FRIGHT Then
SpriteArray[Sprites][offset] = 5
SpriteArray[Sprites][LastFrame] = 5
SpriteArray[Sprites][FirstFrame] = 5
ElseIf SpriteArray[Sprites][State] = DIE Then
SpriteArray[Sprites][offset] = 6
SpriteArray[Sprites][LastFrame] = 6
SpriteArray[Sprites][FirstFrame] = 6
ElseIf SpriteArray[Sprites][State] = EMERGE Then
SpriteArray[Sprites][offset] = 0
SpriteArray[Sprites][LastFrame] = 4
SpriteArray[Sprites][FirstFrame] = 1
Endif
EndIf
FlashMonsters()
EndSub
'*******************************************************************************************
Sub EatPellet
erasePelletFromScreen = "FALSE"
mazeData = Maze[(SpriteArray[SBC][mazeRow])][(SpriteArray[SBC][mazeCol])]
'Pellet = mazeToken[1]. Energizer = mazeToken[2]:
If (mazeData = mazeTokens[1] Or mazeData = mazeTokens[2]) Then
Maze[(SpriteArray[SBC][mazeRow])][(SpriteArray[SBC][mazeCol])]=mazeTokens[0] 'empty this maze location
pelletCount = pelletCount - 1
erasePelletFromScreen = "True"
gameScore = gameScore + pelletScore
If (mazeData = mazeTokens[1]) Then
gameScore = gameScore + pelletScore
ElseIf (mazeData = mazeTokens[2]) then
monsterEatenCtr=0
SetMonstersToFrightState()
gameScore = gameScore + energizerScore
energizerTimer = ACTIVE
energizerTime = initialCountDownTime
EndIf
If pelletCount <= 0 Then
gameState = ADVANCE_LEVEL
EndIf
EndIf
DoEnergizerTimer()
EndSub
'*******************************************************************************************
'Sets all monsters to FRIGHT state. VY & VX are zeroed out so that the monsters can switch
'directions. (MoveMonstersTowardTarget( ) normally restricts the monsters to forward-only movements):
Sub SetMonstersToFrightState
For ee = firstMonster to lastMonster
if SpriteArray[ee][State] <> DIE then
SpriteArray[ee][State] = FRIGHT
shapes.SetOpacity(ImageArray[ee][5],100)
SpriteArray[ee][VY] = 0
SpriteArray[ee][VX] = 0
EndIf
Endfor
EndSub
'*******************************************************************************************
'Sets all monsters to CHASE state. This is a bug fix to keep the monsters from switching out of DIE
'mode prematurely:
Sub MakeMonstersChase
For mc = firstMonster to lastMonster
If SpriteArray[mc][State] <> DIE then
SpriteArray[mc][State] = CHASE
EndIf
Endfor
EndSub
'*******************************************************************************************
'Manages the count down timer that determines how long an energizer lasts.
Sub DoEnergizerTimer
If (energizerTimer = ACTIVE) Then
If (energizerTime <> 0) Then
energizerTime = energizerTime -1
Else
energizerTimer = INACTIVE
monsterEatenCtr=0
MakeMonstersChase()
Endif
Endif
EndSub
'*******************************************************************************************
'Dispatch routine for erasing pellets/energizers from the screen:
Sub ErasePellet
pelletColor = "black"
pelletX = SpriteArray[SBC][screenX] + sWidth - mazeScale
pelletY = SpriteArray[SBC][screenY] + sHeight - mazeScale
DrawEnergizer()
EndSub
'*******************************************************************************************
'Draws/erases an energizer
Sub DrawEnergizer
pelletSize = 6
xOffset = -6
yOffset = -6
DP()
Endsub
'*******************************************************************************************
'Draws/erases a pellet
Sub DrawPellet
pelletSize = 3
xOffset = -3
yOffset = -3
DP()
EndSub
'*******************************************************************************************
Sub DP
GraphicsWindow.BrushColor = pelletColor
GraphicsWindow.FillEllipse(pelletX+xOffset, pelletY+yOffset, pelletSize, pelletSize)
EndSub
'*******************************************************************************************
'Removes sprites from the maze
Sub ClearSpritesFromaze
For r=firstSprite To lastSprite
For t = 1 To 6
Shapes.move(ImageArray[r][t],-100,-100)
EndFor
EndFor
EndSub
'*******************************************************************************************
'Draws sprites on screen while advancing through the animation sequence setup by SetupAnimationSequence().
Sub DrawSprites
'To reduce flicker only draw sprites that are moving (SBC sometimes stops)
If SpriteArray[Sprites][dx]<>0 Or SpriteArray[Sprites][dy]<>0 Then
'Get a reference to the current animation frame. We will hide it later:
oldFrameCtr=SpriteArray[Sprites][FrameCtr]
SpriteArray[Sprites][frameCtr]=SpriteArray[Sprites][frameCtr]+1+SpriteArray[Sprites][offset]
'Advance to next frame and check to see if all frames have been displayed:
If SpriteArray[Sprites][frameCtr]>SpriteArray[Sprites][lastFrame] then
SpriteArray[Sprites][frameCtr]=SpriteArray[Sprites][firstFrame]
Endif
'Update screen coordinates:
SpriteArray[Sprites][screenX]= SpriteArray[Sprites][screenX]+ SpriteArray[Sprites][DX] * 1
SpriteArray[Sprites][screenY]= SpriteArray[Sprites][screenY]+ SpriteArray[Sprites][DY] * 1.5
'Get reference to new animation frame and apply rotation (for SBC):
newFrameCtr=SpriteArray[Sprites][frameCtr]
if Sprites = SBC Then
Shapes.Rotate(ImageArray[Sprites][newFrameCtr], selectedRotation)
EndIf
'Finally, hide previous frame and show new animation frame:
shapes.Move(ImageArray[Sprites][oldFrameCtr],-20,-20)
Shapes.Move(ImageArray[Sprites][newFrameCtr], SpriteArray[Sprites][screenX], SpriteArray[Sprites][screenY])
EndIf
If erasePelletFromScreen = "True" Then
ErasePellet()
EndIf
EndSub
'*******************************************************************************************
'This routine intializes general purpose global lookup tables.
Sub InitializeLookupTables
'The xModifier & yModifier arrays are used to modify the XY screen coordinates and RC maze coordinates:
xModifier[0] = 0 'Stop moving
xModifier[1] =-1 'Move Left (when added to X)
xModifier[2] = 0 '
xModifier[3] = 1 'Move Right (when added to X)
xModifier[4] = 0
yModifier[0] = 0 'Stop moving
yModifier[1] = 0 '
yModifier[2] =-1 'Move Up (when added to Y)
yModifier[3] = 0 '
yModifier[4] = 1 'Move Down (when added to Y)
'rotationLookupTable holds the rotation angles for SBC. SbcDirection is used as an index:
rotationLookupTable[1] = 180
rotationLookupTable[2] = 270
rotationLookupTable[3] = 0
rotationLookupTable[4] = 90
EndSub
'*******************************************************************************************
'Sets up sprite data structure and establishes related variables:
Sub InitializeSprites
'State variables for sprites:
DIE = 0
NORMAL = 1
CHASE = 2
SCATTER = 3 '<--not implemented yet
FRIGHT = 4
EMERGE = 5
'State variables for energizer timer:
ACTIVE = 1
INACTIVE = 0
'The sprite data structure is a 2D array. These variables are indexes into the 2nd dimension of that array.
'(Dimension#1 slects the sprite, dimension #2 sets/gets properties of the particular sprite:
firstSprite = SBC
lastSprite = PinkMonster
firstMonster = RedMonster
lastMonster = PinkMonster
'Variables for dimension #2:
screenX = 1 'screen x coordinate
screenY = 2 'screen y coordinate
mazeCol = 3 'maze col
mazeRow = 4 'maze row
DX = 5 'x/col modifier
DY = 6 'y/row modifier
targetCol= 7 'maze target col
targetRow= 8 'maze target row
VX = 9 'visited maze col
VY = 10 'visited maze row
State = 11
Lives = 12
FrameCtr = 13 'Index into ImageArray[ ][ ]
Offset = 14
FirstFrame = 15
LastFrame = 16
cycleCounter= 17
spriteSpeed= 18
'Initialize:
For spriteCtr = firstSprite To lastSprite
SpriteArray[spriteCtr][FirstFrame] = 1
SpriteArray[spriteCtr][LastFrame] = 4
SpriteArray[spriteCtr][FrameCtr] = 4
SpriteArray[spriteCtr][offset] = 4
SpriteArray[spriteCtr][DX] = 0
SpriteArray[spriteCtr][DY] = 0
SpriteArray[spriteCtr][VX] = 0
SpriteArray[spriteCtr][VY] = 0
SpriteArray[spriteCtr][targetCol] = 0
SpriteArray[spriteCtr][targetRow] = 0
SpriteArray[spriteCtr][State] = CHASE
SpriteArray[spriteCtr][spriteSpeed] = 1
SpriteArray[spriteCtr][cycleCounter] = 1
Endfor
SpriteArray[SBC][State] = NORMAL
sbcDirection = Dir_R
EndSub
'*******************************************************************************************
Sub PositionSpritesInMaze
'Used for alignment hacks:
xxOffset= 0
yyOffset= 0
'Position SBC two tiles underneath Monster pen:
SpriteArray[SBC][mazeCol] = 15
SpriteArray[SBC][mazeRow] = 24
'Position Red Monster outside & above Monster pen:
SpriteArray[RedMonster][mazeCol] = 12
SpriteArray[RedMonster][mazeRow] = 12
'Blue, Orange and Pink Monsters inside Monster pen:
SpriteArray[BlueMonster][mazeCol] = 12
SpriteArray[BlueMonster][mazeRow] = 16
SpriteArray[OrangeMonster][mazeCol] = 17
SpriteArray[OrangeMonster][mazeRow] = 16
SpriteArray[PinkMonster][mazeCol] = 14
SpriteArray[PinkMonster][mazeRow] = 15
'Set correct screen positions:
For Sprites = firstSprite to lastSprite
AdjustScreenCoords()
EndFor
EndSub
'*******************************************************************************************
'Using maze RC values, calculate screen XYs:
Sub AdjustScreenCoords
SpriteArray[Sprites][screenX] = (SpriteArray[Sprites][mazeCol]) * mazeScale - mazeScale
SpriteArray[Sprites][screenY] = (SpriteArray[Sprites][mazeRow]) * mazeScale * 1.5 - mazeScale
EndSub
'*******************************************************************************************
Sub LoadBitmaps
'The sprite data structure is a 2D array. These variables are indexes into the 2nd dimension of that array.
'(Dimension#1 slects the sprite, dimension #2 sets/gets properties of the particular sprite.
'Variables to select the sprites (dimension #1 of SpriteArray):
SBC = 1
RedMonster = 2
BlueMonster = 3
OrangeMonster = 4
PinkMonster = 5
sWidth = mazeScale * 2
sHeight = mazeScale * 2
'ImageArray is a 2D array that holds references to the bitmaps used by the sprites. Dimension #1 is used
'to select the sprite, dimension #2 is used to select the bitmap.
'Load bitmaps for normal animation sequence:
filePath = Program.Directory +"\"
'SBC animation frames
ImageArray[SBC][1]=shapes.addimage("http://farm9.staticflickr.com/8240/8528887960_413fda8a5a_t.jpg")
ImageArray[SBC][2]=shapes.addimage("http://farm9.staticflickr.com/8379/8528887958_f8f6d3e534_t.jpg")
ImageArray[SBC][3]=shapes.addimage("http://farm9.staticflickr.com/8520/8527774169_b73baef828_t.jpg")
ImageArray[SBC][4]=shapes.addimage("http://farm9.staticflickr.com/8379/8528887958_f8f6d3e534_t.jpg")
'Red Monster animation frames
ImageArray[RedMonster][1]=shapes.addimage("http://farm9.staticflickr.com/8388/8528887972_d45aa82d69_t.jpg")
ImageArray[RedMonster][2]=shapes.addimage("http://farm9.staticflickr.com/8388/8528887972_d45aa82d69_t.jpg")
ImageArray[RedMonster][3]=shapes.addimage("http://farm9.staticflickr.com/8388/8528887972_d45aa82d69_t.jpg")
ImageArray[RedMonster][4]=shapes.addimage("http://farm9.staticflickr.com/8388/8528887972_d45aa82d69_t.jpg")
'Blue Monster animation frames
ImageArray[BlueMonster][1]=shapes.addimage("http://farm9.staticflickr.com/8378/8527774263_5f7d6e6aac_t.jpg")
ImageArray[BlueMonster][2]=shapes.addimage("http://farm9.staticflickr.com/8378/8527774263_5f7d6e6aac_t.jpg")
ImageArray[BlueMonster][3]=shapes.addimage("http://farm9.staticflickr.com/8378/8527774263_5f7d6e6aac_t.jpg")
ImageArray[BlueMonster][4]=shapes.addimage("http://farm9.staticflickr.com/8378/8527774263_5f7d6e6aac_t.jpg")
'Orange Monster animation frames
ImageArray[OrangeMonster][1]=shapes.addimage("http://farm9.staticflickr.com/8377/8527774201_6fced83ebf_t.jpg")
ImageArray[OrangeMonster][2]=shapes.addimage("http://farm9.staticflickr.com/8377/8527774201_6fced83ebf_t.jpg")
ImageArray[OrangeMonster][3]=shapes.addimage("http://farm9.staticflickr.com/8377/8527774201_6fced83ebf_t.jpg")
ImageArray[OrangeMonster][4]=shapes.addimage("http://farm9.staticflickr.com/8377/8527774201_6fced83ebf_t.jpg")
'Pink Monster animation frames
ImageArray[PinkMonster][1]=shapes.addimage("http://farm9.staticflickr.com/8523/8527774181_5fa1ebe6bb_t.jpg")
ImageArray[PinkMonster][2]=shapes.addimage("http://farm9.staticflickr.com/8523/8527774181_5fa1ebe6bb_t.jpg")
ImageArray[PinkMonster][3]=shapes.addimage("http://farm9.staticflickr.com/8523/8527774181_5fa1ebe6bb_t.jpg")
ImageArray[PinkMonster][4]=shapes.addimage("http://farm9.staticflickr.com/8523/8527774181_5fa1ebe6bb_t.jpg")
For s= 1 to 5
'Load bitmaps for FRIGHT Mode:
ImageArray[s][5]=shapes.addimage("http://farm9.staticflickr.com/8102/8528933134_d80645e3cc_t.jpg")
'Load bitmaps for DIE mode:
ImageArray[s][6]=shapes.addimage("http://farm9.staticflickr.com/8532/8528888036_85d4b2906d_t.jpg")
Shapes.SetOpacity(ImageArray[s][6],50)
Endfor
ClearSpritesFromaze()
EndSub
''*******************************************************************************************
'Loads maze pattern into maze array, counts the number of pellets added to maze, and gets the
'maze XY coordinates for special areas. Also creates and populates the mazeToken[ ] lookup table:
'
Sub LoadMaze
M[1] = "/------\/----------\/------\"
M[2] = "|......||..........||......|"
M[3] = "|*/--\.||./------\.||./--\*|"
M[4] = "|.(--).().(------).().(--).|"
M[5] = "|..........................|"
M[6] = "(-\./\./---\./\./---\./\./-)"
M[7] = "oo|.||.| |.||.| |.||.|oo"
M[8] = "oo|.||.(---).||.(---).||.|oo"
M[9] = "oo|.||.......||.......||.|oo"
M[10] = "oo|.|(--\+/--)(--\+/--)|.|oo"
M[11] = "--).(---)+(------)+(---).(--"
M[12] = "LT+.+++++++E++++++++++++.+SR"
M[13] = "--\./---\+/AAAAAAo+/---\./--"
M[14] = "oo|.|/--)+|+Co+B+|+(--\|.|oo"
M[15] = "oo|.||++++|+oo+o+|++++||.|oo"
M[16] = "oo|.||+/\+|MCo+B+|+/\+||.|oo"
M[17] = "oo|.()+||+(------)+||+().|oo"
M[18] = "oo|.+++||++++++++++||+++.|oo"
M[19] = "oo|./--)(--\+/\+/--)(--\.|oo"
M[20] = "oo|.(------)+||+(------).|oo"
M[21] = "oo|.......+++||+++.......|oo"
M[22] = "oo|./---\./--)(--\./---\.|oo"
M[23] = "/-).(---).(------).(---).(-\"
M[24] = "|............++............|"
M[25] = "|./--\./---\./\./---\./--\.|"
M[26] = "|.|oo|.|/--).||.(--\|.|oo|.|"
M[27] = "|.|oo|.||....||....||.|oo|.|"
M[28] = "|*|oo|.||./--)(--\.||.|oo|*|"
M[29] = "|.(--).().(------).().(--).|"
M[30] = "|..........................|"
M[31] = "(--------------------------)"
maxMazeRows = Array.GetItemCount(M)
maxMazeCols = Text.GetLength(M[1])
'mazeTokens[ ] hold tokens that represent walkable space in the maze:
firstToken = 0
lastToken = 2
mazeTokens[0]= "+"
mazeTokens[1]= "."
mazeTokens[2]= "*"
'Load the maze pattern into the maze[ ] [ ] array:
For rows = 1 To maxMazeRows
For cols = 1 To maxMazeCols
maze[rows][cols] = Text.GetSubText(M[rows], cols, 1)
If maze[rows][cols] = mazeTokens[1] Or maze[rows][cols] = mazeTokens[2] Then
pelletCount = pelletCount + 1
EndIf
'Special areas:
If Maze[rows][cols] ="M" Then 'DIE mode target Monster Pen tile
Maze[rows][cols] = mazeTokens[0]
monsterpenX = cols
MonsterPenY = rows
ElseIf Maze[rows][cols] ="E" Then 'Emerge mode target tile
Maze[rows][cols] = mazeTokens[0]
emergeX = cols
emergeY = rows
ElseIf Maze[rows][cols] ="L" Then 'Left tunnel tile
Maze[rows][cols] = mazeTokens[0]
leftTunnelX = cols
leftTunnelY = rows
ElseIf Maze[rows][cols] ="R" Then 'Right tunnel tile
Maze[rows][cols] = mazeTokens[0]
rightTunnelX = cols
rightTunnelY = rows
ElseIf Maze[rows][cols] ="S" Then 'Right slow-down tunnel tile
Maze[rows][cols] = mazeTokens[0]
sld1X = cols
sld1Y = rows
ElseIf Maze[rows][cols] ="T" Then 'Right slow-down tunnel tile
Maze[rows][cols] = mazeTokens[0]
sld2X = cols
sld2Y = rows
EndIf
EndFor
EndFor
'Delete the temporary array holding the maze structure:
M=""
EndSub
'*******************************************************************************************
'Steps through maze[ ] [ ] and draws the pattern on screen:
Sub DrawMaze
mazeBackgroundColor = "black"
GraphicsWindow.BackgroundColor= mazeBackgroundColor
x = 0
y = 0
mWidth = mazeScale
mHeight = mazeScale
MMX = (X + 1 * mWidth)
MMY = (Y + 1.5 * mHeight)
MMH = (1.5 * mHeight)
MMW = (1 * mWidth)
For rows = 1 To maxMazeRows
tempMMYrows = MMY*rows 'helps speed up draw operations a bit.
For cols = 1 To maxMazeCols
mazeData = Maze[rows][cols]
GraphicsWindow.PenColor = mazeBorderColor
GraphicsWindow.PenWidth = 2
' Upper Left corner:
if mazeData = "/" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, mazeCol+MMW*cols, TempMMYrows)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, MMY+MMH*rows)
'Upper Right corner:
elseif mazeData = "\" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols-MMW, TempMMYrows)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, TempMMYrows+MMH)
'Lower Left corner:
elseif mazeData = "(" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, TempMMYrows-MMH)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols+MMW, TempMMYrows)
'Lower right corner:
elseif mazeData = ")" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, TempMMYrows-MMH)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols-MMW, TempMMYrows)
'
'Vertical line:
elseif mazeData = "-" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols-MMW, TempMMYrows)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols+MMW, TempMMYrows)
'
'Vertical line for top door
elseif mazeData = "A" then
GraphicsWindow.PenColor="white"
GraphicsWindow.PenWidth="1"
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols-MMW, TempMMYrows)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols+MMW, TempMMYrows)
'
'Horizontal line:
elseif mazeData = "|" then
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, TempMMYrows-MMH)
GraphicsWindow.DrawLine(MMX*cols,TempMMYrows, MMX*cols, TempMMYrows+MMH)
'Pellet:
elseif mazeData = "." then
pelletColor = "white"
pelletX=(cols * MMW)
pelletY=(rows * MMY)
DrawPellet()
'Energizer:
elseif mazeData = "*" then
pelletColor = "white"
pelletX=(cols * MMW)
pelletY=(rows * MMY)
DrawEnergizer()
Endif
EndFor
EndFor
EndSub
'*******************************************************************************************
'There are three invisible borders that keep the blue, pink and orange ghosts in the monster pen
'and also keeps the monsters from getting back in unless they are in EMERGE or DIE modes.
'The doors are "opened" by adding their tokens to the mazeToken[ ] array and extending the lastToken pointer.
'The doors are "closed" by resetting the lastToken pointer:
Sub CloseDoors
lastToken = 2
EndSub
'*******************************************************************************************
Sub OpenLeftDoor
mazeTokens[3] = "B"
lastToken = lastToken + 1
EndSub
'*******************************************************************************************
Sub OpenRightDoor
mazeTokens[3] = "C"
lastToken = lastToken + 1
EndSub
'*******************************************************************************************
Sub OpenTopDoor
mazeTokens[3] = "A"
lastToken = lastToken + 1
EndSub
'*******************************************************************************************
'This routines causes the monsters to leave the monster pen one-by-one after a certain number of
'cycles have past. This done at game start, on each new level and when a level is replayed . The
'invisible "doors" open whenever the monsters are in EMERGE or DIE modes:
Sub LeaveMonsterPenOneByOne
If globalCycleCtr = 100 then
SpriteArray[PinkMonster][state] = EMERGE
ElseIf globalCycleCtr = 200 Then
SpriteArray[OrangeMonster][state] = EMERGE
Elseif globalCycleCtr = 400 Then
SpriteArray[BlueMonster][state] = EMERGE
EndIf
EndSub
'*******************************************************************************************
'Dispatches update-related routines:
Sub Update
SpriteArray[Sprites][cycleCounter]=SpriteArray[Sprites][cycleCounter]+1
'Do updates when a sprite reaches a new tile. Distance between tiles is set by MazeScale:
if (SpriteArray[Sprites][cycleCounter] > mazeScale) Then
MoveSBC()
SetupMonsterTargets()
SetupSpriteSpeed()
OpenCloseDoors()
MoveMonstersTowardTarget()
CheckGoThroughTunnels()
SpriteArray[Sprites][cycleCounter]=1
DisplayScore()
DisplayLevel()
EndIf
Endsub
'*******************************************************************************************
'Displaches draw-related routines:
Sub Draw
SetupAnimationSequence()
DrawSprites()
CollisionDetect()
CheckGoThroughTunnels()
Endsub
'*******************************************************************************************
'Ensures that sprites are moving at correct speed:
Sub SetupSpriteSpeed
If SpriteArray[Sprites][state] = CHASE Then
SpriteArray[Sprites][spriteSpeed] = 1
ElseIf SpriteArray[Sprites][state] = FRIGHT Then
SpriteArray[Sprites][spriteSpeed] = 2
ElseIf SpriteArray[Sprites][state] = NORMAL Then
SpriteArray[Sprites][spriteSpeed] = 1
ElseIf SpriteArray[Sprites][state] = DIE Then
SpriteArray[Sprites][spriteSpeed] = 1
EndIf
EndSub
'*******************************************************************************************
'Can't speed up maze drawing, so black out the game screen and then construct maze and position
'bitmaps underneath the black cover:
Sub ConstructGameElements
BlackOutGameScreen()
LoadMaze()
DrawMaze()
DisplayLevel()
DisplayLives()
ClearSpritesFromaze()
InitializeSprites()
PositionSpritesInMaze()
RemoveBlackScreen()
EndSub
'*******************************************************************************************
'Causes the monsters to flash briefly as a warning to the player that the monsters are about
'to swtich from Fright to Chase states:
'***BUG ??: This routine doesn't work well with Silverlight***
Sub FlashMonsters
If (energizerTimer = ACTIVE) And (SpriteArray[Sprites][State] = FRIGHT) Then
If (energizerTime < 20) Then
If (Math.Remainder(energizerTime,3)=0) Then
shapes.SetOpacity(ImageArray[sprites][5],100) 'Visible
Else
shapes.SetOpacity(ImageArray[sprites][5],10) 'Faint
EndIf
EndIf
EndIf
EndSub
'*********************************************************************************
'Allows game to cage in or release monsters from monster pen:
Sub OpenCloseDoors
If SpriteArray[Sprites][State] = CHASE Then
CloseDoors()
ElseIf SpriteArray[Sprites][State] = FRIGHT Then
CloseDoors()
ElseIf SpriteArray[Sprites][State] = NORMAL Then
CloseDoors()
ElseIf SpriteArray[Sprites][State] = DIE Then
OpenLeftDoor()
OpenRightDoor()
OpenTopDoor()
ElseIf SpriteArray[Sprites][State] = EMERGE Then
OpenLeftDoor()
OpenRightDoor()
OpenTopDoor()
EndIf
EndSub
'**************************************************************************
Sub ScoreAndBonusManager
If (hasEatenMonster = "True") Then
monsterEatenCtr = monsterEatenCtr + 1
gameScore = gameScore + monsterPts +(monsterEatenCtr * monsterPts)
'Give player a bonus when all 4 monsters are eaten in succession:
If monsterEatenCtr = 4 Then
gameScore = gameScore + monsterBonusPts
splashText=monsterBonusPts + "PT BONUS!"
DisplayLevelSplash()
monsterEatenCtr=0
EndIf
monstersEatenPerLevel = monstersEatenPerLevel + 1
'Give player an extra life whenever 16 monsters are eaten per level:
If monstersEatenPerLevel = 16 Then
SpriteArray[sbc][lives] = SpriteArray[sbc][lives] + 1
splashText="EXTRA LIFE ADDED!"
monstersEatenPerLevel=0
DisplayLevelSplash()
EndIf
hasEatenMonster="False"
EndIf
If hasReached50K="False" Then
If gameScore > 50000 Then
hasReached50K="True"
SpriteArray[sbc][lives] = SpriteArray[sbc][lives] + 1
splashText="EXTRA LIFE ADDED!"
DisplayLevelSplash()
DisplayLives()
EndIf
EndIf
EndSub
'*******************************************************************************
'Bounding Box collision detection routine from "Beginning Microsoft Small Basic", 9-30
Sub CheckRectangles
isTouching = "False"
Object1X=SpriteArray[sbc][screenX]
Object1Y=SpriteArray[sbc][screenY]
Object2X=SpriteArray[Sprites][screenX]
Object2Y=SpriteArray[Sprites][screenY]
If ((Object1X + 6 +sWidth - 6) > Object2X +6) Then
If (Object1X +6 < (Object2X+6 + sWidth - 6)) Then
If ((Object1Y+6 + sHeight - 6) > Object2Y+6) Then
If (Object1Y+6 < (Object2Y+6 + sHeight - 6)) Then
isTouching = "True"
EndIf
EndIf
EndIf
EndIf
EndSub
'************************************************************************
'Allows sprites to travel through tunnels and causes the monsters to slow down at tunnel entrances:
sub CheckGoThroughTunnels
If Sprites <> SBC Then
if (SpriteArray[Sprites][mazecol]=sld1X And SpriteArray[Sprites][mazeRow]=sld2Y) or (SpriteArray[Sprites][mazecol]=sld2X And SpriteArray[Sprites][mazeRow]=sld2Y) Then
SpriteArray[Sprites][spriteSpeed]=4
EndIf
endif
If SpriteArray[Sprites][mazeCol] = rightTunnelX and SpriteArray[Sprites][mazeRow] = rightTunnelY Then
SpriteArray[Sprites][mazeCol] = leftTunnelX
SpriteArray[Sprites][mazeRow] = leftTunnelY
AdjustScreenCoords()
ElseIf SpriteArray[Sprites][mazeCol] = leftTunnelX and SpriteArray[Sprites][mazeRow] = leftTunnelY Then
SpriteArray[Sprites][mazeCol] = rightTunnelX
SpriteArray[Sprites][mazeRow] = rightTunnelY
AdjustScreenCoords()
EndIf
EndSub
'********************************************************************
'Shows the per-monster points at the location where the monster was eaten:
Sub ShowEatSplash
GraphicsWindow.BrushColor="white"
GraphicsWindow.FontName="Arial"
o=shapes.AddText(monsterPts +(monsterEatenCtr * monsterPts))
osx = SpriteArray[Sprites][screenX] - sWidth
osy = SpriteArray[Sprites][screenY] + sHeight
Shapes.Move(o,osx,osy)
SmallDelay()
Shapes.Remove(o)
EndSub
'*******************************************************************************************
sub SetupGraphicsWindow
GraphicsWindow.Title="Small Basic Chomper"
GraphicsWindow.Width= gamescreenWidth
GraphicsWindow.Height=gameScreenHeight
GraphicsWindow.CanResize="false"
GraphicsWindow.BrushColor="white"
GraphicsWindow.FontSize = 10
GraphicsWindow.FontBold = "False"
GraphicsWindow.DrawText(10,0,"SCORE: ")
GraphicsWindow.DrawText(100,0,"LEVEL: ")
GraphicsWindow.DrawText(180,0,"LIVES: ")
scoreShape=Shapes.AddText(gameScore)
livesShape=Shapes.AddText(SpriteArray[sbc][Lives])
levelShape=Shapes.AddText(gameLevel)
Shapes.Move(scoreShape,50,0)
Shapes.Move(levelShape,135,0)
Shapes.Move(livesShape,220,0)
endsub
'*******************************************************************************************
Sub DisplayScore
Shapes.SetText(scoreShape,gamescore)
EndSub
'*******************************************************************************************
Sub DisplayLives
Shapes.SetText(livesShape,SpriteArray[sbc][lives])
EndSub
'*******************************************************************************************
Sub DisplayLevel
Shapes.SetText(levelShape,gameLevel)
EndSub
'*******************************************************************************************
Sub BlackoutGameScreen
GraphicsWindow.BrushColor="black"
blkScreen = Shapes.AddRectangle(gamescreenWidth, gameScreenHeight)
Endsub
'*******************************************************************************************
Sub RemoveBlackScreen
Shapes.Remove(blkScreen)
EndSub
' Football 0.5
' Copyright (c) 2013 Nonki Takahashi. All rights reserved.
'
' History:
' 0.5 2013/03/10 Changed not to kick back by forward. (ZVL057-3)
' 0.4 2013/03/06 VRAM array removed. (ZVL057-2)
' 0.3b 2013/03/05 Enabled to play and added semaphore. (ZVL057-1)
' 0.2a 2013/03/05 Enabled score and paddle. (ZVL057-0)
' 0.1a 2013/03/05 Graphics created. (ZVL057)
'
GraphicsWindow.Title = "Football 0.5"
GraphicsWindow.BackgroundColor = "#222222"
Sound_Init() ' preload sounds
Num_Init()
Court_Init()
Paddle_Init()
Score_Init()
player = 1
Ball_Init()
Timer.Interval = 10
Timer.Tick = OnTick
GraphicsWindow.KeyUp = OnKeyDown
While "True"
If beep Then
Sound.PlayAndWait(urlBeep)
beep = "False"
EndIF
If ping Then
Sound.Stop(urlPing)
Sound.Play(urlPing)
ping = "False"
EndIF
Program.Delay(10)
EndWhile
Sub OnKeyDown
If semaphore Then
Goto okd_exit
Else
semaphore = "True"
EndIf
key = GraphicsWindow.LastKey
If key = "S" Then ' player 1 paddle up
player = 1
Paddle_Up()
ElseIf key = "D" Then ' player 1 paddle down
player = 1
Paddle_Down()
ElseIf key = "K" Then ' player 2 paddle up
player = 2
Paddle_Up()
ElseIf key = "L" Then ' player 2 paddle down
player = 2
Paddle_Down()
EndIf
semaphore = "False"
okd_exit:
EndSub
Sub OnTick
If semaphore Then
Goto ot_exit
Else
semaphore = "True"
EndIf
Ball_Update()
semaphore = "False"
ot_exit:
EndSub
Sub Ball_Init
' param player - 1 or 2
ballX = x0 + (centerCol - 1) * sizeX
ballY = y0 + (centerRow - 1) * sizeY
If ball = "" Then
ball = Shapes.AddRectangle(sizeX, sizeY)
EndIf
Shapes.Move(ball, ballX, ballY)
If player = 1 Then
vx = 4
vy = (Math.GetRandomNumber(10) - 5.5) / 2
ElseIf player = 2 Then
vx = -4
vy = (Math.GetRandomNumber(10) - 5.5) / 2
EndIf
EndSub
Sub Ball_Update
' param ballY, ballX - ball position
' param vx, vy - velocity of ball [pixel/tick]
ballX = ballX + vx
ballY = ballY + vy
Shapes.Move(ball, ballX, ballY)
If 0 < vy Then
If bottomY - sizeY <= ballY Then
vy = -vy
ping = "True"
EndIf
ElseIf vy < 0 Then
If ballY <= topY + sizeY Then
vy = -vy
ping = "True"
EndIf
EndIf
If ballX < goalX[1] Then
player = 2
s = score[player]["score"] + 1
Score_Set()
beep = "True"
Program.Delay(2000)
player = 1
Ball_Init()
ElseIf goalX[2] < ballX Then
player = 1
s = score[player]["score"] + 1
Score_Set()
beep = "True"
Program.Delay(2000)
player = 2
Ball_Init()
ElseIf 0 < vx Then
If Math.Abs(paddleX[2][1] - sizeX - ballX) <= Math.Abs(vx) And paddleY[2] - sizeY <= ballY And ballY <= paddleY[2] + 5 * sizeY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(paddleX[2][2] - sizeX - ballX) <= Math.Abs(vx) And paddleY[2] - sizeY <= ballY And ballY <= paddleY[2] + 5 * sizeY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(goalX[2] - sizeX - ballX) <= Math.Abs(vx) And topY + sizeY <= ballY And ballY <= goalUpY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(goalX[2] - sizeX - ballX) <= Math.Abs(vx) And goalLowY <= ballY And ballY <= bottomY Then
vx = -vx
ping = "True"
EndIf
ElseIf vx < 0 Then
If Math.Abs(paddleX[1][1] + sizeX - ballX) <= Math.Abs(vx) And paddleY[1] - sizeY <= ballY And ballY <= paddleY[1] + 5 * sizeY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(paddleX[1][2] + sizeX - ballX) <= Math.Abs(vx) And paddleY[1] - sizeY <= ballY And ballY <= paddleY[1] + 5 * sizeY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(goalX[1] + sizeX - ballX) <= Math.Abs(vx) And topY + sizeY <= ballY And ballY <= goalUpY Then
vx = -vx
ping = "True"
ElseIf Math.Abs(goalX[1] + sizeX - ballX) <= Math.Abs(vx) And goalLowY <= ballY And ballY <= bottomY Then
vx = -vx
ping = "True"
EndIf
EndIf
EndSub
Sub Court_Init
init[0] = "----+----1----+----2----+----3----+----4----+----5----+----6"
init[1] = " ********************************************************* "
init[2] = " * * "
init[3] = " * * * "
init[4] = " * * "
init[5] = " * * * "
init[6] = " * * "
init[7] = " * * * "
init[8] = " * * "
init[9] = " * "
init[10] = " "
init[11] = " * "
init[12] = " "
init[13] = " * "
init[14] = " "
init[15] = " * "
init[16] = " "
init[17] = " * "
init[18] = " "
init[19] = " * "
init[20] = " "
init[21] = " * "
init[22] = " * * "
init[23] = " * * * "
init[24] = " * * "
init[25] = " * * * "
init[26] = " * * "
init[27] = " * * * "
init[28] = " * * "
init[29] = " ********************************************************* "
init[30] = " "
nCols = Text.GetLength(init[0])
nRows = 30
centerCol = nCols /2
centerRow = nRows / 2
sizeX = 10
sizeY = 14
x0 = Math.Floor((GraphicsWindow.Width - sizeX * nCols) / 2)
y0 = Math.Floor((GraphicsWindow.Height - sizeY * nRows) / 2)
goalCol[1] = 2 ' left end
goalX[1] = x0 + (goalCol[1] - 1) * sizeX
goalCol[2] = nCols - 2 ' right end
goalX[2] = x0 + (goalCol[2] - 1) * sizeX
topRow = 1 ' top end
topY = y0 + (topRow - 1) * sizeY
bottomRow = nRows - 1 ' bottom end
bottomY = y0 + (bottomRow - 1) * sizeY
goalUpRow = 9 ' upper row of goal
goalUpY = y0 + (goalUpRow - 1) * sizeY
goalLowRow = nRows - 9 ' lower row of goal
goalLowY = y0 + (goalLowRow - 1) * sizeY
GraphicsWindow.PenWidth = 2
GraphicsWindow.PenColor = "LightGray"
GraphicsWindow.BrushColor = "LightGray"
For row = 1 To nRows
y = y0 + (row - 1) * sizeY
For col = 1 To nCols
i = (row - 1) * nCols + col
x = x0 + (col - 1) * sizeX
If Text.GetSubText(init[row], col, 1) <> " " Then
GraphicsWindow.FillRectangle(x, y, sizeX, sizeY)
EndIf
EndFor
EndFor
EndSub
Sub Num_Init
num[0][1] = "***"
num[0][2] = "* *"
num[0][3] = "* *"
num[0][4] = "* *"
num[0][5] = "***"
num[1][1] = " *"
num[1][2] = " *"
num[1][3] = " *"
num[1][4] = " *"
num[1][5] = " *"
num[2][1] = "***"
num[2][2] = " *"
num[2][3] = "***"
num[2][4] = "* "
num[2][5] = "***"
num[3][1] = "***"
num[3][2] = " *"
num[3][3] = "***"
num[3][4] = " *"
num[3][5] = "***"
num[4][1] = "* *"
num[4][2] = "* *"
num[4][3] = "***"
num[4][4] = " *"
num[4][5] = " *"
num[5][1] = "***"
num[5][2] = "* "
num[5][3] = "***"
num[5][4] = " *"
num[5][5] = "***"
num[6][1] = "***"
num[6][2] = "* "
num[6][3] = "***"
num[6][4] = "* *"
num[6][5] = "***"
num[7][1] = "***"
num[7][2] = " *"
num[7][3] = " *"
num[7][4] = " *"
num[7][5] = " *"
num[8][1] = "***"
num[8][2] = "* *"
num[8][3] = "***"
num[8][4] = "* *"
num[8][5] = "***"
num[9][1] = "***"
num[9][2] = "* *"
num[9][3] = "***"
num[9][4] = " *"
num[9][5] = "***"
num[" "][1] = " "
num[" "][2] = " "
num[" "][3] = " "
num[" "][4] = " "
num[" "][5] = " "
EndSub
Sub Paddle_Init
upRow = topRow + 2 ' upper end for paddle
upY = y0 + (upRow - 1) * sizeY
lowRow = bottomRow - 6 ' lower end for paddle
lowY = y0 + (lowRow - 1) * sizeY
paddleX[1][1] = goalX[1] + 2 * sizeX
paddleX[1][2] = goalX[2] - (nCols / 4) * sizeX
paddleY[1] = y0 + (centerRow - 3) * sizeY
paddleX[2][1] = goalX[1] + (nCols / 4) * sizeX
paddleX[2][2] = goalX[2] - 2 * sizeX
paddleY[2] = y0 + (centerRow - 3) * sizeY
For player = 1 To 2
y = paddleY[player]
For i = 1 To 2
paddle[player][i] = Shapes.AddRectangle(sizeX, sizeY * 5)
x = paddleX[player][i]
Shapes.Move(paddle[player][i], x, y)
EndFor
EndFor
EndSub
Sub Paddle_Down
' param player - 1 or 2
If paddleY[player] < lowY Then
paddleY[player] = paddleY[player] + sizeY
y = paddleY[player]
For i = 1 To 2
x = paddleX[player][i]
Shapes.Move(paddle[player][i], x, y)
EndFor
EndIf
EndSub
Sub Paddle_Up
' param player - 1 or 2
If upY < paddleY[player] Then
paddleY[player] = paddleY[player] - sizeY
y = paddleY[player]
For i = 1 To 2
x = paddleX[player][i]
Shapes.Move(paddle[player][i], x, y)
EndFor
EndIf
EndSub
Sub Score_Init
For player = 1 To 2
score[player]["score"] = 0
s = score[player]["score"]
len = Text.GetLength(s)
If len = 1 Then
s = " " + s
EndIf
For o = 2 To 1 Step -1
d = Text.GetSubText(s, 3 - o, 1)
For i = 1 To 15
j = (o - 1) * 15 + i
col = Math.Remainder(i - 1, 3) + 1
row = Math.Floor((i - 1) / 3) + 1
x = x0 + sizeX * (centerCol - 10 + 12 * (player - 1) + 4 * (2 - o) + col - 1)
y = y0 + sizeY * (2 + row - 1)
obj = Shapes.AddRectangle(sizeX, sizeY + 1)
score[player]["obj" + j] = obj
Shapes.Move(obj, x, y)
If Text.GetSubText(num[d][row], col, 1) = " " Then
Shapes.SetOpacity(obj, 0)
EndIf
EndFor
EndFor
EndFor
EndSub
Sub Score_Set
' param player - 1 or 2
' param s - score
score[player]["score"] = s
len = Text.GetLength(s)
If len = 1 Then
s = " " + s
EndIf
For o = 2 To 1 Step -1
d = Text.GetSubText(s, 3 - o, 1)
For i = 1 To 15
j = (o - 1) * 15 + i
col = Math.Remainder(i - 1, 3) + 1
row = Math.Floor((i - 1) / 3) + 1
obj = score[player]["obj" + j]
If Text.GetSubText(num[d][row], col, 1) = " " Then
Shapes.SetOpacity(obj, 0)
Else
Shapes.SetOpacity(obj, 100)
EndIf
EndFor
EndFor
EndSub
Sub Sound_Init
urlPing = "http://www.nonkit.com/smallbasic.files/se_sad05.wav"
Sound.PlayAndWait(urlPing) ' test for preload
urlBeep = "http://www.nonkit.com/smallbasic.files/se_sad08.wav"
Sound.PlayAndWait(urlBeep) ' test for preload
EndSub
' SNAKEBITE-SB
' by Davey~Wavey, v1 Nov. 2009
' Written for SmallBasic v0.7
'
' Inspired by the ZX81 game SNAKEBITE.
'
' Eat the snake by chewing off it's tail. Eat all tail segments to progress to next level.
' Watch out though, you may just make it angry!
'
' Use the cursor keys to move around. (You can press any other key to stop moving!)
' NOTE: If it crashes a lot, try commenting out the 'Sound.PlayChimes()' line. SB doesn't like sound!
'
' I've laid the code out so that all the normal routines used in a game are present. If you're
' learning to write your own game, a similar setup should work well for you. Have fun!
' set up the permanent loop (Q key terminates when on intro screen)
While 1=1
' initialise game environment
environment()
' show intro
introScreen()
While lives > 0
' INITIALISE LEVEL
' Next line won't play anything if we have already played the intro screen music!?!?!?!!!
' It also seems to cause the prog to crash more often when enabled.
'Sound.Play (progDir + "\muzak.mid")
levelConfig() ' level maps can be found at end of program listing below - have fun designing some
paintLevel()
snakeSetup()
playerSetup()
' MAIN LOOP
While (snakeSize > 2) And lives > 0
' if snake 'change direction' delay has expired, try to change snake direction
If snakeMoveDelay = 0 Then
snakeDirection() ' will only change direction at random times
moveSnake()
EndIf
' alternative method to check for key press - also delays movement of player
If playerMoveDelay = 0 Then
checkKeys()
movePlayer()
' Check for PLAYER COLLISIONS
playerCollisions()
EndIf
' ADJUST (or reset) DELAYS
' I admit this isn't the best way to do this.
' To get accurate speed, you should be calculating the
' frames-per-second and using that to slow various elements down.
If snakeMoveDelay > 0 Then
snakeMoveDelay = snakeMoveDelay-1
Else
snakeMoveDelay = level[thisLevel]["snakeDelay"]
EndIf
If playerMoveDelay > 0 Then
playerMoveDelay = playerMoveDelay-1
Else
playerMoveDelay = playerDelay
EndIf
' test snake length increase - NOT CURRENTLY USED
'If Mouse.IsLeftButtonDown="True" AND processing=0 Then
' addSegment()
'ElseIf Mouse.IsLeftButtonDown="False" And processing=1 Then
' mUp()
'EndIf
EndWhile ' main level (or lives) loop
' next line is irrellevant as the Sound.Play command above doesn't work!
'Sound.Stop (progDir + "\muzak.mid")
' if we still have some lives, then we must have eaten all the snake
If lives > 0 Then
moveSnake() ' update tail position since snake length just decreased
GraphicsWindow.ShowMessage("YEAH, YOU BEAT THIS SNAKE!!!", "WHOOPIE!")
' move to next level
thisLevel=thisLevel+1
' go back to level 1 if we've completed them all
If thisLevel>levels Then
thisLevel=1
EndIf
' increase player speed (by decreasing the delay) - player gets a slight advantage for each level cleared :-)
If playerDelay > 20 Then
playerDelay = playerDelay - 10
EndIf
GraphicsWindow.Clear()
EndIf
EndWhile ' lives > 0
' DEAD MEAT!
' next line doesn't work!
'Sound.Play (progDir + "\gameover.mid")
GraphicsWindow.ShowMessage("THAT PUNKY SNAKE BEAT YOU THIS TIME!!! You scored: "+score, "EATEN!!!")
' next line is irrellevant as the Play command above doesn't work!
'Sound.Stop (progDir + "\gameover.mid")
EndWhile
' =====================================================================
' =====================================================================
' ====================== S U B R O U T I N E S ==============================
' =====================================================================
' =====================================================================
Sub environment
' initialise the game environment
' progDir = Program.Directory + "\assets" ' this is used to locate the graphics and music used in the game
progDir = "http://smallbasic.com/drop/snakebite"
GraphicsWindow.Title = "~S~N~A~K~E~B~I~T~E~ v1 for SmallBasic by Davey~Wavey, Nov 2009"
GraphicsWindow.BackgroundColor = "Black"
GraphicsWindow.Width = 800 ' grass sprite is 128 x 128
GraphicsWindow.Height = 600 ' 4 x 128 plus status area
GraphicsWindow.Left = desktop.Width/2-(GraphicsWindow.Width/2) ' 800
GraphicsWindow.Top = desktop.Height/2-(GraphicsWindow.Height/2)-100 '50
gwTop = 18 ' set game window top offset
gwBottom = gwTop+(4*128)
gwLeft = (GraphicsWindow.Width/2)-(3*128) ' set game window left offset
gwRight = gwLeft+(6*128)
' initialise game environment
thisLevel = 1
score = 0
lives = 5
playerDelay = 500 ' speed of player movement - lower value = faster player = easier (unless you go too fast!)
snakeMoveDelay = 0 ' this gets set by each level and is the speed of the snake - lower = faster
angrySnake = -1 ' a counter. if >0 it indicates that snake is angry (makes snake faster)
digestionDelay = 0 ' delay to prevent multiple tail pieces being eaten at once.
processing = 0 ' a flag used in sub processes to prevent multiple runs
player = "" ' blank player array
snake = "" ' blank snake array
'Timer.Interval = 2 ' set interval to check for key presses
'Timer.Tick = checkKeys
EndSub
' =====================================================================
Sub introScreen
' display the game intro screen and wait for Space to be pressed
GraphicsWindow.Clear()
' this Play command works, but then prevents any other music playing!?!?!
Sound.Play (progDir + "\intro.mid")
' show intro graphic
img = ImageList.LoadImage(progDir + "\titleScreen_800x600.jpg")
GraphicsWindow.DrawImage(img, 0,0 )
' wait for keypress
lastkey = ""
While lastkey <> "Space"
lastkey = GraphicsWindow.LastKey
If lastkey = "Q" Then
Program.End()
EndIf
EndWhile
Sound.Stop (progDir + "\intro.mid")
Program.Delay(500)
EndSub
' =====================================================================
Sub paintLevel
' draw the level objects at the start of each level
' create a black rectangle over the whole graphics window so we can create a fade effect after the level has been drawn
GraphicsWindow.BrushColor = "Black"
bbox = Shapes.AddRectangle( 800, 600 )
Shapes.SetOpacity (bbox, 100)
' draw dirt
img = ImageList.LoadImage(progDir + "\status_800x70.png")
For y = 0 to 600 Step 70
GraphicsWindow.DrawImage (img, 0, y)
EndFor
' draw the grass
img = ImageList.LoadImage(progDir + "\grass_128d.png")
For x = 0 To 5
For y = 0 To 3
GraphicsWindow.DrawImage (img, (x*128)+gwLeft, (y*128)+gwTop)
EndFor
EndFor
' draw the flowers
img = ImageList.LoadImage(progDir + "\flower1_32.png")
Shapes.SetOpacity(img, 20)
For x = 1 To 20
GraphicsWindow.DrawImage (img, ((Math.GetRandomNumber(24)-1)*32)+gwLeft, ((Math.GetRandomNumber(16)-1)*32)+gwTop )
EndFor
img = ImageList.LoadImage(progDir + "\flower2_32.png")
Shapes.SetOpacity(img, 20)
For x = 1 To 10
GraphicsWindow.DrawImage (img, ((Math.GetRandomNumber(24)-1)*32)+gwLeft, ((Math.GetRandomNumber(16)-1)*32)+gwTop )
EndFor
' draw the level blocks
img = ImageList.LoadImage(progDir + "\wall_32.png")
For my = 1 To 16
For mx = 1 To 24
block = text.GetSubText( level[thisLevel][my], mx, 1 )
' position WALLS
If block = "W" Then
GraphicsWindow.DrawImage (img, ((mx-1)*32)+gwLeft, ((my-1)*32)+gwTop) ' DrawRectangle( (mx-1)*32, (my-1)*32, 32, 32 )
EndIf
' position PLAYER
If block = "P" Then
player["x"] = ((mx-1)*32+12)+gwLeft ' calculate x,y from 32 x 32 level grid blocks
player["startX"] = player["x"] ' remember start position for when player dies
player["y"] = ((my-1)*32+12)+gwTop
player["startY"] = player["y"]
EndIf
' position SNAKE
If block = "S" Then
level[thisLevel]["snakeX"] = ((mx-1)*32+16)+gwLeft
level[thisLevel]["snakeY"] = ((my-1)*32+16)+gwTop
EndIf
EndFor
EndFor
' draw the border (using the snake body part)
img = ImageList.LoadImage(progDir + "\body_18.png")
For y = 0 To 600 Step 530
For x=5 to 790 Step 18
' draw top and bottom border
GraphicsWindow.DrawImage ( img, x, y)
EndFor
EndFor
For x = 0 To 800 Step 784
For y = 15 to 530 Step 18
' draw left and right border
GraphicsWindow.DrawImage ( img, x, y)
EndFor
EndFor
' show status bar
status()
' fade the screen in
Shapes.Move (bbox, 0, 0)
For lwp = 100 To 0 Step -1
Shapes.SetOpacity(bbox, lwp)
Program.Delay(20)
EndFor
EndSub
' =====================================================================
Sub snakeSetup
' create the snake array and display snake in starting position
headPart = ImageList.LoadImage(progDir + "\head_24.png")
headAngryPart = ImageList.LoadImage(progDir + "\headAngry_24.png")
headSize = 22 '24 ' radius of head
headOffset = 11
bodyPart = ImageList.LoadImage(progDir + "\body_18.png")
bodySize = 18 '18
bodyOffset = 9
tailPart = ImageList.LoadImage(progDir + "\tail_16.png")
tailSize = 16 '32 '16
tailOffset = 8
snake = ""
snake[0]["happySnake"] = Shapes.AddImage(headPart)
snake[0]["angrySnake"] = Shapes.AddImage(headAngryPart)
snakeSize = level[thisLevel]["snakeSize"] ' this value will change during game as snake eats/is eaten
' remember current pen width
'pw = GraphicsWindow.PenWidth
'GraphicsWindow.PenWidth = 0
For snakePart = 1 to snakeSize
' create the snake segments
If snakePart = 1 Then
'GraphicsWindow.BrushColor="Brown"
snake[snakePart]["sprite"] = snake[0]["happySnake"] 'Shapes.AddEllipse(headSize,headSize) ' head
' Zoom for this shape has been done above
ElseIf snakePart <> snakeSize Then
'GraphicsWindow.BrushColor="Chocolate"
snake[snakePart]["sprite"] = Shapes.AddImage(bodyPart) 'Shapes.AddEllipse(bodySize,bodySize) ' body
Else
'GraphicsWindow.BrushColor="SandyBrown"
snake[snakePart]["sprite"] = Shapes.AddImage(tailPart) 'Shapes.AddEllipse(tailSize,tailSize) ' tail
EndIf
' locate snake on screen - probably needs to be part of each level config
snake[snakePart]["x"] = level[thisLevel]["snakeX"]
snake[snakePart]["y"] = level[thisLevel]["snakeY"]
' as all segments start at the same x,y we must increment the initial delay for each successive segment
If snakePart > 2 Then
snake[snakePart]["delay"] = ((snakePart-1)*(bodySize-4))+4
Else
snake[2]["delay"] = bodySize '18
EndIf
EndFor
' set initial direction
snake[1]["moves"] = level[thisLevel]["snakeDir"]
snake[1]["delay"] = "0" ' need to initialise delay for snake head - used to determine delay before direction change
' reinstate previous pen width
'GraphicsWindow.PenWidth=pw
EndSub
' =====================================================================
Sub playerSetup
' create the player and display at start position
'GraphicsWindow.BrushColor="Lime"
img = ImageList.LoadImage(progDir + "\player2_24.png") ' from www.freeicons.dk
player["sprite"] = Shapes.AddImage(img) 'Shapes.AddRectangle( 20,20 )
Shapes.Move( player["sprite"], player["x"]-11, player["y"]-11 ) ' -11 offset instead of -12 works better!?!?!
playerMoveDelay = playerDelay ' initialise player movement speed (delay)
EndSub
' =====================================================================
Sub snakeDirection
' check if snake is ready for a CHANGE of DIRECTION
' using the 'delay' element of the snake head (snake[1]) as a counter for the change direction delay
' this delay gets decreased in the moveSnake sub
If snake[1]["delay"] = 0 Then
' reset change direction delay
snake[1]["delay"] = level[thisLevel]["dirDelay"]
' yes, time for a direction change, but only 25% chance of changing
If Math.GetRandomNumber(4) <> 3 Then
' not yet - leave the snake going the same way and delay another direction change for a while
snake[1]["delay"] = level[thisLevel]["dirDelay"]
Else
' yep, let's change direction
dir = Math.GetRandomNumber(4)
' EDGE BOUNCE - if snake is heading into window edge, force a direction change
'If (dir = 1 And snake[1]["y"] < 20) Then
' dir = 3 ' go S
'EndIf
'If (dir = 3 And snake[1]["y"] > GraphicsWindow.Height-(20)) Then
' dir = 1 ' go N
'EndIf
'If (dir = 4 And snake[1]["x"] < 20) Then
' dir = 2 ' go E
'EndIf
'If (dir = 2 And snake[1]["x"] > GraphicsWindow.Width-(8+20)) Then
' dir = 4 ' go W
'EndIf
' point snake head in appropriate direction
snake[1]["moves"] = dir
' reset delay until next direction change
snake[1]["delay"] = level[thisLevel]["dirDelay"]
EndIf
' ANGRY SNAKE calculation
' to slow this effect down, we're only trying to instigate 'angry mode' at each direction change
If (level[thisLevel]["getAngry"] = 1) Then
' only try to instigate angry mode in snake is currently happy
If angrySnake < 0 Then
'GraphicsWindow.Title="HAPPY SNAKE {:-)"
rn = Math.GetRandomNumber(100)
If (rn = 7) Then
angrySnake = Math.GetRandomNumber(50)+20
level[thisLevel]["snakeDelay"] = level[thisLevel]["snakeDelay"]/2
EndIf
' if angrySnake counter has reached zero, reset snake speed back to normal
ElseIf angrySnake = 0 Then
level[thisLevel]["snakeDelay"] = level[thisLevel]["snakeDelay"]*2 ' set snake delay back to level setting
EndIf
If angrySnake > -1 Then
angrySnake = angrySnake-1 ' decrease angry snake counter
'GraphicsWindow.Title="ANGRY SNAKE }:-/"
EndIf
EndIf
EndIf ' change direction delay=0
EndSub
' =====================================================================
Sub moveSnake
' move snake segments
For snakePart = 1 To snakeSize
' find out which direction we're moving in
dir = text.GetSubText(snake[snakePart]["moves"], 1, 1)
' check if head is about to collide with a wall
If snakePart = 1 Then
shapes.Rotate(snake[1]["sprite"], ((dir-1)*90) ) ' point snake head in correct direction
snakeCollisions()
EndIf
' only move snakepart if it's delay is zero - or this is the head, which always gets moved
If snakePart = 1 Or snake[snakePart]["delay"] = 0 Then
' take direction off moves list for this snake part
If snakePart > 1 Then
snake[snakePart]["moves"] = Text.GetSubTextToEnd(snake[snakePart]["moves"], 2)
EndIf
' add this movement onto next snake part's movement list
If snakePart < snakeSize Then
snake[snakepart+1]["moves"] = text.Append(snake[snakepart+1]["moves"],dir)
EndIf
' update x,y co-ordinates of snake part
If dir = 1 Then
snake[snakePart]["y"] = snake[snakePart]["y"]-1 ' moving N
ElseIf dir = 2 Then
snake[snakePart]["x"] = snake[snakePart]["x"]+1 ' moving E
ElseIf dir = 3 Then
snake[snakePart]["y"] = snake[snakePart]["y"]+1 ' moving S
ElseIf dir = 4 Then
snake[snakePart]["x"] = snake[snakePart]["x"]-1 ' moving W
EndIf
' wrap snake at window edge
If snake[snakePart]["x"] < gwLeft Then
snake[snakePart]["x"] = gwRight
ElseIf snake[snakePart]["x"] > gwRight Then
snake[snakePart]["x"] = gwLeft
ElseIf snake[snakePart]["y"] < gwTop Then
snake[snakePart]["y"] = gwBottom-8
ElseIf snake[snakePart]["y"] > gwBottom-8 Then
snake[snakePart]["y"] = gwTop
EndIf
EndIf
' The offsets allow for the various snake segment sizes
If snakePart = 1 Then
offset=headOffset
ElseIf snakePart<>snakeSize Then
offset = bodyOffset
Else
offset = tailOffset
EndIf
' DRAW SNAKE PART in new position
shapes.Move(snake[snakePart]["sprite"], snake[snakePart]["x"]-offset, snake[snakePart]["y"]-offset )
' DECREASE SNAKE PART DELAY
If snake[snakePart]["delay"] > 0 Then
snake[snakePart]["delay"] = snake[snakePart]["delay"] - 1
EndIf
EndFor
' as snake gets shorter, processing speed increases, so we need to add a delay
If snakeSize < 7 Then 'level[thisLevel]["snakeSize"] Then
'For snakePart = snakeSize To level[thisLevel]["snakeSize"]
Program.Delay (0.2*(level[thisLevel]["snakeSize"]-snakeSize))
'EndFor
EndIf
EndSub
' =====================================================================
Sub snakeCollisions
' this is a recursive function
' it checks for a snake collision with a level object (i.e. a wall) in the current snake direction
' if it finds one, it chooses a new direction, then calls itself to check it for a collision
' after completing, 'dir' will have a direction that does not cause a collision
' Up
If dir = 1 Then
sx = math.Floor((snake[1]["x"]-gwLeft)/32)+1
sy = math.Floor(((snake[1]["y"]-gwTop)-(headSize/2))/32)+1
If Text.GetSubText( level[thisLevel][sy], sx, 1) = "W" Then
' choose a new direction then check it for collisions by recursing this sub
dir = Math.GetRandomNumber(4)
snakeCollisions()
EndIf
' Down
ElseIf dir = 3 Then
sx = math.Floor((snake[1]["x"]-gwLeft)/32)+1
sy = math.Floor(((snake[1]["y"]-gwTop)+(headSize/2))/32)+1
If Text.GetSubText( level[thisLevel][sy], sx, 1) = "W" Then
' choose a new direction then check it for collisions by recursing this sub
dir = Math.GetRandomNumber(4)
snakeCollisions()
EndIf
' Right
ElseIf dir = 2 Then
sx = math.Floor(((snake[1]["x"]-gwLeft)+(headSize/2))/32)+1
sy = math.Floor((snake[1]["y"]-gwTop)/32)+1
If Text.GetSubText( level[thisLevel][sy], sx, 1) = "W" Then
' choose a new direction then check it for collisions by recursing this sub
dir = Math.GetRandomNumber(4)
snakeCollisions()
EndIf
' Left
ElseIf dir = 4 Then
sx = math.Floor(((snake[1]["x"]-gwLeft)-(headSize/2))/32)+1
sy = math.Floor((snake[1]["y"]-gwTop)/32)+1
If Text.GetSubText( level[thisLevel][sy], sx, 1) = "W" Then
' choose a new direction then check it for collisions by recursing this sub
dir = Math.GetRandomNumber(4)
snakeCollisions()
EndIf
EndIf
' set snake in new safe direction
snake[1]["moves"] = dir
EndSub
' =====================================================================
Sub checkKeys
' indicate if player is to move
keyPress = GraphicsWindow.LastKey
EndSub
' =====================================================================
Sub movePlayer
' depending on the key pressed, move the player in the required direction
' unless we hit the edge of the screen, or a wall
If keyPress <> "" Then ' only process if a key was pressed
move = 0 ' initially prevent any movement
' CHECK LEFT
If keyPress = "Left" Then
px = math.Floor(((player["x"]-13)-gwLeft)/32)+1 ' subtract 13 from x to allow for half sprite width offset
py = math.Floor(((player["y"]-gwTop))/32)+1
' hit edge of screen?
If player["x"]-13 > gwLeft Then
move = 1
EndIf
' hit a wall?
If Text.GetSubText( level[thisLevel][py], px, 1) = "W" Then
move = 0
EndIf
EndIf
' CHECK RIGHT
If keyPress = "Right" Then
px = math.Floor(((player["x"]+13)-gwLeft)/32)+1
py = math.Floor((player["y"]-gwTop)/32)+1
' hit edge of screen?
If player["x"]+13 < gwRight Then
move = 1
EndIf
' hit a wall?
If Text.GetSubText( level[thisLevel][py], px, 1) = "W" Then
move = 0
EndIf
EndIf
' CHECK UP
If keyPress = "Up" Then
px = math.Floor(((player["x"])-gwLeft)/32)+1
py = math.Floor(((player["y"]-13)-gwTop)/32)+1
' hit edge of screen?
If player["y"]-13 > gwTop Then
move = 1
EndIf
' hit a wall?
If Text.GetSubText( level[thisLevel][py], px, 1) = "W" Then
move = 0
EndIf
EndIf
' CHECK DOWN
If keyPress = "Down" Then
px = math.Floor(((player["x"])-gwLeft)/32)+1
py = math.Floor(((player["y"]+13)-gwTop)/32)+1
' hit edge of screen?
If player["y"]+13 < gwBottom Then
move = 1
EndIf
' hit a wall?
If Text.GetSubText( level[thisLevel][py], px, 1) = "W" Then
move = 0
EndIf
EndIf
' ADJUST PLAYER LOCATION and rotate player to point the correct direction
If keyPress = "Left" Then
player["x"] = player["x"] - move
Shapes.Rotate(player["sprite"], 270)
EndIf
If keyPress = "Right" Then
player["x"] = player["x"] + move
Shapes.Rotate(player["sprite"], 90)
EndIf
If keyPress = "Up" Then
player["y"] = player["y"] - move
Shapes.Rotate(player["sprite"], 0)
EndIf
If keyPress = "Down" Then
player["y"] = player["y"] + move
Shapes.Rotate(player["sprite"], 180)
EndIf
' MOVE PLAYER SPRITE
Shapes.Move( player["sprite"], player["x"]-11, player["y"]-11 )
keyPress = ""
EndIf
EndSub
' =====================================================================
Sub playerCollisions
' detect player colliding with various things
' detect player/snake tail collision
If (digestionDelay <= 0) Then
' have no idea why I have to subtract 4 from the tailOffset calculations here!!
If (math.Abs(player["x"] - (snake[snakeSize]["x"]-tailOffset)-4) < 10) And (Math.Abs(player["y"] - (snake[snakeSize]["y"]-tailOffset)-4) < 10) AND snake[snakeSize]["delay"] = 0 Then
digestionDelay = 60 ' don't allow another piece to be eaten for a while
' decrease snake length
snakeSize = snakeSize - 1
shapes.Remove(snake[snakeSize]["sprite"])
snake[snakeSize]["sprite"] = snake[snakeSize+1]["sprite"]
'level[thisLevel]["snakeDelay"] = level[thisLevel]["snakeDelay"] - (2*thisLevel) ' make snake faster each level - now set in level settings, therefore redundant here
Sound.PlayChimes()
score = score + 10 ' increase player score
status() ' update status area
EndIf
Else
digestionDelay = digestionDelay-1 ' just decrease the delay
EndIf
' detect player/snake head collision
If (math.Abs(player["x"] - (snake[1]["x"]-headOffset)) < 16) And (Math.Abs(player["y"] - (snake[1]["y"]-headOffset)) < 16) Then
playerEaten()
EndIf
EndSub
' =====================================================================
Sub playerEaten
' when eaten, animate the player sprite for a while
Sound.PlayBellRing()
lives = lives - 1
status() ' update status area
' set player back to their start location
player["x"] = player["startX"]
player["y"] = player["startY"]
' if player was eaten at player start location, move player to snake start location to prevent continuous death
If (math.Abs(player["x"] - (snake[1]["x"]-headOffset)) < 36) And (Math.Abs(player["y"] - (snake[1]["y"]-headOffset)) < 36) Then
player["x"] = level[thisLevel]["snakeX"]
player["y"] = level[thisLevel]["snakeY"]
EndIf
' you spin me right round baby, right round, like a record....
For x = 1 to 3
For y = 0 To 360
Shapes.Rotate( player["sprite"], y )
Shapes.SetOpacity( player["sprite"], y/2 )
Program.Delay(2)
EndFor
EndFor
If lives > 0 Then
Shapes.Animate( player["sprite"], player["x"]-11, player["y"]-11, 500 )
For lwp = 1 to 1000000
EndFor
EndIf
EndSub
' =====================================================================
Sub addSegment
' NOT USING THIS AT PRESENT - USEFUL IF FOOD IS ADDED FOR SNAKE TO EAT
' this code hasn't been updated since snake was changed from Ellipse shapes to graphic shapes, so needs some work if used!
processing = 1 ' flag that we're working on it!
' increase snake size and delay movement of new tail
snakeSize = snakeSize + 1
snake[snakeSize]["delay"] = snake[snakeSize-1]["delay"]+12
' need to remove old tail due to Small Basic's layering of graphic shapes
Shapes.Remove(snake[snakeSize-1]["sprite"])
' add a new body part
GraphicsWindow.BrushColor = "Chocolate"
snake[snakeSize-1]["sprite"] = Shapes.AddEllipse(bodySize, bodySize)
Shapes.Move(snake[snakeSize-1]["sprite"], snake[snakeSize-1]["x"], snake[snakeSize-1]["y"])
' add new tail
snake[snakeSize]["x"] = snake[snakeSize-1]["x"]
snake[snakeSize]["y"] = snake[snakeSize-1]["y"]
GraphicsWindow.BrushColor = "SandyBrown"
snake[snakeSize]["sprite"] = Shapes.AddEllipse(tailSize, tailSize)
Shapes.Move(snake[snakeSize]["sprite"], snake[snakeSize]["x"], snake[snakeSize]["y"])
EndSub
Sub mUp
' NOT USED AT PRESENT - put here to handle mouse button presses
' used in conjunction with AddSegment subroutine above
processing = 0 ' cancel the mousedown action - have to do this 'cos the 'puter is much faster than our likkle fingers
EndSub
' =====================================================================
Sub status
' show the various game values in status area
GraphicsWindow.BrushColor = "White"
GraphicsWindow.PenColor = "White"
GraphicsWindow.FontSize = 32
GraphicsWindow.DrawText ( 20, 550, "Round: Lives: Score:")
GraphicsWindow.FillRectangle ( 140,555, 80, 32 )
GraphicsWindow.FillRectangle ( 370,555, 80, 32 )
GraphicsWindow.FillRectangle ( 610,555, 160, 32 )
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText ( 170, 550, thisLevel )
GraphicsWindow.DrawText ( 400, 550, lives )
GraphicsWindow.DrawText ( 640, 550, score )
EndSub
' =====================================================================
Sub levelConfig
' configuration settings for each of the levels
'
' to add new levels, simply duplicate the last one below, change it's level number, make a new layout,
' then increase the 'levels' value below. To test your new level without playing all the earlier ones, change
' the 'thisLevel' variable (at the beginning of the program code above).
levels = 5
level[1]["snakeDir"] = Math.GetRandomNumber(4) ' start snake off in a random direction: 1=N, 2=E, 3=S, 4=W
level[1]["snakeSize"] = 12 ' length of snake
level[1]["snakeDelay"]= 700 ' speed of snake (higher = slower)
level[1]["dirDelay"] = 50 ' delay (moves) before snake can change direction (lower = more jittery snake)
level[1]["getAngry"] = 1 ' flag indicating if the snake can switch to angry mode (=1) or not (=0)
' W = wall segment
' S = Snake start location
' P = Player start location
level[0][0]= ".........1.........2...." ' just a ruler
level[1][1]= "W W"
level[1][2]= " "
level[1][3]= " WWWWWWWWWWWWWW "
level[1][4]= " "
level[1][5]= " "
level[1][6]= " S "
level[1][7]= " "
level[1][8]= " "
level[1][9]= " "
level[1][10]= " "
level[1][11]= " "
level[1][12]= " P "
level[1][13]= " "
level[1][14]= " WWWWWWWWWWWWWW "
level[1][15]= " "
level[1][16]= "W W"
level[2]["snakeDir"] = Math.GetRandomNumber(4) ' start snake off in a random direction: 1=N, 2=E, 3=S, 4=W
level[2]["snakeSize"] = 14 ' length of snake
level[2]["snakeDelay"]= 1100 ' speed of snake (higher = slower)
level[2]["dirDelay"] = 50 ' delay (moves) before snake can change direction (lower = more jittery snake
level[2]["getAngry"] = 1 ' flag indicating if the snake can switch to angry mode (=1) or not (=0)
level[0][0]= ".........1.........2...." ' just a ruler
level[2][1]= " "
level[2][2]= " WWWWWWWWWWWWWWWW "
level[2][3]= " W W "
level[2][4]= " W WWWWWWWWWWWWW W "
level[2][5]= " W WW WWW WW W "
level[2][6]= " W WWWWWWWWWWWWW W "
level[2][7]= " W P WW S W "
level[2][8]= " WWWWW W WWWWWW "
level[2][9]= " WW W W "
level[2][10]= " W WWWWWWW W "
level[2][11]= " WWW W WW WW W "
level[2][12]= " W WWWW WWWWWWW W "
level[2][13]= " W W "
level[2][14]= " WWWWWWWWWWWWWWWW "
level[2][15]= " "
level[2][16]= " "
level[3]["snakeDir"] = 1 'Math.GetRandomNumber(4) ' start snake off in a random direction: 1=N, 2=E, 3=S, 4=W
level[3]["snakeSize"] = 16 ' length of snake
level[3]["snakeDelay"]= 600 ' speed of snake (higher = slower)
level[3]["dirDelay"] = 30 ' delay (moves) before snake can change direction (lower = more jittery snake
level[3]["getAngry"] = 1 ' flag indicating if the snake can switch to angry mode (=1) or not (=0)
level[0][0]= ".........1.........2...." ' just a ruler
level[3][1]= " "
level[3][2]= " WWWW WWWW "
level[3][3]= " WW W W WWW "
level[3][4]= " WW W WW "
level[3][5]= " W WWW WWW W "
level[3][6]= " W W W W "
level[3][7]= " WW WWWWW WWWWWW WW "
level[3][8]= " W P W "
level[3][9]= " WW WWWWW WWWWWW WW "
level[3][10]= " W WW W W WW W "
level[3][11]= " W WWWW WWWWW W "
level[3][12]= " WW W W WW "
level[3][13]= " WWWWWWW WWWWWWWW "
level[3][14]= " WSW "
level[3][15]= " W "
level[3][16]= " "
level[4]["snakeDir"] = 3 'Math.GetRandomNumber(4) ' start snake off in a random direction: 1=N, 2=E, 3=S, 4=W
level[4]["snakeSize"] = 18 ' length of snake
level[4]["snakeDelay"]= 500 ' speed of snake (higher = slower)
level[4]["dirDelay"] = 20 ' delay (moves) before snake can change direction (lower = more jittery snake
level[4]["getAngry"] = 0 ' flag indicating if the snake can switch to angry mode (=1) or not (=0)
level[0][0]= ".........1.........2...." ' just a ruler
level[4][1]= " W "
level[4][2]= " WSW "
level[4][3]= " W W "
level[4][4]= " W W "
level[4][5]= " W W "
level[4][6]= " W WW "
level[4][7]= " W WW "
level[4][8]= " W WW "
level[4][9]= " WW W "
level[4][10]= " WW W "
level[4][11]= " WW W "
level[4][12]= " W W "
level[4][13]= " W W "
level[4][14]= " W W "
level[4][15]= " WPW "
level[4][16]= " W "
level[5]["snakeDir"] = 3 'Math.GetRandomNumber(4) ' start snake off in a random direction: 1=N, 2=E, 3=S, 4=W
level[5]["snakeSize"] = 20 ' length of snake
level[5]["snakeDelay"]= 300 ' speed of snake (higher = slower)
level[5]["dirDelay"] = 20 ' delay (moves) before snake can change direction (lower = more jittery snake
level[5]["getAngry"] = 0 ' flag indicating if the snake can switch to angry mode (=1) or not (=0)
level[0][0]= ".........1.........2...." ' just a ruler
level[5][1]= "WW WW"
level[5][2]= "W P W"
level[5][3]= " WWWWWWWWWWWWWW "
level[5][4]= "WWWWWW WWW WW"
level[5][5]= " "
level[5][6]= " WWWWWWWWWWWWWWW "
level[5][7]= "WW WWW WWWWW"
level[5][8]= " "
level[5][9]= "WW WWW WWW WW"
level[5][10]= " WWWWWWWWWWWWWW "
level[5][11]= " "
level[5][12]= "WWWWWW WWW WW"
level[5][13]= " WWWWWWWWWWWWWW "
level[5][14]= " "
level[5][15]= "W WWWWW WWWWW W"
level[5][16]= "WW S WW"
EndSub
' Challenge of the month August 2012 Free throw basketball by NaochanON MMQ961-1
' Throwed ball traced
' Click ball , move(slide) ball and release ball within blue circle
'
GUI()
GraphicsWindow.MouseDown=Onmousedown
GraphicsWindow.MouseMove=Onmousemove
GraphicsWindow.Mouseup=Onmouseup
While "true"
If move="true" Then
Shoot() ' ball is throwed
Goalcheck() ' if ball goals in or not
Goalin() ' ball goes down throgh goal net
EndIf
Program.Delay(20)
endwhile
sub Goalin
If goal="true" Then
Vx=0
newx=RX+(RW-BD)/2 ' ball falling position
Vy=Vy/3 ' ball falling speed
Gravity=Gravity*0.8
If (PY+BD/2)<Shapes.GetTop(BBall) and Shapes.GetTop(BBall)<(PY+BD) Then
For i=1 To 11
Shapes.Rotate(line[i],10) ' goal net swings
EndFor
Program.Delay(50)
EndIf
'
If (PY+BD)<Shapes.GetTop(BBall) then
staynet() ' Net return initial state
Gravity=7
EndIf
endif
EndSub
Sub staynet
For i=1 To 11
Shapes.Rotate(line[i],0) ' goal net stay
EndFor
EndSub
Sub goalcheck
If goal="false" and RX<newx And newx<RX+RW-BD and math.Abs(newY-PY)<BD/2 Then
Shapes.SetText(smsg," Goal !!!!! ")
Shapes.Animate(smsg,1000,150,1500)
goal="true"
MM=MM+1 ' count up goals
resultshow()
EndIf
endsub
Sub resultshow
result=" Click , move(slide) and release ball within blue circle. " +Text.GetCharacter(10)+ " Throwing = "+NN +" times Goal= "+MM+" times"
Shapes.SetText(sresult,result)
EndSub
Sub Shoot
dn=dn+1
Shapes.ShowShape(gball[dn]) ' trace ball
Shapes.Move(gball[dn],newx,newy)
t3=clock.ElapsedMilliseconds
newx=newx-vx*PM
newy=newy-vy +(t3-t2)*(t3-t2)*Gravity/2/1000000
Shapes.Move(BBall,newx,newy)
GraphicsWindow.Title="Now Ball X= "+math.Floor(newx)+ " Y= "+math.Floor(newy)+" Vx = "+math.Floor(Vx) + " Vy = "+math.Floor(Vy)
If (RX-PW<newx and newx<RX+4) And (PY-PH/2-BD/2<newY And newY<PY) Then ' if ball taches the panel
PM=-1
EndIf
If GH-BD-20<newy Then
move="false"
newx=0
newy=0
Shapes.Animate(BBall,x0,y0,4000) ' ball backs initial position
Program.Delay(4000)
Shapes.Move(smsg,-100,-50) ' hide goal message
GraphicsWindow.Title="Now Ball is "+X0+ " : "+Y0
For i=1 To dn
Shapes.HideShape(gball[i])
EndFor
dn=0
EndIf
EndSub
Sub onmousedown
gx= GraphicsWindow.MouseX
gy= GraphicsWindow.MouseY
If math.Abs(gx-x0)<50 And math.Abs(gy-y0)<50 Then
NN=NN+1
PM=1
catch="true"
goal="false"
Gravity=9.8
t1=clock.ElapsedMilliseconds ' ball caught time
resultshow() ' result
staynet() ' Net return initial state
EndIf
endsub
Sub onmousemove
If catch="true" Then
gx1= GraphicsWindow.MouseX
gy1= GraphicsWindow.MouseY
Shapes.Move(BBall,gx1,gy1)
r=Math.SquareRoot((gx1-x0)*(gx1-x0)+ (gy1-y0)*(gy1-y0)) ' distance from initial position
If r>410 Then
onmouseup() ' forced throwing
endif
EndIf
endsub
Sub onmouseup
If catch="true" Then
gx2= GraphicsWindow.MouseX
gy2= GraphicsWindow.MouseY
t2=clock.ElapsedMilliseconds ' Ball release time
catch="false"
Vx=(gx-gx2)/(t2-t1)*10 ' Ball speed X
Vy=(gy-gy2)/(t2-t1)*10 ' Ball speed Y
newx=shapes.GetLeft(BBall)
newy=shapes.Gettop(BBall)
Move="true"
EndIf
endsub
Sub GUI
GraphicsWindow.Show()
GraphicsWindow.Hide()
GraphicsWindow.Top=20
GraphicsWindow.Left=20
'---------------- initial value ----------------------
GW=1200
GH=650
GraphicsWindow.BackgroundColor="Darkgreen"
GraphicsWindow.Width=GW
GraphicsWindow.Height=GH
GraphicsWindow.BrushColor="Lightcyan"
GraphicsWindow.PenColor="Navy"
GraphicsWindow.PenWidth=3
circle= Shapes.AddEllipse(800,800) ' throwing circle
Shapes.Move(circle,GW-400,GH-400)
'---------------- basketball ----------------------
BD=50
GraphicsWindow.BrushColor="lightgray"
GraphicsWindow.penColor="gray"
For i=1 To 300
gball[i]=Shapes.AddEllipse(BD,BD) ' trace ball
Shapes.Move(gball[i],1200,900)
Shapes.HideShape(gball[i])
endfor
GraphicsWindow.BrushColor="Brown"
GraphicsWindow.PenColor="Coral"
X0=GW-BD
Y0=GH-BD
BBall= Shapes.AddEllipse(BD,BD)
Shapes.Move(BBall,X0,Y0)
'---------------- Message ----------------------
GraphicsWindow.BrushColor="Yellow"
GraphicsWindow.FontSize=25
GraphicsWindow.FontItalic="True"
smsg=shapes.AddText(" ")
Shapes.Move(smsg,-100,-50)
result=" Click , move(slide) and release ball within blue circle. " +Text.GetCharacter(10)+ " Throwing = "+NN +" times Goal= "+MM+" times"
sresult=shapes.AddText(result)
Shapes.Move(sresult,200,10)
'---------------- Goal Net ----------------------
GraphicsWindow.BrushColor="Yellow"
PW=20 ' Panel Width
PH=200 ' Panel Height
PY=200 ' Panel position Y
RX=90 ' Ring position X
RW=110 ' Ring width
panel=shapes.AddRectangle(PW,PH)
GraphicsWindow.BrushColor="Darkgreen"
Ring=shapes.AddRectangle(RW,10)
GraphicsWindow.PenColor="lightcyan"
For i=1 To 11
line[i]=Shapes.AddLine(0+10*i,0,30+5*i,100) ' Net
EndFor
setgoal()
GraphicsWindow.Show()
'--------------------------------------
catch="false"
NN=0
MM=0
EndSub
Sub setgoal
Shapes.Move(panel,RX-PW,PY-PH/2)
Shapes.Move(ring,RX,PY)
For i=1 To 11
Shapes.Move(line[i],RX,PY)
EndFor
endsub
Sizin özel yazdığınız Small Basic oyun kodları veya aradığınız farklı şeyler varsa yorum olarak yazabilirsiniz.