Sample of this week is Small Basic Tetris, ported by Kenneth Kasajian. In all, the program is just about 530 lines long, and is listed after the screenshot.
GraphicsWindow.KeyDown = HandleKey GraphicsWindow.BackgroundColor = GraphicsWindow.GetColorFromRGB( 253, 252, 251 ) While "True" BOXES = 4 ' number of boxes per piece BWIDTH = 25 ' box width in pixels XOFFSET = 40 ' Screen X offset in pixels of where the board starts YOFFSET = 40 ' Screen Y offset in pixels of where the board starts CWIDTH = 10 ' Canvas Width, in number of boxes CHEIGHT = 20 ' Canvas Height, in number of boxes. STARTDELAY = 800 ENDDELAY = 175 PREVIEW_xpos = 13 PREVIEW_ypos = 2 GraphicsWindow.Clear() GraphicsWindow.Title = "Small Basic Tetris" GraphicsWindow.Height = 580 GraphicsWindow.Width = 700 GraphicsWindow.Show() SetupTemplates() SetupCanvas() MainLoop() GraphicsWindow.ShowMessage( "Game Over", "Small Basic Tetris" ) EndWhile Sub MainLoop template = Text.Append("template", Math.GetRandomNumber(7)) CreatePiece() ' in: template ret: h nextPiece = h end = 0 sessionDelay = STARTDELAY While end = 0 If sessionDelay > ENDDELAY Then sessionDelay = sessionDelay - 1 EndIf delay = sessionDelay thisPiece = nextPiece template = Text.Append("template", Math.GetRandomNumber(7)) CreatePiece() ' in: template ret: h nextPiece = h DrawPreviewPiece() h = thisPiece ypos = 0 done = 0 xpos = 3 ' always drop from column 3 CheckStop() ' in: ypos, xpos, h ret: done If done = 1 Then ypos = ypos - 1 MovePiece() 'in: ypos, xpos, h end = 1 EndIf yposdelta = 0 While done = 0 Or yposdelta > 0 MovePiece() 'in: ypos, xpos, h ' Delay, but break if the delay get set to 0 if the piece gets dropped delayIndex = delay While delayIndex > 0 And delay > 0 Program.Delay(10) delayIndex = delayIndex - 10 EndWhile If yposdelta > 0 Then yposdelta = yposdelta - 1 ' used to create freespin, when the piece is rotated Else ypos = ypos + 1 ' otherwise, move the piece down. EndIf ' Check if the piece should stop. CheckStop() ' in: ypos, xpos, h ret: done EndWhile EndWhile EndSub Sub HandleKey ' Stop game If GraphicsWindow.LastKey = "Escape" Then Program.End() EndIf ' Move piece left If GraphicsWindow.LastKey = "Left" Then moveDirection = -1 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 If invalidMove = 0 Then xpos = xpos + moveDirection EndIf MovePiece() 'in: ypos, xpos, h EndIf ' Move piece right If GraphicsWindow.LastKey = "Right" Then moveDirection = 1 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 If invalidMove = 0 Then xpos = xpos + moveDirection EndIf MovePiece() 'in: ypos, xpos, h EndIf ' Move piece down If GraphicsWindow.LastKey = "Down" or GraphicsWindow.LastKey = "Space" Then delay = 0 EndIf ' Rotate piece If GraphicsWindow.LastKey = "Up" Then basetemplate = Array.GetValue(h, -1) ' Array.GetValue(h, -1) = the template name template = "temptemplate" rotation = "CW" CopyPiece() 'in basetemplate, template, rotation Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template name moveDirection = 0 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 ' See if it can be moved so that it will rotate. xposbk = xpos yposdelta = 0 While yposdelta = 0 And Math.Abs(xposbk - xpos) < 3 ' move up to 3 times only ' if the rotation move worked, copy the temp to "rotatedtemplate" and use that from now on If invalidMove = 0 Then basetemplate = template template = "rotatedtemplate" Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template name rotation = "COPY" CopyPiece() 'in basetemplate, template, rotation yposdelta = 1 ' Don't move down if we rotate MovePiece() 'in: ypos, xpos, h ElseIf invalidMove = 2 Then ' Don't support shifting piece when hitting another piece to the right or left. xpos = 99 ' exit the loop Else ' if the rotated piece can't be placed, move it left or right and try again. xpos = xpos - invalidMove ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 EndIf EndWhile If invalidMove <> 0 Then xpos = xposbk Array.SetValue(h, -1, basetemplate) ' Array.GetValue(h, -1) = the template name template = "" EndIf EndIf EndSub Sub DrawPreviewPiece xpos = PREVIEW_xpos ypos = PREVIEW_ypos h = nextPiece XOFFSETBK = XOFFSET YOFFSETBK = YOFFSET XOFFSET = XOFFSET + Array.GetValue(Array.GetValue(h, -1), "pviewx") ' Array.GetValue(h, -1) = the template name YOFFSET = YOFFSET + Array.GetValue(Array.GetValue(h, -1), "pviewy") ' Array.GetValue(h, -1) = the template name MovePiece() 'in: ypos, xpos, h XOFFSET = XOFFSETBK YOFFSET = YOFFSETBK EndSub ' creates template that's a rotated basetemplate Sub CopyPiece 'in basetemplate, template, rotation L = Array.GetValue(basetemplate, "dim") If rotation = "CW" Then For i = 0 to BOXES - 1 ' x' = y y' = L - 1 - x v = Array.GetValue(basetemplate, i) 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) ' new x and y x = (Math.Remainder(v, 10)) y = (L - 1 - Math.Floor(v/10)) Array.SetValue(template, i, x * 10 + y) EndFor ' Count-Cockwise is not currently used ElseIf rotation = "CCW" Then For i = 0 to BOXES - 1 ' x' = L - 1 - y y' = x v = Array.GetValue(basetemplate, i) 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) ' new x and y x = (L - 1 - Math.Remainder(v, 10)) y = Math.Floor(v/10) Array.SetValue(template, i, x * 10 + y) EndFor ElseIf rotation = "COPY" Then For i = 0 to BOXES - 1 Array.SetValue(template, i, Array.GetValue(basetemplate, i)) EndFor Else GraphicsWindow.ShowMessage("invalid parameter", "Error") Program.End() EndIf ' Copy the remain properties from basetemplate to template. Array.SetValue(template, "color", Array.GetValue(basetemplate, "color")) Array.SetValue(template, "dim", Array.GetValue(basetemplate, "dim")) Array.SetValue(template, "pviewx", Array.GetValue(basetemplate, "pviewx")) Array.SetValue(template, "pviewy", Array.GetValue(basetemplate, "pviewy")) EndSub Sub CreatePiece ' in: template ret: h ' Create a new handle, representing an arrayName, that will represent the piece hcount = hcount + 1 h = Text.Append("piece", hcount) Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template name GraphicsWindow.PenWidth = 1 GraphicsWindow.PenColor = "Black" GraphicsWindow.BrushColor = Array.GetValue(template, "color") For i = 0 to BOXES - 1 s = GraphicsWindow.AddRectangle(BWIDTH, BWIDTH) GraphicsWindow.MoveShape(s, -BWIDTH, -BWIDTH) ' move off screen Array.SetValue(h, i, s) EndFor EndSub Sub MovePiece 'in: ypos, xpos, h. ypos/xpos is 0-19, representing the top/left box coordinate of the piece on the canvas. h returned by CreatePiece For i = 0 to BOXES - 1 v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name x = Math.Floor(v/10) y = Math.Remainder(v, 10) ' Array.GetValue(h, i) = box for piece h. ' xpos/ypos = are topleft of shape. x/y is the box offset within the shape. GraphicsWindow.MoveShape(Array.GetValue(h, i), XOFFSET + xpos * BWIDTH + x * BWIDTH, YOFFSET + ypos * BWIDTH + y * BWIDTH) EndFor EndSub Sub ValidateMove ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 i = 0 invalidMove = 0 While i < BOXES v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x/y is the box offset within the shape. x = Math.Floor(v/10) y = Math.Remainder(v, 10) If (x + xpos + moveDirection) < 0 Then invalidMove = -1 i = BOXES ' force getting out of the loop EndIf If (x + xpos + moveDirection) >= CWIDTH Then invalidMove = 1 i = BOXES ' force getting out of the loop EndIf If Array.GetValue("c", (x + xpos + moveDirection) + (y + ypos) * CWIDTH) <> "." Then invalidMove = 2 i = BOXES ' force getting out of the loop EndIf i = i + 1 EndWhile EndSub Sub CheckStop ' in: ypos, xpos, h ret: done done = 0 i = 0 While i < BOXES v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x/y is the box offset within the shape. x = Math.Floor(v/10) y = Math.Remainder(v, 10) If y + ypos > CHEIGHT Or Array.GetValue("c", (x + xpos) + (y + ypos) * CWIDTH) <> "." Then done = 1 i = BOXES ' force getting out of the loop EndIf i = i + 1 EndWhile ' If we need to stop the piece, move the box handles to the canvas If done = 1 Then For i = 0 to BOXES - 1 v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) Array.SetValue("c", (Math.Floor(v/10) + xpos) + (Math.Remainder(v, 10) + ypos - 1) * CWIDTH, Array.GetValue(h, i)) EndFor ' 1 points for every piece successfully dropped score = score + 1 PrintScore() ' Delete clared lines DeleteLines() EndIf EndSub Sub DeleteLines linesCleared = 0 ' Iterate over each row, starting from the bottom For y = CHEIGHT - 1 to 0 Step -1 ' Check to see if the whole row is filled x = CWIDTH While x = CWIDTH x = 0 While x < CWIDTH piece = Array.GetValue("c", x + y * CWIDTH) If piece = "." then x = CWIDTH EndIf x = x + 1 EndWhile ' if non of them were empty (i.e "."), then remove the line. If x = CWIDTH Then ' Delete the line For x1 = 0 to CWIDTH - 1 GraphicsWindow.RemoveShape(Array.GetValue("c", x1 + y * CWIDTH)) EndFor linesCleared = linesCleared + 1 ' Move everything else down one. For y1 = y To 1 Step -1 For x1 = 0 to CWIDTH - 1 piece = Array.GetValue("c", x1 + (y1 - 1) * CWIDTH) Array.SetValue("c", x1 + y1 * CWIDTH, piece) GraphicsWindow.MoveShape(piece, GraphicsWindow.GetLeftOfShape(piece), GraphicsWindow.GetTopOfShape(piece) + BWIDTH) EndFor EndFor EndIf EndWhile EndFor If linesCleared > 0 Then score = score + 100 * Math.Round(linesCleared * 2.15 - 1) PrintScore() EndIf EndSub Sub SetupCanvas ' GraphicsWindow.DrawResizedImage( Flickr.GetRandomPicture( "bricks" ), 0, 0, GraphicsWindow.Width, GraphicsWindow.Height) GraphicsWindow.BrushColor = GraphicsWindow.BackgroundColor GraphicsWindow.FillRectangle(XOFFSET, YOFFSET, CWIDTH*BWIDTH, CHEIGHT*BWIDTH) Program.Delay(200) GraphicsWindow.PenWidth = 1 GraphicsWindow.PenColor = "Pink" For x = 0 To CWIDTH-1 For y = 0 To CHEIGHT-1 Array.SetValue("c", x + y * CWIDTH, ".") ' "." indicates spot is free GraphicsWindow.DrawRectangle(XOFFSET + x * BWIDTH, YOFFSET + y * BWIDTH, BWIDTH, BWIDTH) EndFor EndFor GraphicsWindow.PenWidth = 4 GraphicsWindow.PenColor = "Black" GraphicsWindow.DrawLine(XOFFSET, YOFFSET, XOFFSET, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH, YOFFSET, XOFFSET + CWIDTH*BWIDTH, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.DrawLine(XOFFSET, YOFFSET + CHEIGHT*BWIDTH, XOFFSET + CWIDTH*BWIDTH, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.PenColor = "Lime" GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET, XOFFSET - 4, YOFFSET + CHEIGHT*BWIDTH + 6) GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET, XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET + CHEIGHT*BWIDTH + 6) GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET + CHEIGHT*BWIDTH + 4, XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET + CHEIGHT*BWIDTH + 4) GraphicsWindow.PenColor = "Black" GraphicsWindow.BrushColor = "Pink" x = XOFFSET + PREVIEW_xpos * BWIDTH - BWIDTH y = YOFFSET + PREVIEW_ypos * BWIDTH - BWIDTH GraphicsWindow.FillRectangle(x, y, BWIDTH * 5, BWIDTH * 6) GraphicsWindow.DrawRectangle(x, y, BWIDTH * 5, BWIDTH * 6) GraphicsWindow.FillRectangle(x - 20, y + 190, 310, 170) GraphicsWindow.DrawRectangle(x - 20, y + 190, 310, 170) GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontItalic = "False" GraphicsWindow.FontName = "Comic Sans MS" GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(x, y + 200, "Game control keys:") GraphicsWindow.DrawText(x + 25, y + 220, "Left Arrow = Move piece left") GraphicsWindow.DrawText(x + 25, y + 240, "Right Arrow = Move piece right") GraphicsWindow.DrawText(x + 25, y + 260, "Up Arrow = Rotate piece") GraphicsWindow.DrawText(x + 25, y + 280, "Down Arrow = Drop piece") GraphicsWindow.DrawText(x, y + 320, "Press to stop game") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontName = "Georgia" GraphicsWindow.FontItalic = "True" GraphicsWindow.FontSize = 36 GraphicsWindow.DrawText(x - 20, y + 400, "Small Basic Tetris") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(x - 20, y + 440, "ver.0.1") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score score = 0 PrintScore() EndSub Sub PrintScore GraphicsWindow.PenWidth = 4 GraphicsWindow.BrushColor = "Pink" GraphicsWindow.FillRectangle(500, 65, 153, 50) GraphicsWindow.BrushColor = "Black" GraphicsWindow.DrawRectangle(500, 65, 153, 50) GraphicsWindow.FontItalic = "False" GraphicsWindow.FontSize = 32 GraphicsWindow.FontName = "Impact" GraphicsWindow.BrushColor = "Black" GraphicsWindow.DrawText(505, 70, Text.Append(Text.GetSubText( "00000000", 0, 8 - Text.GetLength( score ) ), score)) EndSub Sub SetupTemplates ' each piece has 4 boxes. ' the index of each entry within a piece represents the box number (1-4) ' the value of each entry represents to box zero-based box coordinate within the piece: tens place is x, ones place y '_X_ '_X_ '_XX Array.SetValue("template1", 0, 10) Array.SetValue("template1", 1, 11) Array.SetValue("template1", 2, 12) Array.SetValue("template1", 3, 22) Array.SetValue("template1", "color", "Yellow") Array.SetValue("template1", "dim", 3) Array.SetValue("template1", "pviewx", -12) Array.SetValue("template1", "pviewy", 12) '_X_ '_X_ 'XX_ Array.SetValue("template2", 0, 10) Array.SetValue("template2", 1, 11) Array.SetValue("template2", 2, 12) Array.SetValue("template2", 3, 02) Array.SetValue("template2", "color", "Magenta") Array.SetValue("template2", "dim", 3) Array.SetValue("template2", "pviewx", 12) Array.SetValue("template2", "pviewy", 12) '_X_ 'XXX '_ Array.SetValue("template3", 0, 10) Array.SetValue("template3", 1, 01) Array.SetValue("template3", 2, 11) Array.SetValue("template3", 3, 21) Array.SetValue("template3", "color", "Gray") Array.SetValue("template3", "dim", 3) Array.SetValue("template3", "pviewx", 0) Array.SetValue("template3", "pviewy", 25) 'XX_ 'XX_ '_ Array.SetValue("template4", 0, 00) Array.SetValue("template4", 1, 10) Array.SetValue("template4", 2, 01) Array.SetValue("template4", 3, 11) Array.SetValue("template4", "color", "Cyan") Array.SetValue("template4", "dim", 2) Array.SetValue("template4", "pviewx", 12) Array.SetValue("template4", "pviewy", 25) 'XX_ '_XX '_ Array.SetValue("template5", 0, 00) Array.SetValue("template5", 1, 10) Array.SetValue("template5", 2, 11) Array.SetValue("template5", 3, 21) Array.SetValue("template5", "color", "Green") Array.SetValue("template5", "dim", 3) Array.SetValue("template5", "pviewx", 0) Array.SetValue("template5", "pviewy", 25) '_XX 'XX_ '_ Array.SetValue("template6", 0, 10) Array.SetValue("template6", 1, 20) Array.SetValue("template6", 2, 01) Array.SetValue("template6", 3, 11) Array.SetValue("template6", "color", "Blue") Array.SetValue("template6", "dim", 3) Array.SetValue("template6", "pviewx", 0) Array.SetValue("template6", "pviewy", 25) '_X '_X '_X '_X Array.SetValue("template7", 0, 10) Array.SetValue("template7", 1, 11) Array.SetValue("template7", 2, 12) Array.SetValue("template7", 3, 13) Array.SetValue("template7", "color", "Red") Array.SetValue("template7", "dim", 4) Array.SetValue("template7", "pviewx", 0) Array.SetValue("template7", "pviewy", 0) EndSub
Community members around the world have put together blogs and forums in various languages. It's great to see all the energy and enthusiasm around Small Basic. Here's a list of links in languages other than English:
Russian: http://www.smallbasic.ru/Forums: http://forum.smallbasic.ru/ Blog: http://habrahabr.ru/blogs/smallbasic/
Portuguese:Blog: http://smallbasicdicas.blogspot.com/API reference: http://www.smallbasic.com/wiki/documentacao-Api-portugues-br.ashx
Turkish:Blog: http://tr.e-uzman.org/category/yazilim/small-basic
If you know of more resources on the web for Small Basic, please do send me a pointer.
Some technical issues with the previous announcement - the blog ended up not showing on RSS feeds, etc. So, here's another announcement!
As promised, we have a new release of Small Basic! This version contains all the most requested features by the user community. Thanks everyone for the great suggestions and for making Small Basic better and better! Please keep the feedback flowing. We're listening.
For those that are new, Microsoft Small Basic is a project that aims at bringing the fun back to programming and encourages everyone, from kids to adults to take their first step into the wondeful world of programming!
At a high level, this release includes the following updates:
Check out the latest version here!
Check out the latest version here.
Here's a complete list of all the updates
Library API Additions
This week's featured sample is the arcade classic Snake! And it comes from PlayDeez, who has also written other interesting Small Basic games (check out the Small Basic forums for more such hotness.)
Here's the screenshot, followed by the source listing.
Initialize() While (GameState <> "") DoGameLoop() EndWhile Program.End() Sub Initialize InitializeVariables() InitializeScreen() EndSub Sub InitializeVariables Array.SetValue("DeltaX","North",0) Array.SetValue("DeltaX","East",1) Array.SetValue("DeltaX","South",0) Array.SetValue("DeltaX","West",-1) Array.SetValue("DeltaY","North",-1) Array.SetValue("DeltaY","East",0) Array.SetValue("DeltaY","South",1) Array.SetValue("DeltaY","West",0) Array.SetValue("NorthFlag","North",1) Array.SetValue("NorthFlag","East",0) Array.SetValue("NorthFlag","South",0) Array.SetValue("NorthFlag","West",0) Array.SetValue("SouthFlag","North",0) Array.SetValue("SouthFlag","East",0) Array.SetValue("SouthFlag","South",1) Array.SetValue("SouthFlag","West",0) Array.SetValue("EastFlag","North",0) Array.SetValue("EastFlag","East",1) Array.SetValue("EastFlag","South",0) Array.SetValue("EastFlag","West",0) Array.SetValue("WestFlag","North",0) Array.SetValue("WestFlag","East",0) Array.SetValue("WestFlag","South",0) Array.SetValue("WestFlag","West",1) Array.SetValue("DirectionInput","N","North") Array.SetValue("DirectionInput","E","East") Array.SetValue("DirectionInput","S","South") Array.SetValue("DirectionInput","W","West") GameDelay = 100 Score = 0 HighScore = 0 GameState = "TitleScreen" ScreenDirty = 1 CurrentDirectory = Text.GetSubText(File.GetSettingsFilePath(),0,Text.GetLength(File.GetSettingsFilePath())-26) EndSub Sub InitializeScreen GraphicsWindow.Show() GraphicsWindow.Width = 640 GraphicsWindow.Height = 480 'TODO: remove hack when able to do so GraphicsWindow.Width = 640 GraphicsWindow.KeyDown = HandleKeyPress EndSub Sub HandleTitleScreenKeyPress Key = GraphicsWindow.LastKey If (Key = "Escape") Then GameState="" Else If (Key="F2") Then GameState = "Play" ScreenDirty = 1 Else If (Key="F1") Then GameState = "Instructions" ScreenDirty = 1 DoInstructionLoop() EndIf EndIf EndIf EndSub Sub HandleInstructionsKeyPress Key = GraphicsWindow.LastKey If (Key = "Escape") Then GameState = "TitleScreen" ScreenDirty = 1 DoTitleScreenLoop() EndIf EndSub Sub HandlePlayKeyPress Key = GraphicsWindow.LastKey If (Key = "Left") Then DirectionInput = DirectionInput + "W" Else If (Key = "Right") Then DirectionInput = DirectionInput + "E" Else If (Key = "Up") Then DirectionInput = DirectionInput + "N" Else If (Key = "Down") Then DirectionInput = DirectionInput + "S" EndIf EndIf EndIf EndIf EndSub Sub HandleGameOverKeyPress Key = GraphicsWindow.LastKey If (Key = "Escape") Then GameState="" Else If (Key="F2") Then GameState = "Play" ScreenDirty = 1 DoPlayLoop() Else If (Key="F1") Then GameState = "Instructions" ScreenDirty = 1 DoInstructionLoop() EndIf EndIf EndIf EndSub Sub HandleKeyPress If (GameState="TitleScreen") Then HandleTitleScreenKeyPress() Else If (GameState="Instructions") Then HandleInstructionsKeyPress() Else If (GameState="Play") Then HandlePlayKeyPress() Else If (GameState="GameOver") Then HandleGameOverKeyPress() Else EndIf EndIf EndIf EndIf EndSub Sub DoTitleScreenLoop If (ScreenDirty = 1) Then ScreenDirty = 0 GraphicsWindow.Clear() GraphicsWindow.BrushColor = "#000000" GraphicsWindow.FontSize = 32 GraphicsWindow.DrawText(0,0,"SBSnake!") GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(0,64," for instructions") GraphicsWindow.DrawText(0,80," for a new game") GraphicsWindow.DrawText(0,96," to exit") EndIf EndSub Sub DoInstructionLoop If (ScreenDirty = 1) Then ScreenDirty = 0 GraphicsWindow.Clear() GraphicsWindow.BrushColor = "#000000" GraphicsWindow.FontSize = 32 GraphicsWindow.DrawText(0,0,"How To Play SBSnake!") GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(0,64,"Use arrow keyss to move the snake") GraphicsWindow.DrawText(0,80,"Avoid hitting your own tail") GraphicsWindow.DrawText(0,96,"Avoid hitting the wall") GraphicsWindow.DrawText(0,112,"Collect red pellets to accumulate score") GraphicsWindow.DrawText(0,128," to return to main menu") EndIf EndSub Sub AddPellet PickPellet: PelletX = Math.GetRandomNumber(40) PelletY = Math.GetRandomNumber(30) Color = GraphicsWindow.GetPixel(PelletX * 16 + 8, PelletY * 16 + 8) If (Color = "#00FF00" Or Color="#FF0000") Then Goto PickPellet EndIf GraphicsWindow.PenWidth = 0 GraphicsWindow.BrushColor = "#FF0000" GraphicsWindow.FillRectangle(PelletX* 16+3, PelletY * 16+3,10,10) EndSub Sub DrawHead GraphicsWindow.PenWidth = 0 GraphicsWindow.BrushColor = "#00FF00" GraphicsWindow.FillRectangle(SnakeHeadX * 16+2, SnakeHeadY * 16+2,12,12) If (Direction="South") Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16,8,4) EndIf If (Direction="North") Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+12,8,4) EndIf If (Direction="East") Then GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16+4,4,8) EndIf If (Direction="West") Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+12, SnakeHeadY*16+4,4,8) EndIf EndSub Sub EraseHead If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16)="#00FF00") Then NorthFlag = 1 Else NorthFlag = Array.GetValue("NorthFlag",Direction) EndIf If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+15)="#00FF00") Then SouthFlag = 1 Else SouthFlag = Array.GetValue("SouthFlag",Direction) EndIf If (GraphicsWindow.GetPixel(SnakeHeadX*16,SnakeHeadY*16+8)="#00FF00") Then WestFlag = 1 Else WestFlag = Array.GetValue("WestFlag",Direction) EndIf If (GraphicsWindow.GetPixel(SnakeHeadX*16+15,SnakeHeadY*16+8)="#00FF00") Then EastFlag = 1 Else EastFlag = Array.GetValue("EastFlag",Direction) EndIf GraphicsWindow.BrushColor = "#FFFFFF" GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16,16,16) GraphicsWindow.BrushColor = "#00FF00" If (AtePellet = 1) Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+3, SnakeHeadY*16+3,10,10) Else GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+4,8,8) EndIf If (NorthFlag = 1) Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16,8,4) EndIf If (SouthFlag = 1) Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+4, SnakeHeadY*16+12,8,4) EndIf If (WestFlag = 1) Then GraphicsWindow.FillRectangle(SnakeHeadX * 16, SnakeHeadY*16+4,4,8) EndIf If (EastFlag = 1) Then GraphicsWindow.FillRectangle(SnakeHeadX * 16+12, SnakeHeadY*16+4,4,8) EndIf EndSub Sub EraseTail If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16)="#00FF00") Then NorthFlag = 1 Else NorthFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16+15)="#00FF00") Then SouthFlag = 1 Else SouthFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16,SnakeTailY*16+8)="#00FF00") Then WestFlag = 1 Else WestFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16+15,SnakeTailY*16+8)="#00FF00") Then EastFlag = 1 Else EastFlag = 0 EndIf GraphicsWindow.BrushColor = "#FFFFFF" GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16,16,16) If (NorthFlag = 1) Then TailDirection = "North" EndIf If (SouthFlag = 1) Then TailDirection = "South" EndIf If (EastFlag = 1) Then TailDirection = "East" EndIf If (WestFlag = 1) Then TailDirection = "West" EndIf SnakeTailX = SnakeTailX + Array.GetValue("DeltaX",TailDirection) SnakeTailY = SnakeTailY + Array.GetValue("DeltaY",TailDirection) If (GraphicsWindow.GetPixel(SnakeTailX*16+3,SnakeTail*16+3)="#00FF00") Then TailPellet = 1 Else TailPellet = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16)="#00FF00") Then NorthFlag = 1 Else NorthFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16+8,SnakeTailY*16+15)="#00FF00") Then SouthFlag = 1 Else SouthFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16,SnakeTailY*16+8)="#00FF00") Then WestFlag = 1 Else WestFlag = 0 EndIf If (GraphicsWindow.GetPixel(SnakeTailX*16+15,SnakeTailY*16+8)="#00FF00") Then EastFlag = 1 Else EastFlag = 0 EndIf If (TailDirection="North") Then SouthFlag = 0 EndIf If (TailDirection="South") Then NorthFlag = 0 EndIf If (TailDirection="East") Then WestFlag = 0 EndIf If (TailDirection="West") Then EastFlag = 0 EndIf GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16,16,16) GraphicsWindow.BrushColor = "#00FF00" If (TailPellet = 1) Then GraphicsWindow.FillRectangle(SnakeTailX * 16+3, SnakeTailY*16+3,10,10) Else GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16+4,8,8) EndIf If (NorthFlag = 1) Then GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16,8,4) EndIf If (SouthFlag = 1) Then GraphicsWindow.FillRectangle(SnakeTailX * 16+4, SnakeTailY*16+12,8,4) EndIf If (WestFlag = 1) Then GraphicsWindow.FillRectangle(SnakeTailX * 16, SnakeTailY*16+4,4,8) EndIf If (EastFlag = 1) Then GraphicsWindow.FillRectangle(SnakeTailX * 16+12, SnakeTailY*16+4,4,8) EndIf EndSub Sub ProcessDirectionInput If (Text.GetLength(DirectionInput)>0) Then Temp = Text.GetSubText(DirectionInput,0,1) DirectionInput = Text.GetSubText(DirectionInput,1,Text.GetLength(DirectionInput)-1) Direction = Array.GetValue("DirectionInput",Temp) EndIf EndSub Sub StartGame Direction="" DirectionInput="" SnakeLength = 1 SnakeMaximumLength = 4 SnakeHeadX = 20 SnakeHeadY = 15 SnakeTailX = 20 SnakeTailY = 15 AtePellet = 0 Score = 0 GraphicsWindow.Clear() DrawHead() AddPellet() UpdateScore() EndSub Sub UpdateScore GraphicsWindow.Title = "SBSnake - "+Score EndSub Sub DoPlayLoop If (ScreenDirty = 1) Then ScreenDirty = 0 StartGame() Else If (Direction <> "" Or DirectionInput<>"") Then ProcessDirectionInput() EraseHead() SnakeHeadX = SnakeHeadX + Array.GetValue("DeltaX",Direction) SnakeHeadY = SnakeHeadY + Array.GetValue("DeltaY",Direction) If (SnakeHeadX<0 Or SnakeHeadX>39 Or SnakeHeadY < 0 Or SnakeHeadY > 29) Then GameState = "GameOver" ScreenDirty = 1 Else If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+8)="#FF0000") Then Score = Score + 1 UpdateScore() AtePellet = 1 SnakeMaximumLength = SnakeMaximumLength + 2 AddPellet() Else AtePellet = 0 EndIf If (GraphicsWindow.GetPixel(SnakeHeadX*16+8,SnakeHeadY*16+8)="#00FF00") Then GameState = "GameOver" DrawHead() ScreenDirty = 1 Else SnakeLength = SnakeLength + 1 DrawHead() While (SnakeLength>SnakeMaximumLength) EraseTail() SnakeLength = SnakeLength - 1 EndWhile Program.Delay(GameDelay) EndIf EndIf EndIf EndIf EndSub Sub DoGameOverLoop If (ScreenDirty = 1) Then ScreenDirty = 0 GraphicsWindow.BrushColor = "#000000" GraphicsWindow.FontSize = 32 GraphicsWindow.DrawText(0,0,"Game Over!") GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(0,64," for instructions") GraphicsWindow.DrawText(0,80," for a new game") GraphicsWindow.DrawText(0,96," to exit") EndIf EndSub Sub DoGameLoop If (GameState = "TitleScreen") Then DoTitleScreenLoop() Else If (GameState = "Instructions") Then DoInstructionLoop() Else If (GameState = "Play") Then DoPlayLoop() Else If (GameState = "GameOver") Then DoGameOverLoop() EndIf EndIf EndIf EndIf EndSub
Do you want your samples to be featured here? Post them in our forums and we'll pick one each week.