Example Script
Â
The following code uses GPIO buttons 1, 2, 3, 4 for controls. It will work on any BrightSign model that has a video output and a GPIO port.
REM
REM The game of Snake
REM demonstrates BrightScript programming concepts
REM June 22, 2008
REM
REM Every BrightScript program must have a single Main()
REM
Sub Main()
game_board=newGameBoard()
While true
game_board.SetSnake(newSnake(game_board.StartX(), game_board.StartY()))
game_board.Draw()
game_board.EventLoop()
if game_board.GameOver() then ExitWhile
End While
End Sub
REM *******************************************************
REM *******************************************************
REM *************** *********************
REM *************** GAME BOARD OBJECT *********************
REM *************** *********************
REM *******************************************************
REM *******************************************************
REM
REM An example BrightScript constructor. "newGameBoard()" is regular Function of module scope
REM BrightScript Objects are "dynamic" and created at runtime. They have no "class".
REM The object container is a BrightScript Component of type roAssocitiveArray (AA).
REM The AA is used to hold member data and member functions.
REM
Function newGameBoard() As Object
game_board=CreateObject("roAssociativeArray") ' Create a BrightScript Component of type/class roAssociativeArray
game_board.Init=gbInit ' Add an entry to the AA of type roFunction with value gbDraw (a sub defined in this module)
game_board.Draw=gbDraw
game_board.SetSnake=gbSetSnake
game_board.EventLoop=gbEventLoop
game_board.GameOver=gbGameOver
game_board.StartX=gbStartX
game_board.StartY=gbStartY
game_board.Init() ' Call the Init member function (which is gbInit)
return game_board
End Function
REM
REM gbInit() is a member function of the game_board BrightScript Object.
REM When it is called, the "this" pointer "m" is set to the appropriate instance by
REM the BrightScript bytecode interpreter
REM
Function gbInit() As Void
REM
REM button presses go to this message port
REM
m.buttons = CreateObject("roMessagePort")
m.gpio = CreateObject("roGpioControlPort")
m.gpio.SetPort(m.buttons)
REM
REM determine optimal size and position for the snake gameboard
REM
CELLWID=16 ' each cell on game in pixels width
CELLHI=16 ' each cell in pix height
MAXWIDE=30 ' max width (in cells) of game board
MAXHI=30 ' max height (in cells) of game board
vidmode=CreateObject("roVideoMode")
w=cint(vidmode.GetResX()/CELLWID)
if w>MAXWIDE then w = MAXWIDE
h=cint(vidmode.GetResY()/CELLHI)
if h>MAXHI then h=MAXHI
xpix = cint((vidmode.GetResX() - w*CELLWID)/2) ' center game board on screen
ypix = cint((vidmode.GetResY() - h*CELLHI)/2) ' center game board on screen
REM
REM Create Text Field with square char cell size
REM
meta=CreateObject("roAssociativeArray")
meta.AddReplace("CharWidth",CELLWID)
meta.AddReplace("CharHeight",CELLHI)
meta.AddReplace("BackgroundColor",&H202020) 'very dark grey
meta.AddReplace("TextColor",&H00FF00) ' Green
m.text_field=CreateObject("roTextField",xpix,ypix,w,h,meta)
if type(m.text_field)<>"roTextField" then
print "unable to create roTextField 1"
stop
endif
End Function
REM
REM As Object refers to type BrightScript Component
REM m the "this" pointer
REM
Sub gbSetSnake(snake As Object)
m.snake=snake
End Sub
Function gbStartX() As Integer
return cint(m.text_field.GetWidth()/2)
End Function
Function gbStartY() As Integer
return cint(m.text_field.GetHeight()/2)
End Function
Function gbEventLoop() As Void
tick_count=0
while true
msg=wait(250, m.buttons) ' wait for a button, or 250ms (1/4 a second) timeout
if type(msg)="roGpioButton" then
if msg.GetInt()=1 m.snake.TurnNorth()
if msg.GetInt()=2 m.snake.TurnSouth()
if msg.GetInt()=3 m.snake.TurnEast()
if msg.GetInt()=4 m.snake.TurnWest()
else 'here if time out happened, move snake forward
tick_count=tick_count+1
if tick_count=6 then
tick_count=0
if m.snake.MakeLonger(m.text_field) then return
else
if m.snake.MoveForward(m.text_field) then return
endif
endif
end while
End Function
Sub gbDraw()
REM
REM given a roTextField Object in "m.text_field", draw a box around its edge
REM
solid=191 ' use asc("*") if graphics not enabled
m.text_field.Cls()
for w=0 to m.text_field.GetWidth()-1
print #m.text_field,@w,chr(solid);
print #m.text_field,@m.text_field.GetWidth()*(m.text_field.GetHeight()-1)+w,chr(solid);
end for
for h=1 to m.text_field.GetHeight()-2
print #m.text_field,@h*m.text_field.GetWidth(),chr(solid);
print #m.text_field,@h*m.text_field.GetWidth()+m.text_field.GetWidth()-1,chr(solid);
end for
m.snake.Draw(m.text_field)
End Sub
Function gbGameOver() As Boolean
msg$= " G A M E O V E R "
msg0$=" "
width = m.text_field.GetWidth()
height = m.text_field.GetHeight()
while true
print #m.text_field,@width*(height/2-1)+(width-len(msg$))/2,msg$;
sleep(300)
print #m.text_field,@width*(height/2-1)+(width-len(msg$))/2,msg0$;
sleep(150)
REM GetMessage returns the message object, or an int 0 if no message available
If m.buttons.GetMessage() <> invalid Then Return False
endwhile
End Function
REM *******************************************************
REM *******************************************************
REM ****************** ***********************
REM ****************** SNAKE OBJECT ***********************
REM ****************** ***********************
REM *******************************************************
REM *******************************************************
REM
REM construct a new snake BrightScript object
REM
Function newSnake(x As Integer, y As Integer) As Object
' Create AA BrightScript Component; the container for a "BrightScript Object"
snake=CreateObject("roAssociativeArray")
snake.Draw=snkDraw
snake.TurnNorth=snkTurnNorth
snake.TurnSouth=snkTurnSouth
snake.TurnEast=snkTurnEast
snake.TurnWest=snkTurnWest
snake.MoveForward=snkMoveForward
snake.MakeLonger=snkMakeLonger
snake.AddSegment=snkAddSegment
snake.EraseEndBit=snkEraseEndBit
REM
REM a "snake" is a list of line segments
REM a line segment is an roAssociativeArray that conains a length and direction (given by the x,y delta needed to move as it is drawn)
REM
snake.seg_list = CreateObject("roList")
snake.AddSegment(1,0,3)
REM
REM The X,Y pos is the position of the head of the snake
REM
snake.snake_X=x
snake.snake_Y=y
snake.body=191 ' use asc("*") if graphics not enabled.
snake.dx=1 ' default snake direction / move offset
snake.dy=0 ' default snake direction / move offset
return snake
End Function
Sub snkDraw(text_field As Object)
x=m.snake_X
y=m.snake_Y
for each seg in m.seg_list
xdelta=seg.xDelta
ydelta=seg.yDelta
for j=1 to seg.Len
text_field.SetCursorPos(x, y)
text_field.SendByte(m.body)
x=x+xdelta
y=y+ydelta
end for
end for
End Sub
Sub snkEraseEndBit(text_field As Object)
x=m.snake_X
y=m.snake_Y
for each seg in m.seg_list
x=x+seg.Len*seg.xDelta
y=y+seg.Len*seg.yDelta
end for
text_field.SetCursorPos(x, y)
text_field.SendByte(32) ' 32 is ascii space, could use asc(" ")
End Sub
Function snkMoveForward(text_field As Object)As Boolean
m.EraseEndBit(text_field)
tail=m.seg_list.GetTail()
REM
REM the following shows how you can use an AA's member functions to perform the same
REM functions the BrightScript . operator does behind the scenes for you (when used on an AA).
REM there is not point to this longer method other than illustration
REM
len=tail.Lookup("Len") ' same as len = tail.Len (or tail.len, BrightScript syntax is not case sensative)
len = len-1
if len=0 then
m.seg_list.RemoveTail()
else
tail.AddReplace("Len",len) ' same as tail.Len=len
endif
return m.MakeLonger(text_field)
End Function
Function snkMakeLonger(text_field As Object) As Boolean
m.snake_X=m.snake_X+m.dx
m.snake_Y=m.snake_Y+m.dy
text_field.SetCursorPos(m.snake_X, m.snake_Y)
if text_field.GetValue()=m.body then return true
text_field.SendByte(m.body)
head = m.seg_list.GetHead()
head.Len=head.Len+1
return false
End Function
Sub snkAddSegment(dx As Integer, dy As Integer, len as Integer)
aa=CreateObject("roAssociativeArray")
aa.AddReplace("xDelta",-dx) ' line segments draw from head to tail
aa.AddReplace("yDelta",-dy)
aa.AddReplace("Len",len)
m.seg_list.AddHead(aa)
End Sub
Sub snkTurnNorth()
if m.dx<>0 or m.dy<>-1 then m.dx=0:m.dy=-1:m.AddSegment(m.dx, m.dy, 0) 'north
End Sub
Sub snkTurnSouth()
if m.dx<>0 or m.dy<>1 then m.dx=0:m.dy=1:m.AddSegment(m.dx, m.dy, 0) 'south
End Sub
Sub snkTurnEast()
if m.dx<>-1 or m.dy<>0 then m.dx=-1:m.dy=0:m.AddSegment(m.dx, m.dy, 0) 'east
End Sub
Sub snkTurnWest()
if m.dx<>1 or m.dy<>0 then m.dx=1:m.dy=0:m.AddSegment(m.dx, m.dy, 0) 'west
End Sub
Â
Â