Simple text scrollers in Monkey X and Monkey2

I coded today simple text scrollers in Monkey X and Monkey2. When the old school bug had bitten me I coded among other things the following:

This night it’s time to just simple text scrollers code.

Let’s take a look at the result of the Monkey X code:

The source code:

Import mojo2
Import brl.databuffer
Import mojo.audio

Function Main()
	New MyApp
End
 
Class MyApp Extends App
	
	Const FONT_HEIGHT:Int = 153
	Const SCROLLTEXT:String = "                      Testing plain text scrolling code... Coded in good old Monkey X Pro...  The picture is from my home, when I was living in Turku, Finland...                       "
 
	field canvas:Canvas
	field fontDat:DataBuffer
	field gfxFont:Image
	field gfxBG:Image
	field chrStartOffset:Int
	field firstChrWidth:Int
	field chrEndOffset:Int
	field x:Float

	
	Method OnCreate()
				
		canvas = New Canvas
		
		gfxBG = Image.Load("bg.jpg",.0,.0)
		gfxFont = Image.Load("font.png")
		fontDat = New DataBuffer(95*4*2) ' 95 characters, for each character two 4 byte integers
		fontDat = DataBuffer.Load("monkey://data/font.dat")
 				
		x = 0
		chrStartOffset = 0
		firstChrWidth = charWidth(0)
		
		SetUpdateRate(15)
	End
	
	Method OnUpdate()
 
		' Scroll the amount of width of the character in the font
		If x < -firstChrWidth Then
			chrStartOffset = chrStartOffset + 1
			
			If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0
			
			firstChrWidth = charWidth(chrStartOffset)
			chrEndOffset = getTextEndOffset()
			
			If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0
			
			x = 0
		Endif
 
		x = x - 2	' scrolling speed
			
	End
	
	Method OnRender()
		canvas.PushMatrix()
'		canvas.Scale(DeviceWidth()/640.0,DeviceHeight()/480.0)
 
 		canvas.SetBlendMode(BlendMode.Alpha)
		canvas.DrawImage(gfxBG,0,0)
 
		canvas.SetBlendMode(BlendMode.Additive)
		
		' draw string to position x
		drawString(x)
		
		canvas.Flush()
		canvas.PopMatrix()	
 
	End
	
	' This function draws text from indexes
	' chrStartOffset to chrEndOffset of the scrolltext string
	Method drawString(x:Int)
		Local xx:float
		Local angle:Int
		Local index:Int
		Local len = SCROLLTEXT.Length()
		Local chrs:Int[]
		chrs = SCROLLTEXT.ToChars()
		Local prevChrWidth:Int
		
		For Local i:Int = chrStartOffset To chrEndOffset
			canvas.DrawRect(x+prevChrWidth, (480 - FONT_HEIGHT) / 2, fontDat.PeekInt((chrs[i]-32)*4*2 + 4), FONT_HEIGHT, gfxFont, fontDat.PeekInt((chrs[i]-32)*4*2), 0, fontDat.PeekInt((chrs[i]-32)*4*2 + 4), FONT_HEIGHT)
			prevChrWidth = prevChrWidth + fontDat.PeekInt((chrs[i]-32)*4*2 + 4)
		Next		

	End
 
	' get character's width in pixels
	Method charWidth:Int(offset:Int)
		Local chrs:Int[]
		chrs = SCROLLTEXT.ToChars()
		Return fontDat.PeekInt((chrs[offset]-32)*4*2 + 4)
	End
	
	Method getTextEndOffset:Int()
		Local chrs:Int[]
		Local c:Int = chrStartOffset
		Local textWidth:Int = 0
		
		chrs = SCROLLTEXT.ToChars()
		
		' Find the endoffset for a character to build a string
		' that's width in pixels is at least 640 + first character's width
		While textWidth < 640 + firstChrWidth
			textWidth = textWidth + charWidth(c)
			c = c + 1

			If c > SCROLLTEXT.Length - 1 Then c = 0
			
		Wend
		
		Return c
		
	End	
End Class

For the font I’ve used my Font 2 PNG and its data file. Notice, that the update rate is only 15, change that to 60.

For the first time I made a text scroller in Monkey2 too. The result is in video below:

As you can see, the code is a little different:

Namespace myapp

#Import "<std>"
#Import "<mojo>"

#Import "gfx/bg.jpg"
#Import "fonts/DoctorJekyllNF.ttf"

Using std..
Using mojo..

Class MyWindow Extends Window

Const SCROLLTEXT:String = "                              Testing simple text scrolling code written in Monkey2...  Later it's time again for old school sine scrollers...                     "

Field bg:Image
Field scrollString:String
Field scrollX:Int
Field chrStartOffset:Int
Field firstChrWidth:Int
Field chrEndOffset:Int
Field font:Font
	
	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )

		Super.New( title,width,height,flags )

		bg = Image.Load("asset::bg.jpg")
		font = Font.Load("asset::DoctorJekyllNF.ttf",80)
		
		scrollX = 0
		chrStartOffset = 0
		firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(0,1))

	End

	Method OnRender( canvas:Canvas ) Override
	
		App.RequestRender()

		canvas.DrawImage(bg,0,0)
		canvas.Font = font
		canvas.Color = Color.Orange
				
		If scrollX < -firstChrWidth Then
			chrStartOffset = chrStartOffset + 1
			
			If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0
			
			firstChrWidth = font.TextWidth(SCROLLTEXT.Mid(chrStartOffset,1))
			chrEndOffset = getTextEndOffset()
			
			If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0
			
			scrollX = 0
		Endif
				
		canvas.DrawText(scrollString,scrollX,200)

		scrollX = scrollX - 2
		
	End

	
	Method getTextEndOffset:Int()
		Local c:Int = chrStartOffset
		Local textWidth:Int = 0
		
		scrollString = ""
		
		' Find the end offset for a character to build a string
		' that's width in pixels is at least 640 + first character's width
		While textWidth < 640 + firstChrWidth
			
			scrollString = scrollString + SCROLLTEXT.Mid(c,1)
			textWidth = textWidth + font.TextWidth(SCROLLTEXT.Mid(c,1))
			c = c + 1
						
			If c > SCROLLTEXT.Length - 1 Then c = 0
			
		Wend
		
		Return c
		
	End	
		
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

In order the get coding going, you may download both the projects with all the data files. Password to download: scroller

Later it’s time to again for sine wave scrollers… 🙂

Have fun!