Last active
March 25, 2022 19:53
-
-
Save sebnozzi/8ca1301d13f7e7eb6f86949ef6909b94 to your computer and use it in GitHub Desktop.
Demo of wrapped scrolling text for the Mini Micro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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