Posted: 12th Feb 2023 21:33
Parameters you need to set are delay (time inbetween characters), line spacing (or line height, the distance between lines vertically), and line length (max number of characters per line). SetDialogText will parse a single string down into the appropriate amount of lines, breaking each line at a space when the next word would exceed the maximum line length.


[color=darkgreen]setDialogText(dialog, string)[/colo]
[color=darkgreen]positionDialog(dialog, x, y)[/colo]
[color=darkgreen]teletype(dialog)[/colo] : returns 1 when finished, else 0
[color=darkgreen]resetDialog(dialog)[/colo]


I used a mono spaced font and attached it but here's a link to where I found it.
https://www.1001freefonts.com/overpass-mono.font


Use the mouse to move the sprite (dialog box) around, the text will be set to follow. Press spacebar to start/restart the teletype effect.


+ Code Snippet
// Project: teletype 
// Author:  Phaelax
// Created: 2023-02-12


SetWindowSize( 1024, 768, 0 )
SetVirtualResolution( 1024, 768 ) 
SetSyncRate( 0, 0 ) 

spr_dialog = createSprite(0)
setSpriteSize(spr_dialog, 540, 300)
setSpriteColor(spr_dialog, 0, 0, 200, 255)
setSpritePosition(spr_dialog, 200, 100)

Global DEFAULT_FONT : DEFAULT_FONT = loadfont("OverpassMono-Regular.ttf")


Type Teletype
	id as integer
	s as string
Endtype


Type Dialog
	timestamp 		as integer		: // Used for tracking the teletype animation
	delay 			as integer		: // Delay between characters
	lineIndex 		as integer		: // Current line being typed out
	textIndex 		as integer		: // Text index position of current line
	//max_line_count 	as integer		: // Number of lines of text permitted in dialog
	max_line_length as integer		: // Max length of a single line of text
	text 			as Teletype[]	: // Holds the text objects and parsed strings
	line_spacing 	as integer		: // Space between each line of text
EndType



stuff as Dialog

stuff.delay           = 20
//stuff.max_line_count  = 8
stuff.max_line_length = 55
stuff.line_spacing    = 24


s$ = "The moon orbiting Earth 2 has been destroyed, the cause is not yet known. As a result, Earth Prime is being bombarded by asteroids. Most of our forces busy protecting Earth 2. We need you to get out there and save our homeworld.  Twelve billion lives are in your hands, don’t let us down."


setDialogText(stuff, s$)
positionDialog(stuff, getSpriteX(spr_dialog)+20, getSpriteY(spr_dialog)+30)





finished = 1

repeat
	
	if getRawKeyPressed(32)
		resetDialog(stuff)
		finished = 0
	endif
	
	
	if finished = 0 then finished = teletype(stuff)
    
    
    setSpritePosition(spr_dialog, getRawMouseX(), getRawMouseY())
    positionDialog(stuff, getSpriteX(spr_dialog)+20, getSpriteY(spr_dialog)+30)


    Print("FPS: "+str(floor(ScreenFPS())))
    Sync()
until getRawKeyPressed(27)
end






function teletype(d ref as Dialog)
	if d.lineIndex <= d.text.length
		
		if GetMilliseconds() >= d.timestamp+d.delay
			inc d.textIndex
			
			if d.textIndex > len(d.text[d.lineIndex].s)
				d.textIndex = 1
				inc d.lineIndex
			endif
			
			if d.lineIndex <= d.text.length
				s$ = mid(d.text[d.lineIndex].s, 1, d.textIndex)
				setTextString(d.text[d.lineIndex].id , s$)
			endif	
			
			d.timestamp = GetMilliseconds()
		endif
	else
		exitfunction 1
	endif
endfunction 0




function setDialogText(d ref as Dialog, s as string)
		
	c = CountStringTokens(s, " ")

	temp$ = ""
	newText as Teletype
	lineCount = 0
	
	for i = 1 to c
		token$ = GetStringToken(s, " ", i)
	
		if len(token$) + len(temp$) > d.max_line_length
			newText.s = temp$
			newText.id = createText("")
			setTextSize(newText.id, 22)
			setTextFont(newText.id, DEFAULT_FONT)
			setTextPosition(newText.id, 0, lineCount*d.line_spacing)
			d.text.insert(newText)
			inc lineCount
			temp$ = ""
		endif
		
		temp$ = temp$ + token$ + " "
		
		if i = c
			newText.s = temp$
			newText.id = createText("")
			setTextSize(newText.id, 22)
			setTextFont(newText.id, DEFAULT_FONT)
			setTextPosition(newText.id, 0, lineCount*d.line_spacing)
			d.text.insert(newText)
			inc lineCount
		endif
		
	next i
endfunction lineCount



function positionDialog(d ref as Dialog, x, y)
	for i = 0 to d.text.length
		setTextPosition(d.text[i].id, x, y + i*d.line_spacing)
	next i
endfunction



function resetDialog(d ref as Dialog)
	d.lineIndex = 0
	d.textIndex = 0
	for i = 0 to d.text.length
		setTextString(d.text[i].id, "")
	next i
endfunction

Posted: 12th Feb 2023 22:48
So apparently SetTextMaxWidth is a thing and I could've avoided a lot of unnecessary work...