Skip to content

Instantly share code, notes, and snippets.

@sebnozzi
Last active March 25, 2022 19:53
Show Gist options
  • Save sebnozzi/8ca1301d13f7e7eb6f86949ef6909b94 to your computer and use it in GitHub Desktop.
Save sebnozzi/8ca1301d13f7e7eb6f86949ef6909b94 to your computer and use it in GitHub Desktop.
Demo of wrapped scrolling text for the Mini Micro
import "stringUtil"
// Renders the given text on the given display in the
// given text size ("small"/"normal"/"large") starting
// at x=left, y=top up to a maximum of "maxWidth" pixels,
// wrapping to a next line if necessary
TextRenderer = {}
TextRenderer.display = null
TextRenderer.left = -1
TextRenderer.top = -1
TextRenderer.maxWidth = -1
TextRenderer.text = ""
TextRenderer.textSize = "normal"
TextRenderer.textColor = color.white
TextRenderer.init = function(maxWidth)
self.maxWidth = maxWidth
end function
// These are the dimensions for the built-in fonts
// available in the PixelDisplay
TextRenderer._charDimensions = {}
TextRenderer._charDimensions["small"] = {"height": 14, "width": 8}
TextRenderer._charDimensions["normal"] = {"height": 24, "width": 14}
TextRenderer._charDimensions["large"] = {"height": 32, "width": 20}
TextRenderer.charDimensions = function
return self._charDimensions[self.textSize]
end function
TextRenderer.maxCols = function
dim = self.charDimensions
charWidth = dim["width"]
result = floor(self.maxWidth / charWidth)
return result
end function
TextRenderer.requiredHeight = function
dim = self.charDimensions
charHeight = dim["height"]
lines = self.text.wrap(self.maxCols)
totalHeight = lines.len * charHeight
return totalHeight
end function
TextRenderer.renderImg = function
height = self.requiredHeight
width = self.maxWidth
offDisp = new PixelDisplay
offDisp.clear color.clear,width,height
self.prepareDisplay offDisp
self.renderOnDisplay offDisp,height
img = offDisp.getImage(0,0,width,height)
return img
end function
// Override this in sublclasses
TextRenderer.prepareDisplay = function(disp)
end function
TextRenderer.renderOnDisplay = function(disp,top)
if not disp isa PixelDisplay then
print "The passed argument must be a PixelDisplay"
exit
end if
// Gather char dimensions
dim = self.charDimensions
charHeight = dim["height"]
charWidth = dim["width"]
// Wrap lines
lines = self.text.wrap(self.maxCols)
// Render lines
for idx in lines.indexes
line = lines[idx]
y = top-charHeight*(idx+1)
self.renderLine line,disp,y,self.textColor,self.textSize
end for
end function
TextRenderer.renderLine = function(line,disp,y,textColor,textSize)
disp.print line,0,y,textColor,textSize
end function
// ============================================================
// ViewPort
ViewPort = new Sprite
// Source can be an Image or PixelDisplay
// Target can be a Sprite or a PixelDisplay
// When targetting sprites, the x/y values are ignored
ViewPort.init = function(source,target,width,height,x=0,y=0)
self._width = width
self._height = height
self._source = source
self._target = target
self._x = x
self._y = y
end function
ViewPort.setOffset = function(offsetX,offsetY)
if self._target isa Sprite then
// Get image at offset
img = self._source.getImage(offsetX,offsetY,self._width,self._height)
// Set image to sprite
self._target.image = img
else if self._target isa PixelDisplay then
x = self._x
y = self._y
w = self._width
h = self._height
self._target.drawImage self._source,x,y,w,h,offsetX,offsetY,w,h
else
print "Invalid target type"
exit
end if
end function
// ============================================================
// DEMO part
if locals == globals then
width = 400
height = 300
x = 500
y = 200
clear
textLines = [
"1) Hello how are you? This is a test for text wrapping on the Mini Micro.",
" ",
"This is another paragraph, just to show what is possible.",
" ",
"2) Hello how are you? This is a test for text wrapping on the Mini Micro.",
" ",
"This is another paragraph, just to show what is possible.",
" ",
"3) Hello how are you? This is a test for text wrapping on the Mini Micro.",
" ",
"This is another paragraph, just to show what is possible.",
" ",
"THE END"]
requiredHeight = 0
img = null
generateImg = function
r = new TextRenderer
r.init width
r.text = textLines.join(char(13))
r.textSize = "large"
r.prepareDisplay = function(disp)
//disp.fillRect 0,0,disp.width,disp.height,color.blue
end function
r.renderLine = function(line,disp,y,textColor,textSize)
disp.print line,2,y-2,color.black,textSize
disp.print line,0,y,textColor,textSize
end function
return r.renderImg
end function
img = generateImg
requiredHeight = img.height
spr = display(4)
viewPortSprite = new Sprite
viewPortSprite.x = x + width / 2
viewPortSprite.y = y + height / 2
viewPortSprite.vx = 3
vp = new ViewPort
//vp.init img,gfx,width,height,x,y
vp.init img,viewPortSprite,width,height
spr.sprites.push viewPortSprite
//gfx.drawRect x,y,width,height,color.red,4
updateVpPosition = function
x = viewPortSprite.x
vx = viewPortSprite.vx
viewPortSprite.x = viewPortSprite.x + viewPortSprite.vx
if x > 700 then
viewPortSprite.x = 700
viewPortSprite.vx = -3
else if x < 300 then
viewPortSprite.x = 300
viewPortSprite.vx = 3
end if
end function
drawRandomCircles = function(amount)
for i in range(0,amount)
r = 100 + rnd * 200
x = rnd * (960 + 300) - 300
y = rnd * (640 + 300) - 300
cr = 40 + rnd * 180
cg = 40 + rnd * 180
cb = 40 + rnd * 180
c = color.rgb(cr,cg,cb)
gfx.fillEllipse x,y,r,r,c
end for
end function
drawRandomCircles(200)
counter = 0
while true
for offsetY in range(requiredHeight - height, 0, -2)
counter = counter + 1 % 100
if counter % 10 == 0 then drawRandomCircles 1
vp.setOffset(0,offsetY)
updateVpPosition
yield
end for
for offsetY in range(0, requiredHeight - height, 2)
counter = counter + 1 % 100
if counter % 10 == 0 then drawRandomCircles 1
vp.setOffset(0,offsetY)
updateVpPosition
yield
end for
end while
end if
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment